/* ========= Reset / Base ========= */ * { box-sizing: border-box; } html, body { height: 100%; } html { -webkit-text-size-adjust: 100%; } body { margin: 0; font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", sans-serif; /* 背景:深色低調漸層 + 細格紋 */ background: radial-gradient(1200px 800px at 20% -10%, #1a1f2b 0%, rgba(15,17,21,0) 60%), radial-gradient(1000px 700px at 120% 20%, #1b1530 0%, rgba(15,17,21,0) 60%), #0f1115; color: #e8eef5; overflow: hidden; /* 禁止整頁捲動(避免白邊彈出) */ overscroll-behavior: none; /* Android/iOS 避免回彈 */ } body::before { content: ""; position: fixed; inset: 0; pointer-events: none; background: repeating-linear-gradient(to right, rgba(255,255,255,.02) 0 1px, transparent 1px 20px), repeating-linear-gradient(to bottom, rgba(255,255,255,.015) 0 1px, transparent 1px 20px); opacity: .22; z-index: 0; } .app-root { position: relative; z-index: 1; } img { max-width: 100%; display: block; } button { font: inherit; cursor: pointer; } input, button, textarea { color: inherit; background: transparent; border: none; outline: none; } :focus-visible { outline: 2px solid #00ffc6; outline-offset: 2px; } .noscript { position: fixed; inset: 0; display:flex; align-items:center; justify-content:center; background:#111; z-index: 1300; } /* 隱藏 number 的上下箭頭(避免遮擋) */ input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } input[type=number] { -moz-appearance: textfield; } /* ========= Layout ========= */ .app-root { display: grid; grid-template-columns: 1fr; grid-template-rows: auto 1fr; height: 100%; } .topbar { position: relative; display:flex; align-items:center; gap: 12px; padding: 12px 14px; border-bottom: 1px solid rgba(255,255,255,.07); background: linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.02)); backdrop-filter: blur(6px); } .brand { margin: 0; font-size: 18px; font-weight: 800; letter-spacing: .5px; } .topbar-right { margin-left: auto; opacity: .85; } .welcome { font-weight: 600; } .content { height: calc(100% - 1px); overflow: auto; padding: 16px; } .section { display: none; } .section.active { display: block; } h2 { margin: 6px 0 12px; font-size: 18px; } .lead { opacity: .85; } /* ========= Sidebar (覆蓋抽屜) ========= */ .sidebar { position: fixed; top: 0; left: 0; height: 100%; width: 280px; transform: translateX(-100%); transition: transform .2s ease; background: #12131a; border-right: 1px solid rgba(255,255,255,.06); z-index: 1100; display: flex; flex-direction: column; } .sidebar.open { transform: translateX(0); } .sidebar-header { padding: 14px 16px; font-weight: 800; border-bottom: 1px solid rgba(255,255,255,.06); } .nav { display:flex; flex-direction:column; height:100%; } .nav-link { text-align: left; padding: 12px 16px; background: transparent; color: #e8eef5; border-bottom: 1px dashed rgba(255,255,255,.06); } .nav-link:hover { background: rgba(255,255,255,.04); } .nav-link.danger { color: #ff6b81; } .nav-spacer { flex: 1; border-top: 1px solid rgba(255,255,255,.06); } .backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.45); opacity: 0; visibility: hidden; transition: opacity .18s ease, visibility .18s ease; z-index: 1050; } .backdrop.show { opacity: 1; visibility: visible; } /* ========= Hamburger(穩定三條線、不擋選單) ========= */ .hamburger { position: relative; width: 40px; height: 40px; border-radius: 8px; display: inline-block; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.08); overflow: hidden; z-index: 1000; /* 低於側欄(1100),不會蓋住選單 */ } .hamburger .bar { position: absolute; left: 50%; width: 22px; height: 2px; background: #e8eef5; border-radius: 2px; transform: translateX(-50%); transition: transform .18s ease, opacity .18s ease, background-color .18s ease; } .hamburger .bar:nth-child(1) { top: 12px; } .hamburger .bar:nth-child(2) { top: 19px; } .hamburger .bar:nth-child(3) { top: 26px; } /* 側欄開啟:讓漢堡退場,不會「擋到選單」 */ .menu-open .hamburger { opacity: 0; pointer-events: none; } /* ========= Cards / Forms ========= */ .card { background: #151821; border: 1px solid rgba(255,255,255,.06); border-radius: 12px; padding: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.25); } .grid-3 { display: grid; gap: 12px; grid-template-columns: repeat(3, minmax(0, 1fr)); } @media (max-width: 900px){ .grid-3 { grid-template-columns: 1fr; } } .kv { display:flex; align-items:center; justify-content:space-between; padding: 8px 0; border-bottom: 1px dashed rgba(255,255,255,.06); } .kv:last-child { border-bottom: none; } .kv span { opacity:.8; } .info-row { display: grid; gap: 12px; grid-template-columns: 1fr; } .info-card { background:#151821; border:1px solid rgba(255,255,255,.06); border-radius:12px; padding:12px; } .info-title { font-weight:700; margin-bottom:6px; } .hint { font-size: 12px; opacity: .7; } .form-grid { display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); } .form-grid.slim label { display:flex; flex-direction:column; gap:6px; } @media (max-width: 680px){ .form-grid { grid-template-columns: 1fr; } } .form-row { display:flex; align-items:flex-end; gap: 12px; flex-wrap: wrap; } .form-row.compact label { display:flex; flex-direction:column; gap:6px; } input[type="text"], input[type="password"], input[type="number"], textarea { width: 100%; padding: 10px 12px; border-radius: 10px; background: #0f1218; border: 1px solid rgba(255,255,255,.08); transition: border-color .12s ease, box-shadow .12s ease; } input:disabled, textarea:disabled { opacity:.55; } .input-short { width: 140px; } .btn-row { display:flex; gap: 10px; align-items:center; flex-wrap: wrap; margin-top: 10px; } .btn-row.end { justify-content: flex-end; } .btn { padding: 10px 14px; border-radius: 10px; border: 1px solid rgba(255,255,255,.08); background: rgba(255,255,255,.06); color: #e8eef5; font-weight: 700; } .btn.primary { background: linear-gradient(90deg,#00ffc6 0%, #ff00e6 100%); color:#14161c; border: none; } .btn.danger { background: #2a1218; border-color: rgba(255,99,121,.35); color: #ff6b81; } /* Switch */ .switch { position: relative; display:inline-block; width: 44px; height: 24px; margin: 0 6px; } .switch input { opacity: 0; width: 0; height: 0; } .slider { position:absolute; inset:0; background:#3a3f4b; border-radius:999px; transition: all .16s ease; } .slider::before { content:""; position:absolute; left:4px; top:4px; width:16px; height:16px; background:#cfd6e4; border-radius:50%; transition: transform .16s ease; } .switch input:checked + .slider { background:#00d08a; } .switch input:checked + .slider::before { transform: translateX(20px); } .switch-group { display:flex; align-items:center; gap:8px; } .switch-text { opacity:.85; } /* 邏輯模組 */ .logic-block .block-head { display:flex; align-items:center; justify-content:space-between; gap: 10px; margin-bottom: 8px; } .logic-block .title { font-weight:800; display:flex; flex-direction:column; } .logic-block .muted { font-size:12px; opacity:.7; } /* 自製下拉 */ .select { position: relative; width: 120px; } .select-btn { width: 100%; padding: 10px 12px; border-radius: 10px; background:#0f1218; border: 1px solid rgba(255,255,255,.08); } .select-list { position: absolute; left: 0; right: 0; top: calc(100% + 6px); margin: 0; padding: 6px; list-style: none; background: #0f1218; border: 1px solid rgba(255,255,255,.12); border-radius: 10px; display: none; z-index: 900; } .select.open .select-list { display: block; } .select-list li { padding: 8px 10px; border-radius: 8px; } .select-list li:hover { background: rgba(255,255,255,.06); } /* ========= Game ========= */ .status { display:flex; align-items:center; gap:8px; } .status-label { opacity:.8; } .status-text { font-weight: 800; } .led { display:inline-block; width:12px; height:12px; border-radius:50%; margin-left:6px; } .led-red { background:#ff4d6d; } .led-green { background:#00d08a; } .led-yellow { background:#ffd166; } .game-log-card { padding: 0; } .log-head { padding: 10px 12px; font-weight: 700; border-bottom: 1px solid rgba(255,255,255,.08); } .game-log { max-height: 42vh; overflow: auto; padding: 6px 8px; } .game-log-entry { display: grid; grid-template-columns: auto auto 1fr auto; gap: 8px 10px; align-items: center; padding: 8px 10px; border-radius: 10px; margin: 6px 2px; line-height: 1.35; word-break: break-word; } .game-log-entry .idx { font-variant-numeric: tabular-nums; opacity: .85; } .game-log-entry .time { font-variant-numeric: tabular-nums; opacity: .8; } .game-log-entry .wl { font-weight: 700; letter-spacing: .5px; } .game-log-entry .profit { font-variant-numeric: tabular-nums; font-weight: 700; } .game-log-entry.win { background: rgba(0, 185, 110, .12); box-shadow: inset 4px 0 0 0 rgba(0, 185, 110, .9); } .game-log-entry.lose { background: rgba(220, 20, 60, .12); box-shadow: inset 4px 0 0 0 rgba(220, 20, 60, .9); } .game-log-entry.even { background: rgba(180, 190, 200, .12); box-shadow: inset 4px 0 0 0 rgba(180, 190, 200, .9); } .game-log-entry.win .wl, .game-log-entry.win .profit { color: #00d08a; } .game-log-entry.lose .wl, .game-log-entry.lose .profit { color: #ff4d6d; } .game-log-entry.even .wl, .game-log-entry.even .profit { color: #b8c2cc; } @media (max-width: 480px) { .game-log-entry { grid-template-columns: auto 1fr auto; } .game-log-entry .time { grid-column: 2 / span 2; } } /* ========= Modal(單一版,含開/關動畫) ========= */ .modal { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,.45); backdrop-filter: saturate(140%) blur(2px); z-index: 1200; /* 高於側欄(1100)與背板(1050) */ opacity: 0; visibility: hidden; transition: opacity .18s ease, visibility .18s ease; } .modal.open { opacity: 1; visibility: visible; } .modal.closing { opacity: 0; visibility: hidden; } .modal-box { width: min(92vw, 520px); background: #12121a; color: #fff; border-radius: 14px; box-shadow: 0 20px 60px rgba(0,0,0,.45), inset 0 0 0 1px rgba(255,255,255,.06); padding: 16px 16px 12px 16px; transform: scale(.98); opacity: 0; transition: transform .2s cubic-bezier(.2,.8,.2,1), opacity .2s ease; } .modal.open .modal-box { transform: scale(1); opacity: 1; } .modal.closing .modal-box { transform: scale(.98); opacity: 0; } .modal-title { margin: 6px 4px 10px; font-size: 18px; font-weight: 700; } .modal-body { padding: 0 4px 8px; color: #cdd2d9; line-height: 1.6; } .modal-actions { display: flex; gap: 10px; justify-content: flex-end; padding: 6px 4px 4px; } /* ========= Toast ========= */ .toast-host { position: fixed; right: 16px; bottom: 16px; z-index: 1150; display: flex; flex-direction: column; gap: 8px; } .toast { display:flex; align-items:center; gap:10px; padding: 10px 12px; border-radius: 12px; background: #151821; border: 1px solid rgba(255,255,255,.08); box-shadow: 0 10px 30px rgba(0,0,0,.25); transform: translateY(6px); opacity: 1; } .toast .dot { width: 10px; height: 10px; border-radius: 50%; display:inline-block; } .toast-success .dot { background: #00d08a; } .toast-error .dot { background: #ff4d6d; } .toast-warn .dot { background: #ffd166; }