{"id":1018,"date":"2025-09-16T06:02:13","date_gmt":"2025-09-16T06:02:13","guid":{"rendered":"https:\/\/badminton.ghancaballes.com\/skilled\/?page_id=1018"},"modified":"2025-09-16T06:04:09","modified_gmt":"2025-09-16T06:04:09","slug":"bs","status":"publish","type":"page","link":"https:\/\/badminton.ghancaballes.com\/skilled\/","title":{"rendered":"New Badminton Shuffler"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1018\" class=\"elementor elementor-1018\" data-elementor-post-type=\"page\">\n\t\t\t\t<div data-marvy_enable_drop_animation=\"false\" data-marvy_enable_fancy_rotate=\"false\" data-marvy_enable_flying_object=\"false\" data-marvy_enable_ripples_animation=\"false\" data-marvy_enable_waves_animation=\"false\" data-marvy_enable_rings_animation=\"false\" data-marvy_enable_topology_animation=\"false\" data-marvy_enable_gradient_animation=\"false\" data-marvy_enable_snow_animation=\"false\" data-marvy_enable_firework_animation=\"false\" data-marvy_enable_cloud_animation=\"false\" class=\"elementor-element elementor-element-ce4f76e e-flex e-con-boxed e-con e-parent\" data-id=\"ce4f76e\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-33f6e53 elementor-widget elementor-widget-shortcode\" data-id=\"33f6e53\" data-element_type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\">\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Roboto:wght@400;500;700&display=swap\" rel=\"stylesheet\">\n\n    <style>\n        \/* Matrix-inspired minimal tokens *\/\n        :root {\n            --mx-bg: #050706;\n            --mx-surface: #0a0f0c;\n            --mx-surface-variant: #0e1511;\n            --mx-text: #c7f9cc;\n            --mx-text-dim: #78c27c;\n            --mx-accent: #00ff66;\n            --mx-accent-2: #00cc55;\n            --mx-border: #11351f;\n            --mx-error: #ff3b3b;\n\n            --bds-primary: var(--mx-accent);\n            --bds-primary-dark: var(--mx-accent-2);\n            --bds-secondary: #00b85b;\n            --bds-danger: var(--mx-error);\n            --bds-warning: #ffd166;\n            --bds-info: #4cc9f0;\n\n            --bds-light-gray: var(--mx-surface-variant);\n            --bds-medium-gray: #183024;\n            --bds-dark-gray: #2a4a37;\n            --bds-text: var(--mx-text);\n            --bds-text-light: var(--mx-text-dim);\n            --bds-bg: var(--mx-bg);\n            --bds-card-bg: var(--mx-surface);\n            --bds-border: var(--mx-border);\n            --bds-input-bg: #060c09;\n\n            --bds-radius: 4px;\n            --bds-shadow: none;\n            --bds-shadow-lg: none;\n        }\n\n        \/* Light view (inverted) *\/\n        #bds-app-wrapper.dark-mode {\n            --bds-bg: #f7faf8;\n            --bds-card-bg: #ffffff;\n            --bds-text: #0b1d12;\n            --bds-text-light: #365044;\n            --bds-border: #cfded5;\n            --bds-input-bg: #ffffff;\n            --bds-light-gray: #eef4f1;\n            --bds-medium-gray: #d6e2db;\n\n            --bds-primary: #0a8f4a;\n            --bds-primary-dark: #086f39;\n            --bds-secondary: #12a05a;\n            --bds-info: #2a9df4;\n            --bds-warning: #e0a800;\n        }\n\n\/* Light theme readability fixes *\/\n#bds-app-wrapper.dark-mode .player-tag {\n    background-color: #eef4f1;\n    color: #0b1d12;\n    border-color: #cfded5;\n}\n#bds-app-wrapper.dark-mode .player-skill {\n    background: #e6f3ec;\n    color: #0b1d12;\n    border-color: #cfded5;\n}\n#bds-app-wrapper.dark-mode .player-box {\n    color: #0b1d12;\n    border-color: #cfded5;\n}\n\n        #bds-app-wrapper {\n            font-family: \"JetBrains Mono\", \"Fira Code\", \"Courier New\", monospace !important;\n            line-height: 1.35;\n            font-size: 13px;\n            text-align: left;\n            background-color: var(--bds-bg);\n            color: var(--bds-text);\n            touch-action: manipulation;\n            -webkit-text-size-adjust: 100%;\n        }\n        #bds-app-wrapper *, #bds-app-wrapper *::before, #bds-app-wrapper *::after { box-sizing: border-box; }\n\n        #bds-app-wrapper .app-container { max-width: 600px; margin: 0 auto; padding: 0.7rem 0.6rem 5rem 0.6rem; }\n        #bds-app-wrapper h1, #bds-app-wrapper h3, #bds-app-wrapper h4, #bds-app-wrapper h5 { font-weight: 600; line-height: 1.15; margin: 0 0 0.4rem 0; color: var(--bds-text); }\n        #bds-app-wrapper h1 { font-size: 1.05rem; display: flex; align-items: center; gap: 0.4rem; }\n        #bds-app-wrapper h3 { font-size: 0.95rem; }\n        #bds-app-wrapper h4 { font-size: 0.85rem; border-bottom: 1px solid var(--bds-border); padding-bottom: 0.3rem; margin-bottom: 0.4rem; }\n        #bds-app-wrapper h5 { font-size: 0.75rem; margin-top: 0.7rem; color: var(--bds-text-light); text-transform: uppercase; letter-spacing: 1px; }\n        #bds-app-wrapper p { margin: 0 0 0.4rem 0; color: var(--bds-text-light); }\n\n        #bds-app-wrapper button, #bds-app-wrapper input, #bds-app-wrapper textarea, #bds-app-wrapper select {\n            font-family: inherit !important;\n            font-size: 0.85rem;\n            line-height: 1.25;\n            margin: 0;\n            transition: none;\n        }\n\n        #bds-app-wrapper textarea,\n        #bds-app-wrapper input,\n        #bds-app-wrapper select {\n            width: 100%;\n            padding: 6px 8px;\n            margin-bottom: 0.4rem;\n            border: 1px solid var(--bds-border);\n            border-radius: var(--bds-radius);\n            background-color: var(--bds-input-bg);\n            color: var(--bds-text);\n        }\n        #bds-app-wrapper textarea:focus,\n        #bds-app-wrapper input:focus,\n        #bds-app-wrapper select:focus {\n            border-color: var(--bds-primary);\n            outline: none;\n            box-shadow: none;\n        }\n        #bds-app-wrapper input[type=\"number\"] { text-align: center; font-weight: 600; font-size: 0.9rem; }\n\n        #bds-app-wrapper button {\n            display: inline-flex;\n            align-items: center;\n            justify-content: center;\n            gap: 0.35rem;\n            min-height: 30px;\n            padding: 5px 8px;\n            font-weight: 600;\n            border: 1px solid var(--bds-primary);\n            border-radius: var(--bds-radius);\n            cursor: pointer;\n            color: #021a0c;\n            background-color: var(--bds-primary);\n            box-shadow: none;\n        }\n        #bds-app-wrapper button:hover:not(:disabled) {\n            background-color: var(--bds-primary-dark);\n        }\n        #bds-app-wrapper button:disabled {\n            background-color: var(--bds-medium-gray);\n            border-color: var(--bds-medium-gray);\n            cursor: not-allowed;\n        }\n        #bds-app-wrapper button.btn-secondary { background-color: var(--bds-secondary); border-color: var(--bds-secondary); color: #021a0c; }\n        #bds-app-wrapper button.btn-danger { background-color: #ff3b3b; border-color: #ff3b3b; color: #fff; }\n        #bds-app-wrapper button.btn-info { background-color: var(--bds-info); border-color: var(--bds-info); color: #021a0c; }\n        #bds-app-wrapper button.btn-warning { background-color: var(--bds-warning); border-color: var(--bds-warning); color: #1c1c1c; }\n        #bds-app-wrapper button.btn-toggle { background-color: transparent; color: var(--bds-text); border: 1px solid var(--bds-border); }\n\n        #bds-app-wrapper header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.6rem; }\n        #bds-app-wrapper .bds-app-title { display: flex; align-items: center; gap: 0.4rem; flex-grow: 1; }\n        #bds-app-wrapper .bds-logo { height: 24px; width: auto; border-radius: 2px; }\n        #bds-app-wrapper .bds-app-title h1 { margin: 0; }\n        #bds-app-wrapper .version-tag {\n            font-size: 0.6rem; font-weight: 600;\n            color: var(--bds-text-light);\n            background-color: var(--bds-light-gray);\n            padding: 1px 5px; border-radius: 2px;\n            margin-left: 0.4rem;\n        }\n\n        .bds-card {\n            background: var(--bds-card-bg);\n            padding: 0.6rem;\n            border-radius: var(--bds-radius);\n            border: 1px solid var(--bds-border);\n            box-shadow: none;\n            margin-bottom: 0.5rem;\n        }\n\n        #bds-app-wrapper .court-visual { display: flex; align-items: center; justify-content: space-around; margin: 0.4rem 0; }\n        #bds-app-wrapper .court-side { width: 45%; text-align: center; }\n\n        #bds-app-wrapper .player-box {\n            background: transparent;\n            color: var(--bds-text);\n            padding: 4px;\n            border-radius: var(--bds-radius);\n            font-weight: 600;\n            margin-bottom: 0.25rem;\n            border: 1px solid var(--bds-border);\n            display: flex; align-items: center; justify-content: center; gap: 5px;\n        }\n        #bds-app-wrapper .player-box.team-b { border-color: #0f5f2c; }\n\n        #bds-app-wrapper .player-skill {\n            display: inline-flex; align-items: center; font-size: 0.65rem;\n            padding: 1px 5px; border-radius: 999px;\n            background: #0c1a12; border: 1px solid var(--bds-border);\n        }\n\n        #bds-app-wrapper .vs-divider { font-size: 0.8rem; font-weight: 700; color: var(--bds-text-light); }\n        #bds-app-wrapper .court-actions { display: flex; flex-direction: column; gap: 0.25rem; margin-top: 0.2rem; }\n        #bds-app-wrapper .court-action-buttons { display: grid; grid-template-columns: 1fr 1fr; gap: 0.25rem; }\n        #bds-app-wrapper .winner-selection { display: none; background: var(--bds-light-gray); padding: 0.4rem; border-radius: var(--bds-radius); margin-top: 0.25rem; }\n\n        #bds-app-wrapper .player-tag-container { display: flex; flex-wrap: wrap; gap: 0.25rem; }\n        #bds-app-wrapper .player-tag {\n            display: inline-flex; align-items: center; gap: 5px;\n            padding: 3px 6px;\n            border-radius: 999px;\n            background-color: #0c1a12;\n            border: 1px solid var(--bds-border);\n            font-size: 0.75rem;\n            color: var(--bds-text);\n        }\n        #bds-app-wrapper .player-tag .skill-dot { width: 5px; height: 5px; border-radius: 999px; display: inline-block; }\n        #bds-app-wrapper .skill-Beg { background: #f97316; }\n        #bds-app-wrapper .skill-Int { background: #3b82f6; }\n        #bds-app-wrapper .skill-Adv { background: #10b981; }\n\n        #bds-app-wrapper .pending-list { display: flex; flex-direction: column; gap: 0.25rem; margin-bottom: 0.25rem; }\n        #bds-app-wrapper .pending-item { display: flex; justify-content: space-between; align-items: center; padding: 5px; background: #0c1a12; border-radius: 4px; border: 1px solid var(--bds-border); }\n        #bds-app-wrapper .pending-item .meta { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; }\n        #bds-app-wrapper .pending-item .remove-btn { background: transparent; color: var(--bds-danger); border: 1px solid var(--bds-danger); box-shadow: none; padding: 3px 6px; border-radius: 4px; }\n\n        #bds-app-wrapper .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); z-index: 10000; display: none; align-items: flex-end; }\n        #bds-app-wrapper .modal-overlay.is-open { display: flex; }\n        #bds-app-wrapper .modal-container { background: var(--bds-card-bg); width: 100%; max-width: 600px; margin: 0 auto; border-top-left-radius: 6px; border-top-right-radius: 6px; max-height: 90vh; display: flex; flex-direction: column; border: 1px solid var(--bds-border); }\n        #bds-app-wrapper .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 0.6rem; border-bottom: 1px solid var(--bds-border); }\n        #bds-app-wrapper .modal-body { padding: 0.6rem; overflow-y: auto; flex-grow: 1; }\n        #bds-app-wrapper .modal-footer { display: flex; justify-content: flex-end; gap: 0.3rem; padding: 0.5rem 0.6rem; border-top: 1px solid var(--bds-border); background-color: #0c1a12; }\n        #bds-app-wrapper .close-modal-btn { background: none; color: var(--bds-text); border: 1px solid var(--bds-border); }\n        \n        \/* Close button visibility *\/\n#bds-app-wrapper .close-modal-btn {\n    background: transparent;\n    border: 1px solid var(--bds-border);\n    color: var(--bds-text);\n}\n\n#bds-app-wrapper.dark-mode .close-modal-btn {\n    background: #eef4f1;\n    border-color: #cfded5;\n    color: #0b1d12;\n}\n\n        #bds-app-wrapper .bottom-nav {\n            position: fixed; bottom: 0; left: 0; right: 0;\n            background: var(--bds-card-bg);\n            padding: 0.3rem 0.5rem;\n            display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.3rem;\n            max-width: 600px; margin: 0 auto; z-index: 9999;\n            border-top: 1px solid var(--bds-border);\n        }\n        #bds-app-wrapper .nav-btn {\n            display: flex; flex-direction: column; align-items: center; gap: 1px;\n            background: none; color: var(--bds-text-light); padding: 3px 2px; border-radius: 4px; font-size: 0.65rem;\n        }\n        #bds-app-wrapper .nav-btn:hover { background: #0c1a12; color: var(--bds-text); }\n\n        #bds-app-wrapper .notification {\n            position: fixed; top: -100px; left: 50%; transform: translateX(-50%);\n            padding: 8px 12px; border-radius: 4px; color: #021a0c; font-weight: 700; z-index: 10001;\n            text-align: center; transition: top 0.2s ease-in-out, opacity 0.2s ease-in-out;\n            background-color: var(--bds-primary); border: 1px solid #0f5f2c;\n        }\n        #bds-app-wrapper .notification.show { top: 32px; opacity: 1; }\n        #bds-app-wrapper .notification.error { background-color: var(--bds-danger); color: #fff; border-color: var(--bds-danger); }\n\n        #bds-app-wrapper .hidden { display: none !important; }\n        #bds-app-wrapper .stat-row, .history-item { display: flex; justify-content: space-between; align-items: center; padding: 0.25rem 0.15rem; border-bottom: 1px solid var(--bds-border); }\n        #bds-app-wrapper .history-item { flex-wrap: wrap; }\n        #bds-app-wrapper .stat-row:last-child, .history-item:last-child { border-bottom: none; }\n        #bds-app-wrapper .stat-player-name.removed { text-decoration: line-through; color: var(--bds-text-light); }\n        #bds-app-wrapper .stat-player-name .removal-info { font-size: 0.7em; font-style: italic; color: var(--bds-text-light); margin-left: 0.3rem; }\n        #bds-app-wrapper .stat-text { display: flex; flex-direction: column; align-items: flex-end; font-size: 0.75em; }\n        #bds-app-wrapper .stat-text .removal-info { font-size: 0.75em; color: var(--bds-text-light); }\n        #bds-app-wrapper .history-teams .winner { font-weight: bold; color: var(--bds-primary); }\n        #bds-app-wrapper .history-teams .winner::before { content: '\u2301 '; }\n\n        #bds-app-wrapper .empty-state {\n            text-align: center; padding: 0.6rem; border: 1px dashed var(--bds-border);\n            border-radius: var(--bds-radius);\n        }\n        #bds-app-wrapper .empty-state p { font-size: 0.85rem; color: var(--bds-text); margin-top: 0.3rem; }\n        #bds-app-wrapper .empty-state .icon { font-size: 1.2rem; opacity: 0.5; }\n\n        \/* Theme switch slider *\/\n        #bds-app-wrapper .theme-switch { position: relative; display: inline-block; width: 40px; height: 20px; }\n        #bds-app-wrapper .theme-switch input { opacity: 0; width: 0; height: 0; }\n        #bds-app-wrapper .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #0c1a12; transition: .3s; border-radius: 20px; border: 1px solid var(--bds-border); }\n        #bds-app-wrapper .slider:before { position: absolute; content: \"\"; height: 14px; width: 14px; left: 3px; bottom: 2px; background-color: var(--bds-primary); transition: .3s; border-radius: 50%; }\n        #bds-app-wrapper input:checked + .slider { background-color: #0c1a12; }\n        #bds-app-wrapper input:checked + .slider:before { transform: translateX(18px); }\n\n        \/* Help content *\/\n        #bds-app-wrapper .help-content h4 { margin-top: 0.4rem; margin-bottom: 0.3rem; color: var(--bds-primary); }\n        #bds-app-wrapper .help-content ul { list-style: none; padding-left: 0; margin-bottom: 0.4rem; }\n        #bds-app-wrapper .help-content li { padding-left: 1rem; position: relative; margin-bottom: 0.35rem; }\n        #bds-app-wrapper .help-content li::before { content: '>'; position: absolute; left: 0; top: 0; color: var(--bds-primary); font-size: 0.85rem; line-height: 1; }\n        #bds-app-wrapper .help-content code { background: #0c1a12; padding: 0 6px; border-radius: 4px; border: 1px solid var(--bds-border); }\n\n        \/* Temp court styling *\/\n        #bds-app-wrapper .temp-court.pending {\n            opacity: 0.6;\n            border: 1px dashed var(--bds-border);\n        }\n        #bds-app-wrapper .temp-court.pending .court-actions button,\n        #bds-app-wrapper .temp-court.pending .court-actions .winner-selection,\n        #bds-app-wrapper .temp-court.pending .court-actions .court-action-buttons {\n            pointer-events: none;\n        }\n    <\/style>\n\n    <div id=\"bds-app-wrapper\">\n        <div id=\"notification\" class=\"notification\"><\/div>\n        <div class=\"app-container\">\n            <header>\n                <div class=\"bds-app-title\">\n                    <img decoding=\"async\" src=\"https:\/\/badminton.ghancaballes.com\/skilled\/wp-content\/uploads\/2025\/07\/blacksheeptext.png\" alt=\"Logo\" class=\"bds-logo\">\n                    <h1>BlackSheep Shuffler <span class=\"version-tag\">v5.0.1<\/span><\/h1>\n                <\/div>\n                <div class=\"theme-switch-wrapper\">\n                    <label class=\"theme-switch\" for=\"theme-checkbox\" title=\"Toggle Light\/Dark Mode\">\n                        <input type=\"checkbox\" id=\"theme-checkbox\" \/>\n                        <div class=\"slider\"><\/div>\n                    <\/label>\n                <\/div>\n            <\/header>\n                        <!-- Initial Setup: Add-by-1 with skill and pending list -->\n            <div id=\"setupControls\" class=\"bds-card\">\n                <h3>Initial Setup<\/h3>\n                <div>\n                    <label for=\"playerNameInput\">Player Name<\/label>\n                    <input type=\"text\" id=\"playerNameInput\" placeholder=\"Enter player name...\" \/>\n                <\/div>\n                <div>\n                    <label for=\"playerSkillSelect\">Skill<\/label>\n                    <select id=\"playerSkillSelect\">\n                        <option value=\"Beg\">Beginner<\/option>\n                        <option value=\"Int\" selected>Intermediate<\/option>\n                        <option value=\"Adv\">Advanced<\/option>\n                    <\/select>\n                <\/div>\n                <button id=\"addPendingPlayerBtn\" class=\"btn-secondary\" style=\"width:100%; margin-bottom:0.5rem;\">Add Player<\/button>\n\n                <div>\n                    <h4>Players to Start<\/h4>\n                    <div id=\"pendingPlayersList\" class=\"pending-list\"><\/div>\n                <\/div>\n\n                <div>\n                    <label for=\"courtCount\">Number of courts<\/label>\n                    <input type=\"number\" id=\"courtCount\" placeholder=\"Number of courts\" min=\"1\" max=\"10\" \/>\n                <\/div>\n                <div style=\"display:grid; grid-template-columns:1fr 1fr; gap:0.5rem; margin-top:0.4rem;\">\n                    <button id=\"aboutBtn\" class=\"btn-info\">About<\/button>\n                    <button id=\"startBtn\" class=\"btn-primary\" disabled>Start<\/button>\n                <\/div>\n            <\/div>\n\n            <div id=\"results\"><\/div>\n        <\/div>\n\n        <div class=\"bottom-nav hidden\" id=\"actionBar\">\n            <button id=\"statsBtn\" class=\"nav-btn\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 20v-6M6 20v-10M18 20V4\"\/><\/svg><span>Stats<\/span>\n            <\/button>\n            <button id=\"historyBtn\" class=\"nav-btn\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M1 4v6h6M23 20v-6h-6\"\/><path d=\"M20.49 9A9 9 0 0 0 7.54 5.04M3.51 15a9 9 0 0 0 12.95 4.97\"\/><\/svg><span>History<\/span>\n            <\/button>\n            <button id=\"manageGameBtn\" class=\"nav-btn\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12.22 2h-4.44a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8.88z\"\/><path d=\"M18 2v6h6M12 18v-6M9 15h6\"\/><\/svg><span>Manage<\/span>\n            <\/button>\n            <button id=\"helpBtn\" class=\"nav-btn\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"\/><path d=\"M12 17h.01\"\/><\/svg><span>Help<\/span>\n            <\/button>\n        <\/div>\n\n        <!-- Management Modal -->\n        <div class=\"modal-overlay\" id=\"managementModal\">\n            <div class=\"modal-container\">\n                <div class=\"modal-header\"><h3>Management<\/h3><\/div>\n                <div class=\"modal-body\">\n                    <div id=\"mainManagementPanel\">\n                        <div class=\"management-section\">\n                            <h5>Add New Player<\/h5>\n                            <input id=\"mgmtNewPlayerName\" type=\"text\" placeholder=\"Enter player name...\" \/>\n                            <select id=\"mgmtNewPlayerSkill\">\n                                <option value=\"Beg\">Beginner<\/option>\n                                <option value=\"Int\" selected>Intermediate<\/option>\n                                <option value=\"Adv\">Advanced<\/option>\n                            <\/select>\n                            <button id=\"addPlayerBtn\" class=\"btn-primary\">Add Player<\/button>\n                        <\/div>\n\n                        <div class=\"management-section\">\n                            <h5>Change Skill<\/h5>\n                            <select id=\"skillChangePlayerSelect\"><option value=\"\">Select Player<\/option><\/select>\n                            <select id=\"skillChangeSkillSelect\">\n                                <option value=\"Beg\">Beginner<\/option>\n                                <option value=\"Int\" selected>Intermediate<\/option>\n                                <option value=\"Adv\">Advanced<\/option>\n                            <\/select>\n                            <button id=\"changeSkillBtn\" class=\"btn-secondary\">Update Skill<\/button>\n                        <\/div>\n\n                        <div class=\"management-section\">\n                            <h5>Rename Player<\/h5>\n                            <select id=\"renamePlayerSelect\"><option value=\"\">Select Player<\/option><\/select>\n                            <input id=\"renamePlayerInput\" type=\"text\" placeholder=\"Enter new name...\" \/>\n                            <button id=\"renamePlayerBtn\" class=\"btn-secondary\">Rename Player<\/button>\n                        <\/div>\n\n                        <div class=\"management-section\">\n                            <h5>Remove Player<\/h5>\n                            <select id=\"playerToRemove\"><option value=\"\">Select Player<\/option><\/select>\n                            <button id=\"removePlayerBtn\" class=\"btn-danger\">Remove Selected Player<\/button>\n                        <\/div>\n\n                        <div class=\"management-section\">\n                            <h5>Court Management<\/h5>\n                            <div style=\"display:grid; grid-template-columns:1fr 1fr; gap:0.5rem;\">\n                                <button id=\"addCourtBtn\" class=\"btn-primary\">Add Court<\/button>\n                                <div>\n                                    <select id=\"courtToRemove\" style=\"margin-bottom:0;\"><option value=\"\">Select Court<\/option><\/select>\n                                    <button id=\"removeCourtBtn\" class=\"btn-danger\" style=\"margin-top:0.4rem;\">Remove Selected<\/button>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n\n                        <div class=\"management-section\">\n                            <h5>Rename Court<\/h5>\n                            <select id=\"courtToRename\"><option value=\"\">Select Court<\/option><\/select>\n                            <input id=\"courtRenameInput\" type=\"text\" placeholder=\"Enter court name...\" \/>\n                            <button id=\"renameCourtBtn\" class=\"btn-secondary\">Rename Court<\/button>\n                        <\/div>\n\n                        <div class=\"management-section\">\n                            <h5>Schedule Custom Game<\/h5>\n                            <select id=\"tempPlayer1\"><option value=\"\">Select Player 1<\/option><\/select>\n                            <select id=\"tempPlayer2\"><option value=\"\">Select Player 2<\/option><\/select>\n                            <select id=\"tempPlayer3\"><option value=\"\">Select Player 3<\/option><\/select>\n                            <select id=\"tempPlayer4\"><option value=\"\">Select Player 4<\/option><\/select>\n                            <input id=\"tempAfterGames\" type=\"number\" min=\"0\" placeholder=\"Insert after X games\" \/>\n                            <button id=\"scheduleTempBtn\" class=\"btn-secondary\">Schedule \/ Update<\/button>\n                            <button id=\"cancelTempBtn\" class=\"btn-danger\" style=\"margin-top:0.4rem;\">Cancel Custom Game<\/button>\n                        <\/div>\n\n                        <div class=\"management-section\">\n                            <h5>Game Actions<\/h5>\n                            <button id=\"undoBtn\" class=\"btn-secondary hidden\">Undo Last Action<\/button>\n                            <button id=\"resetGameBtn\" class=\"btn-danger\" style=\"margin-top:0.4rem;\">Reset Everything<\/button>\n                        <\/div>\n                    <\/div>\n\n                    <div id=\"editTeamsPanel\" class=\"hidden\">\n                        <h4 id=\"editCourtTitle\"><\/h4>\n                        <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; margin-bottom: 0.5rem;\">\n                            <div>\n                                <h5>Team A<\/h5>\n                                <select id=\"editPlayerA1\"><\/select>\n                                <select id=\"editPlayerA2\"><\/select>\n                            <\/div>\n                            <div>\n                                <h5>Team B<\/h5>\n                                <select id=\"editPlayerB1\"><\/select>\n                                <select id=\"editPlayerB2\"><\/select>\n                            <\/div>\n                        <\/div>\n                        <button id=\"saveTeamsBtn\" class=\"btn-primary\">Save Teams<\/button>\n                        <button data-action=\"cancel-submodal\" class=\"btn-secondary\" style=\"margin-top:0.4rem;\">Cancel<\/button>\n                    <\/div>\n\n                    <div id=\"swapPlayerPanel\" class=\"hidden\">\n                        <h4 id=\"swapCourtTitle\"><\/h4>\n                        <div class=\"management-section\">\n                            <label for=\"playerToSwapOut\">Player to remove:<\/label>\n                            <select id=\"playerToSwapOut\"><\/select>\n                        <\/div>\n                        <div class=\"management-section\">\n                            <label for=\"playerToSwapIn\">Player to add:<\/label>\n                            <select id=\"playerToSwapIn\"><\/select>\n                        <\/div>\n                        <button id=\"confirmSwapBtn\" class=\"btn-primary\">Confirm Swap<\/button>\n                        <button data-action=\"cancel-submodal\" class=\"btn-secondary\" style=\"margin-top:0.4rem;\">Cancel<\/button>\n                    <\/div>\n                <\/div>\n                <div class=\"modal-footer\"><button class=\"close-modal-btn\">Close<\/button><\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Help Modal -->\n        <div class=\"modal-overlay\" id=\"helpModal\">\n            <div class=\"modal-container\">\n                <div class=\"modal-header\"><h3>Help & How-To<\/h3><\/div>\n                <div class=\"modal-body\">\n                    <div class=\"help-content\">\n                        <h4>Quick Start<\/h4>\n                        <ul>\n                            <li>Add players one by one with their skill (Beginner, Intermediate, Advanced).<\/li>\n                            <li>Set the number of courts and press Start. You need at least 4 players and enough players to fill the courts.<\/li>\n                            <li>The app automatically assigns players to courts: it prioritizes those who rested the longest and keeps games varied and fair.<\/li>\n                        <\/ul>\n\n                        <h4>Completing Games<\/h4>\n                        <ul>\n                            <li>Tap Complete Game, then choose the winner (Team A or Team B). Scores are not recorded.<\/li>\n                            <li>Winners\/losers are tracked in Player Stats. All four players move to the resting list and new games are filled automatically when possible.<\/li>\n                        <\/ul>\n\n                        <h4>Managing Players & Courts<\/h4>\n                        <ul>\n                            <li>Use the Manage panel to add players (with skill), change a player\u2019s skill, remove players, add\/remove courts, and undo the last action.<\/li>\n                            <li>Changing skills takes effect for future shuffles and manual edits\/swaps; it doesn\u2019t disrupt ongoing games.<\/li>\n                            <li>You cannot remove a player who\u2019s currently on a court.<\/li>\n                        <\/ul>\n\n                        <h4>Editing & Swapping<\/h4>\n                        <ul>\n                            <li>Edit lets you re-pair the 4 players already on a court. Swapping allows substituting a resting player with someone on court.<\/li>\n                            <li>The app validates team choices; invalid combinations are blocked with a message.<\/li>\n                        <\/ul>\n\n                        <h4>Stats & History<\/h4>\n                        <ul>\n                            <li>Player Stats shows total games, wins-losses, and when a player left if removed.<\/li>\n                            <li>History lists all games and winners in reverse order.<\/li>\n                        <\/ul>\n\n                        <h4>Tips<\/h4>\n                        <ul>\n                            <li>If a court can\u2019t be filled right away, the app will wait until compatible players become available.<\/li>\n                            <li>Use the skill change tool to keep games balanced as players arrive or improve.<\/li>\n                            <li>Theme toggle in the header switches between light and dark modes.<\/li>\n                        <\/ul>\n                    <\/div>\n                <\/div>\n                <div class=\"modal-footer\"><button class=\"close-modal-btn\">Close<\/button><\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Stats Modal -->\n        <div class=\"modal-overlay\" id=\"statsModal\">\n            <div class=\"modal-container\">\n                <div class=\"modal-header\"><h3>Statistics<\/h3><small id=\"stats-date\"><\/small><\/div>\n                <div class=\"modal-body\">\n                    <div id=\"player-stats-content\" class=\"tab-content active\"><\/div>\n                <\/div>\n                <div class=\"modal-footer\">\n                    <button class=\"close-modal-btn\">Close<\/button>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- History Modal -->\n        <div class=\"modal-overlay\" id=\"historyModal\">\n            <div class=\"modal-container\">\n                <div class=\"modal-header\"><h3>Match History<\/h3><\/div>\n                <div class=\"modal-body\" id=\"historyModalBody\"><\/div>\n                <div class=\"modal-footer\"><button class=\"close-modal-btn\">Close<\/button><\/div>\n            <\/div>\n        <\/div>\n\n        <!-- About Modal (includes condensed how-to during setup) -->\n        <div class=\"modal-overlay\" id=\"aboutModal\">\n            <div class=\"modal-container\">\n                <div class=\"modal-header\"><h3>About & How-To<\/h3><\/div>\n                <div class=\"modal-body\">\n                    <div class=\"about-content\">\n                        <p><strong>Author:<\/strong> Ghan Caballes<\/p>\n                        <p><strong>Collaborator:<\/strong> Van Ruiz, Aljun Montebon, Owen Pelito<\/p>\n                        <p><strong>Version:<\/strong> 5.0.1<\/p>\n                    <\/div>\n                    <div class=\"help-content\">\n                        <h4>How to Use<\/h4>\n                        <ul>\n                            <li>Add players one by one with their skill, set courts, press Start.<\/li>\n                            <li>Complete games by choosing the winner; new games auto-fill when possible.<\/li>\n                            <li>Manage skills, players, and courts in the Manage panel. Undo is available.<\/li>\n                        <\/ul>\n\n                        <h4>Fair Shuffle<\/h4>\n                        <ul>\n                            <li>Prioritizes players who rested longest.<\/li>\n                            <li>Minimizes repeat partners\/opponents among available options.<\/li>\n                            <li>If no group fits at the moment, courts wait for compatible players.<\/li>\n                        <\/ul>\n                    <\/div>\n                <\/div>\n                <div class=\"modal-footer\"><button class=\"close-modal-btn\">Close<\/button><\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n    document.addEventListener('DOMContentLoaded', () => {\n        const appWrapper = document.getElementById('bds-app-wrapper');\n        if (!appWrapper) { return; }\n\n        \/\/ Pending (pre-start) players: [{ name: originalCase, lower: normalized, skill: 'Beg'|'Int'|'Adv' }]\n        let pendingPlayers = [];\n\n        \/\/ State during a session\n        let state = {\n            courts: [],\n            courtNames: [],\n            restingPlayers: [],\n            playCount: {},\n            matchHistory: [],\n            teamPairings: {},\n            opponentPairings: {},\n            allPlayersList: [],\n            playerMeta: {}, \/\/ { [lowerName]: { name, skill, isActive:true } }\n            gameInProgress: false,\n            undoStack: [],\n            completedGameCount: 0,\n            tempCourt: {\n                pending: false,\n                active: false,\n                players: [],\n                insertedAfterGames: 0,\n                readyAtGameCount: 0,\n                createdAt: null\n            }\n        };\n\n        const RESTRICTED_VS_BEGINNER = new Set(['chad','charie','chris','hannah','tope','angel','bobby']);\n\n        \/\/ Helpers\n        const get = (selector, parent = document) => parent.querySelector(selector);\n        const getAll = (selector, parent = document) => parent.querySelectorAll(selector);\n        const showNotification = (message, type = 'success') => { const el = get('#notification'); el.textContent = message; el.className = `notification ${type} show`; setTimeout(() => el.classList.remove('show'), 2500); };\n        const normalizeName = (name) => (name || '').trim().toLowerCase();\n        const getSkill = (name) => {\n            const meta = state.playerMeta[normalizeName(name)];\n            return meta?.skill || 'Int';\n        };\n        const isBeg = (name) => getSkill(name) === 'Beg';\n        const isAdv = (name) => getSkill(name) === 'Adv';\n        const isRestrictedName = (name) => RESTRICTED_VS_BEGINNER.has(normalizeName(name));\n        const getCourtLabel = (idx) => state.courtNames[idx] || `Court ${idx + 1}`;\n        const isTempPlayerLocked = (name) => state.tempCourt?.pending && state.tempCourt.players.some(p => normalizeName(p) === normalizeName(name));\n        const getEligibleRestingPlayers = () => state.restingPlayers.filter(p => !isTempPlayerLocked(p));\n\n        const saveState = () => {\n            if (state.gameInProgress) {\n                const stateToSave = { ...state, undoStack: [] };\n                localStorage.setItem('badmintonGameState', JSON.stringify(stateToSave));\n            }\n        };\n        const loadState = () => {\n            const savedStateJSON = localStorage.getItem('badmintonGameState');\n            if (!savedStateJSON) return;\n            try {\n                const loadedState = JSON.parse(savedStateJSON);\n                if (loadedState && loadedState.gameInProgress) {\n                    if (!loadedState.undoStack) loadedState.undoStack = [];\n                    if (!loadedState.playerMeta) {\n                        loadedState.playerMeta = {};\n                        (loadedState.allPlayersList || []).forEach(name => {\n                            const ln = normalizeName(name);\n                            if (!loadedState.playerMeta[ln]) loadedState.playerMeta[ln] = { name, skill: 'Int', isActive: true };\n                        });\n                    }\n                    if (!loadedState.courtNames || loadedState.courtNames.length !== loadedState.courts.length) {\n                        loadedState.courtNames = Array.from({ length: loadedState.courts.length }, (_, i) => `Court ${i + 1}`);\n                    }\n                    if (!loadedState.tempCourt) {\n                        loadedState.tempCourt = {\n                            pending: false,\n                            active: false,\n                            players: [],\n                            insertedAfterGames: 0,\n                            readyAtGameCount: 0,\n                            createdAt: null\n                        };\n                    }\n                    if (!loadedState.completedGameCount) loadedState.completedGameCount = 0;\n                    state = loadedState;\n                    get('#setupControls').classList.add('hidden');\n                    get('#actionBar').classList.remove('hidden');\n                    renderAll();\n                }\n            } catch (e) {\n                console.error(\"Error parsing saved state:\", e);\n                localStorage.removeItem('badmintonGameState');\n            }\n        };\n        const applyTheme = (theme) => { if (theme === 'dark') { appWrapper.classList.add('dark-mode'); get('#theme-checkbox').checked = true; } else { appWrapper.classList.remove('dark-mode'); get('#theme-checkbox').checked = false; } };\n        const loadTheme = () => applyTheme(localStorage.getItem('theme') || 'light');\n\n        const getPairKey = (p1, p2) => [p1, p2].sort().join('|');\n        const shuffleArray = (arr) => { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } };\n        const openModal = (id, onOpenCallback) => { const modal = get(`#${id}`); if (modal) { modal.classList.add('is-open'); if (onOpenCallback) onOpenCallback(); } };\n        const closeModal = (id) => { const modal = get(`#${id}`); if (modal) { modal.classList.remove('is-open'); if (id === 'managementModal') resetManagementModal(); } };\n        const resetManagementModal = () => {\n            get('#mainManagementPanel').classList.remove('hidden');\n            get('#editTeamsPanel').classList.add('hidden');\n            get('#swapPlayerPanel').classList.add('hidden');\n            delete get('#managementModal').dataset.editingCourt;\n        };\n\n        \/\/ Commands with Undo\n        const commandProcessor = {\n            execute(command) {\n                const beforeState = JSON.parse(JSON.stringify(state));\n                const success = command.execute();\n                if (success) {\n                    state.undoStack.push(() => { state = beforeState; });\n                    if (state.undoStack.length > 10) { state.undoStack.shift(); }\n                }\n                renderAll();\n                return success;\n            },\n            undo() {\n                if (state.undoStack.length > 0) {\n                    const undoCommand = state.undoStack.pop();\n                    undoCommand();\n                    renderAll();\n                    showNotification('Last action has been undone.');\n                } else {\n                    showNotification('Nothing to undo.', 'error');\n                }\n            }\n        };\n                \/\/ Record winner without scores\n        const RecordWinnerCommand = (courtIndex, winner) => ({\n            execute: () => {\n                const court = state.courts[courtIndex];\n                if (!court || !court.players || court.players.length !== 4) return false;\n\n                const wasTemp = !!court.isTemp;\n\n                const { teamA, teamB, startTime, players } = court;\n                const now = Date.now();\n                players.forEach(p => {\n                    const ps = state.playCount[p];\n                    ps.games++;\n                    ps.lastGameEndTime = now;\n                    if ((winner === 'A' && teamA.includes(p)) || (winner === 'B' && teamB.includes(p))) { ps.wins++; } else { ps.losses++; }\n                });\n                state.restingPlayers.push(...players);\n                state.matchHistory.push({\n                    court: courtIndex + 1,\n                    courtName: getCourtLabel(courtIndex),\n                    teamA, teamB,\n                    winner,\n                    startTime,\n                    endTime: new Date(now).toISOString()\n                });\n                state.courts[courtIndex] = { players: [], teamA: [], teamB: [], startTime: null };\n                state.completedGameCount++;\n\n                showNotification('Winner Recorded!');\n\n                if (wasTemp) {\n                    finalizeTempCourtIfNeeded(courtIndex);\n                }\n\n                handleTempCourtActivation(courtIndex);\n                refillAllEmptyCourts();\n                return true;\n            }\n        });\n\n        const validateCourtTeams = (teamA, teamB) => {\n            const group = [...teamA, ...teamB];\n            const hasBeg = group.some(isBeg);\n            const hasAdv = group.some(isAdv);\n            if (hasBeg && hasAdv) {\n                return { ok: false, msg: 'Invalid combination.' };\n            }\n            if (hasBeg && group.some(isRestrictedName)) {\n                return { ok: false, msg: 'Invalid combination.' };\n            }\n            const advPlayers = group.filter(isAdv);\n            if (advPlayers.length === 2) {\n                const [a1, a2] = advPlayers;\n                const a1Team = teamA.includes(a1) ? 'A' : 'B';\n                const a2Team = teamA.includes(a2) ? 'A' : 'B';\n                if (a1Team === a2Team) {\n                    return { ok: false, msg: 'Invalid combination.' };\n                }\n            }\n            return { ok: true, msg: '' };\n        };\n\n        const SaveTeamsCommand = (courtIndex, newTeamA, newTeamB) => ({\n            execute: () => {\n                if (new Set([...newTeamA, ...newTeamB]).size !== 4) {\n                    showNotification('Each player must be unique.', 'error');\n                    return false;\n                }\n                const validation = validateCourtTeams(newTeamA, newTeamB);\n                if (!validation.ok) {\n                    showNotification(validation.msg, 'error');\n                    return false;\n                }\n                const oldTeamA = [...state.courts[courtIndex].teamA];\n                const oldTeamB = [...state.courts[courtIndex].teamB];\n                updatePairingStats(oldTeamA, oldTeamB, -1);\n                updatePairingStats(newTeamA, newTeamB, 1);\n                state.courts[courtIndex].teamA = newTeamA;\n                state.courts[courtIndex].teamB = newTeamB;\n                state.courts[courtIndex].players = [...newTeamA, ...newTeamB];\n                showNotification(`Teams for ${getCourtLabel(courtIndex)} updated.`);\n                closeModal('managementModal');\n                return true;\n            }\n        });\n\n        const SwapPlayerCommand = (courtIndex, playerOut, playerIn) => ({\n            execute: () => {\n                const court = state.courts[courtIndex];\n                if (!court || !playerOut || !playerIn) return false;\n                const { teamA, teamB } = court;\n\n                const newTeamA = [...teamA];\n                const newTeamB = [...teamB];\n                if (newTeamA.includes(playerOut)) {\n                    newTeamA[newTeamA.indexOf(playerOut)] = playerIn;\n                } else if (newTeamB.includes(playerOut)) {\n                    newTeamB[newTeamB.indexOf(playerOut)] = playerIn;\n                } else {\n                    showNotification('Selected player is not on this court.', 'error');\n                    return false;\n                }\n\n                const validation = validateCourtTeams(newTeamA, newTeamB);\n                if (!validation.ok) {\n                    showNotification(validation.msg, 'error');\n                    return false;\n                }\n\n                updatePairingStats(teamA, teamB, -1);\n                court.teamA = newTeamA;\n                court.teamB = newTeamB;\n                court.players = [...newTeamA, ...newTeamB];\n                updatePairingStats(court.teamA, court.teamB, 1);\n\n                state.restingPlayers = state.restingPlayers.filter(p => p !== playerIn);\n                state.restingPlayers.push(playerOut);\n\n                showNotification(`${playerIn} swapped with ${playerOut}.`);\n                closeModal('managementModal');\n                return true;\n            }\n        });\n\n        const initPairings = (players) => {\n            state.teamPairings = {};\n            state.opponentPairings = {};\n            for (let i = 0; i < players.length; i++) {\n                for (let j = i + 1; j < players.length; j++) {\n                    const key = getPairKey(players[i], players[j]);\n                    state.teamPairings[key] = 0;\n                    state.opponentPairings[key] = 0;\n                }\n            }\n        };\n\n        const updatePairingsForNewPlayers = (newPlayers) => {\n            const allPlayers = state.allPlayersList;\n            for (const newPlayer of newPlayers) {\n                for (const existingPlayer of allPlayers) {\n                    if (newPlayer === existingPlayer) continue;\n                    const key = getPairKey(newPlayer, existingPlayer);\n                    if (!(key in state.teamPairings)) state.teamPairings[key] = 0;\n                    if (!(key in state.opponentPairings)) state.opponentPairings[key] = 0;\n                }\n            }\n        };\n\n        const updatePairingStats = (teamA, teamB, increment = 1) => {\n            if (!teamA || teamA.length < 2 || !teamB || teamB.length < 2) return;\n            const teamAKey = getPairKey(teamA[0], teamA[1]);\n            const teamBKey = getPairKey(teamB[0], teamB[1]);\n            state.teamPairings[teamAKey] = (state.teamPairings[teamAKey] || 0) + increment;\n            state.teamPairings[teamBKey] = (state.teamPairings[teamBKey] || 0) + increment;\n            teamA.forEach(p1 => teamB.forEach(p2 => {\n                const oppKey = getPairKey(p1, p2);\n                state.opponentPairings[oppKey] = (state.opponentPairings[oppKey] || 0) + increment;\n            }));\n        };\n\n        const rebuildPairings = () => {\n            initPairings(state.allPlayersList);\n            state.matchHistory.forEach(match => updatePairingStats(match.teamA, match.teamB, 1));\n            state.courts.forEach(court => {\n                if (court.players && court.players.length === 4) {\n                    updatePairingStats(court.teamA, court.teamB, 1);\n                }\n            });\n        };\n\n        const getCombinations = (array, size) => {\n            function* f(prefix, array) {\n                if (prefix.length === size) { yield prefix; return; }\n                for (let i = 0; i < array.length; i++) {\n                    yield* f(prefix.concat(array[i]), array.slice(i + 1));\n                }\n            }\n            return Array.from(f([], array));\n        };\n\n        const groupViolatesC1 = (group) => {\n            const hasBeg = group.some(isBeg);\n            const hasAdv = group.some(isAdv);\n            return hasBeg && hasAdv;\n        };\n\n        const groupViolatesC2 = (group) => {\n            const hasBeg = group.some(isBeg);\n            if (!hasBeg) return false;\n            return group.some(isRestrictedName);\n        };\n\n        const findBestGame = (candidates) => {\n            if (candidates.length < 4) return null;\n            const combos = getCombinations(candidates, 4);\n            let best = null;\n            let bestScore = Infinity;\n\n            for (const group of combos) {\n                if (groupViolatesC1(group)) continue;\n                if (groupViolatesC2(group)) continue;\n\n                const advCount = group.filter(isAdv).length;\n\n                const splits = [\n                    [[group[0], group[1]], [group[2], group[3]]],\n                    [[group[0], group[2]], [group[1], group[3]]],\n                    [[group[0], group[3]], [group[1], group[2]]]\n                ];\n\n                for (const [teamA, teamB] of splits) {\n                    if (advCount === 2) {\n                        const advPlayers = group.filter(isAdv);\n                        const [a1, a2] = advPlayers;\n                        const a1Team = teamA.includes(a1) ? 'A' : 'B';\n                        const a2Team = teamA.includes(a2) ? 'A' : 'B';\n                        if (a1Team === a2Team) continue;\n                    }\n\n                    let score = 0;\n                    score += (state.teamPairings[getPairKey(teamA[0], teamA[1])] || 0);\n                    score += (state.teamPairings[getPairKey(teamB[0], teamB[1])] || 0);\n                    teamA.forEach(p1 => teamB.forEach(p2 => { score += (state.opponentPairings[getPairKey(p1, p2)] || 0); }));\n\n                    if (score < bestScore) {\n                        bestScore = score;\n                        best = { players: group, teamA, teamB };\n                    }\n                }\n            }\n\n            return best;\n        };\n\n        const handleTempCourtActivation = (completedCourtIndex) => {\n            if (!state.tempCourt?.pending) return;\n            if (state.completedGameCount < state.tempCourt.readyAtGameCount) return;\n\n            const allFree = state.tempCourt.players.every(p => state.restingPlayers.includes(p));\n            if (!allFree) return;\n\n            state.tempCourt.pending = false;\n            state.tempCourt.active = true;\n\n            const tempCourt = {\n                players: [...state.tempCourt.players],\n                teamA: [state.tempCourt.players[0], state.tempCourt.players[1]],\n                teamB: [state.tempCourt.players[2], state.tempCourt.players[3]],\n                startTime: new Date().toISOString(),\n                isTemp: true\n            };\n\n            state.courts[completedCourtIndex] = tempCourt;\n            updatePairingStats(tempCourt.teamA, tempCourt.teamB);\n\n            state.restingPlayers = state.restingPlayers.filter(p => !state.tempCourt.players.includes(p));\n            showNotification('Custom game is now active!');\n        };\n\n        const finalizeTempCourtIfNeeded = (courtIndex) => {\n            const court = state.courts[courtIndex];\n            if (!court?.isTemp) return;\n\n            state.courts[courtIndex] = { players: [], teamA: [], teamB: [], startTime: null };\n\n            state.tempCourt.active = false;\n            state.tempCourt.players = [];\n            state.tempCourt.insertedAfterGames = 0;\n            state.tempCourt.readyAtGameCount = 0;\n            state.tempCourt.createdAt = null;\n\n            showNotification('Custom game completed. Regular court restored.');\n        };\n\n        const refillAllEmptyCourts = () => {\n            let availablePlayers = [...state.restingPlayers];\n            const emptyCourts = state.courts.map((c, i) => i).filter(i => !state.courts[i].players || state.courts[i].players.length === 0);\n\n            for (const courtIndex of emptyCourts) {\n                if (availablePlayers.length < 4) break;\n\n                const priorityQueue = availablePlayers\n                    .filter(p => !isTempPlayerLocked(p))\n                    .sort((a,b) => (state.playCount[a].lastGameEndTime || 0) - (state.playCount[b].lastGameEndTime || 0));\n\n                if (priorityQueue.length < 4) break;\n\n                const poolSizes = [8, 12, 16];\n                let placed = false;\n\n                for (const size of poolSizes) {\n                    const candidates = priorityQueue.slice(0, size);\n                    const bestGame = findBestGame(candidates);\n                    if (bestGame) {\n                        state.courts[courtIndex] = { players: bestGame.players, teamA: bestGame.teamA, teamB: bestGame.teamB, startTime: new Date().toISOString() };\n                        updatePairingStats(bestGame.teamA, bestGame.teamB);\n                        availablePlayers = availablePlayers.filter(p => !bestGame.players.includes(p));\n                        placed = true;\n                        break;\n                    }\n                }\n\n                if (!placed) {\n                    showNotification(`No compatible match for ${getCourtLabel(courtIndex)} yet.`, 'error');\n                    break;\n                }\n            }\n\n            state.restingPlayers = availablePlayers;\n        };\n\n        const initializeGameFromPending = () => {\n            const courtCount = parseInt(get('#courtCount').value);\n            if (!courtCount || courtCount < 1) {\n                showNotification('Please enter a valid number of courts.', 'error');\n                return;\n            }\n            if (pendingPlayers.length < 4) {\n                showNotification('At least 4 players are required.', 'error');\n                return;\n            }\n            if (courtCount > Math.floor(pendingPlayers.length \/ 4)) {\n                showNotification('Not enough players for the number of courts specified.', 'error');\n                return;\n            }\n\n            const names = pendingPlayers.map(p => p.name);\n            shuffleArray(names);\n\n            state = {\n                courts: Array.from({ length: courtCount }, () => ({ players: [], teamA: [], teamB: [], startTime: null })),\n                courtNames: Array.from({ length: courtCount }, (_, i) => `Court ${i + 1}`),\n                restingPlayers: [...names],\n                playCount: {},\n                matchHistory: [],\n                teamPairings: {},\n                opponentPairings: {},\n                allPlayersList: [...names],\n                playerMeta: {},\n                gameInProgress: true,\n                undoStack: [],\n                completedGameCount: 0,\n                tempCourt: {\n                    pending: false,\n                    active: false,\n                    players: [],\n                    insertedAfterGames: 0,\n                    readyAtGameCount: 0,\n                    createdAt: null\n                }\n            };\n\n            pendingPlayers.forEach(p => {\n                const lower = normalizeName(p.name);\n                state.playerMeta[lower] = { name: p.name, skill: p.skill, isActive: true };\n                state.playCount[p.name] = { wins: 0, losses: 0, games: 0, isActive: true, lastGameEndTime: 0, removalTimestamp: null };\n            });\n\n            initPairings(names);\n\n            get('#setupControls').classList.add('hidden');\n            get('#actionBar').classList.remove('hidden');\n\n            refillAllEmptyCourts();\n            renderAll();\n        };\n\n        const renderEmptyState = (icon, message) => `<div class=\"empty-state\"><div class=\"icon\">${icon}<\/div><p>${message}<\/p><\/div>`;\n        const skillDot = (name) => `<span class=\"skill-dot skill-${getSkill(name)}\"><\/span>`;\n        const skillLabel = (name) => `<span class=\"player-skill\">${getSkill(name)}<\/span>`;\n\n        const renderAll = () => {\n            const resultsEl = get('#results');\n            resultsEl.innerHTML = '';\n\n            if (state.tempCourt?.pending) {\n                resultsEl.appendChild(renderTempCourtPending());\n            }\n\n            const eligibleResting = getEligibleRestingPlayers();\n            const maxEmptyCourtsToShow = Math.floor(eligibleResting.length \/ 4);\n            let emptyCourtsShown = 0;\n\n            state.courts.forEach((court, idx) => {\n                const hasPlayers = court.players && court.players.length === 4;\n                if (!hasPlayers && !court.isTemp) {\n                    if (emptyCourtsShown >= maxEmptyCourtsToShow) {\n                        return;\n                    }\n                    emptyCourtsShown++;\n                }\n                resultsEl.appendChild(renderCourt(court, idx));\n            });\n\n            resultsEl.appendChild(renderSection('Resting Players', state.restingPlayers));\n            get('#undoBtn').classList.toggle('hidden', state.undoStack.length === 0);\n            updateDropdowns();\n            saveState();\n        };\n\n        const renderTempCourtPending = () => {\n            const div = document.createElement('div');\n            div.className = 'bds-card court temp-court pending';\n            const { players, readyAtGameCount } = state.tempCourt;\n            const remaining = Math.max(0, readyAtGameCount - state.completedGameCount);\n            const playerBox = (name, cls='') => `<div class=\"player-box ${cls}\">${name} ${name !== '--' ? skillLabel(name) : ''}<\/div>`;\n\n            div.innerHTML = `\n                <h3>Custom Game (Scheduled)<\/h3>\n                <p>Activates after ${remaining} more game(s).<\/p>\n                <div class=\"court-visual\">\n                    <div class=\"court-side\">\n                        ${players[0] ? playerBox(players[0]) : playerBox('--')}\n                        ${players[1] ? playerBox(players[1]) : playerBox('--')}\n                    <\/div>\n                    <div class=\"vs-divider\">VS<\/div>\n                    <div class=\"court-side\">\n                        ${players[2] ? playerBox(players[2], 'team-b') : playerBox('--', 'team-b')}\n                        ${players[3] ? playerBox(players[3], 'team-b') : playerBox('--', 'team-b')}\n                    <\/div>\n                <\/div>\n                <div class=\"court-actions\">${renderEmptyState('\u23f3', 'Waiting to activate...')}<\/div>\n            `;\n            return div;\n        };\n\n        const renderCourt = (court, idx) => {\n            const div = document.createElement('div');\n            div.className = `bds-card court${court.isTemp ? ' temp-court' : ''}`;\n            div.dataset.court = idx;\n            const { players, teamA, teamB } = court;\n            const hasPlayers = players && players.length === 4;\n\n            const playerBox = (name, cls='') => `<div class=\"player-box ${cls}\">${name} ${name !== '--' ? skillLabel(name) : ''}<\/div>`;\n\n            const buttonsHTML = hasPlayers ? `\n                <button class=\"btn-primary complete-button\" data-action=\"complete\">Complete Game<\/button>\n                <div class=\"winner-selection\">\n                    <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 0.25rem;\">\n                        <button data-action=\"record-winner-a\" class=\"btn-primary\">Team A Won<\/button>\n                        <button data-action=\"record-winner-b\" class=\"btn-secondary\">Team B Won<\/button>\n                    <\/div>\n                    <div style=\"margin-top:0.25rem;\">\n                        <button data-action=\"cancel-win\" class=\"btn-toggle\" style=\"width:100%;\">Cancel<\/button>\n                    <\/div>\n                <\/div>\n                <div class=\"court-action-buttons\">\n                    <button class=\"btn-info\" data-action=\"edit-teams\">Edit<\/button>\n                    <button class=\"btn-warning\" data-action=\"sitout\">Swap<\/button>\n                <\/div>` : renderEmptyState('\ud83c\udff8', 'Waiting for players...');\n\n            div.innerHTML = `\n                <h3>${getCourtLabel(idx)}<\/h3>\n                <div class=\"court-visual\">\n                    <div class=\"court-side\">\n                        ${teamA && teamA[0] ? playerBox(teamA[0]) : playerBox('--')}\n                        ${teamA && teamA[1] ? playerBox(teamA[1]) : playerBox('--')}\n                    <\/div>\n                    <div class=\"vs-divider\">VS<\/div>\n                    <div class=\"court-side\">\n                        ${teamB && teamB[0] ? playerBox(teamB[0], 'team-b') : playerBox('--', 'team-b')}\n                        ${teamB && teamB[1] ? playerBox(teamB[1], 'team-b') : playerBox('--', 'team-b')}\n                    <\/div>\n                <\/div>\n                <div class=\"court-actions\">${buttonsHTML}<\/div>\n            `;\n            return div;\n        };\n\n        const renderSection = (title, players) => {\n            const div = document.createElement('div');\n            div.className = 'bds-card';\n            const content = players.length > 0 ? `\n                <div class=\"player-tag-container\">\n                    ${[...players]\n                        .sort((a,b) => (state.playCount[a]?.lastGameEndTime || 0) - (state.playCount[b]?.lastGameEndTime || 0))\n                        .map(p => `<span class=\"player-tag\">${skillDot(p)} ${p} (${state.playCount[p]?.games || 0})<\/span>`).join('')}\n                <\/div>\n            ` : renderEmptyState('\ud83d\ude34', 'All players are on court!');\n            div.innerHTML = `<h4>${title} (${players.length})<\/h4>${content}`;\n            return div;\n        };\n\n        const populateSelect = (selectEl, options, placeholder, currentVal) => {\n            if (!selectEl) return;\n            selectEl.innerHTML = '';\n            if (placeholder !== undefined) {\n                const ph = document.createElement('option');\n                ph.value = '';\n                ph.textContent = placeholder;\n                selectEl.appendChild(ph);\n            }\n            options.forEach(option => {\n                const opt = document.createElement('option');\n                if (typeof option === 'object' && option.value !== undefined) {\n                    opt.value = option.value;\n                    opt.textContent = option.text ?? option.value;\n                } else {\n                    opt.value = option;\n                    opt.textContent = option;\n                }\n                selectEl.appendChild(opt);\n            });\n            if (currentVal) selectEl.value = currentVal;\n        };\n\n        const updateDropdowns = () => {\n            const activePlayers = state.allPlayersList.filter(p => state.playCount[p]?.isActive);\n            const activeOptions = activePlayers.map(p => ({ value: p, text: `${p} (${getSkill(p)})` }));\n            const courtOptions = state.courtNames.map((name, i) => ({ value: i, text: name }));\n            populateSelect(get('#playerToRemove'), activeOptions, 'Select Player');\n            populateSelect(get('#skillChangePlayerSelect'), activeOptions, 'Select Player');\n            populateSelect(get('#renamePlayerSelect'), activeOptions, 'Select Player');\n            populateSelect(get('#courtToRemove'), courtOptions, 'Select Court');\n            populateSelect(get('#courtToRename'), courtOptions, 'Select Court');\n\n            populateSelect(get('#tempPlayer1'), activeOptions, 'Select Player 1', state.tempCourt?.players?.[0]);\n            populateSelect(get('#tempPlayer2'), activeOptions, 'Select Player 2', state.tempCourt?.players?.[1]);\n            populateSelect(get('#tempPlayer3'), activeOptions, 'Select Player 3', state.tempCourt?.players?.[2]);\n            populateSelect(get('#tempPlayer4'), activeOptions, 'Select Player 4', state.tempCourt?.players?.[3]);\n            if (state.tempCourt?.pending) {\n                get('#tempAfterGames').value = state.tempCourt.insertedAfterGames;\n            }\n        };\n\n        const renderPlayerStats = () => {\n            const container = get('#player-stats-content');\n            container.innerHTML = '';\n            const playersWithStats = state.allPlayersList.map(p => ({ name: p, skill: getSkill(p), ...state.playCount[p] }));\n            playersWithStats.sort((a, b) => (b.isActive - a.isActive) || (b.games - a.games) || (b.wins - a.wins));\n            if (playersWithStats.length === 0) {\n                container.innerHTML = renderEmptyState('\ud83d\udcca', 'No stats to show yet.');\n                return;\n            }\n            playersWithStats.forEach(({ name, skill, wins, losses, games, isActive, removalTimestamp }) => {\n                const row = document.createElement('div');\n                row.className = 'stat-row';\n                const gameStats = `${games} Games (${wins}W - ${losses}L)`;\n                const timeString = isActive ? '' : `<div class=\"removal-info\">Left at ${new Date(removalTimestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}<\/div>`;\n                row.innerHTML = `<span class=\"stat-player-name ${!isActive ? 'removed' : ''}\">${name} (${skill})<\/span><div class=\"stat-text\"><span>${gameStats}<\/span>${timeString}<\/div>`;\n                container.appendChild(row);\n            });\n            get('#stats-date').textContent = new Date().toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' });\n        };\n\n        const renderHistory = () => {\n            const container = get('#historyModalBody');\n            container.innerHTML = '';\n            if (state.matchHistory.length === 0) {\n                container.innerHTML = renderEmptyState('\ud83d\udcdc', 'No matches recorded.');\n                return;\n            }\n            [...state.matchHistory].reverse().forEach(match => {\n                const winnerA = match.winner === 'A' ? 'winner' : '';\n                const winnerB = match.winner === 'B' ? 'winner' : '';\n                const courtLabel = match.courtName || match.courtLabel || (match.court ? `Court ${match.court}` : 'Court');\n                const item = document.createElement('div');\n                item.className = 'history-item';\n                item.innerHTML = `\n                    <div class=\"history-court\">${courtLabel}<\/div>\n                    <div class=\"history-teams\"><span class=\"${winnerA}\">${match.teamA.join(' & ')}<\/span> vs <span class=\"${winnerB}\">${match.teamB.join(' & ')}<\/span><\/div>\n                `;\n                container.appendChild(item);\n            });\n        };\n\n        const addPlayerMidSession = () => {\n            const name = (get('#mgmtNewPlayerName').value || '').trim();\n            const skill = get('#mgmtNewPlayerSkill').value;\n            if (!name) return;\n            const lower = normalizeName(name);\n            if (state.allPlayersList.some(p => normalizeName(p) === lower)) {\n                showNotification('Player already exists.', 'error');\n                return;\n            }\n            state.allPlayersList.push(name);\n            state.playerMeta[lower] = { name, skill, isActive: true };\n            state.restingPlayers.push(name);\n            state.playCount[name] = { wins: 0, losses: 0, games: 0, isActive: true, lastGameEndTime: 0, removalTimestamp: null };\n            updatePairingsForNewPlayers([name]);\n\n            get('#mgmtNewPlayerName').value = '';\n            showNotification(`${name} (${skill}) added.`);\n            renderAll();\n        };\n\n        const changeSkillForPlayer = () => {\n            const player = get('#skillChangePlayerSelect').value;\n            const newSkill = get('#skillChangeSkillSelect').value;\n            if (!player) { showNotification('Select a player.', 'error'); return; }\n            const lower = normalizeName(player);\n            if (!state.playerMeta[lower]) { showNotification('Player not found.', 'error'); return; }\n            state.playerMeta[lower].skill = newSkill;\n            showNotification(`Updated ${player} to ${newSkill}.`);\n            renderAll();\n        };\n\n        const renamePlayer = () => {\n            const oldName = get('#renamePlayerSelect').value;\n            const newName = (get('#renamePlayerInput').value || '').trim();\n            if (!oldName) { showNotification('Select a player to rename.', 'error'); return; }\n            if (!newName) { showNotification('Enter a new name.', 'error'); return; }\n\n            const oldLower = normalizeName(oldName);\n            const newLower = normalizeName(newName);\n            if (!newLower) { showNotification('Invalid name.', 'error'); return; }\n\n            const existing = state.allPlayersList.find(p => normalizeName(p) === newLower);\n            if (existing && normalizeName(existing) !== oldLower) {\n                showNotification('Another player already has that name.', 'error');\n                return;\n            }\n\n            state.allPlayersList = state.allPlayersList.map(p => normalizeName(p) === oldLower ? newName : p);\n            state.restingPlayers = state.restingPlayers.map(p => normalizeName(p) === oldLower ? newName : p);\n\n            state.courts = state.courts.map(court => {\n                const replace = (arr) => arr.map(p => normalizeName(p) === oldLower ? newName : p);\n                return {\n                    ...court,\n                    players: replace(court.players || []),\n                    teamA: replace(court.teamA || []),\n                    teamB: replace(court.teamB || [])\n                };\n            });\n\n            state.matchHistory = state.matchHistory.map(match => ({\n                ...match,\n                teamA: match.teamA.map(p => normalizeName(p) === oldLower ? newName : p),\n                teamB: match.teamB.map(p => normalizeName(p) === oldLower ? newName : p)\n            }));\n\n            const oldKey = Object.keys(state.playCount).find(k => normalizeName(k) === oldLower) || oldName;\n            if (state.playCount[oldKey]) {\n                state.playCount[newName] = state.playCount[oldKey];\n                delete state.playCount[oldKey];\n            }\n\n            const oldMeta = state.playerMeta[oldLower] || { name: oldName, skill: 'Int', isActive: true };\n            delete state.playerMeta[oldLower];\n            state.playerMeta[newLower] = { ...oldMeta, name: newName };\n\n            if (state.tempCourt?.players?.length) {\n                state.tempCourt.players = state.tempCourt.players.map(p => normalizeName(p) === oldLower ? newName : p);\n            }\n\n            rebuildPairings();\n\n            get('#renamePlayerInput').value = '';\n            showNotification(`Renamed ${oldName} to ${newName}.`);\n            renderAll();\n        };\n\n        const removePlayer = () => {\n            const player = get('#playerToRemove').value;\n            if (!player) return;\n            if (state.courts.some(c => c.players.includes(player))) {\n                showNotification('Cannot remove a player who is on a court.', 'error');\n                return;\n            }\n            if (state.playCount[player]) {\n                state.playCount[player].isActive = false;\n                state.playCount[player].removalTimestamp = new Date().toISOString();\n            }\n            state.restingPlayers = state.restingPlayers.filter(p => p !== player);\n            showNotification(`${player} has been removed.`);\n            renderAll();\n        };\n\n        const addCourt = () => {\n            const totalActivePlayers = state.allPlayersList.filter(p => state.playCount[p]?.isActive).length;\n            const maxPossibleCourts = Math.floor(totalActivePlayers \/ 4);\n            if (state.courts.length >= maxPossibleCourts) {\n                showNotification('Not enough players to add a new court.', 'error');\n                return;\n            }\n            const courtName = (prompt('Enter a name for the new court:') || '').trim();\n            if (!courtName) {\n                showNotification('Court name is required.', 'error');\n                return;\n            }\n            state.courts.push({ players: [], teamA: [], teamB: [], startTime: null });\n            state.courtNames.push(courtName);\n            showNotification('A new court has been added.');\n            refillAllEmptyCourts();\n            renderAll();\n        };\n\n        const removeCourt = () => {\n            const courtVal = get('#courtToRemove').value;\n            if (courtVal === '') { showNotification('Please select a court.', 'error'); return; }\n            const courtIndex = parseInt(courtVal);\n            if (isNaN(courtIndex) || courtIndex < 0 || courtIndex >= state.courts.length) {\n                showNotification('Invalid court selected.', 'error'); return;\n            }\n            const court = state.courts[courtIndex];\n            if (court.players && court.players.length > 0) {\n                updatePairingStats(court.teamA, court.teamB, -1);\n                state.restingPlayers.push(...court.players);\n            }\n            state.courts.splice(courtIndex, 1);\n            state.courtNames.splice(courtIndex, 1);\n            showNotification(`Court removed.`);\n            renderAll();\n        };\n\n        const renameCourt = () => {\n            const courtVal = get('#courtToRename').value;\n            const newName = (get('#courtRenameInput').value || '').trim();\n            if (courtVal === '') { showNotification('Select a court to rename.', 'error'); return; }\n            if (!newName) { showNotification('Enter a new court name.', 'error'); return; }\n            const courtIndex = parseInt(courtVal);\n            if (isNaN(courtIndex) || courtIndex < 0 || courtIndex >= state.courts.length) {\n                showNotification('Invalid court selected.', 'error'); return; }\n            state.courtNames[courtIndex] = newName;\n            get('#courtRenameInput').value = '';\n            showNotification(`Court renamed to ${newName}.`);\n            renderAll();\n        };\n\n        const scheduleTempCourt = () => {\n            const p1 = get('#tempPlayer1').value;\n            const p2 = get('#tempPlayer2').value;\n            const p3 = get('#tempPlayer3').value;\n            const p4 = get('#tempPlayer4').value;\n            const afterGames = parseInt(get('#tempAfterGames').value);\n\n            const players = [p1, p2, p3, p4].filter(Boolean);\n            if (players.length !== 4 || new Set(players).size !== 4) {\n                showNotification('Select 4 unique players.', 'error');\n                return;\n            }\n            if (isNaN(afterGames) || afterGames < 0) {\n                showNotification('Enter a valid number of games.', 'error');\n                return;\n            }\n\n            state.tempCourt = {\n                pending: true,\n                active: false,\n                players: players,\n                insertedAfterGames: afterGames,\n                readyAtGameCount: state.completedGameCount + afterGames,\n                createdAt: new Date().toISOString()\n            };\n\n            showNotification('Custom game scheduled.');\n            renderAll();\n        };\n\n        const cancelTempCourt = () => {\n            if (!state.tempCourt?.pending && !state.tempCourt?.active) {\n                showNotification('No custom game to cancel.', 'error');\n                return;\n            }\n            if (state.tempCourt.active) {\n                showNotification('Cannot cancel while custom game is active.', 'error');\n                return;\n            }\n            state.tempCourt = {\n                pending: false,\n                active: false,\n                players: [],\n                insertedAfterGames: 0,\n                readyAtGameCount: 0,\n                createdAt: null\n            };\n            showNotification('Custom game canceled.');\n            renderAll();\n        };\n\n        const openEditModal = (idx) => {\n            const court = state.courts[idx];\n            get('#managementModal').dataset.editingCourt = idx;\n            get('#editCourtTitle').textContent = `Edit Teams for ${getCourtLabel(idx)}`;\n            populateSelect(get('#editPlayerA1'), court.players, 'Select Player', court.teamA[0]);\n            populateSelect(get('#editPlayerA2'), court.players, 'Select Player', court.teamA[1]);\n            populateSelect(get('#editPlayerB1'), court.players, 'Select Player', court.teamB[0]);\n            populateSelect(get('#editPlayerB2'), court.players, 'Select Player', court.teamB[1]);\n            get('#mainManagementPanel').classList.add('hidden');\n            get('#editTeamsPanel').classList.remove('hidden');\n            openModal('managementModal');\n        };\n\n        const openSwapModal = (idx) => {\n            const court = state.courts[idx];\n            get('#managementModal').dataset.editingCourt = idx;\n            get('#swapCourtTitle').textContent = `Swap Player on ${getCourtLabel(idx)}`;\n            populateSelect(get('#playerToSwapOut'), court.players, 'Select player on court');\n            populateSelect(get('#playerToSwapIn'), state.restingPlayers, 'Select resting player');\n            get('#mainManagementPanel').classList.add('hidden');\n            get('#swapPlayerPanel').classList.remove('hidden');\n            openModal('managementModal');\n        };\n\n        const renderPendingList = () => {\n            const list = get('#pendingPlayersList');\n            if (!list) return;\n            list.innerHTML = '';\n            if (pendingPlayers.length === 0) {\n                list.innerHTML = renderEmptyState('\u2795', 'Add players one by one to get started.');\n            } else {\n                pendingPlayers.forEach((p, idx) => {\n                    const row = document.createElement('div');\n                    row.className = 'pending-item';\n                    row.innerHTML = `\n                        <div class=\"meta\">${p.name} <span class=\"player-skill\">${p.skill}<\/span><\/div>\n                        <button class=\"remove-btn\" data-remove-index=\"${idx}\">Remove<\/button>\n                    `;\n                    list.appendChild(row);\n                });\n            }\n            validateStartEligibility();\n        };\n\n        const validateStartEligibility = () => {\n            const startBtn = get('#startBtn');\n            const courts = parseInt(get('#courtCount').value) || 0;\n            const ok = pendingPlayers.length >= 4 && courts >= 1 && courts <= Math.floor(pendingPlayers.length \/ 4);\n            startBtn.disabled = !ok;\n        };\n\n        const addPendingPlayer = () => {\n            const name = (get('#playerNameInput').value || '').trim();\n            const skill = get('#playerSkillSelect').value;\n            if (!name) { showNotification('Enter a player name.', 'error'); return; }\n            const lower = normalizeName(name);\n            if (!lower) { showNotification('Invalid name.', 'error'); return; }\n            if (pendingPlayers.some(p => p.lower === lower)) {\n                showNotification('Player already added.', 'error'); return;\n            }\n            pendingPlayers.push({ name, lower, skill });\n            get('#playerNameInput').value = '';\n            renderPendingList();\n        };\n\n        appWrapper.addEventListener('click', (e) => {\n            const target = e.target.closest('button');\n            if (!target) return;\n\n            const id = target.id;\n            const action = target.dataset.action;\n\n            const actions = {\n                addPendingPlayerBtn: addPendingPlayer,\n                startBtn: initializeGameFromPending,\n                aboutBtn: () => openModal('aboutModal'),\n\n                helpBtn: () => openModal('helpModal'),\n                statsBtn: () => openModal('statsModal', renderPlayerStats),\n                historyBtn: () => openModal('historyModal', renderHistory),\n                manageGameBtn: () => openModal('managementModal'),\n\n                undoBtn: () => commandProcessor.undo(),\n                addPlayerBtn: addPlayerMidSession,\n                changeSkillBtn: changeSkillForPlayer,\n                renamePlayerBtn: renamePlayer,\n                removePlayerBtn: removePlayer,\n                addCourtBtn: addCourt,\n                removeCourtBtn: removeCourt,\n                renameCourtBtn: renameCourt,\n                scheduleTempBtn: scheduleTempCourt,\n                cancelTempBtn: cancelTempCourt,\n                resetGameBtn: () => { if (confirm('Are you sure? This will erase all data.')) { localStorage.removeItem('badmintonGameState'); window.location.reload(); } },\n                saveTeamsBtn: () => {\n                    const idx = parseInt(get('#managementModal').dataset.editingCourt);\n                    const teamA = [get('#editPlayerA1').value, get('#editPlayerA2').value];\n                    const teamB = [get('#editPlayerB1').value, get('#editPlayerB2').value];\n                    commandProcessor.execute(SaveTeamsCommand(idx, teamA, teamB));\n                },\n                confirmSwapBtn: () => {\n                    const idx = parseInt(get('#managementModal').dataset.editingCourt);\n                    const pOut = get('#playerToSwapOut').value;\n                    const pIn = get('#playerToSwapIn').value;\n                    commandProcessor.execute(SwapPlayerCommand(idx, pOut, pIn));\n                }\n            };\n\n            if (actions[id]) { actions[id](); return; }\n\n            if (target.matches('.close-modal-btn')) {\n                const modal = target.closest('.modal-overlay');\n                if (modal) closeModal(modal.id);\n                return;\n            }\n\n            if (action) {\n                const courtDiv = target.closest('.court');\n                if (courtDiv) {\n                    const idx = parseInt(courtDiv.dataset.court);\n                    if (action === 'complete' || action === 'cancel-win') {\n                        get('.winner-selection', courtDiv).style.display = action === 'complete' ? 'block' : 'none';\n                        get('.complete-button', courtDiv).style.display = action === 'complete' ? 'none' : 'block';\n                        get('.court-action-buttons', courtDiv).style.display = action === 'complete' ? 'none' : 'grid';\n                    } else if (action === 'record-winner-a') {\n                        commandProcessor.execute(RecordWinnerCommand(idx, 'A'));\n                    } else if (action === 'record-winner-b') {\n                        commandProcessor.execute(RecordWinnerCommand(idx, 'B'));\n                    } else if (action === 'edit-teams') {\n                        openEditModal(idx);\n                    } else if (action === 'sitout') {\n                        openSwapModal(idx);\n                    }\n                } else if (action === 'cancel-submodal') {\n                    resetManagementModal();\n                }\n            }\n        });\n\n        get('#pendingPlayersList').addEventListener('click', (e) => {\n            const btn = e.target.closest('button[data-remove-index]');\n            if (!btn) return;\n            const idx = parseInt(btn.dataset.removeIndex);\n            if (!isNaN(idx)) {\n                pendingPlayers.splice(idx, 1);\n                renderPendingList();\n            }\n        });\n\n        get('#theme-checkbox').addEventListener('change', (e) => {\n            const theme = e.target.checked ? 'dark' : 'light';\n            localStorage.setItem('theme', theme);\n            applyTheme(theme);\n        });\n\n        appWrapper.addEventListener('click', e => { if (e.target.classList.contains('modal-overlay')) closeModal(e.target.id) });\n\n        const editPanel = get('#editTeamsPanel');\n        editPanel.addEventListener('focusin', e => { if(e.target.tagName === 'SELECT') e.target.dataset.previousValue = e.target.value; });\n        editPanel.addEventListener('change', e => {\n            if(e.target.tagName !== 'SELECT') return;\n            const changedSelect = e.target;\n            const newPlayer = changedSelect.value;\n            const oldPlayer = changedSelect.dataset.previousValue;\n            if (newPlayer === oldPlayer) return;\n            const otherSelect = Array.from(getAll('select', editPanel)).find(sel => sel !== changedSelect && sel.value === newPlayer);\n            if (otherSelect) {\n                otherSelect.value = oldPlayer;\n            }\n            changedSelect.dataset.previousValue = newPlayer;\n        });\n\n        get('#courtCount').addEventListener('input', validateStartEligibility);\n        get('#playerNameInput').addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); addPendingPlayer(); } });\n\n        loadTheme();\n        loadState();\n        renderPendingList();\n    });\n    <\/script>\n    <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1018","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/badminton.ghancaballes.com\/skilled\/wp-json\/wp\/v2\/pages\/1018","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/badminton.ghancaballes.com\/skilled\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/badminton.ghancaballes.com\/skilled\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/badminton.ghancaballes.com\/skilled\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/badminton.ghancaballes.com\/skilled\/wp-json\/wp\/v2\/comments?post=1018"}],"version-history":[{"count":7,"href":"https:\/\/badminton.ghancaballes.com\/skilled\/wp-json\/wp\/v2\/pages\/1018\/revisions"}],"predecessor-version":[{"id":1026,"href":"https:\/\/badminton.ghancaballes.com\/skilled\/wp-json\/wp\/v2\/pages\/1018\/revisions\/1026"}],"wp:attachment":[{"href":"https:\/\/badminton.ghancaballes.com\/skilled\/wp-json\/wp\/v2\/media?parent=1018"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}