:root{--bg:#0d0d0d;--panel-bg:#1a1a1a;--panel-border:#2a2a2a;--text:#e0e0e0;--text-dim:#666;--accent:#00e5ff;--accent-dim:#00e5ff26;--red:#f44;--green:#00e676;--orange:#ff9800;--yellow:#ffd600;--mono:"SF Mono", "Fira Code", "Consolas", monospace;--sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--fs-base:clamp(.8rem, .7rem + .3vw, 1rem);--fs-xs:clamp(.625rem, .55rem + .2vw, .75rem);--fs-sm:clamp(.6875rem, .6rem + .25vw, .8125rem);--fs-md:clamp(.75rem, .65rem + .3vw, .875rem);--fs-lg:clamp(.875rem, .75rem + .4vw, 1.125rem);--fs-xl:clamp(1rem, .85rem + .5vw, 1.375rem);--fs-2xl:clamp(1.125rem, .95rem + .6vw, 1.625rem);--sp-xs:clamp(.125rem, .1rem + .1vw, .25rem);--sp-sm:clamp(.25rem, .2rem + .15vw, .5rem);--sp-md:clamp(.5rem, .4rem + .3vw, .75rem);--sp-lg:clamp(.75rem, .6rem + .4vw, 1rem);--sp-xl:clamp(1rem, .8rem + .5vw, 1.5rem);--radius-sm:3px;--radius-md:clamp(3px, .2rem + .1vw, 5px);--radius-lg:clamp(4px, .25rem + .15vw, 6px);--touch-min:44px}*,:before,:after{box-sizing:border-box;margin:0;padding:0}html,body,#root{background:var(--bg);width:100%;min-height:100dvh;color:var(--text);font-family:var(--sans);font-size:var(--fs-base);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;line-height:1.5}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:var(--panel-bg)}::-webkit-scrollbar-thumb{background:var(--panel-border);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--text-dim)}.app{flex-direction:column;height:100dvh;display:flex;overflow:hidden}.app-header{padding:var(--sp-sm) var(--sp-lg);background:var(--panel-bg);border-bottom:1px solid var(--panel-border);justify-content:space-between;align-items:center;gap:var(--sp-md);flex-shrink:0;display:flex}.header-left{align-items:baseline;gap:var(--sp-md);flex-shrink:0;display:flex}.header-left h1{font-size:var(--fs-xl);color:var(--accent);letter-spacing:1px;font-weight:600}.device-name{font-size:var(--fs-sm);color:var(--text-dim);font-family:var(--mono)}.header-center{align-items:center;gap:var(--sp-md);flex-wrap:wrap;justify-content:center;display:flex}.status-indicator{align-items:center;gap:var(--sp-sm);padding:var(--sp-xs) var(--sp-md);border-radius:var(--radius-md);font-size:var(--fs-xs);letter-spacing:.5px;white-space:nowrap;font-weight:600;display:flex}.status-indicator.ready{color:var(--green);background:#00e6761a;border:1px solid #00e6764d}.status-indicator.disconnected{color:var(--red);background:#ff44441a;border:1px solid #ff44444d}.status-dot{border-radius:50%;width:8px;min-width:8px;height:8px;min-height:8px}.status-indicator.ready .status-dot{background:var(--green);animation:2s infinite pulse}.status-indicator.disconnected .status-dot{background:var(--red)}@keyframes pulse{0%,to{opacity:1}50%{opacity:.4}}.state-breakdown{gap:var(--sp-xs);flex-wrap:wrap;display:flex}.state-badge{font-size:var(--fs-xs);padding:var(--sp-xs) var(--sp-sm);border-radius:var(--radius-sm);font-family:var(--mono);white-space:nowrap;font-weight:500}.state-badge[data-state=ready]{color:var(--green);background:#00e6761a}.state-badge[data-state=disconnected]{color:var(--red);background:#ff44441a}.header-right{flex-shrink:0}.connect-btn{padding:var(--sp-sm) var(--sp-lg);border:1px solid var(--accent);border-radius:var(--radius-md);color:var(--accent);font-family:var(--sans);font-size:var(--fs-sm);cursor:pointer;letter-spacing:.5px;min-height:var(--touch-min);white-space:nowrap;background:0 0;font-weight:600;transition:all .15s}.connect-btn:hover{background:var(--accent-dim)}.connect-btn:active{background:var(--accent);color:var(--bg)}.app-nav{background:var(--panel-bg);border-bottom:1px solid var(--panel-border);padding:0 var(--sp-lg);-webkit-overflow-scrolling:touch;scrollbar-width:none;flex-shrink:0;gap:0;display:flex;overflow-x:auto}.app-nav::-webkit-scrollbar{display:none}.nav-btn{padding:var(--sp-sm) var(--sp-lg);min-height:var(--touch-min);color:var(--text-dim);font-family:var(--sans);font-size:var(--fs-sm);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-bottom:2px solid #0000;font-weight:500;transition:all .15s}.nav-btn:hover{color:var(--text)}.nav-btn.active{color:var(--accent);border-bottom-color:var(--accent)}.app-main{flex:1;overflow:hidden auto}.dashboard{gap:var(--sp-sm);padding:var(--sp-sm);grid-template-columns:repeat(3,1fr);max-width:100%;display:grid}.dashboard-section{background:var(--panel-bg);border:1px solid var(--panel-border);border-radius:var(--radius-lg);padding:var(--sp-sm) var(--sp-md);min-width:0}.dashboard-section h3{font-size:var(--fs-xs);color:var(--accent);letter-spacing:1.5px;text-transform:uppercase;margin-bottom:var(--sp-sm);padding-bottom:var(--sp-xs);border-bottom:1px solid var(--panel-border);font-weight:600}.graph-section{grid-column:1/-1}.graph-grid{gap:var(--sp-xs);grid-template-columns:repeat(auto-fill,minmax(clamp(140px,20vw,280px),1fr));display:grid}.signal-row{padding:var(--sp-xs) 0;align-items:center;gap:var(--sp-xs);font-size:var(--fs-sm);display:flex}.signal-label{color:var(--text-dim);min-width:0;font-size:var(--fs-xs);text-overflow:ellipsis;white-space:nowrap;flex:auto;overflow:hidden}.signal-value{font-family:var(--mono);color:var(--text);text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:0;font-weight:600}.signal-value.unavailable{color:var(--text-dim);font-style:italic}.signal-unit{color:var(--text-dim);font-size:var(--fs-xs);flex:none;min-width:0}.signal-status{color:var(--orange);font-size:.6rem;font-family:var(--mono);margin-left:auto}.diagnostics{padding:var(--sp-lg);max-width:100%}.diagnostics h2{font-size:var(--fs-lg);color:var(--accent);letter-spacing:1px;margin-bottom:var(--sp-md);font-weight:600}.diag-grid{gap:var(--sp-xs);margin-bottom:var(--sp-md);grid-template-columns:repeat(2,1fr);display:grid}.diag-item{padding:var(--sp-xs) var(--sp-sm);background:var(--panel-bg);border:1px solid var(--panel-border);border-radius:var(--radius-sm);font-size:var(--fs-sm);justify-content:space-between;min-width:0;display:flex}.diag-label{color:var(--text-dim);font-family:var(--mono);font-size:var(--fs-xs);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.diag-value{font-family:var(--mono);font-size:var(--fs-xs);text-overflow:ellipsis;white-space:nowrap;margin-left:var(--sp-sm);text-align:right;overflow:hidden}.diag-characteristics{margin-bottom:var(--sp-md)}.diag-characteristics h3{font-size:var(--fs-sm);margin-bottom:var(--sp-xs);font-weight:600}.char-table-wrapper{-webkit-overflow-scrolling:touch;overflow-x:auto}.char-table{border-collapse:collapse;width:100%;font-size:var(--fs-xs);min-width:400px}.char-table th,.char-table td{padding:var(--sp-xs) var(--sp-sm);border:1px solid var(--panel-border);text-align:left;font-family:var(--mono);font-size:var(--fs-xs);white-space:nowrap}.char-table th{background:var(--panel-bg);color:var(--text-dim)}.diag-tabs{gap:var(--sp-xs);margin-bottom:var(--sp-md);-webkit-overflow-scrolling:touch;scrollbar-width:none;display:flex;overflow-x:auto}.diag-tabs::-webkit-scrollbar{display:none}.diag-tab{padding:var(--sp-sm) var(--sp-lg);min-height:var(--touch-min);background:var(--panel-bg);border:1px solid var(--panel-border);border-radius:var(--radius-sm);color:var(--text-dim);font-size:var(--fs-xs);font-family:var(--mono);cursor:pointer;white-space:nowrap;flex-shrink:0;transition:all .15s}.diag-tab.active{background:var(--accent-dim);border-color:var(--accent);color:var(--accent)}.diag-tab:hover{color:var(--text)}.diag-terminal{border:1px solid var(--panel-border);border-radius:var(--radius-lg);padding:var(--sp-sm);font-family:var(--mono);font-size:var(--fs-xs);background:#0a0a0a;max-height:min(400px,50vh);overflow-y:auto}.terminal-content{flex-direction:column;gap:2px;display:flex}.terminal-empty{color:var(--text-dim);padding:var(--sp-md);text-align:center;font-style:italic}.terminal-line{gap:var(--sp-sm);padding:2px 0;display:flex}.terminal-dir{flex-shrink:0;min-width:30px;font-weight:600}.terminal-line.tx .terminal-dir{color:var(--green)}.terminal-line.rx .terminal-dir{color:var(--accent)}.terminal-line.ok .terminal-dir{color:var(--green)}.terminal-line.error .terminal-dir{color:var(--red)}.terminal-data{color:var(--text);word-break:break-all;min-width:0}.terminal-time{color:var(--text-dim);font-size:var(--fs-xs);flex-shrink:0;margin-left:auto}.settings{padding:var(--sp-lg)}.settings h2{font-size:var(--fs-lg);color:var(--accent);margin-bottom:var(--sp-md);font-weight:600}.settings-content{background:var(--panel-bg);border:1px solid var(--panel-border);border-radius:var(--radius-lg);padding:var(--sp-lg);gap:var(--sp-md);color:var(--text-dim);font-size:var(--fs-base);flex-direction:column;display:flex}.live-graph{padding:var(--sp-xs);flex-direction:column;align-items:center;min-width:0;display:flex}.live-graph canvas{width:100%;height:auto;display:block}.graph-label{font-size:var(--fs-xs);color:var(--text-dim);font-family:var(--mono);margin-bottom:2px}.error-banner{color:var(--red);padding:var(--sp-sm) var(--sp-lg);font-size:var(--fs-sm);font-family:var(--mono);text-align:center;background:#ff444426;border:1px solid #ff444480;flex-shrink:0}.error-banner:empty{display:none}.error-detail{gap:var(--sp-sm);padding:var(--sp-xs) var(--sp-lg);color:var(--orange);font-family:var(--mono);font-size:var(--fs-xs);background:#ff980014;border:1px solid #ff980040;flex-wrap:wrap;flex-shrink:0;display:flex}.error-op,.error-name{margin-right:var(--sp-sm);font-weight:600}.error-msg{color:var(--text-dim)}.phase-label{font-family:var(--mono);font-size:var(--fs-xs);color:var(--text-dim);padding:var(--sp-xs) var(--sp-sm);background:var(--panel-bg);border:1px solid var(--panel-border);border-radius:var(--radius-sm)}.start-btn{border-color:var(--green);color:var(--green)}.start-btn:hover{background:#00e67626}.disconnect-btn{border-color:var(--red);color:var(--red)}.disconnect-btn:hover{background:#ff444426}.gatt-inspector{margin-bottom:var(--sp-lg)}.gatt-inspector h3{font-size:var(--fs-sm);color:var(--accent);letter-spacing:1px;margin-bottom:var(--sp-sm);font-weight:600}.gatt-summary{gap:var(--sp-md);margin-bottom:var(--sp-md);display:flex}.gatt-stat{font-family:var(--mono);font-size:var(--fs-xs);color:var(--text-dim);padding:var(--sp-xs) var(--sp-sm);background:var(--panel-bg);border:1px solid var(--panel-border);border-radius:var(--radius-sm)}.gatt-service{background:var(--panel-bg);border:1px solid var(--panel-border);border-radius:var(--radius-md);margin-bottom:var(--sp-sm);overflow:hidden}.gatt-service-header{padding:var(--sp-sm) var(--sp-md);border-bottom:1px solid var(--panel-border);background:#00e5ff08;justify-content:space-between;align-items:center;display:flex}.gatt-service-uuid{font-family:var(--mono);font-size:var(--fs-xs);color:var(--accent);font-weight:600}.gatt-service-type{font-family:var(--mono);color:var(--text-dim);font-size:.6rem}.gatt-characteristics{padding:var(--sp-xs) 0}.gatt-char{padding:var(--sp-xs) var(--sp-md)}.gatt-char+.gatt-char{border-top:1px solid #2a2a2a80}.gatt-char-uuid{font-family:var(--mono);font-size:var(--fs-xs);color:var(--text);align-items:center;gap:var(--sp-sm);margin-bottom:2px;display:flex}.gatt-role-badge{letter-spacing:.5px;border-radius:2px;padding:1px 5px;font-size:.55rem;font-weight:700}.gatt-role-badge.rx{color:var(--accent);background:#00e5ff26;border:1px solid #00e5ff4d}.gatt-role-badge.tx{color:var(--green);background:#00e67626;border:1px solid #00e6764d}.gatt-char-props{flex-wrap:wrap;gap:3px;display:flex}.gatt-prop{font-family:var(--mono);background:var(--panel-border);color:var(--text-dim);border-radius:2px;padding:1px 5px;font-size:.6rem}.gatt-prop.notify{color:var(--accent);background:#00e5ff1a}.gatt-prop.read{color:var(--green);background:#00e6761a}.gatt-prop.write,.gatt-prop.writeWithoutResponse{color:var(--orange);background:#ff98001a}.gatt-prop.indicate{color:#aa3bff;background:#aa3bff1a}.gatt-char-empty,.gatt-empty{font-family:var(--mono);font-size:var(--fs-xs);color:var(--text-dim);padding:var(--sp-sm) var(--sp-md);font-style:italic}.raw-ble-test{margin-bottom:var(--sp-lg)}.raw-ble-test h3{font-size:var(--fs-sm);color:var(--accent);letter-spacing:1px;margin-bottom:var(--sp-sm);font-weight:600}.raw-ble-controls{gap:var(--sp-xs);margin-bottom:var(--sp-md);flex-wrap:wrap;display:flex}.raw-test-btn{padding:var(--sp-sm) var(--sp-lg);min-height:var(--touch-min);background:var(--panel-bg);border:1px solid var(--panel-border);border-radius:var(--radius-sm);color:var(--text);font-family:var(--mono);font-size:var(--fs-xs);cursor:pointer;white-space:nowrap;transition:all .15s}.raw-test-btn:hover:not(:disabled){border-color:var(--accent);color:var(--accent)}.raw-test-btn:disabled{opacity:.4;cursor:not-allowed}.raw-test-btn.clear-btn{color:var(--text-dim)}.raw-test-results{gap:var(--sp-xs);flex-direction:column;display:flex}.raw-test-empty{font-family:var(--mono);font-size:var(--fs-xs);color:var(--text-dim);padding:var(--sp-md);text-align:center;font-style:italic}.raw-test-entry{background:var(--panel-bg);border:1px solid var(--panel-border);border-radius:var(--radius-sm);overflow:hidden}.raw-test-entry.error{border-color:#ff44444d}.raw-test-tx,.raw-test-rx{gap:var(--sp-sm);padding:var(--sp-xs) var(--sp-sm);font-family:var(--mono);font-size:var(--fs-xs);display:flex}.raw-test-tx{background:#00e67608;border-bottom:1px solid #2a2a2a80}.raw-test-rx{background:#00e5ff08}.raw-dir{min-width:24px;font-weight:700}.raw-test-tx .raw-dir{color:var(--green)}.raw-test-rx .raw-dir{color:var(--accent)}.raw-data{color:var(--text);word-break:break-all;flex:1;min-width:0}.raw-data.error-text{color:var(--red)}.raw-time{color:var(--text-dim);flex-shrink:0;margin-left:auto}.diag-transport-summary{margin-bottom:var(--sp-lg)}.diag-transport-summary h3{font-size:var(--fs-sm);color:var(--accent);letter-spacing:1px;margin-bottom:var(--sp-sm);font-weight:600}.status-connected{color:var(--green)}.status-disconnected,.status-error{color:var(--red)}.status-initializing,.status-no-response{color:var(--orange)}.status-ready{color:var(--green)}.status-connecting{color:var(--yellow)}@media (width<=1023px){.dashboard{grid-template-columns:repeat(2,1fr)}.graph-grid{grid-template-columns:repeat(auto-fill,minmax(clamp(120px,25vw,220px),1fr))}}@media (width<=767px){.app-header{padding:var(--sp-sm);gap:var(--sp-sm);flex-wrap:wrap}.header-left{flex:auto}.device-name{display:none}.header-center{justify-content:space-between;gap:var(--sp-sm);flex:100%;order:3}.state-breakdown{display:none}.header-right{flex:none}.connect-btn{font-size:var(--fs-xs);padding:var(--sp-sm) var(--sp-md)}.app-nav{padding:0 var(--sp-sm)}.nav-btn{text-align:center;padding:var(--sp-sm) var(--sp-sm);flex:1}.dashboard{grid-template-columns:1fr}.graph-grid{grid-template-columns:repeat(auto-fill,minmax(clamp(100px,30vw,180px),1fr))}.diag-grid{grid-template-columns:1fr}.signal-row{flex-wrap:wrap}.signal-label{flex:100%;min-width:0}.signal-value{text-align:left;flex:1}.diag-terminal{max-height:min(300px,40vh)}}.app{background:var(--bg);flex-direction:column;width:100%;height:100vh;display:flex}
