fix(ui): remove artificial phone bezels, implement responsive full-height layout with sticky header and bottom tabs

This commit is contained in:
Christian 2026-10-15 15:36:31 +02:00
parent ae10dc0d34
commit 4d1d0527ee
2 changed files with 140 additions and 120 deletions

View file

@ -28,53 +28,59 @@
user-select: none;
}
body {
html, body {
width: 100%;
min-height: 100%;
background-color: var(--bg-main);
color: var(--text-primary);
font-family: var(--font-ui);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow-x: hidden;
}
/* Burner Phone Container (Mobile viewport lock) */
#burner-device {
/* App Main Container: Clean, native-feeling layout on both mobile & desktop */
#app-container {
width: 100%;
max-width: 480px;
height: 100vh;
max-height: 940px;
max-width: 640px; /* Comfortable max width on larger screens without feeling like a claustrophobic fake phone */
min-height: 100vh;
background: var(--bg-main);
display: flex;
flex-direction: column;
position: relative;
border: 1px solid var(--border-color);
box-shadow: 0 0 40px rgba(0,0,0,0.85);
overflow: hidden;
padding-bottom: 84px; /* Space for sticky bottom tab bar */
}
@media (min-width: 520px) {
#burner-device {
border-radius: 28px;
margin: 20px 0;
border: 2px solid #2a3440;
@media (min-width: 680px) {
#app-container {
border-left: 1px solid var(--border-color);
border-right: 1px solid var(--border-color);
}
}
/* System Status Bar (Top) */
#system-bar {
background: var(--bg-header);
/* Sticky Top Navigation & HUD Header */
#sticky-header {
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 40;
background: rgba(11, 14, 18, 0.96);
backdrop-filter: blur(10px);
border-bottom: 1px solid var(--border-color);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
}
/* Status / Top Brand Bar */
#system-bar {
padding: 6px 14px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: var(--font-mono);
font-size: 0.75rem;
font-size: 0.72rem;
color: var(--text-secondary);
letter-spacing: 0.5px;
z-index: 20;
border-bottom: 1px solid rgba(36, 45, 54, 0.5);
}
.status-left, .status-right {
@ -83,6 +89,15 @@ body {
gap: 8px;
}
.brand-tag {
font-weight: 800;
letter-spacing: 1px;
color: var(--brand-gold);
display: inline-flex;
align-items: center;
gap: 4px;
}
.secure-indicator {
display: inline-flex;
align-items: center;
@ -107,26 +122,23 @@ body {
/* Hero Financial HUD */
#hud-summary {
background: linear-gradient(180deg, #12171e 0%, #0d1117 100%);
border-bottom: 1px solid var(--border-color);
padding: 12px 16px;
padding: 10px 14px;
display: flex;
justify-content: space-between;
align-items: flex-end;
position: relative;
}
.hud-title {
font-family: var(--font-mono);
font-size: 0.7rem;
font-size: 0.68rem;
text-transform: uppercase;
color: var(--text-secondary);
letter-spacing: 1px;
letter-spacing: 0.8px;
}
.hud-cash-val {
font-family: var(--font-mono);
font-size: 1.6rem;
font-size: 1.55rem;
font-weight: 800;
color: var(--brand-gold);
text-shadow: 0 0 10px rgba(234, 179, 8, 0.2);
@ -135,7 +147,7 @@ body {
.hud-rate-val {
font-family: var(--font-mono);
font-size: 0.8rem;
font-size: 0.78rem;
color: var(--neon-green);
margin-top: 2px;
}
@ -149,7 +161,7 @@ body {
.bonds-val {
font-family: var(--font-mono);
font-size: 1.1rem;
font-size: 1.05rem;
font-weight: bold;
color: var(--neon-cyan);
display: flex;
@ -160,8 +172,7 @@ body {
/* Police Heat Bar */
#heat-container {
background: #090c0f;
padding: 4px 16px 8px;
border-bottom: 1px solid var(--border-color);
padding: 4px 14px 6px;
display: flex;
flex-direction: column;
gap: 3px;
@ -177,7 +188,7 @@ body {
.heat-bar-track {
width: 100%;
height: 6px;
height: 5px;
background: #1c232b;
border-radius: 3px;
overflow: hidden;
@ -193,30 +204,30 @@ body {
/* Main Viewport Content */
#main-viewport {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding: 14px;
padding: 12px 14px;
display: flex;
flex-direction: column;
gap: 12px;
padding-bottom: 90px; /* Space for bottom nav */
}
/* Bottom Tab Navigation Bar */
/* Bottom Tab Navigation Bar - Fixed at bottom of screen */
#bottom-nav {
position: absolute;
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 70px;
background: rgba(11, 14, 18, 0.95);
backdrop-filter: blur(8px);
left: 50%;
transform: translateX(-50%);
width: 100%;
max-width: 640px;
height: 68px;
background: rgba(11, 14, 18, 0.97);
backdrop-filter: blur(12px);
border-top: 1px solid var(--border-color);
display: flex;
justify-content: space-around;
align-items: center;
z-index: 30;
padding-bottom: 6px;
z-index: 50;
padding-bottom: env(safe-area-inset-bottom, 4px);
box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.5);
}
.nav-tab {
@ -230,14 +241,14 @@ body {
background: none;
border: none;
cursor: pointer;
font-size: 0.7rem;
font-size: 0.72rem;
font-family: var(--font-mono);
padding: 8px 0;
transition: color 0.15s, transform 0.1s;
}
.nav-tab:active {
transform: scale(0.94);
transform: scale(0.92);
}
.nav-tab.active {
@ -249,7 +260,7 @@ body {
}
.nav-tab iconify-icon {
font-size: 1.45rem;
font-size: 1.5rem;
}
/* Card Components */
@ -260,7 +271,7 @@ body {
padding: 12px 14px;
position: relative;
overflow: hidden;
transition: border-color 0.2s;
transition: border-color 0.2s, background-color 0.2s;
}
.card:hover {
@ -277,26 +288,27 @@ body {
.card-title-group {
display: flex;
align-items: center;
gap: 8px;
gap: 10px;
}
.drug-icon-box {
width: 36px;
height: 36px;
width: 38px;
height: 38px;
border-radius: 8px;
background: var(--bg-card-sub);
display: flex;
align-items: center;
justify-content: center;
border: 1px solid var(--border-color);
flex-shrink: 0;
}
.drug-icon-box iconify-icon {
font-size: 1.5rem;
font-size: 1.55rem;
}
.card-title {
font-size: 0.95rem;
font-size: 0.98rem;
font-weight: 700;
letter-spacing: 0.3px;
}
@ -329,7 +341,7 @@ body {
color: var(--text-primary);
}
/* Buttons */
/* Touch-Optimized Action Buttons */
.btn-grid-actions {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
@ -344,13 +356,13 @@ body {
}
.btn-tactical {
background: #192028;
background: #181f26;
color: var(--text-primary);
border: 1px solid #2d3844;
border-radius: 8px;
padding: 8px 4px;
padding: 9px 4px;
font-family: var(--font-mono);
font-size: 0.72rem;
font-size: 0.74rem;
font-weight: 600;
cursor: pointer;
display: flex;
@ -358,12 +370,13 @@ body {
align-items: center;
justify-content: center;
gap: 2px;
transition: background 0.15s, border-color 0.15s, transform 0.05s;
transition: background 0.12s, border-color 0.12s, transform 0.05s;
text-align: center;
min-height: 48px; /* High tactile accessibility for thumbs */
}
.btn-tactical:active:not(:disabled) {
transform: scale(0.96);
transform: scale(0.95);
background: #25313d;
}
@ -379,18 +392,18 @@ body {
}
.btn-primary-action {
background: #1b2e21;
border-color: #2e593b;
background: #172c1f;
border-color: #2b5637;
color: #4ade80;
}
.btn-primary-action:hover:not(:disabled) {
background: #24422e;
background: #203f2c;
}
.btn-sell-action {
background: #2d2613;
border-color: #63501a;
background: #2b2310;
border-color: #5c4b1a;
color: #facc15;
}
@ -406,17 +419,17 @@ body {
align-items: center;
justify-content: center;
gap: 10px;
padding: 20px 0;
padding: 16px 0;
}
.btn-unlock {
background: #201a08;
border: 1px solid var(--brand-gold);
color: var(--brand-gold);
padding: 10px 18px;
padding: 11px 20px;
border-radius: 8px;
font-family: var(--font-mono);
font-size: 0.85rem;
font-size: 0.86rem;
font-weight: bold;
cursor: pointer;
display: flex;
@ -447,7 +460,7 @@ body {
border: 2px solid var(--border-accent);
border-radius: 16px;
width: 100%;
max-width: 380px;
max-width: 400px;
padding: 22px;
display: flex;
flex-direction: column;
@ -507,10 +520,12 @@ body {
/* Toast Messages */
#toast-container {
position: absolute;
top: 60px;
left: 14px;
right: 14px;
position: fixed;
top: 76px;
left: 50%;
transform: translateX(-50%);
width: 90%;
max-width: 580px;
z-index: 80;
display: flex;
flex-direction: column;
@ -519,16 +534,16 @@ body {
}
.toast {
background: rgba(16, 21, 28, 0.95);
background: rgba(16, 21, 28, 0.96);
border: 1px solid var(--border-accent);
border-left: 4px solid var(--neon-green);
border-radius: 8px;
padding: 8px 12px;
padding: 9px 12px;
font-size: 0.8rem;
font-family: var(--font-mono);
color: var(--text-primary);
box-shadow: 0 4px 14px rgba(0,0,0,0.5);
animation: slideDown 0.3s ease;
box-shadow: 0 4px 16px rgba(0,0,0,0.6);
animation: slideDown 0.25s ease;
}
.toast.danger {

View file

@ -2,8 +2,8 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>EL PURO - SilkNet OS</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>EL PURO</title>
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
@ -14,59 +14,64 @@
</head>
<body>
<div id="burner-device">
<div id="app-container">
<!-- Top Status Bar -->
<div id="system-bar">
<div class="status-left">
<span class="secure-indicator">
<span class="secure-dot"></span> SECURE
</span>
<span id="user-badge" style="cursor: pointer;">[ANON]</span>
</div>
<div class="status-right">
<span id="system-clock">15:00</span>
<iconify-icon icon="lucide:battery-medium"></iconify-icon>
</div>
</div>
<!-- HUD Summary (Cash, Income, Clean Bonds) -->
<div id="hud-summary">
<div>
<div class="hud-title">Dirty Cash</div>
<div class="hud-cash-val">$<span id="hud-cash">0.00</span></div>
<div class="hud-rate-val">+$<span id="hud-rate">0.00</span>/s</div>
</div>
<div class="hud-bonds">
<div class="hud-title">Clean Bonds</div>
<div class="bonds-val">
<iconify-icon icon="game-icons:tied-scroll"></iconify-icon>
<span id="hud-bonds">0</span>
<!-- Sticky Header (Status bar + Financial HUD + Heat Bar) -->
<header id="sticky-header">
<!-- Top Status Bar -->
<div id="system-bar">
<div class="status-left">
<span class="brand-tag">
<iconify-icon icon="game-icons:flasks"></iconify-icon> EL PURO
</span>
<span class="secure-indicator">
<span class="secure-dot"></span> SECURE
</span>
</div>
<div class="status-right">
<span id="user-badge" style="cursor: pointer; text-decoration: underline;">[ANON]</span>
<span id="system-clock">15:00</span>
</div>
<div class="hud-rate-val" style="color: var(--neon-cyan);">+<span id="hud-multiplier">0</span>% Boost</div>
</div>
</div>
<!-- Police Heat Bar -->
<div id="heat-container">
<div class="heat-label-row">
<span>POLICE HEAT</span>
<span id="heat-pct">0%</span>
<!-- HUD Summary (Cash, Income, Clean Bonds) -->
<div id="hud-summary">
<div>
<div class="hud-title">Dirty Cash</div>
<div class="hud-cash-val">$<span id="hud-cash">0.00</span></div>
<div class="hud-rate-val">+$<span id="hud-rate">0.00</span>/s</div>
</div>
<div class="hud-bonds">
<div class="hud-title">Clean Bonds</div>
<div class="bonds-val">
<iconify-icon icon="game-icons:tied-scroll"></iconify-icon>
<span id="hud-bonds">0</span>
</div>
<div class="hud-rate-val" style="color: var(--neon-cyan);">+<span id="hud-multiplier">0</span>% Boost</div>
</div>
</div>
<div class="heat-bar-track">
<div id="heat-bar-fill"></div>
<!-- Police Heat Bar -->
<div id="heat-container">
<div class="heat-label-row">
<span>POLICE HEAT</span>
<span id="heat-pct">0%</span>
</div>
<div class="heat-bar-track">
<div id="heat-bar-fill"></div>
</div>
</div>
</div>
</header>
<!-- Toast Notifications Container -->
<div id="toast-container"></div>
<!-- Main Viewport with Dynamic Views -->
<main id="main-viewport">
<!-- Views will be dynamically injected / rendered here -->
<!-- Views are rendered dynamically by game.js -->
</main>
<!-- Bottom Navigation Bar -->
<!-- Bottom Navigation Bar (Fixed for quick thumb access) -->
<nav id="bottom-nav">
<button class="nav-tab active" data-tab="lab">
<iconify-icon icon="game-icons:flasks"></iconify-icon>