claw-code/.guardrails/mcp-server/web/css/layout.css

1229 lines
22 KiB
CSS

/**
* 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;
}