/** * Layout Styles * Navigation, grid system, page structure, and responsive design */ /* ==================== BASE STYLES ==================== */ * { box-sizing: border-box; margin: 0; padding: 0; } html { font-size: 16px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } body { font-family: var(--font-family-base); font-size: var(--text-base); line-height: var(--leading-normal); color: var(--color-text-primary); background-color: var(--color-bg-primary); min-height: 100vh; } /* ==================== APP SHELL ==================== */ .app { display: flex; min-height: 100vh; } /* ==================== SIDEBAR ==================== */ .sidebar { width: var(--sidebar-width); background-color: var(--color-surface); border-right: 1px solid var(--color-border); display: flex; flex-direction: column; position: fixed; top: 0; left: 0; bottom: 0; z-index: var(--z-sticky); transition: width var(--transition-normal); } .sidebar-header { display: flex; align-items: center; height: var(--header-height); padding: 0 var(--space-4); border-bottom: 1px solid var(--color-border); } .sidebar-logo { display: flex; align-items: center; gap: var(--space-3); text-decoration: none; color: var(--color-text-primary); } .sidebar-logo-icon { width: 32px; height: 32px; background-color: var(--color-primary); border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; font-weight: var(--font-bold); color: white; flex-shrink: 0; } .sidebar-logo-text { font-size: var(--text-lg); font-weight: var(--font-semibold); white-space: nowrap; } .sidebar-nav { flex: 1; padding: var(--space-4); overflow-y: auto; } .sidebar-nav-list { list-style: none; } .sidebar-nav-item { margin-bottom: var(--space-1); } .sidebar-nav-link { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); color: var(--color-text-secondary); text-decoration: none; border-radius: var(--radius-md); transition: all var(--transition-fast); white-space: nowrap; } .sidebar-nav-link:hover { background-color: var(--color-surface-hover); color: var(--color-text-primary); } .sidebar-nav-link.active { background-color: var(--color-primary-subtle); color: var(--color-primary); } .sidebar-nav-link .icon { width: 20px; height: 20px; flex-shrink: 0; opacity: 0.7; } .sidebar-nav-link.active .icon { opacity: 1; } .sidebar-footer { padding: var(--space-4); border-top: 1px solid var(--color-border); } .sidebar-version { font-size: var(--text-xs); color: var(--color-text-tertiary); text-align: center; } /* ==================== MAIN CONTENT ==================== */ .main { flex: 1; margin-left: var(--sidebar-width); display: flex; flex-direction: column; min-height: 100vh; transition: margin-left var(--transition-normal); } /* ==================== HEADER ==================== */ .header { height: var(--header-height); background-color: var(--color-surface); border-bottom: 1px solid var(--color-border); display: flex; align-items: center; justify-content: space-between; padding: 0 var(--space-6); position: sticky; top: 0; z-index: var(--z-sticky); } .header-title { font-size: var(--text-xl); font-weight: var(--font-semibold); color: var(--color-text-primary); } .header-actions { display: flex; align-items: center; gap: var(--space-3); } /* ==================== PAGE CONTENT ==================== */ .page { flex: 1; padding: var(--space-6); max-width: var(--container-max-width); width: 100%; margin: 0 auto; } .page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-6); gap: var(--space-4); flex-wrap: wrap; } .page-title { font-size: var(--text-2xl); font-weight: var(--font-bold); color: var(--color-text-primary); } .page-description { font-size: var(--text-sm); color: var(--color-text-secondary); margin-top: var(--space-1); } .page-actions { display: flex; align-items: center; gap: var(--space-3); } /* ==================== CONTENT SECTIONS ==================== */ .content-section { margin-bottom: var(--space-8); } .section-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-4); } .section-title { font-size: var(--text-lg); font-weight: var(--font-semibold); color: var(--color-text-primary); } /* ==================== TOOLBAR ==================== */ .toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-4); flex-wrap: wrap; } .toolbar-left, .toolbar-right { display: flex; align-items: center; gap: var(--space-3); } /* ==================== FILTERS ==================== */ .filters { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); flex-wrap: wrap; } .filter-item { display: flex; align-items: center; gap: var(--space-2); } .filter-label { font-size: var(--text-sm); color: var(--color-text-secondary); } /* ==================== GRID SYSTEM ==================== */ .grid { display: grid; gap: var(--space-6); } .grid-2 { grid-template-columns: repeat(2, 1fr); } .grid-3 { grid-template-columns: repeat(3, 1fr); } .grid-4 { grid-template-columns: repeat(4, 1fr); } /* ==================== SPLIT PANE ==================== */ .split-pane { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-6); height: calc(100vh - var(--header-height) - var(--space-12)); } .split-pane-left, .split-pane-right { overflow: auto; } /* ==================== EMPTY STATE ==================== */ .empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--space-16); text-align: center; } .empty-state-icon { width: 64px; height: 64px; margin-bottom: var(--space-4); color: var(--color-text-tertiary); } .empty-state-title { font-size: var(--text-lg); font-weight: var(--font-semibold); color: var(--color-text-primary); margin-bottom: var(--space-2); } .empty-state-description { font-size: var(--text-sm); color: var(--color-text-secondary); max-width: 400px; margin-bottom: var(--space-6); } /* ==================== LOADING STATE ==================== */ .loading-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--space-16); } .spinner { width: 40px; height: 40px; border: 3px solid var(--color-border); border-top-color: var(--color-primary); border-radius: var(--radius-full); animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .loading-text { margin-top: var(--space-4); font-size: var(--text-sm); color: var(--color-text-secondary); } /* ==================== API KEY PROMPT ==================== */ .api-key-prompt { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; padding: var(--space-6); background-color: var(--color-bg-primary); } .api-key-card { width: 100%; max-width: 400px; background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-xl); padding: var(--space-8); text-align: center; } .api-key-logo { width: 64px; height: 64px; background-color: var(--color-primary); border-radius: var(--radius-lg); display: flex; align-items: center; justify-content: center; font-size: var(--text-2xl); font-weight: var(--font-bold); color: white; margin: 0 auto var(--space-6); } .api-key-title { font-size: var(--text-2xl); font-weight: var(--font-bold); color: var(--color-text-primary); margin-bottom: var(--space-2); } .api-key-description { font-size: var(--text-sm); color: var(--color-text-secondary); margin-bottom: var(--space-6); } /* ==================== MODAL ==================== */ .modal-backdrop { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.7); display: flex; align-items: center; justify-content: center; z-index: var(--z-modal-backdrop); padding: var(--space-4); } .modal { background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-xl); width: 100%; max-width: 600px; max-height: 90vh; display: flex; flex-direction: column; box-shadow: var(--shadow-xl); } .modal-lg { max-width: 900px; } .modal-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-6); border-bottom: 1px solid var(--color-border); } .modal-title { font-size: var(--text-lg); font-weight: var(--font-semibold); color: var(--color-text-primary); } .modal-close { background: none; border: none; color: var(--color-text-tertiary); cursor: pointer; padding: var(--space-1); display: flex; align-items: center; justify-content: center; border-radius: var(--radius-md); transition: all var(--transition-fast); } .modal-close:hover { background-color: var(--color-surface-hover); color: var(--color-text-primary); } .modal-body { padding: var(--space-6); overflow-y: auto; } .modal-footer { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-3); padding: var(--space-4) var(--space-6); border-top: 1px solid var(--color-border); background-color: rgba(0, 0, 0, 0.2); } /* ==================== TOAST ==================== */ .toast-container { position: fixed; bottom: var(--space-6); right: var(--space-6); z-index: var(--z-toast); display: flex; flex-direction: column; gap: var(--space-3); } .toast { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-4); background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); min-width: 300px; max-width: 400px; animation: slideIn var(--transition-normal); } @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } .toast.success { border-left: 4px solid var(--color-success); } .toast.error { border-left: 4px solid var(--color-error); } .toast.warning { border-left: 4px solid var(--color-warning); } .toast.info { border-left: 4px solid var(--color-info); } .toast-icon { flex-shrink: 0; width: 20px; height: 20px; } .toast.success .toast-icon { color: var(--color-success); } .toast.error .toast-icon { color: var(--color-error); } .toast.warning .toast-icon { color: var(--color-warning); } .toast.info .toast-icon { color: var(--color-info); } .toast-content { flex: 1; } .toast-title { font-weight: var(--font-medium); color: var(--color-text-primary); margin-bottom: var(--space-1); } .toast-message { font-size: var(--text-sm); color: var(--color-text-secondary); } .toast-close { background: none; border: none; color: var(--color-text-tertiary); cursor: pointer; padding: 0; display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .toast-close:hover { color: var(--color-text-primary); } /* ==================== RESPONSIVE ==================== */ /* Mobile-first Breakpoints */ @media (max-width: 1024px) { .grid-4 { grid-template-columns: repeat(2, 1fr); } .split-pane { grid-template-columns: 1fr; } } @media (max-width: 768px) { :root { --sidebar-width: 0; } .sidebar { transform: translateX(-100%); } .sidebar.open { transform: translateX(0); width: var(--sidebar-width-mobile, 280px); } .main { margin-left: 0; } .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } .page-header { flex-direction: column; align-items: flex-start; } .toolbar { flex-direction: column; align-items: stretch; } .toolbar-left, .toolbar-right { justify-content: space-between; } .stats-grid { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 480px) { .stats-grid { grid-template-columns: 1fr; } .modal { max-width: 100%; margin: var(--space-4); } .toast-container { left: var(--space-4); right: var(--space-4); } .toast { max-width: 100%; } } /* ==================== HAMBURG MENU PATTERN ==================== */ .hamburger-menu { display: none; width: 44px; height: 44px; padding: 0; background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); cursor: pointer; transition: all var(--transition-fast); flex-direction: column; align-items: center; justify-content: center; gap: 4px; } .hamburger-menu.active { background-color: var(--color-primary-subtle); border-color: var(--color-primary); } @media (max-width: 768px) { .hamburger-menu { display: flex; } .header { padding: 0 var(--space-4); } .header-title { font-size: var(--text-lg); } } .hamburger-icon { width: 24px; height: 2px; background-color: var(--color-text-primary); border-radius: var(--radius-sm); transition: all var(--transition-fast); } .hamburger-icon::before, .hamburger-icon::after { content: ''; position: absolute; width: 24px; height: 2px; background-color: var(--color-text-primary); border-radius: var(--radius-sm); transition: all var(--transition-fast); } .hamburger-icon::before { transform: translateY(-8px); } .hamburger-icon::after { transform: translateY(8px); } .hamburger-menu.active .hamburger-icon { background-color: var(--color-primary); } .hamburger-menu.active .hamburger-icon::before { transform: translateY(0) rotate(45deg); background-color: var(--color-primary); } .hamburger-menu.active .hamburger-icon::after { transform: translateY(0) rotate(-45deg); background-color: var(--color-primary); } /* ==================== TOUCH-FRIENDLY BUTTON SIZES ==================== */ .btn-touch { min-height: 44px; min-width: 44px; padding: var(--space-3) var(--space-4); font-size: var(--text-base); } .btn-touch-sm { min-height: 44px; min-width: 44px; padding: var(--space-2) var(--space-3); font-size: var(--text-sm); } @media (max-width: 768px) { .btn { min-height: 44px; } .form-input, .form-select, .form-textarea { min-height: 44px; font-size: var(--text-base); } } /* ==================== SAFE AREA insets FOR iOS ==================== */ @supports (padding: max(0px)) { body { padding-left: max(0px, var(--ios-safe-area-left)); padding-right: max(0px, var(--ios-safe-area-right)); } .app { padding-top: max(0px, var(--ios-safe-area-top)); padding-bottom: max(0px, var(--ios-safe-area-bottom)); } .header { padding-left: max(var(--space-6), var(--ios-safe-area-left)); padding-right: max(var(--space-6), var(--ios-safe-area-right)); } .toast-container { bottom: max(var(--space-6), var(--ios-safe-area-bottom)); right: max(var(--space-6), var(--ios-safe-area-right)); } } /* ==================== GAME HUD LAYOUTS ==================== */ .game-hud { position: fixed; top: 0; left: 0; right: 0; display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--space-4); padding: var(--space-4); z-index: var(--z-overlay); pointer-events: none; } .game-hud-left, .game-hud-right { display: flex; align-items: center; gap: var(--space-3); pointer-events: auto; } .game-hud-center { display: flex; align-items: center; justify-content: center; gap: var(--space-4); pointer-events: auto; } @media (max-width: 768px) { .game-hud { grid-template-columns: 1fr 1fr; padding: var(--space-2); } .game-hud-center { grid-column: 1 / -1; order: -1; padding-bottom: var(--space-2); } } /* Mobile Game HUD */ .game-hud-mobile { position: fixed; top: 0; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column; z-index: var(--z-overlay); } .game-hud-mobile-top { display: flex; align-items: center; justify-content: space-between; padding: var(--space-2); gap: var(--space-3); } .game-hud-mobile-bottom { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-2); margin-top: auto; } /* ==================== VIRTUAL JOYSTICK PATTERN ==================== */ .virtual-joystick { position: relative; width: 120px; height: 120px; background-color: rgba(0, 0, 0, 0.3); border-radius: var(--radius-full); border: 2px solid rgba(255, 255, 255, 0.2); display: flex; align-items: center; justify-content: center; touch-action: none; } .virtual-joystick-base { position: absolute; width: 80px; height: 80px; background-color: rgba(255, 255, 255, 0.1); border-radius: var(--radius-full); } .virtual-joystick-thumb { position: absolute; width: 40px; height: 40px; background-color: var(--color-primary); border-radius: var(--radius-full); box-shadow: 0 0 12px rgba(0, 0, 0, 0.5); cursor: pointer; transition: transform var(--transition-fast); } .virtual-joystick.active .virtual-joystick-thumb { background-color: var(--color-primary-dark); box-shadow: 0 0 16px rgba(0, 0, 0, 0.7); } @media (max-width: 768px) { .virtual-joystick { width: 100px; height: 100px; } .virtual-joystick-base { width: 60px; height: 60px; } .virtual-joystick-thumb { width: 32px; height: 32px; } } /* ==================== ABILITY BUTTON layouts ==================== */ .ability-bar { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2); background-color: rgba(0, 0, 0, 0.5); border-radius: var(--radius-lg); } .ability-button { position: relative; width: 48px; height: 48px; background-color: var(--color-surface); border: 2px solid var(--color-border); border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all var(--transition-fast); overflow: hidden; } .ability-button:hover { border-color: var(--color-primary); box-shadow: 0 0 8px var(--color-primary-subtle); transform: scale(1.05); } .ability-button:active { transform: scale(0.95); } .ability-button.active { border-color: var(--color-primary); box-shadow: 0 0 12px var(--color-primary-subtle); } .ability-button.on-cooldown { border-color: var(--color-border); opacity: 0.7; } .ability-button.on-cooldown::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.7); animation: cooldownFade 0.5s ease-out forwards; } .ability-icon { width: 24px; height: 24px; flex-shrink: 0; } .ability-key { position: absolute; top: -4px; right: -4px; width: 20px; height: 20px; background-color: var(--color-bg-primary); border: 1px solid var(--color-border); border-radius: var(--radius-sm); font-size: var(--text-xs); font-weight: var(--font-bold); color: var(--color-text-secondary); display: flex; align-items: center; justify-content: center; } @media (max-width: 768px) { .ability-button { width: 44px; height: 44px; min-width: 44px; min-height: 44px; } .ability-bar { gap: var(--space-1); } .ability-key { width: 16px; height: 16px; font-size: 8px; } } /* ==================== INVENTORY GRID RESPONSIVE PATTERN ==================== */ .inventory-grid { display: grid; grid-template-columns: repeat(6, 48px); gap: var(--space-2); padding: var(--space-4); background-color: rgba(0, 0, 0, 0.3); border-radius: var(--radius-lg); } .inventory-slot { width: 48px; height: 48px; background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all var(--transition-fast); position: relative; } .inventory-slot:hover { border-color: var(--color-primary); box-shadow: 0 0 8px var(--color-primary-subtle); transform: scale(1.05); } .inventory-slot.selected { border-color: var(--color-primary); box-shadow: 0 0 12px var(--color-primary-subtle); } .inventory-slot-icon { width: 32px; height: 32px; } .inventory-slot-count { position: absolute; bottom: 2px; right: 2px; font-size: var(--text-xs); font-weight: var(--font-bold); color: white; text-shadow: 0 0 4px rgba(0, 0, 0, 0.8); } @media (max-width: 1024px) { .inventory-grid { grid-template-columns: repeat(4, 48px); } } @media (max-width: 768px) { .inventory-grid { grid-template-columns: repeat(4, 44px); gap: var(--space-1); } .inventory-slot { width: 44px; height: 44px; min-width: 44px; min-height: 44px; } .inventory-slot-icon { width: 28px; height: 28px; } } @media (max-width: 480px) { .inventory-grid { grid-template-columns: repeat(3, 40px); } .inventory-slot { width: 40px; height: 40px; } .inventory-slot-icon { width: 24px; height: 24px; } } /* ==================== GAME MOBILE CONTROLS ==================== */ .game-controls-mobile { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-2); } .game-controls-row { display: flex; align-items: center; justify-content: center; gap: var(--space-2); } .game-controls-left, .game-controls-right { display: flex; align-items: center; gap: var(--space-2); } @media (max-width: 480px) { .game-controls-mobile { position: fixed; bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, 0.8); padding: var(--space-2); z-index: var(--z-overlay); } .game-controls-row { justify-content: space-between; } .game-controls-left { order: 1; } .game-controls-right { order: 2; } } /* ==================== UTILITIES ==================== */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .flex { display: flex; } .flex-col { flex-direction: column; } .items-center { align-items: center; } .justify-between { justify-content: space-between; } .gap-2 { gap: var(--space-2); } .gap-4 { gap: var(--space-4); } .hidden { display: none !important; }