* { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } html, body { width: 100%; height: 100%; overflow: hidden; } #map { width: 100%; height: 100%; z-index: 1; } /* Modal Styling */ .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 4000; justify-content: center; align-items: center; } .modal-content { background: white; padding: 25px; border-radius: 8px; width: 100%; max-width: 450px; position: relative; box-shadow: 0 5px 25px rgba(0,0,0,0.3); } .close-btn { position: absolute; top: 15px; right: 25px; font-size: 30px; cursor: pointer; color: #fff; /* Chuyển sang màu trắng để nổi bật trên nền tối */ z-index: 5000; /* Đảm bảo nằm trên cùng của tất cả các pane */ transition: all 0.2s ease; text-shadow: 0 0 10px rgba(0,0,0,0.5); } .close-btn:hover { color: #ff4d4d; /* Chuyển sang màu đỏ khi di chuột để dễ nhận biết */ transform: scale(1.1); } .form-group { margin-bottom: 15px; } .form-group label { display: block; margin-bottom: 5px; font-weight: 600; color: #333; } .form-group input, .form-group select { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; } .submit-btn { width: 100%; padding: 12px; background-color: #28a745; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; font-size: 16px; } .submit-btn:hover { background-color: #218838; } /* 3D Viewer Overlays (Full Screen) */ #viewer-container { display: none; /* Khởi tạo ẩn để không chặn chuột */ position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 3000; background: black; } #panorama-viewer { width: 100%; height: 100%; } #close-viewer-btn { position: absolute; top: 20px; left: 20px; padding: 12px 24px; background: rgba(255, 255, 255, 0.9); border: none; border-radius: 5px; font-weight: bold; cursor: pointer; z-index: 3001; box-shadow: 0 4px 10px rgba(0,0,0,0.3); } #close-viewer-btn:hover { background: white; } /* Modal Overlay */ .modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); align-items: center; justify-content: center; z-index: 4000; } /* Top Bar */ #top-bar { position: fixed; top: 0; left: 0; width: 100%; height: 60px; /* Fixed height */ background: rgba(20, 20, 20, 0.8); /* Màu tối transparent */ color: #fff; box-shadow: 0 2px 15px rgba(0, 0, 0, 0.4); z-index: 1500; /* Above map, below modals */ display: flex; justify-content: space-between; align-items: center; padding: 0 20px; } .app-brand { display: flex; align-items: center; gap: 10px; } .app-brand h1 { font-size: 20px; color: #fff; margin: 0; } #user-controls { position: relative; } #user-avatar { width: 40px; height: 40px; border-radius: 50%; background: #007bff; color: white; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 18px; cursor: pointer; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); } #user-dropdown { display: none; /* Hidden by default */ position: absolute; top: 50px; /* Below the avatar */ right: -20px; /* Canh sát mép màn hình, bù trừ padding của top-bar */ background: rgba(30, 30, 30, 0.98); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); border-radius: 8px; padding: 10px 0; /* Remove horizontal padding to let hover cover full width */ width: auto; /* Tự động điều chỉnh theo nội dung */ z-index: 1600; /* Above top-bar */ border: 1px solid rgba(255, 255, 255, 0.1); min-width: 180px; /* Đảm bảo không quá nhỏ */ } #user-dropdown.show { display: block; } #user-dropdown h3 { margin: 10px 20px; font-size: 16px; color: #fff; /* Giữ màu trắng cho các tiêu đề khác trong dropdown nếu có */ /* Nếu đây là tiêu đề "Welcome", nó sẽ bị ẩn bởi quy tắc bên dưới */ } #user-dropdown input { width: calc(100% - 40px); margin: 0 20px 10px 20px; padding: 8px; border: 1px solid #444; background: #222; color: #fff; border-radius: 4px; } #user-dropdown .btn-group { display: flex; flex-direction: column; /* Sắp xếp theo cột */ gap: 0; } #user-dropdown .btn-group button, #user-dropdown button { width: 100%; padding: 10px 15px; /* Giảm padding để hộp nhỏ gọn hơn */ background-color: transparent; /* Không sử dụng background button */ color: #ccc; text-align: left; /* Căn lề trái giống menu text */ border: none; border-radius: 0; cursor: pointer; font-weight: 500; font-size: 14px; transition: all 0.2s ease; border-bottom: 1px solid rgba(255, 255, 255, 0.05); } #user-dropdown .btn-group button:hover, #user-dropdown button:hover { background-color: rgba(255, 255, 255, 0.1); /* Hiệu ứng hover nhẹ */ color: #fff; } #user-dropdown button:last-child { border-bottom: none; } /* Dashboard Overlay */ #dashboard-overlay { /* Inherits .modal-overlay styles */ z-index: 4500; /* Above all other modals */ } .dashboard-content { /* Các thuộc tính đã được sửa ở lần trước */ max-width: 800px !important; /* Mở rộng chiều rộng tối đa lên 1800px */ width: 95% !important; height: 85vh; overflow: hidden; /* Cắt bỏ phần tràn nếu có */ position: relative; /* Làm mốc cho nút close-btn absolute */ display: flex !important; flex-direction: row !important; /* Ép buộc luôn nằm ngang */ flex-wrap: nowrap; /* Ngăn chặn các thành phần nhảy xuống hàng dọc */ gap: 0; /* Loại bỏ khoảng hở giữa 2 pane để tạo khối thống nhất */ background: transparent !important; /* Loại bỏ nền chung của panel */ box-shadow: none !important; /* Loại bỏ bóng chung */ padding: 0; } .dashboard-tabs { /* Các thuộc tính đã được sửa ở lần trước */ display: flex; flex-direction: column; /* Danh mục menu dọc */ background: rgba(30, 30, 30, 0.9); backdrop-filter: blur(10px); width: 220px; flex-shrink: 0; /* Không cho phép menu bị thu nhỏ */ border-radius: 15px 0 0 15px; /* Chỉ bo góc bên trái */ padding: 20px 10px; gap: 2px; /* Khoảng cách hẹp giữa các dòng menu */ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); border: 1px solid rgba(255, 255, 255, 0.1); height: 100%; /* Đảm bảo sidebar chiếm toàn bộ chiều cao của dashboard-content */ overflow-y: auto; /* Cho phép cuộn nếu nội dung sidebar quá dài */ } .dashboard-tabs .tab-btn { /* Các thuộc tính đã được sửa ở lần trước */ padding: 12px 15px; border: none; border-radius: 10px; background: none; cursor: pointer; font-weight: 400; color: #aaa; text-align: left; transition: all 0.3s ease; flex: none; /* Ngăn button thay đổi kích thước theo chiều cao của dashboard */ } .dashboard-tabs .tab-btn.active { /* Các thuộc tính đã được sửa ở lần trước */ color: #fff; background: rgba(255, 255, 255, 0.1); box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.05); } .dashboard-tabs .tab-btn:hover:not(.active) { background: rgba(255, 255, 255, 0.05); color: #fff; } #dashboard-tab-content { flex: 1; /* Quan trọng: Giúp phần nội dung chiếm toàn bộ không gian còn lại bên phải */ min-width: 0; /* Ngăn chặn nội dung bên trong đẩy bung layout */ height: 100%; display: block; overflow-y: auto; } .dashboard-tab-pane { display: none !important; /* Ẩn tuyệt đối các tab không hoạt động */ width: 100%; height: 100%; /* Đảm bảo mỗi tab pane chiếm toàn bộ chiều cao của #dashboard-tab-content */ background: rgba(30, 30, 30, 0.9); /* Đồng nhất màu tối với sidebar */ color: #fff; /* Chuyển màu chữ sang trắng cho dark mode */ backdrop-filter: blur(5px); border-radius: 0 15px 15px 0; /* Chỉ bo góc bên phải */ padding: 30px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); overflow-y: auto; border: 1px solid rgba(255, 255, 255, 0.1); border-left: 1px solid rgba(255, 255, 255, 0.05); /* Đường ngăn cách mờ giữa 2 pane */ } .dashboard-tab-pane.active { display: block !important; /* Chỉ tab active mới được phép hiển thị */ } /* Điều chỉnh các phần tử bên trong tab pane cho phù hợp với nền tối */ .dashboard-tab-pane h3 { color: #fff; margin-bottom: 20px; } .dashboard-tab-pane label { color: #ccc; } /* Dashboard List Styles */ .dashboard-list { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; } .dashboard-item { background: rgba(255, 255, 255, 0.05); padding: 15px; border-radius: 10px; display: flex; justify-content: space-between; align-items: center; border: 1px solid rgba(255, 255, 255, 0.1); transition: background 0.2s; } .dashboard-item:hover { background: rgba(255, 255, 255, 0.08); } .item-info { flex: 1; /* Chiếm toàn bộ không gian bên trái */ display: flex; flex-direction: column; gap: 4px; padding-right: 20px; /* Khoảng cách an toàn với các nút bấm */ } .item-info strong { color: #fff; font-size: 16px; } .item-info span { color: #888; font-size: 13px; } .item-actions { display: flex; gap: 10px; flex-shrink: 0; } .item-actions button { padding: 8px 16px; border: none; border-radius: 6px; cursor: pointer; font-weight: 600; font-size: 13px; transition: opacity 0.2s; } .edit-btn { background: #007bff; color: white; } .delete-btn { background: #dc3545; color: white; } .item-actions button:hover { opacity: 0.9; } /* Tùy chỉnh các dòng trong Sidebar */ .sidebar-user-header { display: flex; align-items: center; gap: 12px; padding: 0 10px 10px 10px; } .avatar-circle { width: 45px; height: 45px; border-radius: 50%; background: #007bff; color: white; display: flex; justify-content: center; align-items: center; font-weight: 600; font-size: 20px; } .user-name-text { font-size: 16px; font-weight: 600; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .user-status-text { font-size: 13px; color: #888; padding: 0 10px 15px 10px; } .sidebar-divider { border: none; border-top: 1px solid rgba(255, 255, 255, 0.1); margin: 5px 10px 15px 10px; } .dashboard-tabs .tab-btn.logout-item { margin-top: 10px; color: #ff4d4d; } .dashboard-tabs .tab-btn.logout-item:hover { background: rgba(255, 77, 77, 0.1); color: #ff4d4d; } .admin-only { /* Style for admin-specific elements, or hide by default */ display: none; } .modal-content { background: #fff; padding: 20px; border-radius: 8px; width: 90%; max-width: 500px; box-shadow: 0 4px 15px rgba(0,0,0,0.3); } .modal-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #eee; padding-bottom: 10px; margin-bottom: 15px; } .form-group { margin-bottom: 15px; } .form-group label { display: block; font-weight: bold; margin-bottom: 5px; } .form-group input, .form-group textarea, .form-group select { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; } /* Tabs */ .tab-container { display: flex; gap: 10px; margin-bottom: 10px; } .tab-btn { flex: 1; padding: 8px; cursor: pointer; border: 1px solid #007bff; background: #fff; color: #007bff; border-radius: 4px; } .tab-btn.active { background: #007bff; color: #fff; } .divider { border-top: 1px dashed #ccc; padding-top: 15px; } .modal-footer { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; } .save-btn { background: #28a745; color: #fff; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; } .cancel-btn { background: #6c757d; color: #fff; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; } /* Action Modal Specifics */ .action-modal-content { text-align: center; max-width: 400px; } .action-buttons { display: flex; flex-direction: column; gap: 12px; margin-top: 20px; } .edit-btn-large, .delete-btn-large { padding: 15px; border: none; border-radius: 6px; font-size: 16px; font-weight: bold; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 10px; transition: opacity 0.2s; } .edit-btn-large { background: #007bff; color: white; } .delete-btn-large { background: #dc3545; color: white; } .edit-btn-large:hover, .delete-btn-large:hover { opacity: 0.9; } .action-modal-content p { color: #666; margin-top: 5px; } /* Scene Callout Bubble Marker */ .scene-callout { background: white; border: 3px solid #007bff; border-radius: 10px; width: 64px; height: 64px; position: relative; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); transition: transform 0.2s ease-in-out; display: flex; /* Căn giữa nội dung bên trong */ cursor: pointer; } .scene-img-wrapper { width: 100%; height: 100%; overflow: hidden; /* Cắt ảnh nếu tràn ra ngoài border-radius */ border-radius: 7px; /* Bo góc (10px - 3px border) */ padding: 2px; /* Tạo khoảng hở giữa ảnh và viền xanh */ } .scene-callout:hover { transform: scale(1.1); border-color: #0056b3; z-index: 1000; } .scene-callout img { width: 100%; height: 100%; object-fit: cover; border-radius: 5px; /* Bo góc ảnh nhẹ hơn wrapper một chút */ display: block; } .scene-callout::after { content: ''; position: absolute; bottom: -12px; left: 50%; transform: translateX(-50%); border-width: 12px 8px 0; border-style: solid; border-color: #007bff transparent transparent; } /* Custom Tooltip Styling */ .custom-scene-tooltip { background: rgba(0, 0, 0, 0.8) !important; color: white !important; border: none !important; border-radius: 4px !important; padding: 8px 12px !important; font-size: 13px !important; box-shadow: 0 2px 8px rgba(0,0,0,0.4) !important; } .custom-scene-tooltip .scene-hover-info strong { font-size: 15px; color: #ffd700; /* Màu vàng cho tiêu đề */ display: block; margin-bottom: 3px; } .logout-modal-dark { background: rgba(30, 30, 30, 0.95) !important; border: 1px solid rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); box-shadow: 0 10px 40px rgba(0,0,0,0.6) !important; } #logout-confirm-modal, #delete-asset-confirm-modal, #success-modal { z-index: 5500; } #share-member-modal, #share-link-modal { z-index: 6000; } /* --- Pannellum Custom Hotspot (Callout Bubble) --- */ /* Container chính của hotspot do Pannellum quản lý */ .pnlm-custom-hotspot { width: 64px; height: 64px; /* Căn chỉnh để tâm bong bóng nằm đúng vị trí tọa độ pitch/yaw */ margin-left: -32px; margin-top: -32px; z-index: 10; /* Xóa bỏ icon sprite mặc định của Pannellum */ background: none !important; } .pnlm-custom-hotspot * { box-sizing: border-box; } /* Bong bóng callout */ .hotspot-callout-bubble { position: relative; width: 100%; height: 100%; cursor: pointer; transition: transform 0.2s ease-in-out; } .hotspot-callout-bubble:hover { transform: scale(1.15); z-index: 1000; } /* Khung chứa ảnh thumbnail tròn */ .hotspot-thumb-frame { width: 100%; height: 100%; border: 3px solid #ffffff; border-radius: 50%; overflow: hidden; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); background-color: #333; display: flex; align-items: center; justify-content: center; } .hotspot-thumb-frame img { width: 100%; height: 100%; object-fit: cover; } /* Đuôi nhọn của bong bóng trỏ xuống vị trí chính xác */ .hotspot-callout-bubble::after { content: ''; position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%); border-width: 10px 7px 0; border-style: solid; border-color: #ffffff transparent transparent; } /* Tooltip tiêu đề xuất hiện khi hover */ .hotspot-callout-title { position: absolute; top: -45px; /* Hiển thị phía trên bong bóng */ left: 50%; transform: translateX(-50%); background: rgba(0, 0, 0, 0.85); color: #fff; padding: 5px 12px; border-radius: 20px; font-size: 13px; font-weight: 500; white-space: nowrap; opacity: 0; visibility: hidden; transition: all 0.3s ease; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5); pointer-events: none; z-index: 100; } /* Hiệu ứng khi rê chuột qua hotspot */ .hotspot-callout-bubble:hover .hotspot-callout-title { opacity: 1; visibility: visible; top: -55px; /* Nhích lên một chút khi xuất hiện */ } /* --- Media Library Dashboard --- */ .dashboard-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 20px; margin-top: 15px; } .media-card { background: rgba(255, 255, 255, 0.05); border-radius: 12px; overflow: hidden; border: 1px solid rgba(255, 255, 255, 0.1); display: flex; flex-direction: column; } .media-card.trash-item { border-color: rgba(220, 53, 69, 0.4); } .media-thumb { position: relative; width: 100%; height: 120px; background: #000; } .media-thumb img { width: 100%; height: 100%; object-fit: cover; } .badge-trash { position: absolute; top: 8px; right: 8px; background: #dc3545; color: white; font-size: 10px; padding: 2px 6px; border-radius: 4px; font-weight: bold; } .media-info { padding: 12px; flex: 1; } .media-info strong { display: block; font-size: 15px; margin-bottom: 5px; } .media-info .desc { font-size: 12px; color: #aaa; margin-bottom: 8px; } .media-info .parent-link { font-size: 11px; color: #007bff; margin-bottom: 5px; } .media-info .date { font-size: 10px; color: #666; } .media-actions { padding: 10px; display: flex; gap: 8px; border-top: 1px solid rgba(255, 255, 255, 0.05); } .edit-btn-small, .delete-btn-small { flex: 1; padding: 6px; font-size: 11px; border: none; border-radius: 4px; cursor: pointer; font-weight: 600; } .edit-btn-small { background: #28a745; color: white; } .delete-btn-small { background: #dc3545; color: white; } .media-actions button:hover { opacity: 0.8; } /* --- Scene Card Dashboard --- */ .scene-card { position: relative; height: 220px; border-radius: 12px; overflow: hidden; border: 1px solid rgba(255, 255, 255, 0.1); background-size: cover; background-position: center; display: flex; flex-direction: column; justify-content: flex-end; transition: transform 0.2s ease; cursor: default; } .scene-card:hover { transform: translateY(-5px); border-color: rgba(0, 123, 255, 0.5); } .scene-card-overlay { padding: 15px; background: linear-gradient(to top, rgba(0,0,0,0.95) 20%, rgba(0,0,0,0.6) 70%, transparent 100%); color: #fff; } .scene-card-info strong { display: block; font-size: 16px; margin-bottom: 4px; color: #fff; } .scene-card-info .scene-desc { font-size: 12px; color: #ccc; margin-bottom: 8px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } .scene-card-meta { display: flex; flex-wrap: wrap; gap: 10px; font-size: 11px; color: #aaa; margin-bottom: 10px; } /* --- Edit Metadata Modal (Dark Theme) --- */ #edit-scene-metadata-modal .modal-content { background: rgba(30, 30, 30, 0.95); color: #fff; border: 1px solid rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); max-width: 500px; } #edit-scene-metadata-modal .form-group label { color: #ccc; } #edit-scene-metadata-modal input, #edit-scene-metadata-modal textarea, #edit-scene-metadata-modal select { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.2); color: #fff; } #edit-mini-map { height: 200px; width: 100%; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.1); } /* --- Privacy Settings Enhancements --- */ .privacy-settings-btn { background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); color: white; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 18px; transition: all 0.2s; } .privacy-settings-btn:hover { background: rgba(0, 123, 255, 0.4); border-color: #007bff; } /* Search Dropdown */ .search-dropdown { position: absolute; top: 100%; left: 0; width: 100%; background: #2a2a2a; border: 1px solid #444; border-top: none; max-height: 200px; overflow-y: auto; z-index: 100; border-radius: 0 0 4px 4px; box-shadow: 0 4px 12px rgba(0,0,0,0.5); } .search-item { padding: 10px 15px; cursor: pointer; border-bottom: 1px solid #333; font-size: 14px; } .search-item:hover { background: #3a3a3a; color: #00d4ff; } /* Shared Users List */ .shared-users-list { margin-top: 10px; max-height: 150px; overflow-y: auto; background: rgba(0,0,0,0.2); border-radius: 4px; padding: 5px; } .share-list-item { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; background: rgba(255,255,255,0.05); margin-bottom: 4px; border-radius: 3px; font-size: 13px; } .remove-share-btn { color: #ff4d4d; cursor: pointer; font-weight: bold; padding: 0 5px; }