mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
Mobile-focused fixes for the web UI: keyboard-accessory layout and overlap, native input visibility above the keyboard, CJK input handling, terminal touch scrolling, tab-menu tap targets, mic-recording glow containment, and mobile resize/keyboard-state handling on tab switch, plus mobile visual-regression test coverage and snapshots. Co-Authored-By: Saqeb Akhter <saqeb.akhter@gmail.com>
2368 lines
53 KiB
CSS
2368 lines
53 KiB
CSS
/* ============================================================================
|
|
Mobile & Touch Styles
|
|
Extracted from styles.css for cleaner separation.
|
|
Loaded only on small/medium screens via media attribute in index.html.
|
|
============================================================================ */
|
|
|
|
/* ============================================================================
|
|
Mobile Init Flash Prevention
|
|
Hides elements that are off by default on mobile BEFORE JS runs.
|
|
The inline <script> in <head> adds .mobile-init to <html> synchronously.
|
|
app.init() removes .mobile-init after applying visibility settings.
|
|
============================================================================ */
|
|
html.mobile-init .header-font-controls,
|
|
html.mobile-init .header-system-stats,
|
|
html.mobile-init .header-tokens,
|
|
html.mobile-init .monitor-panel,
|
|
html.mobile-init .subagents-panel,
|
|
html.mobile-init .project-insights-panel,
|
|
html.mobile-init .file-browser-panel {
|
|
display: none !important;
|
|
}
|
|
|
|
/* ============================================================================
|
|
iOS Zoom Prevention (all mobile/tablet sizes)
|
|
iOS Safari ignores user-scalable=no since iOS 10.
|
|
font-size >= 16px on inputs prevents auto-zoom on focus.
|
|
touch-action: manipulation prevents double-tap zoom.
|
|
============================================================================ */
|
|
@media (max-width: 768px) {
|
|
/* Prevent iOS auto-zoom on input focus (triggers at font-size < 16px) */
|
|
input, textarea, select {
|
|
font-size: 16px !important;
|
|
}
|
|
|
|
/* Prevent double-tap zoom globally */
|
|
html {
|
|
touch-action: manipulation;
|
|
}
|
|
}
|
|
|
|
/* ============================================================================
|
|
Tablet Breakpoint (430px - 768px)
|
|
============================================================================ */
|
|
@media (max-width: 768px) and (min-width: 430px) {
|
|
/* Compact header for tablet - fixed at top, includes safe area padding */
|
|
.header {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
min-height: 48px;
|
|
max-height: 48px;
|
|
padding: 0.35rem 0.5rem;
|
|
padding-left: calc(0.5rem + var(--safe-area-left));
|
|
padding-right: calc(0.5rem + var(--safe-area-right));
|
|
background: #0a0a0a;
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
|
contain: none;
|
|
overflow: visible;
|
|
z-index: 1200;
|
|
}
|
|
|
|
/* iOS safe area adjustment for fixed header - header extends into notch area */
|
|
.ios-device .header {
|
|
padding-top: calc(0.35rem + var(--safe-area-top));
|
|
min-height: calc(48px + var(--safe-area-top));
|
|
max-height: calc(48px + var(--safe-area-top));
|
|
}
|
|
|
|
/* Push ALL content below fixed header (not just .main) so banners
|
|
(respawn, timer, orchestrator) between header and main are visible */
|
|
.app {
|
|
padding-top: 54px;
|
|
}
|
|
|
|
.ios-device .app {
|
|
padding-top: calc(54px + var(--safe-area-top));
|
|
}
|
|
|
|
/* Font controls - smaller on tablet, visibility controlled by JS */
|
|
.header-font-controls {
|
|
gap: 0.15rem;
|
|
padding: 0.15rem 0.25rem;
|
|
}
|
|
|
|
.header-font-controls .btn-icon-sm {
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
|
|
/* System stats - compact on tablet, visibility controlled by JS */
|
|
.header-system-stats {
|
|
font-size: 0.6rem;
|
|
gap: 0.25rem;
|
|
}
|
|
|
|
.mobile-header-utility-toggle {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 44px;
|
|
height: 44px;
|
|
padding: 0;
|
|
margin: -4px 0.2rem -4px 0;
|
|
background: transparent;
|
|
border: none;
|
|
border-radius: 6px;
|
|
color: var(--text-muted);
|
|
order: -1;
|
|
position: relative;
|
|
z-index: 2;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.mobile-header-utility-toggle.active,
|
|
.mobile-header-utility-toggle:active {
|
|
background: rgba(255, 255, 255, 0.08);
|
|
color: var(--text);
|
|
}
|
|
|
|
.header-right {
|
|
position: fixed;
|
|
top: calc(52px + var(--safe-area-top));
|
|
left: calc(0.5rem + var(--safe-area-left));
|
|
right: auto;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
max-width: calc(100vw - 1rem - var(--safe-area-left) - var(--safe-area-right));
|
|
padding: 0.35rem;
|
|
background: rgba(10, 10, 10, 0.96);
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
border-radius: 8px;
|
|
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
|
|
overflow-x: auto;
|
|
scrollbar-width: none;
|
|
z-index: 2000;
|
|
}
|
|
|
|
.header-right::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.header-right.mobile-collapsed {
|
|
display: none;
|
|
}
|
|
|
|
.btn-icon-header:not(.btn-sm) {
|
|
width: 44px;
|
|
height: 44px;
|
|
}
|
|
|
|
/* Compact session tabs — .tabs-two-rows override needed to match
|
|
specificity of .session-tabs.tabs-two-rows in styles.css (0,2,0) */
|
|
.session-tabs,
|
|
.session-tabs.tabs-two-rows {
|
|
flex-wrap: nowrap;
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
-webkit-overflow-scrolling: touch;
|
|
scrollbar-width: none;
|
|
max-height: 52px;
|
|
gap: 3px;
|
|
}
|
|
|
|
.session-tabs::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.session-tab {
|
|
padding: 0.4rem 0.6rem;
|
|
font-size: 0.75rem;
|
|
min-height: 40px;
|
|
}
|
|
|
|
.session-tab .tab-name {
|
|
max-width: 80px;
|
|
}
|
|
|
|
/* Compact toolbar - includes safe area padding */
|
|
.toolbar {
|
|
padding: 0.4rem 0.5rem;
|
|
padding-left: calc(0.5rem + var(--safe-area-left));
|
|
padding-right: calc(0.5rem + var(--safe-area-right));
|
|
gap: 0.4rem;
|
|
}
|
|
|
|
/* Hide instance count buttons on tablet too */
|
|
.tab-count-group {
|
|
display: none;
|
|
}
|
|
|
|
/* Compact toolbar buttons */
|
|
.btn-toolbar {
|
|
padding: 0.4rem 0.8rem;
|
|
font-size: 0.8rem;
|
|
min-height: 40px;
|
|
}
|
|
|
|
.case-select-group {
|
|
max-width: 150px;
|
|
}
|
|
|
|
.toolbar-select {
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
/* Stack panels vertically */
|
|
.monitor-panel,
|
|
.subagents-panel {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
left: 0;
|
|
right: 0;
|
|
border-radius: 8px 8px 0 0;
|
|
max-height: 40vh;
|
|
}
|
|
|
|
/* Project insights - compact on tablet, visibility controlled by JS */
|
|
.project-insights-panel {
|
|
max-width: 280px;
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
/* ---- Settings Modal: Tablet Optimizations ---- */
|
|
|
|
.modal-tabs {
|
|
overflow-x: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
scrollbar-width: none;
|
|
flex-wrap: nowrap;
|
|
}
|
|
|
|
.modal-tabs::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.modal-tab-btn {
|
|
padding: 0.4rem 0.75rem;
|
|
font-size: 0.7rem;
|
|
white-space: nowrap;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* Settings grid stays 2-col on tablet but tighter */
|
|
.settings-grid {
|
|
gap: 0.4rem 0.75rem;
|
|
}
|
|
|
|
.settings-item {
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
/* Event type grid - slightly tighter */
|
|
.event-type-grid {
|
|
grid-template-columns: 1fr 40px 40px 40px;
|
|
gap: 5px 6px;
|
|
}
|
|
|
|
.event-label {
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
/* ---- Subagent Windows: Tablet Optimizations ---- */
|
|
|
|
.subagent-window {
|
|
width: 320px;
|
|
height: 280px;
|
|
min-width: 240px;
|
|
min-height: 160px;
|
|
}
|
|
|
|
.subagent-window-header {
|
|
padding: 0.35rem 0.5rem;
|
|
}
|
|
|
|
.subagent-window-title .id {
|
|
font-size: 0.7rem;
|
|
max-width: 180px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.subagent-window-title .status {
|
|
font-size: 0.55rem;
|
|
}
|
|
|
|
.subagent-window-body {
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
/* ---- Respawn Banner: Tablet Optimizations ---- */
|
|
|
|
.respawn-banner {
|
|
padding: 0.25rem 0.5rem;
|
|
padding-left: calc(0.5rem + var(--safe-area-left));
|
|
padding-right: calc(0.5rem + var(--safe-area-right));
|
|
font-size: 0.65rem;
|
|
}
|
|
|
|
.respawn-compact-layout {
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.respawn-status-row1 {
|
|
gap: 0.4rem;
|
|
}
|
|
|
|
.respawn-action-log {
|
|
max-height: 2.6em;
|
|
font-size: 0.6rem;
|
|
}
|
|
|
|
.respawn-countdown-timer {
|
|
font-size: 0.55rem;
|
|
}
|
|
|
|
/* Respawn timer bar — slimmer on tablet */
|
|
.respawn-timer-bar {
|
|
width: 24px;
|
|
}
|
|
|
|
/* Show desktop voice button on tablet (hidden by max-width:1023px in styles.css,
|
|
mobile .btn-voice-mobile only shows at <430px) */
|
|
.toolbar-center .btn-toolbar.btn-voice {
|
|
display: flex !important;
|
|
}
|
|
|
|
/* Toolbar — use desktop-style sizing on tablet (plenty of room at 430-768px) */
|
|
.toolbar {
|
|
padding: 0 0.5rem;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.toolbar-left,
|
|
.toolbar-right {
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
/* Instance count controls are hidden on tablet, so toolbar-group needs gap
|
|
to space out Run / Stop / Run Shell (desktop uses gap:0 because -1+ separates them) */
|
|
.toolbar-group {
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.btn-toolbar {
|
|
padding: 0.4rem 0.75rem;
|
|
font-size: 0.75rem;
|
|
min-height: unset;
|
|
}
|
|
}
|
|
|
|
/* ============================================================================
|
|
Phone Breakpoint (<430px)
|
|
============================================================================ */
|
|
@media (max-width: 430px) {
|
|
/* Compact header brand on phones — acts as home button */
|
|
.header-brand {
|
|
padding-right: 0.25rem;
|
|
margin-right: 0.2rem;
|
|
border-right: none;
|
|
}
|
|
|
|
.header-brand .logo {
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
/* Font controls - compact on phones, visibility controlled by JS */
|
|
.header-font-controls {
|
|
gap: 0.1rem;
|
|
padding: 0.1rem 0.2rem;
|
|
}
|
|
|
|
.header-font-controls .btn-icon-sm {
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
|
|
.header-font-controls .font-size-display {
|
|
font-size: 0.6rem;
|
|
min-width: 14px;
|
|
}
|
|
|
|
/* System stats - very compact on phones, visibility controlled by JS */
|
|
.header-system-stats {
|
|
font-size: 0.55rem;
|
|
gap: 0.15rem;
|
|
}
|
|
|
|
/* Token count - compact on phones, visibility controlled by JS */
|
|
.header-tokens {
|
|
font-size: 0.6rem;
|
|
padding: 0.1rem 0.3rem;
|
|
}
|
|
|
|
/* Ultra-compact header for mobile - fixed at top */
|
|
.header {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
min-height: 36px;
|
|
max-height: 36px;
|
|
padding: 0.15rem 0.3rem;
|
|
padding-left: calc(0.3rem + var(--safe-area-left));
|
|
padding-right: calc(0.3rem + var(--safe-area-right));
|
|
gap: 0.15rem;
|
|
overflow: hidden;
|
|
background: #0a0a0a;
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
|
contain: none;
|
|
z-index: 1200;
|
|
}
|
|
|
|
/* iOS safe area adjustment for fixed header - header extends into notch area */
|
|
.ios-device .header {
|
|
padding-top: calc(0.15rem + var(--safe-area-top));
|
|
min-height: calc(36px + var(--safe-area-top));
|
|
max-height: calc(36px + var(--safe-area-top));
|
|
}
|
|
|
|
/* Push ALL content below fixed header (not just .main) so banners
|
|
(respawn, timer, orchestrator) between header and main are visible.
|
|
Bottom padding for the fixed toolbar (40px) so terminal content
|
|
doesn't extend behind it. JS overrides paddingBottom on .main
|
|
when keyboard is visible, and resetLayout() clears the inline
|
|
style to re-expose this CSS value. */
|
|
.app {
|
|
padding-top: 42px;
|
|
}
|
|
|
|
.ios-device .app {
|
|
padding-top: calc(42px + var(--safe-area-top));
|
|
}
|
|
|
|
.main {
|
|
padding-bottom: calc(40px + var(--safe-area-bottom));
|
|
}
|
|
|
|
/* iOS Safari: toolbar is pushed up by (100vh - --app-height) to clear the
|
|
browser's bottom bar. Match that offset in main's padding so the terminal
|
|
doesn't extend behind the toolbar. */
|
|
.ios-device.safari-browser .main {
|
|
padding-bottom: calc(40px + var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)));
|
|
}
|
|
|
|
.header-right {
|
|
position: fixed;
|
|
top: calc(40px + var(--safe-area-top));
|
|
left: calc(0.3rem + var(--safe-area-left));
|
|
right: auto;
|
|
display: flex;
|
|
align-items: center;
|
|
padding-left: 0.2rem;
|
|
gap: 0.1rem;
|
|
max-width: calc(100vw - 0.6rem - var(--safe-area-left) - var(--safe-area-right));
|
|
padding: 0.25rem;
|
|
background: rgba(10, 10, 10, 0.96);
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
border-radius: 8px;
|
|
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
|
|
overflow-x: auto;
|
|
scrollbar-width: none;
|
|
border-left: none;
|
|
z-index: 2000;
|
|
}
|
|
|
|
.header-right::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.header-right.mobile-collapsed {
|
|
display: none;
|
|
}
|
|
|
|
.mobile-header-utility-toggle {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 44px;
|
|
height: 44px;
|
|
padding: 0;
|
|
margin: -6px 0.15rem -6px 0;
|
|
background: transparent;
|
|
border: none;
|
|
border-radius: 5px;
|
|
color: var(--text-muted);
|
|
order: -1;
|
|
position: relative;
|
|
z-index: 2;
|
|
flex-shrink: 0;
|
|
border-left: none;
|
|
}
|
|
|
|
/* Smaller header buttons on mobile */
|
|
.btn-icon-header {
|
|
width: 26px;
|
|
height: 26px;
|
|
padding: 0;
|
|
}
|
|
|
|
.btn-icon-header svg {
|
|
width: 12px;
|
|
height: 12px;
|
|
}
|
|
|
|
/* Hide header settings gear and lifecycle log on mobile - settings moved to toolbar */
|
|
.btn-icon-header.btn-settings,
|
|
.btn-icon-header.btn-lifecycle-log {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Mobile voice input button in toolbar — initially hidden via inline style,
|
|
shown by VoiceInput._showButtons() clearing the inline display */
|
|
.btn-voice-mobile {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 26px;
|
|
height: 26px;
|
|
background: #1a2a3f;
|
|
border: 1px solid rgba(59, 130, 246, 0.3);
|
|
border-radius: 4px;
|
|
color: #93c5fd;
|
|
cursor: pointer;
|
|
flex-shrink: 0;
|
|
order: 5; /* Between Run Shell and settings gear */
|
|
}
|
|
|
|
.btn-voice-mobile svg {
|
|
width: 13px;
|
|
height: 13px;
|
|
}
|
|
|
|
.btn-voice-mobile:active {
|
|
background: #2a3a5f;
|
|
}
|
|
|
|
.btn-voice-mobile.recording {
|
|
background: rgba(239, 68, 68, 0.25);
|
|
border-color: rgba(239, 68, 68, 0.6);
|
|
color: #ef4444;
|
|
animation: mobile-voice-pulse 1.2s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes mobile-voice-pulse {
|
|
0%, 100% {
|
|
box-shadow: inset 0 0 0 1px rgba(239, 68, 68, 0.35);
|
|
background: rgba(239, 68, 68, 0.2);
|
|
}
|
|
50% {
|
|
box-shadow: inset 0 0 0 2px rgba(239, 68, 68, 0.75);
|
|
background: rgba(239, 68, 68, 0.35);
|
|
}
|
|
}
|
|
|
|
/* Mobile app settings gear in toolbar - far right */
|
|
.btn-settings-mobile {
|
|
display: inline-flex !important;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 26px;
|
|
height: 26px;
|
|
background: transparent;
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
border-radius: 4px;
|
|
color: #9ca3af;
|
|
font-size: 0.85rem;
|
|
cursor: pointer;
|
|
flex-shrink: 0;
|
|
order: 6; /* Far right */
|
|
position: relative;
|
|
}
|
|
|
|
.btn-settings-mobile svg {
|
|
width: 13px;
|
|
height: 13px;
|
|
}
|
|
|
|
.btn-settings-mobile:active {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
color: #fff;
|
|
}
|
|
|
|
/* App container - prevent scrolling, strict layout */
|
|
.app {
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
/* When keyboard is visible, pin the app container to the viewport.
|
|
iOS Safari scrolls the page to bring the focused input (xterm's hidden
|
|
textarea) into view, even with overflow:hidden. position:fixed prevents
|
|
the browser from scrolling the document under the app. */
|
|
.keyboard-visible .app {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: auto;
|
|
height: var(--app-height, 100dvh);
|
|
}
|
|
|
|
/* Ultra-compact session tabs — .tabs-two-rows override needed to match
|
|
specificity of .session-tabs.tabs-two-rows in styles.css (0,2,0) */
|
|
.session-tabs,
|
|
.session-tabs.tabs-two-rows {
|
|
flex: 1;
|
|
flex-wrap: nowrap;
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
-webkit-overflow-scrolling: touch;
|
|
scrollbar-width: none;
|
|
max-height: 36px;
|
|
gap: 2px;
|
|
padding: 0;
|
|
}
|
|
|
|
.session-tabs::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
/* Smaller tabs for mobile */
|
|
.session-tab {
|
|
flex-shrink: 0;
|
|
min-height: 32px;
|
|
max-height: 32px;
|
|
padding: 0.35rem 0.5rem;
|
|
font-size: 0.7rem;
|
|
gap: 0.25rem;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* Smaller status indicator on mobile */
|
|
.session-tab .tab-status {
|
|
width: 4px;
|
|
height: 4px;
|
|
}
|
|
|
|
/* Truncate tab names more aggressively on mobile */
|
|
.session-tab .tab-name {
|
|
max-width: 50px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
/* Hide close/gear buttons on non-active tabs on mobile */
|
|
.session-tab .tab-close,
|
|
.session-tab .tab-gear {
|
|
display: none;
|
|
}
|
|
|
|
/* Gear icon on active tab - tiny, subtle */
|
|
.session-tab.active .tab-gear {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 0.65rem;
|
|
line-height: 1;
|
|
width: 32px;
|
|
height: 32px;
|
|
margin-left: auto;
|
|
opacity: 0.6;
|
|
}
|
|
|
|
/* Close button on active tab - large for easy tapping */
|
|
.session-tab.active .tab-close {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 1.1rem;
|
|
line-height: 1;
|
|
width: 20px;
|
|
height: 18px;
|
|
margin-left: -2px;
|
|
}
|
|
|
|
/* Clean dark toolbar - positioned near bottom */
|
|
.toolbar {
|
|
position: fixed;
|
|
bottom: var(--safe-area-bottom);
|
|
left: 0;
|
|
right: 0;
|
|
height: 40px;
|
|
min-height: 40px;
|
|
max-height: 40px;
|
|
padding: 0.3rem 0.4rem;
|
|
padding-left: calc(0.4rem + var(--safe-area-left));
|
|
padding-right: calc(0.4rem + var(--safe-area-right));
|
|
flex-wrap: nowrap;
|
|
gap: 0.3rem;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
background: #111111;
|
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
|
z-index: 50;
|
|
/* Smooth transition for keyboard show/hide */
|
|
transition: transform 0.15s ease-out;
|
|
/* Ensure transform works properly */
|
|
will-change: transform;
|
|
}
|
|
|
|
/* iOS Safari with tab bar: position: fixed uses the layout viewport which
|
|
extends behind the browser chrome. Offset the toolbar upward by the delta
|
|
between 100vh (layout) and --app-height (visual). */
|
|
.ios-device.safari-browser .toolbar {
|
|
bottom: calc(var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)));
|
|
}
|
|
|
|
/* When keyboard is visible the JS translateY already accounts for the full
|
|
distance from the visual-viewport bottom to the layout-viewport bottom
|
|
(keyboard + Safari bar). Remove the CSS Safari-bar offset to avoid
|
|
double-counting, which otherwise creates a visible gap above the keyboard. */
|
|
.keyboard-visible.ios-device.safari-browser .toolbar {
|
|
bottom: var(--safe-area-bottom);
|
|
}
|
|
.keyboard-visible.ios-device.safari-browser .keyboard-accessory-bar {
|
|
bottom: calc(var(--safe-area-bottom) + 40px);
|
|
}
|
|
|
|
/* Show case selector in center */
|
|
.toolbar-center {
|
|
display: flex !important;
|
|
align-items: center;
|
|
}
|
|
|
|
.toolbar-center .btn-toolbar.btn-voice {
|
|
display: none !important;
|
|
}
|
|
|
|
.toolbar-right {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Hide version display on mobile */
|
|
.version-display {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Toolbar layout */
|
|
.toolbar-left {
|
|
flex: 1 1 0;
|
|
min-width: 0;
|
|
align-items: center;
|
|
gap: 0.3rem;
|
|
}
|
|
|
|
.toolbar-left .toolbar-group {
|
|
display: flex;
|
|
flex: 1 1 0;
|
|
min-width: 0;
|
|
align-items: center;
|
|
gap: 0.3rem;
|
|
}
|
|
|
|
.toolbar-left .toolbar-group:first-child {
|
|
flex: 1 1 0;
|
|
min-width: 0;
|
|
justify-content: space-between;
|
|
gap: 0.3rem;
|
|
flex-wrap: nowrap;
|
|
align-items: center;
|
|
}
|
|
|
|
/* Hide instance count buttons (±) on mobile - cleaner UI */
|
|
.tab-count-group {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Compact toolbar buttons for mobile - white text on dark */
|
|
.btn-toolbar {
|
|
min-height: 26px !important;
|
|
max-height: 26px !important;
|
|
height: 26px !important;
|
|
padding: 0 0.5rem !important;
|
|
font-size: 0.65rem !important;
|
|
border-radius: 4px;
|
|
line-height: 26px;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-weight: 500;
|
|
letter-spacing: 0.01em;
|
|
color: #fff;
|
|
}
|
|
|
|
/* Run button group — split button with dropdown */
|
|
.run-btn-group {
|
|
display: flex;
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.btn-toolbar.btn-run {
|
|
flex: 0 0 auto;
|
|
padding: 0 0.6rem !important;
|
|
font-weight: 500;
|
|
border-radius: 4px 0 0 4px !important;
|
|
border-right: none !important;
|
|
}
|
|
|
|
.btn-toolbar.btn-run svg {
|
|
width: 10px;
|
|
height: 10px;
|
|
margin-right: 3px;
|
|
}
|
|
|
|
.btn-toolbar.btn-run-gear {
|
|
flex: 0 0 auto;
|
|
padding: 0 0.35rem !important;
|
|
min-width: unset !important;
|
|
border-radius: 0 4px 4px 0 !important;
|
|
border-left: 1px solid rgba(255,255,255,0.15) !important;
|
|
}
|
|
|
|
.btn-toolbar.btn-run-gear svg {
|
|
width: 10px;
|
|
height: 10px;
|
|
}
|
|
|
|
/* Claude mode colors on mobile */
|
|
.btn-toolbar.btn-run.mode-claude,
|
|
.btn-toolbar.btn-run-gear.mode-claude {
|
|
background: #1e3a5f;
|
|
border-color: rgba(59, 130, 246, 0.3);
|
|
color: #93c5fd;
|
|
}
|
|
|
|
.btn-toolbar.btn-run.mode-claude:active,
|
|
.btn-toolbar.btn-run-gear.mode-claude:active {
|
|
background: #2563eb;
|
|
border-color: rgba(59, 130, 246, 0.5);
|
|
}
|
|
|
|
/* OpenCode mode colors on mobile */
|
|
.btn-toolbar.btn-run.mode-opencode,
|
|
.btn-toolbar.btn-run-gear.mode-opencode {
|
|
background: #0a2e2a;
|
|
border-color: rgba(16, 185, 129, 0.3);
|
|
color: #6ee7b7;
|
|
}
|
|
|
|
.btn-toolbar.btn-run.mode-opencode:active,
|
|
.btn-toolbar.btn-run-gear.mode-opencode:active {
|
|
background: #0d4a40;
|
|
border-color: rgba(16, 185, 129, 0.5);
|
|
}
|
|
|
|
/* Run mode dropdown menu — positioned above toolbar on mobile */
|
|
.run-mode-menu {
|
|
bottom: 100%;
|
|
left: 0;
|
|
margin-bottom: 6px;
|
|
min-width: 160px;
|
|
max-width: 80vw;
|
|
}
|
|
|
|
.run-mode-option {
|
|
padding: 10px 12px;
|
|
font-size: 0.8rem;
|
|
cursor: pointer;
|
|
-webkit-tap-highlight-color: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.run-mode-history {
|
|
-webkit-overflow-scrolling: touch;
|
|
touch-action: manipulation;
|
|
}
|
|
|
|
/* Stop button - visible on mobile, icon-only */
|
|
.btn-toolbar.btn-stop {
|
|
display: flex !important;
|
|
flex: 0 0 auto;
|
|
padding: 0 8px !important;
|
|
min-width: unset;
|
|
order: 3; /* Left of Run Shell */
|
|
}
|
|
|
|
.btn-toolbar.btn-stop svg {
|
|
width: 10px;
|
|
height: 10px;
|
|
margin-right: 0;
|
|
}
|
|
|
|
/* Secondary action - Run Shell - right side */
|
|
.btn-toolbar.btn-shell {
|
|
flex: 0 0 auto;
|
|
background: transparent;
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
color: #9ca3af;
|
|
order: 4; /* Right position */
|
|
}
|
|
|
|
.btn-toolbar.btn-shell:hover,
|
|
.btn-toolbar.btn-shell:active {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
color: #fff;
|
|
}
|
|
|
|
/* Hide case selector on mobile - simplified toolbar */
|
|
.case-select-group {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Simplified toolbar layout — Run, Shell, and Case */
|
|
.toolbar-left .toolbar-group:first-child {
|
|
width: 100%;
|
|
gap: 8px;
|
|
}
|
|
|
|
.btn-toolbar.btn-shell {
|
|
flex: 0 0 auto;
|
|
min-width: 54px;
|
|
width: 54px;
|
|
white-space: nowrap;
|
|
padding: 0 8px !important;
|
|
overflow: hidden;
|
|
font-size: 0 !important;
|
|
}
|
|
|
|
.btn-toolbar.btn-shell::after {
|
|
content: "Shell";
|
|
font-size: 0.65rem;
|
|
}
|
|
|
|
/* Mobile case button - visible on mobile */
|
|
.btn-toolbar.btn-case-mobile {
|
|
display: flex !important;
|
|
flex: 1 1 0 !important;
|
|
min-width: 0;
|
|
padding: 0 8px !important;
|
|
order: 2; /* Between Run and Run Shell */
|
|
overflow: hidden;
|
|
justify-content: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
.btn-toolbar.btn-case-mobile #mobileCaseName {
|
|
max-width: none;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* Mobile case settings gear button - next to Run */
|
|
.btn-case-settings-mobile {
|
|
display: inline-flex !important;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 26px;
|
|
height: 26px;
|
|
background: transparent;
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
border-radius: 4px;
|
|
color: #9ca3af;
|
|
cursor: pointer;
|
|
flex-shrink: 0;
|
|
order: 1; /* Next to Run */
|
|
}
|
|
|
|
.btn-case-settings-mobile:active {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
color: #fff;
|
|
}
|
|
|
|
@media (max-width: 374px) {
|
|
.toolbar {
|
|
padding: 0 2px;
|
|
}
|
|
|
|
.toolbar-left,
|
|
.toolbar-left .toolbar-group,
|
|
.toolbar-left .toolbar-group:first-child {
|
|
gap: 2px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 430px) {
|
|
.btn-case-settings-mobile {
|
|
display: none !important;
|
|
}
|
|
}
|
|
|
|
/* Mobile case settings popover */
|
|
.case-settings-popover-mobile {
|
|
position: fixed;
|
|
bottom: calc(var(--safe-area-bottom) + 46px);
|
|
left: 8px;
|
|
right: 8px;
|
|
background: #1e1e1e;
|
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
border-radius: 8px;
|
|
padding: 0.6rem 0.75rem;
|
|
z-index: 1000;
|
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
|
|
display: block;
|
|
}
|
|
|
|
.case-settings-popover-mobile.hidden {
|
|
display: none !important;
|
|
}
|
|
|
|
.case-settings-popover-mobile .checkbox-inline {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font-size: 0.75rem;
|
|
color: #e5e7eb;
|
|
}
|
|
|
|
.case-settings-popover-mobile .form-hint {
|
|
display: block;
|
|
margin-top: 0.2rem;
|
|
font-size: 0.6rem;
|
|
color: #6b7280;
|
|
}
|
|
|
|
/* Keyboard Accessory Bar - quick actions above keyboard */
|
|
.keyboard-accessory-bar {
|
|
display: none;
|
|
position: fixed;
|
|
bottom: calc(var(--safe-area-bottom) + 40px); /* Above toolbar */
|
|
left: 0;
|
|
right: 0;
|
|
height: 44px;
|
|
background: #1a1a1a;
|
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
|
padding: 6px 8px;
|
|
padding-left: calc(8px + var(--safe-area-left));
|
|
padding-right: calc(8px + var(--safe-area-right));
|
|
gap: 8px;
|
|
align-items: center;
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
-webkit-overflow-scrolling: touch;
|
|
z-index: 51;
|
|
transition: transform 0.15s ease-out;
|
|
will-change: transform;
|
|
}
|
|
|
|
.keyboard-accessory-bar.visible {
|
|
display: flex;
|
|
}
|
|
|
|
/* 隐藏滚动条但保留滑动能力 */
|
|
.keyboard-accessory-bar::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.accessory-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
gap: 4px;
|
|
padding: 6px 12px;
|
|
background: #2a2a2a;
|
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
border-radius: 6px;
|
|
color: #e5e5e5;
|
|
font-size: 0.65rem;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: background 0.15s, border-color 0.15s;
|
|
}
|
|
|
|
/* Confirm state — button turns amber and shows "Tap again" */
|
|
.accessory-btn.confirming {
|
|
background: #6b4f00;
|
|
border-color: #b8860b;
|
|
color: #ffd54f;
|
|
}
|
|
|
|
.accessory-btn:active {
|
|
background: #3a3a3a;
|
|
}
|
|
|
|
.accessory-btn svg {
|
|
width: 14px;
|
|
height: 14px;
|
|
}
|
|
|
|
.accessory-btn-arrow {
|
|
padding: 6px 10px;
|
|
background: #2563eb;
|
|
border-color: rgba(59, 130, 246, 0.5);
|
|
color: #fff;
|
|
}
|
|
|
|
.accessory-btn-arrow:active {
|
|
background: #1d4ed8;
|
|
}
|
|
|
|
.accessory-btn-dismiss {
|
|
margin-left: auto;
|
|
flex: 1 1 0;
|
|
max-width: 100px;
|
|
padding: 10px 8px;
|
|
background: #2563eb;
|
|
border-color: rgba(59, 130, 246, 0.5);
|
|
color: #fff;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.accessory-btn-dismiss svg {
|
|
width: 22px;
|
|
height: 22px;
|
|
}
|
|
|
|
.accessory-btn-dismiss:active {
|
|
background: #1d4ed8;
|
|
}
|
|
|
|
/* Voice preview — positioned above accessory bar on mobile */
|
|
.voice-preview {
|
|
bottom: calc(var(--safe-area-bottom) + 94px);
|
|
font-size: 0.8rem;
|
|
max-width: 90%;
|
|
padding: 6px 14px;
|
|
}
|
|
|
|
/* Add case button - compact (keeping for when shown via menu) */
|
|
.btn-case-add {
|
|
display: none !important;
|
|
}
|
|
|
|
.btn-case-settings {
|
|
display: none !important;
|
|
}
|
|
|
|
/* When keyboard is visible, also move accessory bar up */
|
|
.keyboard-visible .keyboard-accessory-bar.visible {
|
|
/* Position is handled by JS transform along with toolbar */
|
|
}
|
|
|
|
/* Paste overlay for iOS clipboard access */
|
|
.paste-overlay {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: rgba(0, 0, 0, 0.6);
|
|
z-index: 10000;
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: center;
|
|
padding-top: 15vh;
|
|
}
|
|
|
|
.paste-dialog {
|
|
background: var(--bg-secondary, #1e1e2e);
|
|
border: 1px solid var(--border-color, #444);
|
|
border-radius: 12px;
|
|
padding: 12px;
|
|
width: calc(100% - 24px);
|
|
max-width: 400px;
|
|
}
|
|
|
|
.paste-textarea {
|
|
width: 100%;
|
|
min-height: 80px;
|
|
max-height: 200px;
|
|
background: var(--bg-primary, #0d0d14);
|
|
color: var(--text-primary, #e0e0e0);
|
|
border: 1px solid var(--border-color, #444);
|
|
border-radius: 8px;
|
|
padding: 8px;
|
|
font-family: inherit;
|
|
font-size: 16px;
|
|
resize: none;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.paste-textarea:focus {
|
|
outline: none;
|
|
border-color: var(--accent-color, #7aa2f7);
|
|
}
|
|
|
|
.paste-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 8px;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.paste-cancel, .paste-new, .paste-send, .paste-image {
|
|
padding: 8px 18px;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 14px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Image attach button — left-aligned, accent outline */
|
|
.paste-image {
|
|
margin-right: auto;
|
|
background: var(--bg-tertiary, #333);
|
|
color: var(--accent-color, #7aa2f7);
|
|
border: 1px solid var(--accent-color, #7aa2f7);
|
|
}
|
|
|
|
.paste-cancel {
|
|
background: var(--bg-tertiary, #333);
|
|
color: var(--text-secondary, #aaa);
|
|
}
|
|
|
|
.paste-new {
|
|
background: var(--bg-tertiary, #333);
|
|
color: var(--accent-color, #7aa2f7);
|
|
border: 1px solid var(--accent-color, #7aa2f7);
|
|
}
|
|
|
|
.paste-send {
|
|
background: var(--accent-color, #7aa2f7);
|
|
color: #fff;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* LEGACY: Hide old toolbar select (no longer used on mobile) */
|
|
.toolbar-select {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Keep btn-case-add styling for tablet/future use */
|
|
.toolbar .btn-case-add {
|
|
min-width: 26px !important;
|
|
max-width: 26px !important;
|
|
width: 26px !important;
|
|
min-height: 26px !important;
|
|
max-height: 26px !important;
|
|
height: 26px !important;
|
|
padding: 0 !important;
|
|
font-size: 0.9rem;
|
|
font-weight: bold;
|
|
display: inline-flex !important;
|
|
align-items: center;
|
|
justify-content: center;
|
|
line-height: 1;
|
|
border-radius: 4px;
|
|
background: transparent;
|
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
color: #9ca3af;
|
|
}
|
|
|
|
.btn-case-add:hover,
|
|
.btn-case-add:active {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
color: #fff;
|
|
}
|
|
|
|
/* Panels on mobile - full width, positioned above toolbar, visibility controlled by JS */
|
|
.monitor-panel,
|
|
.subagents-panel {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
left: 0;
|
|
right: 0;
|
|
border-radius: 8px 8px 0 0;
|
|
bottom: calc(44px + 2rem + var(--safe-area-bottom));
|
|
max-height: 35vh;
|
|
}
|
|
|
|
/* Full-screen modals on phones */
|
|
.modal-content {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
height: 100%;
|
|
max-height: 100%;
|
|
border-radius: 0;
|
|
margin: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
/* Small modals (confirmations, dialogs) — auto-height, not full-screen */
|
|
.modal-content.modal-sm {
|
|
height: auto;
|
|
max-height: 85vh;
|
|
border-radius: 12px;
|
|
margin: 1rem;
|
|
width: calc(100% - 2rem);
|
|
}
|
|
|
|
/* Modal safe area padding - all sides for full-screen modals */
|
|
.ios-device .modal-content {
|
|
padding-top: var(--safe-area-top);
|
|
padding-bottom: var(--safe-area-bottom);
|
|
padding-left: var(--safe-area-left);
|
|
padding-right: var(--safe-area-right);
|
|
}
|
|
|
|
.modal-header {
|
|
padding: 0.75rem 1rem;
|
|
}
|
|
|
|
.modal-header h3 {
|
|
font-size: 1rem;
|
|
}
|
|
|
|
.modal-body {
|
|
padding: 0.75rem 1rem;
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.modal-footer,
|
|
.form-actions {
|
|
padding: 0.75rem 1rem;
|
|
padding-bottom: calc(0.75rem + var(--safe-area-bottom));
|
|
}
|
|
|
|
/* Terminal container safe area */
|
|
.ios-device .terminal-container {
|
|
padding-bottom: var(--safe-area-bottom);
|
|
}
|
|
|
|
/* Main area must fill available space */
|
|
.main {
|
|
flex: 1;
|
|
min-height: 0; /* Allow flex item to shrink below content size */
|
|
}
|
|
|
|
/* Show CLI info bar on mobile (Claude version/model) */
|
|
.cli-info-bar {
|
|
display: block;
|
|
}
|
|
|
|
/* Mobile terminal — JS touch handler (terminal.scrollLines()) drives
|
|
scrollback because xterm.js DOM renderer doesn't populate xterm-viewport's
|
|
scroll area. touch-action:none lets our JS handler own the gesture. */
|
|
.terminal-container {
|
|
height: 100%;
|
|
min-height: 0;
|
|
position: relative;
|
|
overflow: visible;
|
|
touch-action: none;
|
|
}
|
|
|
|
.terminal-container .xterm,
|
|
.terminal-container .xterm-viewport,
|
|
.terminal-container .xterm-screen {
|
|
touch-action: none;
|
|
}
|
|
|
|
.response-viewer {
|
|
padding-bottom: var(--safe-area-bottom, 0px);
|
|
}
|
|
|
|
.response-viewer-body {
|
|
font-size: 12px;
|
|
padding: 12px;
|
|
}
|
|
|
|
/* Compact welcome overlay for mobile */
|
|
.welcome-content {
|
|
max-width: calc(100vw - 1.5rem);
|
|
padding: 1rem 0.75rem;
|
|
}
|
|
|
|
.welcome-title {
|
|
font-size: 1.2rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.welcome-desc {
|
|
font-size: 0.8rem;
|
|
margin-bottom: 0.4rem;
|
|
}
|
|
|
|
.welcome-actions {
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.welcome-btn {
|
|
width: 100%;
|
|
justify-content: center;
|
|
min-height: 44px;
|
|
padding: 0.75rem 1rem;
|
|
font-size: 0.85rem;
|
|
}
|
|
|
|
.history-show-more {
|
|
display: block;
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
|
|
.welcome-ralph-link {
|
|
display: block;
|
|
margin: 0.75rem auto 0;
|
|
}
|
|
|
|
.welcome-hint {
|
|
font-size: 0.7rem;
|
|
margin-top: 0.75rem;
|
|
}
|
|
|
|
/* Ralph wizard responsive */
|
|
.modal-wizard {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.wizard-progress {
|
|
padding: 0.5rem;
|
|
}
|
|
|
|
.wizard-step {
|
|
padding: 0.3rem;
|
|
}
|
|
|
|
.wizard-step-number {
|
|
width: 24px;
|
|
height: 24px;
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
.wizard-step-label {
|
|
display: none;
|
|
}
|
|
|
|
/* Timer banner - includes safe area padding */
|
|
.timer-banner {
|
|
padding-left: calc(0.5rem + var(--safe-area-left));
|
|
padding-right: calc(0.5rem + var(--safe-area-right));
|
|
}
|
|
|
|
/* ---- Respawn Banner: Mobile Optimizations ---- */
|
|
|
|
.respawn-banner {
|
|
padding: 0.3rem 0.5rem;
|
|
padding-left: calc(0.5rem + var(--safe-area-left));
|
|
padding-right: calc(0.5rem + var(--safe-area-right));
|
|
font-size: 0.65rem;
|
|
}
|
|
|
|
/* Stack banner vertically on mobile — status on top, action log below */
|
|
.respawn-compact-layout {
|
|
flex-direction: column;
|
|
gap: 0.15rem;
|
|
}
|
|
|
|
/* Let status column shrink to fit */
|
|
.respawn-status-col {
|
|
flex-shrink: 1;
|
|
min-width: 0;
|
|
gap: 0.1rem;
|
|
}
|
|
|
|
/* Row1: wrap allowed, key info prioritized via order */
|
|
.respawn-status-row1 {
|
|
flex-wrap: wrap;
|
|
gap: 0.25rem;
|
|
row-gap: 0.1rem;
|
|
}
|
|
|
|
/* State label — smaller on phone, stays first */
|
|
.respawn-state {
|
|
font-size: 0.6rem;
|
|
padding: 0.05rem 0.3rem;
|
|
}
|
|
|
|
/* Confidence badge — compact */
|
|
.respawn-banner .detection-confidence {
|
|
font-size: 0.5rem;
|
|
padding: 0.02rem 0.2rem;
|
|
}
|
|
|
|
/* Cycles — compact */
|
|
.respawn-cycles {
|
|
font-size: 0.55rem;
|
|
}
|
|
|
|
/* Run timer — compact */
|
|
.respawn-timer {
|
|
font-size: 0.55rem;
|
|
padding: 0 0.25rem;
|
|
}
|
|
|
|
/* Tokens — compact, truncate if long */
|
|
.respawn-tokens {
|
|
font-size: 0.55rem;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
max-width: 120px;
|
|
}
|
|
|
|
/* Spinner icon — smaller on phone */
|
|
.respawn-indicator {
|
|
font-size: 0.65rem;
|
|
}
|
|
|
|
/* Stop button — 36px touch target, pushed right */
|
|
.respawn-banner .btn-icon-only {
|
|
min-width: 36px;
|
|
min-height: 36px;
|
|
font-size: 1rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-left: auto;
|
|
border-radius: 6px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* Row2: tighter spacing, smaller text */
|
|
.respawn-status-row2 {
|
|
font-size: 0.55rem;
|
|
gap: 0.3rem;
|
|
min-height: 0;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
/* Detection badges — smaller on phone */
|
|
.respawn-banner .detection-hook,
|
|
.respawn-banner .detection-ai-check,
|
|
.respawn-banner .detection-status {
|
|
font-size: 0.55rem;
|
|
padding: 0.02rem 0.2rem;
|
|
}
|
|
|
|
/* Countdown timers — inline, no progress bars */
|
|
.respawn-countdown-timers {
|
|
gap: 0.2rem;
|
|
}
|
|
|
|
.respawn-countdown-timer {
|
|
font-size: 0.5rem;
|
|
padding: 0.02rem 0.2rem;
|
|
gap: 0.15rem;
|
|
}
|
|
|
|
/* Hide progress bars on phone — values are enough */
|
|
.respawn-countdown-timer .respawn-timer-bar {
|
|
display: none;
|
|
}
|
|
|
|
/* Action log — single-line strip below status, show latest entry only */
|
|
.respawn-action-log {
|
|
border-left: none;
|
|
border-top: 1px solid rgba(34, 197, 94, 0.15);
|
|
padding-left: 0;
|
|
padding-top: 0.15rem;
|
|
max-height: 1.4em;
|
|
font-size: 0.55rem;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* ---- Session Options Modal: Respawn Tab Mobile Optimizations ---- */
|
|
|
|
/* Respawn header — keep horizontal, compact */
|
|
.respawn-header {
|
|
flex-direction: row;
|
|
gap: 0.4rem;
|
|
align-items: center;
|
|
}
|
|
|
|
/* Enable/Stop buttons — compact */
|
|
.respawn-header .respawn-actions {
|
|
display: flex;
|
|
gap: 0.3rem;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.respawn-header .respawn-actions .btn-toolbar {
|
|
min-height: 28px !important;
|
|
font-size: 0.7rem !important;
|
|
padding: 0.2rem 0.5rem !important;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
/* Duration preset buttons — grid layout, 4 columns for even spacing */
|
|
.duration-presets {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 0.2rem;
|
|
}
|
|
|
|
.duration-preset-btn {
|
|
min-height: 32px;
|
|
padding: 0.2rem 0.25rem;
|
|
font-size: 0.65rem;
|
|
border-radius: 5px;
|
|
text-align: center;
|
|
}
|
|
|
|
/* Custom duration — spans full row below */
|
|
.duration-custom {
|
|
grid-column: 1 / -1;
|
|
display: flex;
|
|
gap: 0.25rem;
|
|
align-items: center;
|
|
}
|
|
|
|
.duration-custom .duration-preset-btn {
|
|
flex: 0 0 auto;
|
|
min-width: 50px;
|
|
}
|
|
|
|
.duration-custom-input.visible {
|
|
flex: 1;
|
|
}
|
|
|
|
.duration-custom-input input {
|
|
width: 100%;
|
|
min-height: 28px;
|
|
font-size: 16px; /* Prevents iOS zoom */
|
|
}
|
|
|
|
/* Preset selector row — full-width dropdown, buttons below */
|
|
.preset-selector {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 0.25rem;
|
|
}
|
|
|
|
.preset-selector select {
|
|
grid-column: 1 / -1;
|
|
min-height: 32px;
|
|
font-size: 16px; /* Prevents iOS zoom */
|
|
border-radius: 5px;
|
|
padding: 0.2rem 0.4rem;
|
|
}
|
|
|
|
.preset-selector .btn {
|
|
min-height: 32px;
|
|
font-size: 0.65rem;
|
|
border-radius: 5px;
|
|
padding: 0.2rem 0.4rem;
|
|
}
|
|
|
|
/* Textareas — prevent iOS zoom with 16px font, compact height */
|
|
#sessionOptionsModal textarea {
|
|
font-size: 16px;
|
|
min-height: 32px !important;
|
|
max-height: 56px;
|
|
height: auto !important;
|
|
border-radius: 6px;
|
|
padding: 0.3rem 0.5rem;
|
|
}
|
|
|
|
/* Override inline min-height styles on respawn textareas */
|
|
#modalRespawnPrompt {
|
|
min-height: 32px !important;
|
|
max-height: 56px;
|
|
}
|
|
|
|
#modalRespawnKickstart {
|
|
min-height: 32px !important;
|
|
max-height: 48px;
|
|
}
|
|
|
|
/* Checkboxes — compact touch area */
|
|
#sessionOptionsModal .checkbox-inline {
|
|
min-height: 30px;
|
|
font-size: 0.75rem;
|
|
padding: 0.15rem 0;
|
|
gap: 0.4rem;
|
|
}
|
|
|
|
#sessionOptionsModal .checkbox-inline input[type="checkbox"] {
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
|
|
/* Respawn options row — stack if needed */
|
|
#sessionOptionsModal .respawn-options-row {
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
/* Form section headers — compact on mobile */
|
|
#sessionOptionsModal .form-section-header {
|
|
margin-top: 0.75rem;
|
|
padding-top: 0.5rem;
|
|
font-size: 0.65rem;
|
|
}
|
|
|
|
/* Form rows — tighter spacing */
|
|
#sessionOptionsModal .form-row {
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
#sessionOptionsModal .form-row label {
|
|
font-size: 0.65rem;
|
|
margin-bottom: 0.2rem;
|
|
}
|
|
|
|
/* Form hints — compact */
|
|
#sessionOptionsModal .form-hint {
|
|
font-size: 0.6rem;
|
|
margin-top: 0.2rem;
|
|
}
|
|
|
|
/* ---- Context Tab: Mobile Optimizations ---- */
|
|
|
|
/* Context settings cards — tighter padding */
|
|
.context-setting {
|
|
padding: 0.625rem;
|
|
}
|
|
|
|
/* Stack context setting header vertically on narrow screens */
|
|
.context-setting-header {
|
|
flex-wrap: wrap;
|
|
gap: 0.4rem;
|
|
}
|
|
|
|
.context-setting-header .input-suffix-sm input {
|
|
width: 60px;
|
|
font-size: 16px; /* Prevents iOS zoom */
|
|
min-height: 36px;
|
|
}
|
|
|
|
.context-setting input[type="text"] {
|
|
font-size: 16px; /* Prevents iOS zoom */
|
|
min-height: 36px;
|
|
padding: 0.4rem 0.6rem;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
/* Color picker — larger swatches for touch */
|
|
.color-picker {
|
|
gap: 8px;
|
|
}
|
|
|
|
.color-swatch {
|
|
width: 36px;
|
|
height: 36px;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
/* Toggle switches — larger touch area */
|
|
.form-row-switch {
|
|
min-height: 40px;
|
|
gap: 0.4rem;
|
|
}
|
|
|
|
/* Number inputs in context tab — prevent iOS zoom */
|
|
.context-settings-grid input[type="number"] {
|
|
font-size: 16px;
|
|
min-height: 36px;
|
|
}
|
|
|
|
/* ---- Ralph Tab: Mobile Optimizations ---- */
|
|
|
|
/* Ralph limits grid — 2 columns on mobile */
|
|
.ralph-limits-grid {
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.ralph-limits-grid .form-col input[type="number"] {
|
|
font-size: 16px; /* Prevents iOS zoom */
|
|
min-height: 36px;
|
|
padding: 0.4rem 0.5rem;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
/* Ralph phrase input — prevent iOS zoom */
|
|
#modalRalphPhrase {
|
|
font-size: 16px;
|
|
min-height: 40px;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
/* Save button — full width, proper touch target */
|
|
.ralph-config-actions {
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.ralph-config-actions .btn-toolbar {
|
|
width: 100%;
|
|
min-height: 44px;
|
|
font-size: 0.85rem;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
/* ---- Summary Tab: Mobile Optimizations ---- */
|
|
|
|
/* Filter buttons — larger touch targets */
|
|
.run-summary-filters {
|
|
gap: 0.3rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.filter-btn {
|
|
padding: 0.35rem 0.75rem;
|
|
font-size: 0.7rem;
|
|
min-height: 32px;
|
|
}
|
|
|
|
/* Timeline events — tighter on mobile */
|
|
.timeline-event {
|
|
padding: 0.4rem 0.5rem;
|
|
margin-bottom: 0.25rem;
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
/* Summary footer — stack vertically */
|
|
.run-summary-footer {
|
|
flex-direction: column;
|
|
gap: 0.4rem;
|
|
padding: 0.5rem 0;
|
|
}
|
|
|
|
.run-summary-actions {
|
|
flex-wrap: wrap;
|
|
gap: 0.3rem;
|
|
}
|
|
|
|
.run-summary-actions .btn-toolbar {
|
|
flex: 1;
|
|
min-height: 36px;
|
|
font-size: 0.7rem;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.auto-refresh-label {
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
.ralph-panel {
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.ralph-summary {
|
|
padding: 0.4rem 0.5rem;
|
|
padding-left: calc(0.5rem + var(--safe-area-left));
|
|
padding-right: calc(0.5rem + var(--safe-area-right));
|
|
}
|
|
|
|
/* Project insights panel - compact on mobile, visibility controlled by JS */
|
|
.project-insights-panel {
|
|
max-width: 100%;
|
|
font-size: 0.65rem;
|
|
bottom: calc(44px + 2rem + var(--safe-area-bottom));
|
|
}
|
|
|
|
/* File browser panel - compact on mobile, visibility controlled by JS */
|
|
.file-browser-panel {
|
|
max-width: 100%;
|
|
max-height: 50vh;
|
|
bottom: calc(44px + 2rem + var(--safe-area-bottom));
|
|
}
|
|
|
|
/* Notification drawer - full width on mobile, includes safe area padding */
|
|
.notification-drawer {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
right: 0;
|
|
border-radius: 0;
|
|
padding-left: var(--safe-area-left);
|
|
padding-right: var(--safe-area-right);
|
|
padding-bottom: var(--safe-area-bottom);
|
|
}
|
|
|
|
/* Scroll margin for inputs - helps with keyboard visibility */
|
|
input, textarea, [contenteditable] {
|
|
scroll-margin-bottom: 200px;
|
|
scroll-margin-top: 80px;
|
|
}
|
|
|
|
/* When keyboard is visible, the JS paddingBottom on .main already reserves
|
|
space for toolbar + accessory bar. No extra padding needed here — it was
|
|
double-counting and creating dead space between terminal and the bars. */
|
|
|
|
/* Ensure modals scroll properly when keyboard is visible */
|
|
.keyboard-visible .modal-body {
|
|
max-height: 40vh;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
/* When keyboard opens in case modal, let body grow taller */
|
|
.keyboard-visible #createCaseModal .modal-body {
|
|
max-height: 60vh;
|
|
}
|
|
|
|
/* Mobile Case Picker - Mobile-specific overrides */
|
|
.mobile-case-picker .modal-backdrop {
|
|
background: rgba(0, 0, 0, 0.5);
|
|
}
|
|
|
|
.mobile-case-picker-sheet {
|
|
max-height: 60vh;
|
|
padding-bottom: var(--safe-area-bottom);
|
|
animation: slideUp 0.2s ease-out;
|
|
}
|
|
|
|
@keyframes slideUp {
|
|
from {
|
|
transform: translateY(100%);
|
|
}
|
|
to {
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.mobile-case-picker-header .modal-close {
|
|
width: 32px;
|
|
height: 32px;
|
|
font-size: 1.5rem;
|
|
}
|
|
|
|
.mobile-case-picker-footer {
|
|
padding-bottom: calc(12px + var(--safe-area-bottom));
|
|
}
|
|
|
|
/* ---- Settings Modal: Mobile Optimizations ---- */
|
|
|
|
/* Scrollable tabs row - prevent overflow on small screens */
|
|
.modal-tabs {
|
|
overflow-x: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
scrollbar-width: none;
|
|
gap: 0.25rem;
|
|
padding: 0 0.75rem 0.5rem 0.75rem;
|
|
flex-wrap: nowrap;
|
|
}
|
|
|
|
.modal-tabs::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.modal-tab-btn {
|
|
padding: 0.35rem 0.6rem;
|
|
font-size: 0.65rem;
|
|
white-space: nowrap;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* ---- Case Modal: Mobile Touch Optimizations ---- */
|
|
|
|
/* Larger tab buttons for case modal - easy to tap */
|
|
#createCaseModal .modal-tabs {
|
|
gap: 0.5rem;
|
|
padding: 0.5rem 1rem 0.75rem;
|
|
}
|
|
|
|
#createCaseModal .modal-tab-btn {
|
|
flex: 1;
|
|
min-height: 44px;
|
|
padding: 0.6rem 1rem;
|
|
font-size: 0.8rem;
|
|
font-weight: 500;
|
|
border-radius: 8px;
|
|
justify-content: center;
|
|
text-align: center;
|
|
}
|
|
|
|
/* Touch-friendly form inputs in case modal */
|
|
#createCaseModal .form-row {
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
#createCaseModal .form-row label {
|
|
font-size: 0.8rem;
|
|
margin-bottom: 0.4rem;
|
|
font-weight: 500;
|
|
color: #e5e7eb;
|
|
}
|
|
|
|
#createCaseModal .form-row input[type="text"] {
|
|
min-height: 44px;
|
|
font-size: 16px; /* Prevents iOS zoom on focus */
|
|
padding: 0.5rem 0.75rem;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
#createCaseModal .form-row .form-hint {
|
|
font-size: 0.65rem;
|
|
margin-top: 0.35rem;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
/* Touch-friendly action buttons in case modal */
|
|
#createCaseModal .form-actions {
|
|
padding: 0.75rem 1rem;
|
|
padding-bottom: calc(0.75rem + var(--safe-area-bottom));
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
#createCaseModal .form-actions .btn-toolbar {
|
|
min-height: 44px !important;
|
|
max-height: 44px !important;
|
|
height: 44px !important;
|
|
font-size: 0.85rem !important;
|
|
font-weight: 500;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
/* Loading state for submit button */
|
|
#caseModalSubmit.loading {
|
|
opacity: 0.6;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Smooth open animation for case modal from mobile picker */
|
|
#createCaseModal.from-mobile .modal-content {
|
|
animation: caseModalSlideUp 0.25s ease-out;
|
|
}
|
|
|
|
@keyframes caseModalSlideUp {
|
|
from {
|
|
transform: translateY(30px);
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
/* Mobile case picker - larger create button (override btn-toolbar !important) */
|
|
.btn-case-create-mobile {
|
|
min-height: 48px !important;
|
|
max-height: 48px !important;
|
|
height: 48px !important;
|
|
font-size: 0.85rem !important;
|
|
font-weight: 500;
|
|
border-radius: 10px;
|
|
}
|
|
|
|
/* Settings grid - single column on phones */
|
|
.settings-grid {
|
|
grid-template-columns: 1fr;
|
|
gap: 0.35rem;
|
|
}
|
|
|
|
.settings-grid-3col {
|
|
grid-template-columns: 1fr 1fr 1fr;
|
|
}
|
|
|
|
.settings-item {
|
|
padding: 0.35rem 0.5rem;
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
.settings-item-label {
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
.settings-section-header {
|
|
font-size: 0.6rem;
|
|
padding: 0.35rem 0 0.2rem 0;
|
|
margin-top: 0.5rem;
|
|
}
|
|
|
|
/* Form rows - compact on mobile */
|
|
.form-row {
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.form-row label {
|
|
font-size: 0.7rem;
|
|
margin-bottom: 0.2rem;
|
|
}
|
|
|
|
.form-row .form-hint {
|
|
font-size: 0.6rem;
|
|
}
|
|
|
|
.form-row input[type="text"],
|
|
.form-row input[type="number"],
|
|
.form-row textarea,
|
|
.form-row .form-select,
|
|
.form-row select {
|
|
font-size: 0.75rem;
|
|
padding: 0.35rem 0.5rem;
|
|
min-height: 32px;
|
|
}
|
|
|
|
.form-row-switch {
|
|
gap: 0.3rem;
|
|
}
|
|
|
|
.form-row-switch > label:first-child {
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
.form-section-header {
|
|
font-size: 0.6rem;
|
|
margin-top: 0.75rem;
|
|
}
|
|
|
|
/* Event type grid - tighter on mobile */
|
|
.event-type-grid {
|
|
grid-template-columns: 1fr 36px 36px 36px;
|
|
gap: 4px 4px;
|
|
padding: 6px;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.event-header {
|
|
font-size: 0.55rem;
|
|
}
|
|
|
|
.event-label {
|
|
font-size: 0.65rem;
|
|
}
|
|
|
|
.event-type-grid input[type="checkbox"] {
|
|
width: 12px;
|
|
height: 12px;
|
|
}
|
|
|
|
/* Modal footer buttons - full width on mobile */
|
|
.form-actions {
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.form-actions .btn-toolbar {
|
|
flex: 1;
|
|
min-height: 36px !important;
|
|
max-height: 36px !important;
|
|
height: 36px !important;
|
|
font-size: 0.75rem !important;
|
|
}
|
|
|
|
/* ---- Subagent Windows: Mobile Optimizations ---- */
|
|
|
|
/* Compact stacked cards — multiple visible at once, draggable via touch */
|
|
.subagent-window {
|
|
position: fixed;
|
|
width: calc(100% - 8px);
|
|
max-width: calc(100% - 8px);
|
|
height: 110px;
|
|
min-height: 80px;
|
|
max-height: 110px;
|
|
min-width: 200px;
|
|
border-radius: 6px;
|
|
resize: none;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
|
|
}
|
|
|
|
/* Hide resize handle on mobile */
|
|
.subagent-window::after {
|
|
display: none;
|
|
}
|
|
|
|
/* Compact subagent window header */
|
|
.subagent-window-header {
|
|
padding: 0.2rem 0.4rem;
|
|
min-height: 24px;
|
|
}
|
|
|
|
.subagent-window-title {
|
|
gap: 0.2rem;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.subagent-window-title .icon {
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
.subagent-window-title .id {
|
|
font-size: 0.6rem;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
max-width: 45vw;
|
|
}
|
|
|
|
.subagent-window-title .status {
|
|
font-size: 0.45rem;
|
|
padding: 0.05rem 0.15rem;
|
|
}
|
|
|
|
.subagent-model-badge {
|
|
font-size: 0.45rem !important;
|
|
padding: 0.05rem 0.15rem !important;
|
|
}
|
|
|
|
.subagent-window-actions button {
|
|
font-size: 0.7rem;
|
|
padding: 0.15rem 0.35rem;
|
|
min-width: 26px;
|
|
min-height: 26px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.subagent-window-body {
|
|
font-size: 0.6rem;
|
|
padding: 0.2rem 0.35rem;
|
|
}
|
|
|
|
.subagent-window-body .activity-line {
|
|
gap: 0.15rem;
|
|
padding: 0.05rem 0;
|
|
}
|
|
|
|
.subagent-window-body .activity-line .time {
|
|
font-size: 0.5rem;
|
|
}
|
|
|
|
.subagent-window-body .activity-line .tool-name {
|
|
font-size: 0.55rem;
|
|
}
|
|
|
|
.subagent-window-body .activity-line .tool-detail {
|
|
font-size: 0.55rem;
|
|
}
|
|
|
|
/* Hide parent label on mobile to save space */
|
|
.subagent-window-parent {
|
|
display: none;
|
|
}
|
|
|
|
/* ---- Tab Subagent Badges: Smaller on Mobile ---- */
|
|
|
|
.session-tab .tab-subagent-badge {
|
|
height: 14px;
|
|
padding: 0 3px;
|
|
border-radius: 7px;
|
|
margin-left: 2px;
|
|
}
|
|
|
|
.session-tab .tab-subagent-badge .subagent-label {
|
|
font-size: 0.45rem;
|
|
}
|
|
|
|
/* Subagent dropdown - full width near badge on mobile (JS sets top from badge position) */
|
|
.subagent-dropdown {
|
|
position: fixed !important;
|
|
left: 8px !important;
|
|
right: 8px !important;
|
|
bottom: auto !important;
|
|
min-width: auto !important;
|
|
max-width: none !important;
|
|
border-radius: 8px;
|
|
transform: none !important;
|
|
}
|
|
}
|
|
|
|
|
|
/* ============================================================================
|
|
Keyboard Accessory Bar — all mobile/tablet sizes
|
|
Visual styles extracted from phone breakpoint so they apply on iPad too.
|
|
Phone-specific positioning (position: fixed) remains in @media (max-width: 430px).
|
|
============================================================================ */
|
|
.keyboard-accessory-bar {
|
|
display: none;
|
|
height: 44px;
|
|
background: #1a1a1a;
|
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
|
padding: 6px 8px;
|
|
gap: 8px;
|
|
align-items: center;
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
-webkit-overflow-scrolling: touch;
|
|
z-index: 51;
|
|
}
|
|
|
|
.keyboard-accessory-bar.visible {
|
|
display: flex;
|
|
}
|
|
|
|
.keyboard-accessory-bar::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.accessory-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
gap: 4px;
|
|
padding: 6px 12px;
|
|
background: #2a2a2a;
|
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
border-radius: 6px;
|
|
color: #e5e5e5;
|
|
font-size: 0.65rem;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: background 0.15s, border-color 0.15s;
|
|
}
|
|
|
|
.accessory-btn.confirming {
|
|
background: #6b4f00;
|
|
border-color: #b8860b;
|
|
color: #ffd54f;
|
|
}
|
|
|
|
.accessory-btn:active {
|
|
background: #3a3a3a;
|
|
}
|
|
|
|
.accessory-btn svg {
|
|
width: 14px;
|
|
height: 14px;
|
|
}
|
|
|
|
.accessory-btn-arrow {
|
|
padding: 6px 10px;
|
|
background: #2563eb;
|
|
border-color: rgba(59, 130, 246, 0.5);
|
|
color: #fff;
|
|
}
|
|
|
|
.accessory-btn-arrow:active {
|
|
background: #1d4ed8;
|
|
}
|
|
|
|
.accessory-btn-dismiss {
|
|
margin-left: auto;
|
|
flex: 1 1 0;
|
|
max-width: 80px;
|
|
padding: 10px 8px;
|
|
background: #334d6e;
|
|
border-color: rgba(100, 150, 200, 0.4);
|
|
color: #c0d4e8;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.accessory-btn-dismiss svg {
|
|
width: 20px;
|
|
height: 20px;
|
|
}
|
|
|
|
.accessory-btn-dismiss:active {
|
|
background: #3d5f85;
|
|
}
|
|
|
|
/* ============================================================================
|
|
iOS Safari Specific Fixes
|
|
============================================================================ */
|
|
.ios-device.safari-browser {
|
|
/* Prevent pull-to-refresh */
|
|
overscroll-behavior: none;
|
|
}
|
|
|
|
/* JS touch handler now drives terminal scrollback — no native scroll needed.
|
|
-webkit-overflow-scrolling and overflow-y:scroll on xterm-viewport removed. */
|
|
|
|
/* ============================================================================
|
|
Hover State Fallbacks for Touch
|
|
============================================================================ */
|
|
@media (hover: none) and (pointer: coarse) {
|
|
/* Remove hover-dependent UI patterns */
|
|
.session-tab .tab-close,
|
|
.session-tab .tab-gear {
|
|
opacity: 1;
|
|
width: auto;
|
|
padding: 0.15rem 0.25rem;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
/* Simplify button hover states */
|
|
.btn-toolbar:hover {
|
|
transform: none;
|
|
}
|
|
|
|
.btn-icon-header:hover {
|
|
transform: none;
|
|
}
|
|
|
|
/* Show dropdown on tap instead of hover */
|
|
.subagent-dropdown-trigger:active + .subagent-dropdown-menu,
|
|
.subagent-dropdown-trigger:focus + .subagent-dropdown-menu {
|
|
display: block;
|
|
}
|
|
}
|