|
| 1 | +<!DOCTYPE html> |
| 2 | +<html> |
| 3 | +<head> |
| 4 | + <title>MySQLGenius</title> |
| 5 | + <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 6 | + <style> |
| 7 | + *, *::before, *::after { box-sizing: border-box; } |
| 8 | + body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; background: #f5f5f5; color: #333; margin: 0; font-size: 14px; line-height: 1.5; } |
| 9 | + .mg-container { max-width: 1400px; margin: 0 auto; padding: 20px; } |
| 10 | + h4 { margin: 0 0 16px; font-size: 18px; } |
| 11 | + |
| 12 | + /* Tabs */ |
| 13 | + .mg-tabs { display: flex; border-bottom: 2px solid #dee2e6; margin-bottom: 0; } |
| 14 | + .mg-tab { padding: 8px 16px; cursor: pointer; border: 1px solid transparent; border-bottom: none; margin-bottom: -2px; border-radius: 4px 4px 0 0; background: none; font-size: 14px; color: #555; } |
| 15 | + .mg-tab:hover { color: #000; } |
| 16 | + .mg-tab.active { background: #fff; border-color: #dee2e6; border-bottom-color: #fff; color: #000; font-weight: 500; } |
| 17 | + .mg-tab-content { display: none; background: #fff; border: 1px solid #dee2e6; border-top: none; padding: 16px; } |
| 18 | + .mg-tab-content.active { display: block; } |
| 19 | + |
| 20 | + /* Forms */ |
| 21 | + label { display: block; font-weight: 500; margin-bottom: 4px; font-size: 13px; } |
| 22 | + select, input[type="number"], input[type="text"], textarea { border: 1px solid #ced4da; border-radius: 4px; padding: 6px 10px; font-size: 13px; width: 100%; font-family: inherit; } |
| 23 | + select:focus, input:focus, textarea:focus { outline: none; border-color: #80bdff; box-shadow: 0 0 0 2px rgba(0,123,255,.15); } |
| 24 | + textarea { font-family: "SF Mono", "Fira Code", "Fira Mono", Menlo, Consolas, monospace; resize: vertical; } |
| 25 | + textarea[readonly] { background: #f8f9fa; } |
| 26 | + |
| 27 | + /* Grid helpers */ |
| 28 | + .mg-row { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; } |
| 29 | + .mg-col-1 { flex: 0 0 80px; } |
| 30 | + .mg-col-2 { flex: 0 0 160px; } |
| 31 | + .mg-col-3 { flex: 0 0 240px; } |
| 32 | + .mg-col-4 { flex: 0 0 320px; } |
| 33 | + .mg-col-grow { flex: 1 1 200px; } |
| 34 | + .mg-field { margin-bottom: 12px; } |
| 35 | + |
| 36 | + /* Buttons */ |
| 37 | + .mg-btn { display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; border: 1px solid transparent; border-radius: 4px; font-size: 13px; cursor: pointer; font-family: inherit; white-space: nowrap; } |
| 38 | + .mg-btn:disabled { opacity: .5; cursor: not-allowed; } |
| 39 | + .mg-btn-primary { background: #007bff; color: #fff; border-color: #007bff; } |
| 40 | + .mg-btn-primary:hover:not(:disabled) { background: #0069d9; } |
| 41 | + .mg-btn-outline { background: #fff; color: #007bff; border-color: #007bff; } |
| 42 | + .mg-btn-outline:hover:not(:disabled) { background: #e7f1ff; } |
| 43 | + .mg-btn-outline-secondary { background: #fff; color: #6c757d; border-color: #6c757d; } |
| 44 | + .mg-btn-outline-secondary:hover:not(:disabled) { background: #f8f9fa; } |
| 45 | + .mg-btn-outline-danger { background: #fff; color: #dc3545; border-color: #dc3545; padding: 4px 8px; } |
| 46 | + .mg-btn-outline-danger:hover:not(:disabled) { background: #ffeef0; } |
| 47 | + .mg-btn-sm { padding: 3px 8px; font-size: 12px; } |
| 48 | + |
| 49 | + /* Badge */ |
| 50 | + .mg-badge { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 12px; font-weight: 500; } |
| 51 | + .mg-badge-info { background: #d1ecf1; color: #0c5460; } |
| 52 | + .mg-badge-warning { background: #fff3cd; color: #856404; } |
| 53 | + .mg-badge-danger { background: #f8d7da; color: #721c24; } |
| 54 | + .mg-badge-secondary { background: #e2e3e5; color: #383d41; } |
| 55 | + .mg-badge-success { background: #d4edda; color: #155724; } |
| 56 | + |
| 57 | + /* Alert */ |
| 58 | + .mg-alert { padding: 10px 14px; border-radius: 4px; margin-bottom: 12px; font-size: 13px; } |
| 59 | + .mg-alert-danger { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; } |
| 60 | + .mg-alert-warning { background: #fff3cd; color: #856404; border: 1px solid #ffeeba; } |
| 61 | + .mg-alert-info { background: #d1ecf1; color: #0c5460; border: 1px solid #bee5eb; } |
| 62 | + |
| 63 | + /* Card */ |
| 64 | + .mg-card { border: 1px solid #dee2e6; border-radius: 4px; margin-bottom: 12px; } |
| 65 | + .mg-card-header { padding: 8px 12px; background: #f8f9fa; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; font-size: 13px; } |
| 66 | + .mg-card-body { padding: 12px; } |
| 67 | + .mg-card-toggle { cursor: pointer; color: #007bff; text-decoration: none; font-size: 13px; } |
| 68 | + .mg-card-toggle:hover { text-decoration: underline; } |
| 69 | + |
| 70 | + /* Stat grid */ |
| 71 | + .mg-stat-grid { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; font-size: 13px; } |
| 72 | + .mg-stat-grid .mg-stat-label { color: #666; } |
| 73 | + .mg-stat-grid .mg-stat-value { text-align: right; font-weight: 500; } |
| 74 | + .mg-usage-bar { background: #e9ecef; border-radius: 4px; height: 20px; position: relative; overflow: hidden; } |
| 75 | + .mg-usage-bar-fill { height: 100%; border-radius: 4px; transition: width 0.3s; } |
| 76 | + .mg-usage-bar-text { position: absolute; top: 0; left: 0; right: 0; text-align: center; line-height: 20px; font-size: 11px; font-weight: 500; } |
| 77 | + |
| 78 | + /* Table */ |
| 79 | + .mg-table-wrap { overflow-x: auto; } |
| 80 | + table.mg-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; } |
| 81 | + .mg-table th { padding: 10px 12px; text-align: left; white-space: nowrap; font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; color: #5a6770; background: #f1f3f5; border-bottom: 2px solid #d0d7de; user-select: none; } |
| 82 | + .mg-table th.mg-sortable { cursor: pointer; position: relative; padding-right: 20px; } |
| 83 | + .mg-table th.mg-sortable:hover { color: #333; } |
| 84 | + .mg-table th.mg-sortable::after { content: '\2195'; position: absolute; right: 6px; opacity: 0.3; font-size: 10px; } |
| 85 | + .mg-table th.mg-sort-asc::after { content: '\2191'; opacity: 0.8; } |
| 86 | + .mg-table th.mg-sort-desc::after { content: '\2193'; opacity: 0.8; } |
| 87 | + .mg-table th:first-child { border-top-left-radius: 6px; } |
| 88 | + .mg-table th:last-child { border-top-right-radius: 6px; } |
| 89 | + .mg-table td { padding: 8px 12px; border-bottom: 1px solid #eaecef; vertical-align: top; } |
| 90 | + .mg-table tbody tr { transition: background-color 0.15s ease; } |
| 91 | + .mg-table tbody tr:hover { background: #f0f6ff; } |
| 92 | + .mg-table tbody tr:nth-child(even) { background: #fafbfc; } |
| 93 | + .mg-table tbody tr:nth-child(even):hover { background: #f0f6ff; } |
| 94 | + .mg-table tbody tr:last-child td { border-bottom: none; } |
| 95 | + .mg-table em.null { color: #999; font-style: italic; } |
| 96 | + .mg-table .redacted { color: #999; } |
| 97 | + |
| 98 | + /* Numeric table cells */ |
| 99 | + .mg-table td.mg-num { text-align: right; font-variant-numeric: tabular-nums; font-family: "SF Mono", "Fira Code", "Fira Mono", Menlo, Consolas, monospace; font-size: 12px; white-space: nowrap; } |
| 100 | + |
| 101 | + /* SQL code blocks in tables */ |
| 102 | + .mg-sql-block { display: block; padding: 6px 8px; background: #1e1e2e; color: #cdd6f4; border-radius: 5px; font-family: "SF Mono", "Fira Code", "Fira Mono", Menlo, Consolas, monospace; font-size: 11.5px; line-height: 1.5; word-break: break-word; white-space: pre-wrap; max-height: 120px; overflow-y: auto; border: 1px solid #313244; } |
| 103 | + .mg-sql-block::-webkit-scrollbar { width: 4px; } |
| 104 | + .mg-sql-block::-webkit-scrollbar-track { background: transparent; } |
| 105 | + .mg-sql-block::-webkit-scrollbar-thumb { background: #585b70; border-radius: 2px; } |
| 106 | + |
| 107 | + /* SQL syntax colors (Catppuccin Mocha inspired) */ |
| 108 | + .mg-sql-kw { color: #cba6f7; font-weight: 600; } |
| 109 | + .mg-sql-fn { color: #89b4fa; } |
| 110 | + .mg-sql-str { color: #a6e3a1; } |
| 111 | + .mg-sql-num { color: #fab387; } |
| 112 | + .mg-sql-op { color: #89dceb; } |
| 113 | + .mg-sql-comment { color: #6c7086; font-style: italic; } |
| 114 | + .mg-sql-tbl { color: #f9e2af; } |
| 115 | + .mg-sql-star { color: #f38ba8; font-weight: 700; } |
| 116 | + .mg-sql-punc { color: #9399b2; } |
| 117 | + .mg-sql-placeholder { color: #74c7ec; font-style: italic; } |
| 118 | + |
| 119 | + /* Duration color coding */ |
| 120 | + .mg-dur-fast { color: #1a7f37; } |
| 121 | + .mg-dur-moderate { color: #9a6700; } |
| 122 | + .mg-dur-slow { color: #cf222e; font-weight: 600; } |
| 123 | + |
| 124 | + /* Checkbox grid */ |
| 125 | + .mg-checks { display: flex; flex-wrap: wrap; gap: 4px 16px; } |
| 126 | + .mg-check { display: flex; align-items: center; gap: 4px; font-size: 13px; cursor: pointer; } |
| 127 | + .mg-check input { margin: 0; } |
| 128 | + .mg-check .type-hint { color: #999; font-size: 11px; } |
| 129 | + |
| 130 | + /* Inline links */ |
| 131 | + .mg-link { color: #007bff; cursor: pointer; text-decoration: none; font-size: 12px; margin-left: 8px; } |
| 132 | + .mg-link:hover { text-decoration: underline; } |
| 133 | + |
| 134 | + /* Spinner */ |
| 135 | + @keyframes mg-spin { to { transform: rotate(360deg); } } |
| 136 | + .mg-spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid #ccc; border-top-color: #007bff; border-radius: 50%; animation: mg-spin .6s linear infinite; } |
| 137 | + |
| 138 | + /* Utilities */ |
| 139 | + .mg-hidden { display: none !important; } |
| 140 | + .mg-mt { margin-top: 16px; } |
| 141 | + .mg-mb { margin-bottom: 12px; } |
| 142 | + .mg-text-muted { color: #888; font-size: 13px; } |
| 143 | + .mg-text-center { text-align: center; padding: 24px 0; } |
| 144 | + code { font-size: 12px; word-break: break-all; background: #f0f1f3; padding: 2px 6px; border-radius: 3px; color: #24292f; } |
| 145 | + pre.mg-pre { background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; font-size: 12px; } |
| 146 | + |
| 147 | + /* Theme toggle */ |
| 148 | + .mg-theme-toggle { background: none; border: 1px solid #ced4da; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 14px; line-height: 1; color: inherit; } |
| 149 | + .mg-theme-toggle:hover { background: #e9ecef; } |
| 150 | + |
| 151 | + /* --- Dark Theme --- */ |
| 152 | + [data-theme="dark"] body, |
| 153 | + [data-theme="dark"] { background: #161b22; color: #c9d1d9; } |
| 154 | + [data-theme="dark"] .mg-container { color: #c9d1d9; } |
| 155 | + [data-theme="dark"] .mg-tabs { border-bottom-color: #30363d; } |
| 156 | + [data-theme="dark"] .mg-tab { color: #8b949e; } |
| 157 | + [data-theme="dark"] .mg-tab:hover { color: #c9d1d9; } |
| 158 | + [data-theme="dark"] .mg-tab.active { background: #0d1117; border-color: #30363d; border-bottom-color: #0d1117; color: #c9d1d9; } |
| 159 | + [data-theme="dark"] .mg-tab-content { background: #0d1117; border-color: #30363d; } |
| 160 | + [data-theme="dark"] select, |
| 161 | + [data-theme="dark"] input[type="number"], |
| 162 | + [data-theme="dark"] input[type="text"], |
| 163 | + [data-theme="dark"] textarea { background: #0d1117; color: #c9d1d9; border-color: #30363d; } |
| 164 | + [data-theme="dark"] select:focus, |
| 165 | + [data-theme="dark"] input:focus, |
| 166 | + [data-theme="dark"] textarea:focus { border-color: #58a6ff; box-shadow: 0 0 0 2px rgba(88,166,255,.15); } |
| 167 | + [data-theme="dark"] textarea[readonly] { background: #161b22; } |
| 168 | + [data-theme="dark"] label { color: #c9d1d9; } |
| 169 | + [data-theme="dark"] .mg-btn-primary { background: #238636; border-color: #238636; } |
| 170 | + [data-theme="dark"] .mg-btn-primary:hover:not(:disabled) { background: #2ea043; } |
| 171 | + [data-theme="dark"] .mg-btn-outline { background: #0d1117; color: #58a6ff; border-color: #30363d; } |
| 172 | + [data-theme="dark"] .mg-btn-outline:hover:not(:disabled) { background: #161b22; border-color: #58a6ff; } |
| 173 | + [data-theme="dark"] .mg-btn-outline-secondary { background: #0d1117; color: #8b949e; border-color: #30363d; } |
| 174 | + [data-theme="dark"] .mg-btn-outline-secondary:hover:not(:disabled) { background: #161b22; } |
| 175 | + [data-theme="dark"] .mg-btn-outline-danger { background: #0d1117; color: #f85149; border-color: #30363d; } |
| 176 | + [data-theme="dark"] .mg-btn-outline-danger:hover:not(:disabled) { background: #1c0d0d; } |
| 177 | + [data-theme="dark"] .mg-badge-info { background: #0d2a3a; color: #58a6ff; } |
| 178 | + [data-theme="dark"] .mg-badge-warning { background: #2d2000; color: #d29922; } |
| 179 | + [data-theme="dark"] .mg-badge-danger { background: #2d0d0d; color: #f85149; } |
| 180 | + [data-theme="dark"] .mg-badge-secondary { background: #21262d; color: #8b949e; } |
| 181 | + [data-theme="dark"] .mg-badge-success { background: #0d2d1a; color: #3fb950; } |
| 182 | + [data-theme="dark"] .mg-alert-danger { background: #2d0d0d; color: #f85149; border-color: #3d1414; } |
| 183 | + [data-theme="dark"] .mg-alert-warning { background: #2d2000; color: #d29922; border-color: #3d2e00; } |
| 184 | + [data-theme="dark"] .mg-alert-info { background: #0d2a3a; color: #58a6ff; border-color: #0d3a5a; } |
| 185 | + [data-theme="dark"] .mg-card { border-color: #30363d; } |
| 186 | + [data-theme="dark"] .mg-card-header { background: #161b22; border-bottom-color: #30363d; color: #c9d1d9; } |
| 187 | + [data-theme="dark"] .mg-card-toggle { color: #58a6ff; } |
| 188 | + [data-theme="dark"] .mg-stat-grid .mg-stat-label { color: #8b949e; } |
| 189 | + [data-theme="dark"] .mg-usage-bar { background: #21262d; } |
| 190 | + [data-theme="dark"] .mg-table th { background: #161b22; color: #8b949e; border-bottom-color: #30363d; } |
| 191 | + [data-theme="dark"] .mg-table th.mg-sortable:hover { color: #c9d1d9; } |
| 192 | + [data-theme="dark"] .mg-table td { border-bottom-color: #21262d; } |
| 193 | + [data-theme="dark"] .mg-table tbody tr:hover { background: #1c2128; } |
| 194 | + [data-theme="dark"] .mg-table tbody tr:nth-child(even) { background: #0d1117; } |
| 195 | + [data-theme="dark"] .mg-table tbody tr:nth-child(even):hover { background: #1c2128; } |
| 196 | + [data-theme="dark"] .mg-table em.null { color: #484f58; } |
| 197 | + [data-theme="dark"] .mg-table .redacted { color: #484f58; } |
| 198 | + [data-theme="dark"] .mg-dur-fast { color: #3fb950; } |
| 199 | + [data-theme="dark"] .mg-dur-moderate { color: #d29922; } |
| 200 | + [data-theme="dark"] .mg-dur-slow { color: #f85149; } |
| 201 | + [data-theme="dark"] code { background: #21262d; color: #c9d1d9; } |
| 202 | + [data-theme="dark"] pre.mg-pre { background: #161b22; color: #c9d1d9; } |
| 203 | + [data-theme="dark"] .mg-link { color: #58a6ff; } |
| 204 | + [data-theme="dark"] .mg-spinner { border-color: #30363d; border-top-color: #58a6ff; } |
| 205 | + [data-theme="dark"] .mg-text-muted { color: #8b949e; } |
| 206 | + [data-theme="dark"] .mg-check .type-hint { color: #484f58; } |
| 207 | + [data-theme="dark"] .mg-theme-toggle { border-color: #30363d; color: #c9d1d9; } |
| 208 | + [data-theme="dark"] .mg-theme-toggle:hover { background: #21262d; } |
| 209 | + [data-theme="dark"] .mg-db-switcher select { background: #0d1117; color: #c9d1d9; border-color: #30363d; } |
| 210 | + [data-theme="dark"] .mg-db-badge { background: #0d2a3a; color: #58a6ff; } |
| 211 | + </style> |
| 212 | +</head> |
| 213 | +<body> |
| 214 | + <script> |
| 215 | + (function() { |
| 216 | + var saved = localStorage.getItem('mg-theme'); |
| 217 | + var theme = saved || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); |
| 218 | + document.documentElement.setAttribute('data-theme', theme); |
| 219 | + })(); |
| 220 | + </script> |
| 221 | + <div class="mg-container"> |
| 222 | + <%= yield %> |
| 223 | + </div> |
| 224 | +</body> |
| 225 | +</html> |
0 commit comments