/* ============================================================ WebGIS — Main Stylesheet Aesthetic: Industrial-cartographic, dark sidebar + bright map ============================================================ */ @import url('https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=DM+Sans:wght@300;400;500;600&display=swap'); /* ── CSS Variables ─────────────────────────────────────────── */ :root { --bg: #0f1117; --sidebar: #161922; --surface: #1e2130; --surface2: #252a3a; --border: #2d3348; --accent: #4ade80; --accent2: #38bdf8; --warn: #fb923c; --danger: #f87171; --text: #e2e8f0; --text-muted: #64748b; --text-dim: #94a3b8; /* Road/feature colors */ --national: #ef4444; --provincial: #f97316; --district: #3b82f6; --spbu24: #22c55e; --spbuNot: #eab308; --mosque: #a78bfa; --poor: #f43f5e; /* Ownership colors */ --shm: #10b981; --hgb: #6366f1; --hgu: #f59e0b; --hp: #ec4899; --sidebar-w: 340px; --header-h: 52px; --radius: 8px; --font-mono: 'Space Mono', monospace; --font-body: 'DM Sans', sans-serif; --transition: 0.18s ease; } /* ── Reset ──────────────────────────────────────────────────── */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } body { font-family: var(--font-body); background: var(--bg); color: var(--text); display: flex; flex-direction: column; } /* ── Header ─────────────────────────────────────────────────── */ #header { height: var(--header-h); background: var(--sidebar); border-bottom: 1px solid var(--border); display: flex; align-items: center; padding: 0 16px; gap: 12px; flex-shrink: 0; z-index: 1000; } #header .logo { font-family: var(--font-mono); font-size: 14px; font-weight: 700; color: var(--accent); letter-spacing: 0.05em; white-space: nowrap; } #header .logo span { color: var(--text-muted); font-weight: 400; } #header .tagline { font-size: 11px; color: var(--text-muted); border-left: 1px solid var(--border); padding-left: 12px; } #header .spacer { flex: 1; } #header .status-badge { font-size: 11px; font-family: var(--font-mono); background: #0f2d1e; color: var(--accent); border: 1px solid #16532d; border-radius: 4px; padding: 2px 8px; } /* ── Layout ─────────────────────────────────────────────────── */ #app { display: flex; flex: 1; overflow: hidden; } /* ── Sidebar ─────────────────────────────────────────────────── */ #sidebar { width: var(--sidebar-w); background: var(--sidebar); border-right: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; flex-shrink: 0; } #sidebar-tabs { display: flex; border-bottom: 1px solid var(--border); flex-shrink: 0; } .tab-btn { flex: 1; padding: 10px 6px; background: transparent; border: none; color: var(--text-muted); font-family: var(--font-mono); font-size: 10px; cursor: pointer; letter-spacing: 0.04em; transition: var(--transition); border-bottom: 2px solid transparent; display: flex; flex-direction: column; align-items: center; gap: 4px; } .tab-btn svg { width: 16px; height: 16px; } .tab-btn:hover { color: var(--text); background: var(--surface); } .tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); background: rgba(74,222,128,0.05); } #sidebar-content { flex: 1; overflow-y: auto; padding: 12px; scrollbar-width: thin; scrollbar-color: var(--border) transparent; } #sidebar-content::-webkit-scrollbar { width: 4px; } #sidebar-content::-webkit-scrollbar-track { background: transparent; } #sidebar-content::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; } /* ── Panel (tab content) ─────────────────────────────────────── */ .panel { display: none; } .panel.active { display: block; } /* ── Section Headings ────────────────────────────────────────── */ .section-title { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.08em; color: var(--text-muted); text-transform: uppercase; margin: 12px 0 8px; padding-bottom: 4px; border-bottom: 1px solid var(--border); } /* ── Forms ───────────────────────────────────────────────────── */ .form-group { margin-bottom: 10px; } .form-group label { display: block; font-size: 11px; font-weight: 500; color: var(--text-dim); margin-bottom: 4px; letter-spacing: 0.03em; } .form-group input, .form-group select, .form-group textarea { width: 100%; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); font-family: var(--font-body); font-size: 13px; padding: 7px 10px; outline: none; transition: border-color var(--transition); } .form-group input:focus, .form-group select:focus, .form-group textarea:focus { border-color: var(--accent2); } .form-group input[readonly] { color: var(--text-muted); cursor: not-allowed; background: var(--surface); } .form-group textarea { resize: vertical; min-height: 60px; } .form-group select option { background: var(--surface2); } .coord-row { display: flex; gap: 8px; } .coord-row .form-group { flex: 1; } /* ── Buttons ─────────────────────────────────────────────────── */ .btn { display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: var(--radius); border: 1px solid transparent; font-family: var(--font-body); font-size: 13px; font-weight: 500; cursor: pointer; transition: var(--transition); white-space: nowrap; } .btn-primary { background: var(--accent); color: #0a1a0f; border-color: var(--accent); } .btn-primary:hover { background: #22c55e; } .btn-secondary { background: var(--surface2); color: var(--text); border-color: var(--border); } .btn-secondary:hover { background: var(--surface); border-color: var(--text-muted); } .btn-danger { background: transparent; color: var(--danger); border-color: #7f1d1d; } .btn-danger:hover { background: rgba(248,113,113,0.1); } .btn-warn { background: transparent; color: var(--warn); border-color: #7c2d12; } .btn-warn:hover { background: rgba(251,146,60,0.1); } .btn-sm { padding: 4px 10px; font-size: 12px; } .btn-full { width: 100%; justify-content: center; } .btn-row { display: flex; gap: 8px; margin-top: 10px; } /* ── Info box ────────────────────────────────────────────────── */ .info-box { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px; font-size: 12px; color: var(--text-dim); margin-bottom: 10px; } .info-box.accent { border-color: var(--accent2); color: var(--accent2); background: rgba(56,189,248,0.05); } .info-box.success { border-color: var(--accent); color: var(--accent); background: rgba(74,222,128,0.05); } .info-box.warn { border-color: var(--warn); color: var(--warn); background: rgba(251,146,60,0.05); } /* ── Feature list ────────────────────────────────────────────── */ .feature-list { display: flex; flex-direction: column; gap: 6px; } .feature-item { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 10px; display: flex; align-items: center; gap: 8px; cursor: pointer; transition: var(--transition); position: relative; } .feature-item:hover { border-color: var(--accent2); background: var(--surface2); } .feature-item.selected { border-color: var(--accent); background: rgba(74,222,128,0.05); } .feature-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; } .feature-dot.road { border-radius: 2px; height: 4px; width: 20px; } .feature-dot.poly { border-radius: 2px; width: 14px; height: 14px; opacity: 0.7; } .feature-info { flex: 1; min-width: 0; } .feature-name { font-size: 13px; font-weight: 500; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .feature-meta { font-size: 11px; color: var(--text-muted); margin-top: 1px; } .feature-actions { display: flex; gap: 4px; opacity: 0; transition: var(--transition); } .feature-item:hover .feature-actions { opacity: 1; } /* ── Layer control ───────────────────────────────────────────── */ .layer-item { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: var(--radius); cursor: pointer; transition: var(--transition); margin-bottom: 4px; } .layer-item:hover { background: var(--surface2); } .layer-cb { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; } .layer-swatch { width: 24px; height: 10px; border-radius: 2px; flex-shrink: 0; } .layer-swatch.circle { width: 14px; height: 14px; border-radius: 50%; } .layer-label { font-size: 13px; color: var(--text-dim); flex: 1; } .layer-count { font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); background: var(--surface2); padding: 1px 6px; border-radius: 10px; } /* ── Map area ────────────────────────────────────────────────── */ #map-container { flex: 1; position: relative; overflow: hidden; } #map { width: 100%; height: 100%; } /* ── Map toolbar ─────────────────────────────────────────────── */ #map-toolbar { position: absolute; top: 12px; left: 12px; z-index: 500; display: flex; flex-direction: column; gap: 6px; } .map-tool-btn { width: 36px; height: 36px; background: var(--sidebar); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text-dim); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); font-size: 16px; } .map-tool-btn:hover { border-color: var(--accent2); color: var(--accent2); } .map-tool-btn.active { border-color: var(--accent); color: var(--accent); background: rgba(74,222,128,0.1); } /* ── Toast ───────────────────────────────────────────────────── */ #toast-container { position: fixed; bottom: 20px; right: 20px; z-index: 9999; display: flex; flex-direction: column; gap: 8px; } .toast { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 14px; font-size: 13px; color: var(--text); min-width: 220px; box-shadow: 0 4px 20px rgba(0,0,0,0.4); animation: slideIn 0.2s ease; } .toast.success { border-color: var(--accent); } .toast.error { border-color: var(--danger); } .toast.warn { border-color: var(--warn); } @keyframes slideIn { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } } /* ── Modal ───────────────────────────────────────────────────── */ #modal-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.7); z-index: 8000; align-items: center; justify-content: center; } #modal-overlay.open { display: flex; } #modal { background: var(--sidebar); border: 1px solid var(--border); border-radius: 12px; width: min(480px, 95vw); max-height: 90vh; overflow-y: auto; padding: 24px; } #modal h3 { font-family: var(--font-mono); font-size: 14px; color: var(--accent); margin-bottom: 16px; } /* ── Leaflet overrides ───────────────────────────────────────── */ .leaflet-popup-content-wrapper { background: var(--sidebar) !important; color: var(--text) !important; border: 1px solid var(--border) !important; border-radius: var(--radius) !important; box-shadow: 0 4px 20px rgba(0,0,0,0.5) !important; } .leaflet-popup-tip { background: var(--sidebar) !important; } .leaflet-popup-content { font-family: var(--font-body); font-size: 13px; } .popup-title { font-weight: 600; margin-bottom: 6px; color: var(--accent2); } .popup-row { display: flex; gap: 6px; margin-bottom: 3px; } .popup-key { color: var(--text-muted); font-size: 11px; width: 90px; flex-shrink: 0; } .popup-val { color: var(--text); font-size: 12px; } .popup-actions { margin-top: 8px; display: flex; gap: 6px; } /* ── Draw toolbar overrides ──────────────────────────────────── */ .leaflet-draw-toolbar a { background-color: var(--sidebar) !important; color: var(--text) !important; border-color: var(--border) !important; } .leaflet-draw-toolbar a:hover { background-color: var(--surface) !important; } /* ── Coords display ──────────────────────────────────────────── */ #coords-display { position: absolute; bottom: 10px; left: 10px; z-index: 500; background: rgba(15,17,23,0.85); border: 1px solid var(--border); border-radius: var(--radius); padding: 4px 10px; font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); pointer-events: none; } /* ── Stats bar ───────────────────────────────────────────────── */ #stats-bar { background: var(--surface); border-top: 1px solid var(--border); display: flex; align-items: center; padding: 4px 16px; gap: 20px; font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); flex-shrink: 0; } .stat-item { display: flex; gap: 6px; } .stat-label { color: var(--text-muted); } .stat-val { color: var(--text-dim); } /* ── Scrollbar (global) ──────────────────────────────────────── */ * { scrollbar-width: thin; scrollbar-color: var(--border) transparent; } *::-webkit-scrollbar { width: 4px; } *::-webkit-scrollbar-track { background: transparent; } *::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }