diff --git a/public_html/assets/css/jarvis.css b/public_html/assets/css/jarvis.css index 9fcea8f..8aeec51 100644 --- a/public_html/assets/css/jarvis.css +++ b/public_html/assets/css/jarvis.css @@ -1208,3 +1208,159 @@ body::after{ /* ── AGENT TOPOLOGY ────────────────────────────────────────────────── */ #agentTopoCanvas{background:transparent;border-top:1px solid rgba(0,212,255,0.08);display:block} #agent-topo-btn.active{background:rgba(0,212,255,0.15);border-color:rgba(0,212,255,0.5)} + +/* ════════════════════════════════════════════════════════════════════════ + FIRE HD 8 (12th Gen) TABLET MODE + Applied via body.tablet-mode — set automatically on Silk UA detection + Target: 1280×800 landscape, 189 PPI, touch-only input + ════════════════════════════════════════════════════════════════════════ */ + +/* Prevent accidental text selection on touch; restore for inputs */ +body.tablet-mode { -webkit-user-select:none; user-select:none; } +body.tablet-mode input, +body.tablet-mode textarea { -webkit-user-select:auto; user-select:auto; } + +/* ── TOPBAR — taller row, bigger tap zones ─────────────────────── */ +body.tablet-mode #topBar { + height:54px; + padding:0 12px; +} +body.tablet-mode #clock { font-size:1.1rem; letter-spacing:3px; } +body.tablet-mode .tb-logo { font-size:0.95rem; } + +/* Toolbar buttons — min 40px touch target */ +body.tablet-mode .btn-panels, +body.tablet-mode .btn-camera { + font-size:0.62rem; + letter-spacing:1.5px; + padding:9px 13px; + min-height:40px; + margin-right:4px; +} + +/* Theme color dots — bigger tap area */ +body.tablet-mode #themeBar { gap:6px; } +body.tablet-mode .theme-btn { + width:20px; height:20px; + font-size:0.75rem; +} + +/* Swap + logout */ +body.tablet-mode #btn-swap-panels { + font-size:0.65rem; + padding:7px 11px; +} +body.tablet-mode .btn-logout { + font-size:0.72rem; + padding:7px 12px; +} + +/* ── MAIN LAYOUT — narrower side panels → wider center ──────────── */ +/* 220+220 side cols → center gets ~808px instead of ~660px */ +body.tablet-mode #mainLayout { + grid-template-columns:220px 1fr 220px; + padding:8px; + gap:8px; +} + +/* ── PANELS — tighter padding, larger text ──────────────────────── */ +body.tablet-mode .panel { padding:11px; } +body.tablet-mode .panel-title { + font-size:0.67rem; + letter-spacing:2.5px; + margin-bottom:9px; +} + +/* Metric rows */ +body.tablet-mode .metric-label { font-size:0.75rem; } +body.tablet-mode .service-row { font-size:0.75rem; padding:6px 0; } +body.tablet-mode .val-row { font-size:0.75rem; padding:4px 0; } +body.tablet-mode .device-item { font-size:0.75rem; padding:7px 0; } +body.tablet-mode .device-name { font-size:0.75rem; } +body.tablet-mode .device-ip { font-size:0.68rem; } +body.tablet-mode .vm-card { font-size:0.75rem; padding:9px 10px; } + +/* Scrollable side panels — smooth touch inertia */ +body.tablet-mode #leftPanel, +body.tablet-mode #rightPanel { + -webkit-overflow-scrolling:touch; + overscroll-behavior:contain; +} + +/* ── CENTER — arc reactor + chat ────────────────────────────────── */ +/* Scale reactor down so chat gets more vertical room */ +body.tablet-mode #arcReactor { width:180px; height:180px; } +body.tablet-mode .arc-ring.r1 { width:180px; height:180px; } +body.tablet-mode .arc-ring.r2 { width:159px; height:159px; } +body.tablet-mode .arc-ring.r3 { width:139px; height:139px; } +body.tablet-mode .arc-ring.r4 { width:118px; height:118px; } +body.tablet-mode .arc-ring.r5 { width:94px; height:94px; } +body.tablet-mode .arc-ring.r6 { width:72px; height:72px; } +body.tablet-mode .arc-ring.r7 { width:51px; height:51px; } +body.tablet-mode .arc-core { width:30px; height:30px; } + +/* Chat messages — comfortable reading size */ +body.tablet-mode .msg { + font-size:0.95rem; + line-height:1.55; + padding:11px 14px; +} +body.tablet-mode .msg.user { font-size:0.88rem; } +body.tablet-mode .msg.system { font-size:0.78rem; } + +/* Touch-scroll chat log */ +body.tablet-mode #chatLog { + -webkit-overflow-scrolling:touch; + overscroll-behavior:contain; +} + +/* Input row — 16px prevents Silk from zooming on focus */ +body.tablet-mode #textInput { + font-size:1rem; + min-height:46px; + padding:12px 14px; +} +body.tablet-mode #sendBtn { + font-size:0.68rem; + min-height:46px; + padding:0 18px; +} +body.tablet-mode #micBtn { + width:52px; height:52px; + flex-shrink:0; +} +body.tablet-mode #searchBtn { + min-height:46px !important; + padding:0 13px !important; + font-size:1.1rem !important; +} + +/* ── TABS — bigger tap targets ──────────────────────────────────── */ +body.tablet-mode .tab { + font-size:0.58rem; + letter-spacing:1.5px; + padding:9px 12px; +} + +/* ── HA TABLE — more readable on 8" ────────────────────────────── */ +body.tablet-mode .ha-thead th { font-size:0.55rem; padding:6px 3px 8px; } +body.tablet-mode .ha-row td { font-size:0.74rem; padding:6px 3px; } + +/* Toggle slider — bigger for fat fingers */ +body.tablet-mode .ha-toggle { width:36px; height:18px; } +body.tablet-mode .ha-slider::before { width:12px; height:12px; left:2px; top:2px; } +body.tablet-mode .ha-toggle input:checked + .ha-slider::before { transform:translateX(18px); } + +/* ── DISABLE HOVER-RISE — not meaningful on touch ───────────────── */ +body.tablet-mode .panel:hover { + transform:translateY(var(--pty,0px)) !important; + border-color:var(--panel-border) !important; + box-shadow:none !important; + transition:none !important; +} + +/* ── ALERTS ──────────────────────────────────────────────────────── */ +body.tablet-mode .alert-item { font-size:0.75rem; padding:9px 11px; } + +/* ── BOTTOM BAR ─────────────────────────────────────────────────── */ +body.tablet-mode #bottomBar { font-size:0.7rem; height:34px; } diff --git a/public_html/assets/js/jarvis-app.js b/public_html/assets/js/jarvis-app.js index 6d45719..a32bf8b 100644 --- a/public_html/assets/js/jarvis-app.js +++ b/public_html/assets/js/jarvis-app.js @@ -1755,49 +1755,57 @@ document.addEventListener('keydown', function(e) { } }); -// ── KIOSK MODE ─────────────────────────────────────────────────────────────────────── + +// ── FIRE HD 8 TABLET DETECTION ──────────────────────────────────────────────────────── +const IS_SILK = /Silk\//i.test(navigator.userAgent); +const IS_FIRE = /KFTT|KFOT|KFJWI|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFMEWI|KFFOWI|KFSAWA|KFMAWI|KFGIWI|KFDOWI|KFTBWI|KFTRWI|KFKAWI/i.test(navigator.userAgent); +function isTablet() { return IS_SILK || IS_FIRE; } + +function applyTabletMode() { + document.body.classList.add("tablet-mode"); + const kb = document.getElementById("kioskBtn"); + if (kb) kb.title = "Full-screen kiosk (Fire HD 8 layout active)"; +} +if (isTablet()) applyTabletMode(); + +// ── KIOSK MODE ──────────────────────────────────────────────────────────────────────── let _wakeLock = null; async function toggleKiosk() { - const btn = document.getElementById("kioskBtn"); + const btn = document.getElementById("kioskBtn"); const isFs = !!(document.fullscreenElement || document.webkitFullscreenElement); if (!isFs) { - const el = document.documentElement; + applyTabletMode(); + const el = document.documentElement; const req = el.requestFullscreen || el.webkitRequestFullscreen || el.mozRequestFullScreen || el.msRequestFullscreen; if (req) req.call(el).catch(() => {}); - // Screen Wake Lock — keeps tablet display on if ("wakeLock" in navigator) { try { _wakeLock = await navigator.wakeLock.request("screen"); } catch(e) {} } - if (btn) { btn.textContent = "⛶ EXIT"; btn.style.color = "var(--cyan)"; } + if (btn) { btn.textContent = "⧞ EXIT"; btn.style.color = "var(--cyan)"; } } else { const ex = document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen; if (ex) ex.call(document).catch(() => {}); if (_wakeLock) { _wakeLock.release().catch(() => {}); _wakeLock = null; } - if (btn) { btn.textContent = "⛶ KIOSK"; btn.style.color = ""; } + if (btn) { btn.textContent = "⧞ KIOSK"; btn.style.color = ""; } + if (!isTablet()) document.body.classList.remove("tablet-mode"); } } -// Re-acquire wake lock if released by system (e.g. tab switch) document.addEventListener("visibilitychange", async () => { if (_wakeLock && document.visibilityState === "visible") { try { _wakeLock = await navigator.wakeLock.request("screen"); } catch(e) {} } }); -// Sync button label when fullscreen is exited via Esc key -document.addEventListener("fullscreenchange", () => { +function _onFsChange() { const btn = document.getElementById("kioskBtn"); if (!document.fullscreenElement && !document.webkitFullscreenElement) { if (_wakeLock) { _wakeLock.release().catch(() => {}); _wakeLock = null; } - if (btn) { btn.textContent = "⛶ KIOSK"; btn.style.color = ""; } + if (btn) { btn.textContent = "⧞ KIOSK"; btn.style.color = ""; } + if (!isTablet()) document.body.classList.remove("tablet-mode"); } -}); -document.addEventListener("webkitfullscreenchange", () => { - const btn = document.getElementById("kioskBtn"); - if (!document.webkitFullscreenElement && !document.fullscreenElement) { - if (_wakeLock) { _wakeLock.release().catch(() => {}); _wakeLock = null; } - if (btn) { btn.textContent = "⛶ KIOSK"; btn.style.color = ""; } - } -}); +} +document.addEventListener("fullscreenchange", _onFsChange); +document.addEventListener("webkitfullscreenchange", _onFsChange);