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);