html,body,#root{width:100%;min-height:100%;margin:0;padding:0}body{min-width:320px;display:block}*{box-sizing:border-box;margin:0;padding:0}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:#f7fafc;color:#2d3748;line-height:1.6}.app-container{min-height:100vh;background:linear-gradient(135deg,#667eea,#764ba2);padding:20px}.container{max-width:1200px;margin:0 auto}.view-switcher{display:flex;justify-content:center;gap:15px;margin-bottom:30px}.view-switcher .btn{padding:12px 24px;font-size:16px;font-weight:600;border-radius:8px;transition:all .2s}.btn{display:inline-block;font-weight:500;text-align:center;vertical-align:middle;-webkit-user-select:none;user-select:none;border:1px solid transparent;padding:8px 16px;font-size:14px;line-height:1.5;border-radius:6px;text-decoration:none;cursor:pointer;transition:all .15s ease-in-out;background-color:transparent}.btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 8px #0000001a}.btn:disabled{opacity:.6;cursor:not-allowed}.btn-primary{color:#fff;background-color:#4299e1;border-color:#4299e1}.btn-primary:hover:not(:disabled){background-color:#3182ce;border-color:#3182ce}.btn-secondary{color:#4a5568;background-color:#e2e8f0;border-color:#e2e8f0}.btn-secondary:hover:not(:disabled){background-color:#cbd5e0;border-color:#cbd5e0}.btn-success{color:#fff;background-color:#48bb78;border-color:#48bb78}.btn-success:hover:not(:disabled){background-color:#38a169;border-color:#38a169}.btn-danger{color:#fff;background-color:#c53030;border-color:#9b2c2c}.btn-danger:hover:not(:disabled){background-color:#9b2c2c;border-color:#7f1d1d}.btn-disabled{background-color:#e2e8f0;color:#a0aec0;border-color:#e2e8f0}.btn-full{width:100%}.card{background:#fff;border-radius:12px;box-shadow:0 4px 6px #00000012;margin-bottom:20px;overflow:hidden;transition:box-shadow .2s}.card:hover{box-shadow:0 8px 15px #0000001a}.card-header{padding:20px 20px 0}.card-header h3,.card-header h4{margin:0;color:#2d3748;font-weight:600}.card-body{padding:20px}.form-group{margin-bottom:20px}.form-group label{display:block;margin-bottom:5px;font-weight:500;color:#4a5568}.form-input,.form-select{width:100%;padding:10px 12px;border:2px solid #e2e8f0;border-radius:6px;font-size:14px;transition:border-color .2s}.form-input:focus,.form-select:focus{outline:none;border-color:#4299e1;box-shadow:0 0 0 1px #4299e1}.form-input::placeholder{color:#a0aec0}.join-game-container{display:flex;justify-content:center;align-items:center;min-height:100vh;padding:20px}.join-game-content{width:100%;max-width:500px}.game-title{text-align:center;color:#fff;font-size:2.5rem;font-weight:700;margin-bottom:30px;text-shadow:2px 2px 4px rgba(0,0,0,.1)}.divider{height:1px;background-color:#e2e8f0;margin:25px 0}.section{margin-bottom:25px}.section h3{margin-bottom:15px;color:#2d3748;font-size:1.2rem;font-weight:600}.join-form{display:flex;gap:10px}.game-id-input{flex:1;text-transform:uppercase}.how-to-play{list-style:none;padding:0}.how-to-play li{padding:8px 0;border-bottom:1px solid #f7fafc}.how-to-play li:before{content:"•";color:#4299e1;font-weight:700;margin-right:10px}.table-view{background:#fff;border-radius:12px;padding:20px;box-shadow:0 4px 6px #00000012}.game-status{display:flex;justify-content:space-between;flex-wrap:wrap;gap:20px;padding:15px;background:#f7fafc;border-radius:8px;margin-bottom:20px}.status-left,.status-right{display:flex;flex-direction:column;gap:5px}.game-id,.phase,.player-count,.position{background:#4299e1;color:#fff;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600}.connection.connected{background:#48bb78;color:#fff;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600}.connection.disconnected{background:#e53e3e;color:#fff;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600}.table-layout{display:grid;grid-template-columns:1fr 2fr 1fr;grid-template-rows:auto 1fr auto;gap:15px;min-height:500px;margin-bottom:20px}.north-position{grid-column:2;grid-row:1;justify-self:center}.west-position{grid-column:1;grid-row:2;align-self:center}.center-position{grid-column:2;grid-row:2;display:flex;align-items:center;justify-content:center}.east-position{grid-column:3;grid-row:2;align-self:center}.south-position{grid-column:2;grid-row:3;justify-self:center}.player-area{background:#f7fafc;border:2px solid #e2e8f0;border-radius:8px;padding:15px;width:200px;text-align:center;transition:all .2s}.player-area.current-turn{border-color:#4299e1;background:#ebf8ff;box-shadow:0 0 10px #4299e14d}.player-name{font-weight:600;margin-bottom:8px}.player-name.waiting{color:#a0aec0;font-style:italic}.bid-badge{background:#4299e1;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;margin-bottom:8px;display:inline-block}.played-card{display:flex;justify-content:center;margin-top:10px}.card-content{background:#fff;border:1px solid #e2e8f0;border-radius:4px;padding:8px;font-size:12px}.table-view-card-wrap{border-radius:10px;background:#fff;overflow:hidden;display:inline-flex;align-items:stretch;justify-content:stretch;box-shadow:0 3px 8px #02081729}.table-view-card-wrap--seat{width:70px;height:103px}.table-view-card-wrap--trick{width:120px;height:176px}.table-view-card{width:100%;height:100%;display:block;pointer-events:none}.center-area{background:#f7fafc;border:2px solid #e2e8f0;border-radius:12px;padding:20px;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:200px;width:100%;height:100%}.center-area h3{margin-bottom:15px;color:#2d3748}.phase-message{font-size:1.2rem;color:#718096;text-align:center}.played-cards{display:grid;grid-template-columns:repeat(2,1fr);gap:15px;width:100%;max-width:560px;justify-items:center}.trick-card{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:6px}.card-position{text-transform:uppercase;font-size:.85rem;letter-spacing:.06em;font-weight:600;color:#475569}.waiting-message{color:#718096;font-style:italic}.scoreboard{background:#fff;border-radius:8px;padding:14px}.scoreboard h3{margin-bottom:10px;text-align:center;color:#2d3748}.teams{display:grid;grid-template-columns:1fr 1fr;gap:12px}.team{border:1px solid #e2e8f0;border-radius:8px;padding:10px}.team h4{margin-bottom:6px;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.team.north-south h4{color:#4299e1}.team.east-west h4{color:#e53e3e}.team-stats{display:flex;flex-direction:column;gap:3px;line-height:1.25}.messages-section{margin-top:20px;padding:15px;border:1px solid #ddd;border-radius:8px;background:#f9f9f9}.messages-section h4{margin:0 0 10px;color:#333}.messages-list{max-height:150px;overflow-y:auto;margin-bottom:10px;border:1px solid #eee;border-radius:4px;background:#fff}.message-item{padding:8px 12px;border-bottom:1px solid #f0f0f0;display:flex;gap:8px;align-items:center}.message-item:last-child{border-bottom:none}.message-from{font-weight:700;color:#06c;min-width:80px}.message-text{flex:1;color:#333}.message-time{font-size:.8em;color:#666;margin-left:auto}.no-messages{padding:20px;text-align:center;color:#666;font-style:italic}.message-input{display:flex;gap:8px}.message-input input{flex:1;padding:8px 12px;border:1px solid #ddd;border-radius:4px;font-size:14px}.message-input button{padding:8px 16px;background:#06c;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:14px}.message-input button:hover{background:#0052a3}.clickable-seat{cursor:pointer;transition:background-color .2s}.clickable-seat:hover{background-color:#0066cc1a}.seat-hint{font-size:.9em;color:#666;font-style:italic}.player-view{max-width:800px;margin:0 auto}.game-info{margin-bottom:20px}.info-grid{display:flex;justify-content:space-between;flex-wrap:wrap;gap:20px;margin-bottom:15px}.info-left,.info-right{display:flex;flex-direction:column;gap:5px}.turn-indicator{padding:10px;border-radius:6px;text-align:center;background:#f7fafc}.turn-indicator.your-turn{background:#c6f6d5;color:#276749}.your-turn-badge{background:#48bb78;color:#fff;padding:2px 8px;border-radius:4px;font-size:12px;margin-left:10px}.position-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:15px}.position-btn{height:80px;display:flex;align-items:center;justify-content:center;flex-direction:column;font-size:16px;font-weight:600}.position-text{display:flex;flex-direction:column;align-items:center;gap:5px}.taken-badge{background:#e53e3e;color:#fff;padding:2px 6px;border-radius:3px;font-size:10px}.bid-form{display:flex;flex-direction:column;gap:20px}.checkbox-container{display:flex;align-items:center}.checkbox-label{display:flex;align-items:center;gap:10px;cursor:pointer;font-weight:500}.checkbox-label input[type=checkbox]{width:18px;height:18px;accent-color:#e53e3e}.nil-bid-text{color:#e53e3e;font-weight:600}.hand-container{display:flex;flex-direction:column;gap:20px}.hand-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(80px,1fr));gap:10px}.playing-card{aspect-ratio:3/4;background:transparent;border:none;border-radius:8px;display:flex;align-items:stretch;justify-content:stretch;overflow:hidden;box-shadow:0 2px 3px #02081729;cursor:default;transition:all .2s;-webkit-user-select:none;user-select:none}.playing-card-svg{width:100%;height:100%;display:block;pointer-events:none}.playing-card.playable{cursor:pointer}.playing-card.playable:hover{transform:translateY(-4px);box-shadow:0 5px 8px #02081733;border-color:#4299e1}.playing-card.selected{background:#4299e11f;border:2px solid #4299e1;box-shadow:0 4px 7px #02081733}.card-rank{font-size:14px;font-weight:700;margin-bottom:5px}.card-suit{font-size:10px;color:#718096}.play-card-btn{margin-top:15px;padding:12px;font-size:16px}.play-warning{margin-bottom:12px;padding:10px 12px;border:1px solid #fed7d7;border-radius:6px;background:#fff5f5;color:#9b2c2c;font-size:13px;font-weight:500}.play-warning-toast{position:fixed;top:16px;left:50%;transform:translate(-50%);width:min(94vw,620px);display:flex;justify-content:center;pointer-events:none;z-index:2000}.play-warning-toast-badge{padding:10px 16px;border-radius:999px;border:1px solid #fecaca;background:#fff5f5f5;color:#991b1b;font-size:13px;font-weight:700;text-align:center;box-shadow:0 10px 24px #0f172a33;animation:play-warning-toast-in .14s ease-out}@keyframes play-warning-toast-in{0%{opacity:0;transform:translateY(-10px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}.bidding-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}.table-feed-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px}.table-feed-meta{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin-bottom:8px}.table-feed-meta-item{display:flex;justify-content:space-between;align-items:center;gap:6px;padding:5px 7px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc;font-size:11px}.table-feed-sections{display:grid;grid-template-columns:1fr;gap:10px;align-items:start}.table-feed-hand-section{border:1px solid #e2e8f0;border-radius:8px;padding:8px;background:#f8fafc;min-width:0;overflow:hidden}.table-feed-hand-container{gap:10px;min-width:0}.table-feed-bid-form{gap:10px}.table-feed-bid-form .form-group{margin-bottom:0}.bid-button-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;padding:4px 0}.bid-tap-btn{padding:10px 4px;border:2px solid #cbd5e1;border-radius:8px;background:#f8fafc;color:#1e293b;font-size:1rem;font-weight:600;cursor:pointer;transition:all .15s ease;min-height:44px}.bid-tap-btn:active{transform:scale(.95)}.bid-tap-selected{background:#3b82f6;color:#fff;border-color:#2563eb;box-shadow:0 0 0 3px #3b82f64d}.bid-tap-nil{grid-column:span 2}.bid-hint{text-align:center;font-size:.85rem;color:#64748b;padding:4px 0 0}.bid-confirm-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:9999}.bid-confirm-modal{background:#fff;border-radius:12px;padding:24px 32px;box-shadow:0 20px 60px #0000004d;text-align:center;min-width:260px;max-width:90vw}.bid-confirm-title{font-size:1.25rem;font-weight:700;color:#1e293b;margin-bottom:20px}.bid-confirm-actions{display:flex;gap:12px;justify-content:center}.bid-confirm-actions .btn{min-width:100px;padding:10px 20px;font-size:1rem}.table-feed-score-section{border:1px solid #e2e8f0;border-radius:8px;padding:6px;background:#f8fafc;display:grid;gap:4px}.table-feed-score-section .book-history-title{margin-bottom:0}.table-feed-player{border:1px solid #e2e8f0;border-radius:6px;padding:6px;background:#f8fafc;display:flex;flex-direction:column;gap:4px}.table-feed-player.current-turn{border-color:#16a34a;background:#f0fdf4;box-shadow:inset 0 0 0 1px #16a34a40}.table-feed-player-head{display:flex;align-items:center;justify-content:space-between;gap:6px;min-width:0}.table-feed-player-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dealer-marker{width:16px;height:16px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;background:#f59e0b;color:#1f2937;font-size:10px;font-weight:800;line-height:1;border:1px solid #d97706;flex:0 0 16px}.table-feed-row{display:flex;justify-content:space-between;align-items:center;gap:6px;font-size:11px;min-height:30px}.table-feed-row .position-name{font-size:12px}.table-feed-card-wrap{width:44px;height:64px;border:1px solid #e2e8f0;border-radius:4px;background:#fff;overflow:hidden;box-shadow:0 3px 8px #02081729;display:inline-flex;align-items:center;justify-content:center}.table-feed-card{width:100%;height:100%;display:block;pointer-events:none}.table-feed-card-placeholder{width:44px;height:64px;border:1px dashed #cbd5e0;border-radius:4px;color:#a0aec0;background:#f7fafc;display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:600}.table-feed-score-section .teams{gap:8px;margin-bottom:4px}.table-feed-score-section .team{padding:7px}.table-feed-score-section .team h4{margin-bottom:4px;font-size:12px}.table-feed-score-section .team-stats{gap:2px;font-size:11.5px;line-height:1.25}.score-compact{display:grid;gap:5px}.score-compact-team{appearance:none;display:grid;grid-template-columns:minmax(0,1fr) auto auto auto;align-items:center;gap:6px;border:1px solid #dbe4f4;border-radius:6px;background:#fff;padding:5px 6px;min-width:0;position:relative;cursor:pointer;width:100%;text-align:left;font:inherit;color:inherit}.score-compact-team.north-south{border-left:3px solid #2563eb}.score-compact-team.east-west{border-left:3px solid #ef4444}.score-compact-team:focus-visible{outline:2px solid #2563eb;outline-offset:-2px;border-radius:6px}.score-compact-name{font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.score-compact-metric{font-size:10.5px;font-weight:700;color:#1f2937;background:#f8fafc;border:1px solid #e2e8f0;border-radius:999px;padding:1px 6px;line-height:1.4}.score-compact-after-books{margin-top:8px}.bid-status{display:flex;justify-content:space-between;align-items:center;padding:8px;background:#f7fafc;border-radius:4px}.position-name{font-weight:600;color:#2d3748}.bid-value.nil{background:#e53e3e;color:#fff;padding:2px 6px;border-radius:3px;font-size:12px;font-weight:600}.bid-value.normal{background:#4299e1;color:#fff;padding:2px 6px;border-radius:3px;font-size:12px;font-weight:600}.book-feed{margin-top:2px;padding-top:4px;border-top:1px solid #e2e8f0}.book-feed-table-wrap{border:1px solid #e2e8f0;border-radius:6px;overflow-x:auto;background:#fff;max-width:100%;min-width:0}.book-feed-table{width:100%;min-width:0;border-collapse:collapse;table-layout:fixed;font-size:11px}.book-feed-table th,.book-feed-table td{border-bottom:1px solid #e2e8f0;padding:3px 4px;vertical-align:middle}.book-feed-table th{background:#f8fafc;color:#334155;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.03em}.book-feed-table tbody tr:last-child td{border-bottom:none}.book-feed-table .book-col-book{width:10%}.book-feed-table .book-col-winner{width:20%}.book-feed-table .book-col-player{width:17.5%}.book-feed-table th:nth-child(1),.book-feed-table td:nth-child(1),.book-feed-table th:nth-child(2),.book-feed-table td:nth-child(2){text-align:left}.book-feed-table .player-col,.book-feed-card-cell{text-align:center}.book-header-name,.book-cell-name{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.book-header-name,.book-cell-name{max-width:100%}.book-header-seat{display:block;margin-top:2px;font-size:10px;color:#64748b;letter-spacing:.04em}.book-feed-table .latest-book-row{background:#f8fffb}.book-feed-card-cell{padding-left:2px;padding-right:2px}.book-feed-card-wrap{width:22px;height:32px;border:1px solid #dbe4f4;border-radius:3px;background:#fff;overflow:hidden;flex:0 0 22px;margin:0 auto}.book-feed-card{width:100%;height:100%;display:block;pointer-events:none}.book-feed-card.face-down{fill:#1e293b}.book-feed-card-wrap.clickable{cursor:pointer;transition:transform .14s ease,border-color .14s ease}.book-feed-card-wrap.clickable:hover{transform:translateY(-1px) scale(1.06);border-color:#5b7db2}.book-card-preview-overlay{position:fixed;inset:0;z-index:2700;background:#0208177a;display:flex;align-items:center;justify-content:center;padding:16px}.book-card-preview-card{width:clamp(120px,26vw,240px);border:none;background:transparent;padding:0;border-radius:8px;cursor:pointer}.book-card-preview-svg{width:100%;height:auto;display:block}.score-audit-overlay{position:fixed;inset:0;z-index:2600;background:#02081785;display:flex;justify-content:center;align-items:flex-start;padding:16px}.score-audit-modal{width:min(940px,100%);max-height:calc(100vh - 32px);background:#fff;border:1px solid #dbe4f4;border-radius:10px;box-shadow:0 14px 34px #0208174d;display:grid;grid-template-rows:auto 1fr;overflow:hidden}.score-audit-header{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:10px 12px;border-bottom:1px solid #e2e8f0;background:#f8fafc}.score-audit-header h4{margin:0;font-size:14px}.score-audit-body{padding:10px 12px;overflow:auto;display:grid;gap:8px}.score-audit-round{border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;padding:8px;display:grid;gap:6px}.score-audit-round-head,.score-audit-line{display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between;font-size:12px}.score-audit-line strong{color:#0f172a}.score-audit-players{border-top:1px solid #e2e8f0;padding-top:6px;display:grid;gap:2px;font-size:11px;color:#334155}.book-feed-empty{color:#718096;font-style:italic;font-size:12px}@media (max-width: 768px){.table-feed-meta{grid-template-columns:repeat(2,minmax(0,1fr))}.table-feed-sections{grid-template-columns:1fr}}.book-history{margin-top:14px;padding-top:12px;border-top:1px solid #d6e5fa}.book-history-title{font-weight:600;margin-bottom:6px}.book-history-grid{display:grid;gap:6px}.book-history-item{display:block}.table-feed-sections>*{min-width:0}.table-feed-score-section,.book-feed{min-width:0}@media (max-width: 900px){.score-compact-team{grid-template-columns:minmax(0,1fr) auto auto auto;gap:4px;padding:4px 5px}.score-compact-name{font-size:10px}.score-compact-metric{font-size:10px;padding:1px 5px}.book-feed-table th,.book-feed-table td{padding:3px}.book-feed-card-wrap{width:20px;height:29px;flex:0 0 20px}}@media (max-width: 640px){.book-feed-table{font-size:11px}.book-feed-table th,.book-feed-table td{padding:4px}.book-header-seat{font-size:9px;margin-top:1px}.book-feed-card-wrap{width:18px;height:26px;flex:0 0 18px}.score-audit-overlay{padding:8px}.score-audit-modal{max-height:calc(100vh - 16px)}.score-audit-header{padding:8px 10px}.score-audit-header h4{font-size:13px}.score-audit-body{padding:8px 10px}}.welcome-message{text-align:center;margin-top:20px}.welcome-message p{color:#718096;font-size:16px}@media (max-width: 768px){.app-container{padding:10px}.game-title{font-size:2rem}.view-switcher{flex-direction:column;align-items:center}.network-status{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:15px;margin-bottom:20px}.network-status h4{margin:0 0 15px;color:#2d3748;font-size:16px;font-weight:600}.network-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px;margin-bottom:15px}.network-item{display:flex;justify-content:space-between;align-items:center;padding:8px;background:#fff;border-radius:4px;border:1px solid #e2e8f0}.network-item strong{color:#4a5568;font-size:12px}.status-badge{padding:2px 8px;border-radius:12px;font-size:11px;font-weight:600;text-transform:uppercase}.status-badge.connected{background:#c6f6d5;color:#276749}.status-badge.connecting{background:#fed7d7;color:#c53030;animation:pulse 1.5s infinite}.status-badge.disconnected{background:#fed7d7;color:#c53030}.status-badge.error{background:#feb2b2;color:#9b2c2c}.role-badge{padding:2px 8px;border-radius:12px;font-size:11px;font-weight:600;background:#e6fffa;color:#234e52}.peer-id{font-family:Courier New,monospace;font-size:11px;background:#edf2f7;padding:2px 6px;border-radius:3px;color:#2d3748}.heartbeat{font-size:11px;color:#718096}.peer-list{margin-top:15px}.peer-list h5{margin:0 0 10px;color:#4a5568;font-size:14px;font-weight:600}.peer-item{display:flex;align-items:center;gap:10px;padding:8px;background:#fff;border:1px solid #e2e8f0;border-radius:4px;margin-bottom:5px}.peer-name{font-weight:600;color:#2d3748}.peer-id{font-size:10px;color:#718096}.peer-latency{font-size:10px;color:#38a169;background:#c6f6d5;padding:2px 6px;border-radius:10px}.error-log{margin-top:15px;background:#fff5f5;border:1px solid #feb2b2;border-radius:4px;padding:10px}.error-log h5{margin:0 0 10px;color:#c53030;font-size:14px;font-weight:600}.error-item{display:flex;align-items:center;gap:10px;margin-bottom:5px;font-size:12px}.error-time{color:#718096;font-family:Courier New,monospace;min-width:80px}.error-message{color:#c53030}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.network-grid{grid-template-columns:1fr}.network-item,.peer-item{flex-direction:column;align-items:flex-start;gap:5px}.view-switcher .btn{width:200px}.table-layout{grid-template-columns:1fr;grid-template-rows:auto auto auto auto auto;gap:10px}.north-position{grid-column:1;grid-row:1}.west-position{grid-column:1;grid-row:2}.center-position{grid-column:1;grid-row:3}.east-position{grid-column:1;grid-row:4}.south-position{grid-column:1;grid-row:5}.player-area{width:100%;max-width:300px;margin:0 auto}.teams{grid-template-columns:1fr}.info-grid{flex-direction:column;gap:10px}.join-form{flex-direction:column}.hand-grid{grid-template-columns:repeat(auto-fit,minmax(60px,1fr));gap:5px}.position-grid{grid-template-columns:1fr}}@media (max-width: 480px){.game-title{font-size:1.5rem}.hand-grid{grid-template-columns:repeat(auto-fit,minmax(50px,1fr));gap:3px}.playing-card{aspect-ratio:2/3}.card-rank{font-size:12px}.card-suit{font-size:8px}}.harness-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:8px;margin:16px 0}.harness-actions{display:flex;gap:10px;flex-wrap:wrap}.harness-actions .btn{text-decoration:none}.harness-list{display:flex;flex-direction:column;gap:8px}.harness-item{display:flex;justify-content:space-between;align-items:center;background:#f7fafc;border:1px solid #e2e8f0;border-radius:6px;padding:10px 12px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:13px}.harness-item.active{border-color:#4299e1}.harness-item.observer{opacity:.65}.harness-item.pass{border-color:#48bb78;background:#f0fff4}.harness-item.pending{border-color:#ed8936;background:#fffaf0}.harness-status{margin-top:14px;display:flex;gap:20px;flex-wrap:wrap}:root{--bg-deep: #0b1220;--bg-mid: #0f1d34;--bg-soft: #132742;--panel: #ffffff;--text-strong: #0f172a;--text-soft: #475569;--brand: #0ea5a4;--brand-strong: #0b7f7e;--accent: #f97316;--ok: #16a34a;--warn: #ea580c;--danger: #dc2626;--surface: #eaf2ff}body{font-family:Plus Jakarta Sans,Avenir Next,Segoe UI,sans-serif;background:radial-gradient(1200px circle at 20% -10%,#1f375a 0%,var(--bg-deep) 55%);color:var(--text-strong)}.app-container{background:transparent;padding:16px}.app-container.player-mode .container{max-width:760px}.app-container.table-mode .container{max-width:1460px}.card{border-radius:16px;border:1px solid #dbe4f4;box-shadow:0 12px 28px #0208171f;color:var(--text-strong)}.card:hover{box-shadow:0 14px 34px #02081724}.btn{border-radius:10px;font-weight:600}.btn-primary{background:linear-gradient(135deg,var(--brand),#14b8a6);border-color:var(--brand)}.btn-primary:hover:not(:disabled){background:linear-gradient(135deg,var(--brand-strong),#0f9a98);border-color:var(--brand-strong)}.btn-success{background:linear-gradient(135deg,var(--accent),#fb923c);border-color:var(--accent)}.btn-success:hover:not(:disabled){background:linear-gradient(135deg,#ea580c,#f97316);border-color:#ea580c}.game-title{color:#f8fafc;letter-spacing:-.04em}.player-view{display:grid;gap:14px;min-width:0;max-width:100%}.player-menu-bar{position:sticky;top:8px;z-index:120;padding:0;border:1px solid #d7e5f8;border-radius:10px;background:#f8fbffeb;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);box-shadow:0 7px 18px #0208171f}.player-menu-strip{display:flex;flex-wrap:wrap;align-items:center;min-width:0;max-width:100%;overflow-x:visible;white-space:normal}.player-menu-item{display:inline-flex;align-items:baseline;gap:8px;padding:9px 12px;border-right:1px solid #d9e7fb}.player-menu-item:last-child{border-right:none}.player-menu-item-turn{background:#f0fdf4}.player-menu-key{font-size:10px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#64748b}.player-menu-value{font-size:12px;font-weight:700;color:#0f172a}.player-menu-value.game-id{background:#dbeafe;color:#1e3a8a;border:1px solid #bfdbfe}.player-menu-value.phase{background:#e0f2fe;color:#0c4a6e;border:1px solid #bae6fd}.player-menu-value.position{background:#dcfce7;color:#166534;border:1px solid #bbf7d0}.player-menu-value.connection.connected{background:#15803d;color:#fff;border:1px solid #166534}.player-menu-value.connection.disconnected{background:#b91c1c;color:#fff;border:1px solid #991b1b}.table-meta-bar{border:1px solid #d7e5f8;border-radius:10px;background:linear-gradient(180deg,#f6fbff,#edf6ff);display:flex;justify-content:space-between;flex-wrap:wrap;align-items:center;gap:10px;padding:0;overflow:hidden}.table-meta-strip{display:flex;flex-wrap:wrap;align-items:center;min-width:0;max-width:100%;overflow-x:visible;white-space:normal}.table-meta-item{display:inline-flex;align-items:baseline;gap:8px;padding:10px 12px;border-right:1px solid #d9e7fb}.table-meta-item:last-child{border-right:none}.table-meta-key{font-size:10px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#64748b}.table-meta-value{font-size:12px;font-weight:700;color:#0f172a}.table-meta-value.game-id{background:#dbeafe;color:#1e3a8a;border:1px solid #bfdbfe}.table-meta-value.phase{background:#e0f2fe;color:#0c4a6e;border:1px solid #bae6fd}.table-meta-value.player-count{background:#f1f5f9;color:#0f172a;border:1px solid #cbd5e1}.table-meta-value.connection.connected{background:#15803d;color:#fff;border:1px solid #166534}.table-meta-value.connection.disconnected{background:#b91c1c;color:#fff;border:1px solid #991b1b}.table-meta-actions{display:flex;gap:8px;align-items:center;padding:8px}.player-toolbar{display:flex;justify-content:flex-end;margin-bottom:10px}.game-info .card-body{background:linear-gradient(180deg,#fff,#f5f9ff)}.card-header h3,.card-header h4,.card-header h5,.card-body,.card-body p,.card-body div,.section h3{color:var(--text-strong)}.form-group label,.welcome-message p,.phase-message{color:var(--text-soft)}.info-grid{align-items:start}.turn-indicator{border:1px solid #dbe7f9;background:#f8fbff}.turn-indicator.your-turn{border-color:#86efac;background:#f0fdf4}.your-turn-badge{background:var(--ok)}.position-grid{gap:12px}.position-btn{height:72px}.playing-card{border-radius:12px;border:none;background:transparent;box-shadow:0 2px 4px #02081726}.playing-card.playable:hover{box-shadow:0 6px 10px #02081733;border-color:var(--brand)}.playing-card.selected{border:2px solid var(--brand);background:#0891b21f;box-shadow:0 4px 8px #02081733}.card-rank{font-size:16px}.card-suit{font-size:11px;text-transform:uppercase;letter-spacing:.04em}.table-view{background:#fffffff7;border-radius:20px;padding:18px;border:1px solid #d5e3f6;box-shadow:0 18px 42px #030c1f40;color:var(--text-strong)}.table-view .game-status{border:1px solid #d6e5fa;background:linear-gradient(180deg,#f6fbff,#edf6ff);border-radius:14px}.table-layout{gap:18px;min-height:560px}.player-area{background:#f6faff;border:2px solid #d4e2f5;border-radius:12px}.player-area.current-turn{border-color:var(--brand);background:#ecfeff}.center-area{background:linear-gradient(180deg,#f8fbff,#eef6ff);border:2px solid #d9e8fb;border-radius:14px}.phase-message{color:#334155}.trick-card .card{border-radius:10px;border:1px solid #d0def2;box-shadow:inset 0 0 0 1px #f2f7ff}.scoreboard{border:1px solid #d7e5f8;border-radius:12px}.team{border-radius:10px}.game-id,.phase,.player-count,.position{background:#0f766e}.connection.connected{background:#15803d}.connection.disconnected{background:#b91c1c}.network-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:10px}.network-item{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px;background:#f8fbff;border:1px solid #d9e7fb;border-radius:8px}.status-badge{padding:2px 8px;border-radius:999px;font-size:11px;font-weight:700;text-transform:uppercase}.status-badge.connected{background:#dcfce7;color:#166534}.status-badge.disconnected{background:#fee2e2;color:#991b1b}.role-badge{padding:2px 8px;border-radius:999px;font-size:11px;font-weight:700;background:#e0f2fe;color:#0c4a6e}.peer-id{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:11px;color:#334155;background:#eef4ff;border:1px solid #d6e3fb;border-radius:6px;padding:1px 6px}.heartbeat{color:#475569;font-size:12px}.player-bottom-menu{margin-top:8px;display:flex;justify-content:center;gap:8px;flex-wrap:wrap}.debug-panel{margin-top:8px}.debug-toggle{width:100%;border:0;background:transparent;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:14px 16px;cursor:pointer;border-bottom:1px solid #e2e8f0}.debug-toggle h4{margin:0}.debug-toggle span{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#475569}.messages-section.compact{margin-top:14px}.messages-section.compact h5{margin:0 0 8px;color:var(--text-strong)}@media (max-width: 768px){.app-container{padding:10px}.table-view{padding:12px}.player-menu-bar{top:6px}.player-menu-item{gap:6px;padding:8px 9px}.player-menu-value{font-size:11px}.table-meta-bar{flex-direction:column;align-items:stretch}.table-meta-strip{min-width:100%}.table-meta-item{padding:8px 10px}.table-meta-actions{padding-top:0}.table-meta-actions .btn,.player-bottom-menu .btn{width:100%}.table-layout{grid-template-columns:1fr;grid-template-rows:auto;min-height:0}.north-position,.west-position,.center-position,.east-position,.south-position{grid-column:auto;grid-row:auto;justify-self:stretch}.player-area{width:100%}.teams{grid-template-columns:1fr}}.app-container.table-mode{padding:8px;min-height:100vh;display:flex;align-items:stretch;justify-content:flex-start}.app-container.table-mode .container{max-width:none;width:100%;min-height:calc(100vh - 16px);height:auto;min-width:0}.app-container.table-mode .table-view{min-height:calc(100vh - 16px);height:auto;width:100%;padding:0;border-radius:0;display:grid;grid-template-rows:auto 1fr auto auto;gap:0;overflow:visible;min-width:0;max-width:100%}.app-container.table-mode .table-layout{display:grid;grid-template-columns:minmax(132px,16vw) minmax(0,1fr) minmax(132px,16vw);grid-template-rows:auto 1fr auto;min-height:0;height:100%;gap:12px;padding:12px;min-width:0;max-width:100%}.app-container.table-mode .center-area{min-height:0;min-width:0}.app-container.table-mode .west-position{justify-self:end;align-self:center}.app-container.table-mode .east-position{justify-self:start;align-self:center}.app-container.table-mode .south-position{justify-self:center;align-self:center}.app-container.table-mode .north-position{align-self:center}.app-container.table-mode .player-area{width:clamp(132px,16vw,250px);padding:clamp(10px,1vw,14px)}.app-container.table-mode .table-view-card-wrap--seat{width:clamp(56px,5.2vw,82px);height:clamp(82px,7.7vw,121px)}.app-container.table-mode .table-view-card-wrap--trick{width:clamp(92px,9vw,140px);height:clamp(135px,13vw,206px)}.app-container.table-mode .played-cards{max-width:none;gap:12px}.app-container.table-mode .scoreboard-container{width:100%;min-height:0;padding:0 12px 12px}.app-container.table-mode .scoreboard{width:100%;margin:0}.app-container.table-mode .debug-panel{min-height:0;overflow:auto;margin:0 12px 12px}.app-container.table-mode .table-meta-bar{border-radius:0;border-left:none;border-right:none;border-top:none}.app-container.player-mode .table-feed-sections{grid-template-columns:1fr}.app-container.player-mode .table-feed-grid{grid-template-columns:repeat(2,minmax(0,1fr))}@media (max-width: 768px){.app-container.table-mode{padding:10px;display:block}.app-container.table-mode .container{height:auto}.app-container.table-mode .table-view{height:auto;min-height:0;overflow:visible;display:block;padding:0;border-radius:0}.app-container.table-mode .table-layout{grid-template-columns:1fr;grid-template-rows:auto;min-height:0;height:auto;padding:10px}.app-container.table-mode .north-position,.app-container.table-mode .west-position,.app-container.table-mode .center-position,.app-container.table-mode .east-position,.app-container.table-mode .south-position{grid-column:auto;grid-row:auto;justify-self:stretch;align-self:stretch}.app-container.table-mode .player-area{width:100%;max-width:none}.app-container.table-mode .scoreboard-container{padding:0 10px 10px}.app-container.table-mode .debug-panel{margin:0 10px 10px}.app-container.table-mode .table-view-card-wrap--trick{width:clamp(82px,26vw,112px);height:clamp(120px,38vw,164px)}.app-container.player-mode .table-feed-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}.app-container.player-mode{padding:10px}.app-container.player-mode .container{max-width:none;width:100%;min-height:calc(100vh - 20px);min-width:0}.app-container.player-mode .player-menu-bar{top:0;border-radius:0;border-top:none;border-left:none;border-right:none}.app-container.player-mode .table-feed-panel-card{border-radius:0;max-width:100%}.app-container.player-mode .table-feed-panel-card .table-feed-score-section,.app-container.player-mode .table-feed-panel-card .table-feed-player,.app-container.player-mode .table-feed-panel-card .table-feed-meta-item{border-radius:0}.app-container.player-mode .player-view{--player-card-width: clamp(56px, 13vw, 92px);display:grid;gap:12px;width:100%;min-width:0;max-width:100%}.app-container.player-mode .player-core-panels{display:grid;grid-template-columns:1fr;grid-auto-rows:auto;gap:10px;min-width:0;max-width:100%}.app-container.player-mode .player-core-panels .card{margin-bottom:0}.app-container.player-mode .hand-grid{grid-template-columns:repeat(auto-fill,minmax(var(--player-card-width),var(--player-card-width)));justify-content:center;gap:clamp(6px,1.2vw,10px);min-width:0}.app-container.player-mode .playing-card{width:var(--player-card-width)}.app-container.player-mode .table-feed-hand-grid{grid-template-columns:repeat(var(--hand-columns, 7),minmax(0,1fr));justify-items:center;width:100%}.app-container.player-mode .table-feed-hand-grid .playing-card{width:min(var(--player-card-width),100%)}@media (min-width: 900px){.app-container.player-mode{padding:14px}.app-container.player-mode .container{min-height:calc(100vh - 28px)}.app-container.player-mode .player-view{--player-card-width: clamp(62px, 7vw, 96px);gap:14px}.app-container.player-mode .player-core-panels{grid-template-columns:1.1fr 1fr}}@media (max-width: 520px){.app-container.player-mode .table-feed-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
