From 057bab5dad9f57323f4bf975ee75effa4315dad3 Mon Sep 17 00:00:00 2001 From: Edouard Vanbelle Date: Tue, 7 Apr 2026 12:21:07 +0200 Subject: [PATCH 1/4] chore: prepare JS + CSS linter and add CI depending frontend of backend changes --- .github/workflows/ci.yml | 60 ++++++++++++++++++++++++++++++++++++---- README.md | 12 ++++++++ biome.json | 42 ++++++++++++++++++++++++++++ jsconfig.json | 18 ++++++++++++ 4 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 biome.json create mode 100644 jsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b7f0e2f..9add9751 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,11 @@ name: CI on: push: - branches: [ "main", "dev" ] + branches: + - main + - dev + - "feat/**" + - "fix/**" pull_request: branches: [ "main", "dev" ] @@ -12,8 +16,46 @@ env: DATABASE_URL: "postgres://postgres:postgres@localhost/oxicloud_test" jobs: - fmt: + + # Detect which parts of the codebase changed + changes: + runs-on: ubuntu-latest + outputs: + frontend: ${{ steps.filter.outputs.frontend }} + backend: ${{ steps.filter.outputs.backend }} + steps: + - uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + frontend: + - 'static/**' + - 'biome.json' + - 'jsconfig.json' + backend: + - 'src/**' + - 'Cargo.toml' + - 'Cargo.lock' + + frontend-linter: + name: Frontend — Biome + needs: changes + if: needs.changes.outputs.frontend == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Biome + uses: biomejs/setup-biome@v2 + + - name: Run Biome check + run: biome ci static/ + + rust-fmt: name: Rustfmt + needs: changes + if: needs.changes.outputs.backend == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -22,8 +64,10 @@ jobs: components: rustfmt - run: cargo fmt --all --check - clippy: + rust-clippy: name: Clippy + needs: changes + if: needs.changes.outputs.backend == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -33,8 +77,10 @@ jobs: - uses: Swatinem/rust-cache@v2 - run: cargo clippy --all-targets --all-features -- -D warnings - test: + rust-test: name: Tests + needs: changes + if: needs.changes.outputs.backend == 'true' runs-on: ubuntu-latest services: postgres: @@ -65,8 +111,10 @@ jobs: env: DATABASE_URL: "postgres://postgres:postgres@localhost/oxicloud_test" - audit: + rust-audit: name: Security Audit + needs: changes + if: needs.changes.outputs.backend == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -81,7 +129,7 @@ jobs: build: name: Build Check runs-on: ubuntu-latest - needs: [fmt, clippy, test] + needs: [frontend-linter, rust-fmt, rust-clippy, rust-test] steps: - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@stable diff --git a/README.md b/README.md index f11b9a00..c0231010 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,8 @@ Full reference: [`example.env`](example.env) · [Deployment guide](doc/deploymen ## Development +### Server side + ```bash cargo build # Dev build cargo run # Run locally @@ -223,6 +225,16 @@ cargo fmt --all --check # Format check RUST_LOG=debug cargo run # Debug logging ``` +### Client side + +Run server in dev profile: + +```bash +PROFILE=dev cargo run +``` + +CSS & JS linter is `biome` (can be installed via `cargo install biome-cli` or on MacOS: `brew install biome`) + ### Project stats | Metric | Value | diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..56b68bf9 --- /dev/null +++ b/biome.json @@ -0,0 +1,42 @@ +{ + "files": { + "includes": ["static/**/*.js", "static/**/*.css", "static/**/*.json" ] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 4, + "lineWidth": 160, + "lineEnding": "lf" + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "correctness": { + "noUnusedVariables": "warn" + } + } + }, + "javascript": { + "formatter": { + "indentStyle": "space", + "indentWidth": 4, + "quoteStyle": "single", + "semicolons": "always", + "trailingCommas": "none", + "bracketSameLine": false, + "bracketSpacing": true, + "operatorLinebreak": "after" + + } + }, + "css": { + "linter": { + "enabled": true + }, + "formatter": { + "enabled": true + } + } +} diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 00000000..f09567bd --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + // Enable type checking on all JS files (equivalent to @ts-check globally) + "checkJs": true, + "strict": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "exactOptionalPropertyTypes": true, + "target": "ES2022", + "lib": ["ES2022", "DOM"], + // Treat all JS files as modules + "moduleDetection": "force" + }, + "include": ["static/js/**/*.js"], + "exclude": [] +} From 786a778546e2f89eaf6215d7418cc058ce53602e Mon Sep 17 00:00:00 2001 From: Edouard Vanbelle Date: Tue, 7 Apr 2026 23:57:27 +0200 Subject: [PATCH 2/4] fix(main.js): add missing break in swithc/case + apply linter --- static/js/app/main.js | 105 ++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 54 deletions(-) diff --git a/static/js/app/main.js b/static/js/app/main.js index 99b27ae6..cff9ceb8 100644 --- a/static/js/app/main.js +++ b/static/js/app/main.js @@ -3,8 +3,6 @@ * This file contains the core functionality, initialization and state management */ -// @ts-check - const app = window.app; const elements = window.appElements; @@ -96,10 +94,10 @@ const ACTIONS_BAR_TEMPLATES = { }; /** - * - * @param {string} mode - * @param {boolean} [force=false] - * @returns + * + * @param {string} mode + * @param {boolean} [force=false] + * @returns */ function setActionsBarMode(mode, force = false) { if (!elements.actionsBar) return; @@ -202,7 +200,7 @@ function setupActionsBarDelegation() { /** * Read the application hash * - * format: + * format: * * #/
/ * @@ -217,21 +215,21 @@ function setupActionsBarDelegation() { * @returns {OxiContext} */ function deserializeHash() { - let hashContext = /** type {OxiContext} */ {}; + const hashContext = /** type {OxiContext} */ {}; // FIXME rename files into drive ? hashContext.section = 'files'; - let hash_elements = window.location.hash.split("/"); + const hash_elements = window.location.hash.split("/"); - let section = hash_elements[1]; + const section = hash_elements[1]; // FIXME: use navigation.VIEW_FLAGS if (section && ['files', 'shared', 'recent', 'favorites', 'trash', 'photos'].includes(section)) { hashContext.section = section; } - if (hash_elements[1] == 'files' && hash_elements[2] == 'folder' && hash_elements[3] !== null) { + if (hash_elements[1] === 'files' && hash_elements[2] === 'folder' && hash_elements[3] !== null) { hashContext.path = hash_elements[3]; if (hash_elements[4] == 'file' && hash_elements[5] !== null) { @@ -244,7 +242,7 @@ function deserializeHash() { /** * update borwser's url/history - * + * * @param {boolean} insertHistory true to change url and browser's history, false to change url only */ function updateHistory( insertHistory) { @@ -277,8 +275,6 @@ function updateHistory( insertHistory) { console.log(`replace history with ${historyUrl}`) window.history.replaceState(historyData, "", historyUrl); } - - } /** @@ -295,6 +291,7 @@ function switchSectionTo(section) { switch (section) { case "files": switchToFilesSection(); + break; case "shared": switchToSharedSection(); @@ -328,22 +325,22 @@ function switchSectionTo(section) { function initApp() { // Cache DOM elements cacheElements(); - + // Initialize file sharing module first if (window.fileSharing && window.fileSharing.init) { window.fileSharing.init(); } else { console.warn('fileSharing module not fully initialized'); } - + // Then create menus and dialogs after modules have initialized setTimeout(() => { ui.initializeContextMenus(); }, 100); - + // Setup event listeners setupEventListeners(); - + // Ensure inline viewer is initialized if (!window.inlineViewer && typeof InlineViewer !== 'undefined') { try { @@ -352,7 +349,7 @@ function initApp() { console.error('Error initializing inline viewer:', e); } } - + // Initialize favorites module if available if (window.favorites && window.favorites.init) { console.log('Initializing favorites module'); @@ -360,7 +357,7 @@ function initApp() { } else { console.warn('Favorites module not available or not initializable'); } - + // Initialize recent files module if available if (window.recent && window.recent.init) { console.log('Initializing recent files module'); @@ -368,13 +365,13 @@ function initApp() { } else { console.warn('Recent files module not available or not initializable'); } - + // Initialize multi-select / batch actions if (window.multiSelect && window.multiSelect.init) { console.log('Initializing multi-select module'); window.multiSelect.init(); } - + window.addEventListener('authenticationDone', () => { // Check if a context was provided in the URL let hashContext = deserializeHash(); @@ -404,7 +401,7 @@ function initApp() { console.log('Translations loaded, proceeding with authentication'); window.checkAuthentication(); }); - + // Set a timeout as a fallback in case translations take too long setTimeout(() => { if (!window.i18n || !window.i18n.isLoaded || !window.i18n.isLoaded()) { @@ -440,7 +437,7 @@ function cacheElements() { function setupUploadDropdown() { const uploadBtn = document.getElementById('upload-btn'); const menu = document.getElementById('upload-dropdown-menu'); - + if (!uploadBtn || !menu) return; // Abort any previous local bindings (safe across repeated/rebuilt UI) @@ -449,7 +446,7 @@ function setupUploadDropdown() { } uploadDropdownBindingsController = new AbortController(); const signal = uploadDropdownBindingsController.signal; - + // Toggle dropdown on button click uploadBtn.addEventListener('click', (e) => { e.stopPropagation(); @@ -481,14 +478,14 @@ function setupUploadDropdown() { function setupEventListeners() { // Set up drag and drop ui.setupDragAndDrop(); - + // Debounce timer for live search let searchDebounceTimer = null; const SEARCH_DEBOUNCE_MS = 300; const SEARCH_MIN_CHARS = 3; - + // handle history / url change - window.addEventListener("popstate", (e) => { + window.addEventListener("popstate", (e) => { if (e.state === null) { // change is from user (url explicitely change, read information from hash) let hashContext = deserializeHash(); @@ -512,13 +509,13 @@ function setupEventListeners() { // Cancel any pending debounce if (searchDebounceTimer) clearTimeout(searchDebounceTimer); const query = elements.searchInput.value.trim(); - + // In shared view, filter locally if (app.isSharedView && window.sharedView) { window.sharedView.filterAndSortItems(); return; } - + if (query) { window.performSearch(query); } else if (app.isSearchMode) { @@ -530,12 +527,12 @@ function setupEventListeners() { } } }); - + // Search input — Live search (debounced, after 3+ chars) elements.searchInput.addEventListener('input', () => { if (searchDebounceTimer) clearTimeout(searchDebounceTimer); const query = elements.searchInput.value.trim(); - + if (query.length >= SEARCH_MIN_CHARS) { searchDebounceTimer = setTimeout(() => { window.performSearch(query); @@ -550,7 +547,7 @@ function setupEventListeners() { }, SEARCH_DEBOUNCE_MS); } }); - + // Search button document.getElementById('search-button').addEventListener('click', () => { if (searchDebounceTimer) clearTimeout(searchDebounceTimer); @@ -559,14 +556,14 @@ function setupEventListeners() { window.performSearch(query); } }); - + // Upload dropdown setupUploadDropdown(); setupActionsBarDelegation(); if (elements.actionsBar) { elements.actionsBar.dataset.mode = 'files'; } - + // File input elements.fileInput.addEventListener('change', (e) => { if (e.target.files.length > 0) { @@ -574,7 +571,7 @@ function setupEventListeners() { e.target.value = ''; // reset so same file can be re-uploaded } }); - + // Folder input const folderInput = document.getElementById('folder-input'); if (folderInput) { @@ -585,20 +582,20 @@ function setupEventListeners() { } }); } - + // Sidebar navigation elements.navItems.forEach(item => { item.addEventListener('click', () => { // Remove active class from all nav items elements.navItems.forEach(navItem => navItem.classList.remove('active')); - + // Add active class to clicked item item.classList.add('active'); let _updateHistory = true; let itemI18nKey=item.querySelector('span').getAttribute('data-i18n') switch(itemI18nKey) { - case 'nav.shared': + case 'nav.shared': // Switch to shared view switchToSharedSection(); break; @@ -608,7 +605,7 @@ function setupEventListeners() { switchToFavoritesSection(); break; - case 'nav.recent': + case 'nav.recent': // Switch to recent files view switchToRecentFilesSection(); break; @@ -617,7 +614,7 @@ function setupEventListeners() { switchToPhotosSection(); break; - case 'nav.trash': + case 'nav.trash': switchToTrashSection(); break; @@ -625,7 +622,7 @@ function setupEventListeners() { // Use the proper switchToFilesView function which handles all UI restoration window.switchToFilesSection(); // FIXME: because fileview handles it: need to converge code - _updateHistory = false; + _updateHistory = false; } document.title = `OxiCloud: ${window.i18n.t(itemI18nKey)}`; @@ -635,7 +632,7 @@ function setupEventListeners() { } }); }); - + // Load saved view preference const savedView = localStorage.getItem('oxicloud-view'); if (savedView === 'list') { @@ -643,21 +640,21 @@ function setupEventListeners() { } else { ui.switchToGridView(); } - + // User menu window.setupUserMenu(); - + // Global events to close context menus and deselect cards document.addEventListener('click', (e) => { const folderMenu = document.getElementById('folder-context-menu'); const fileMenu = document.getElementById('file-context-menu'); - - if (folderMenu && folderMenu.style.display === 'block' && + + if (folderMenu && folderMenu.style.display === 'block' && !folderMenu.contains(e.target)) { ui.closeContextMenu(); } - - if (fileMenu && fileMenu.style.display === 'block' && + + if (fileMenu && fileMenu.style.display === 'block' && !fileMenu.contains(e.target)) { ui.closeFileContextMenu(); } @@ -693,7 +690,7 @@ function updateStorageUsageDisplay(userData) { usedBytes = userData.storage_used_bytes || 0; // Use == null to allow 0 (unlimited) to pass through; only default to DEFAULT_QUOTA when null/undefined quotaBytes = userData.storage_quota_bytes == null ? DEFAULT_QUOTA : userData.storage_quota_bytes; - + // Calculate percentage (avoid division by zero) if (quotaBytes > 0) { usagePercentage = Math.min(Math.round((usedBytes / quotaBytes) * 100), 100); @@ -707,15 +704,15 @@ function updateStorageUsageDisplay(userData) { // Update the storage display elements const storageFill = document.querySelector('.storage-fill'); const storageInfo = document.querySelector('.storage-info'); - + if (storageFill) { storageFill.style.width = `${usagePercentage}%`; } - + if (storageInfo) { // Remove data-i18n attribute to prevent i18n from overwriting our value storageInfo.removeAttribute('data-i18n'); - + // Use i18n if available if (window.i18n && window.i18n.t) { storageInfo.textContent = window.i18n.t('storage.used', { @@ -727,7 +724,7 @@ function updateStorageUsageDisplay(userData) { storageInfo.textContent = `${usagePercentage}% used (${usedFormatted} / ${quotaFormatted})`; } } - + console.log(`Updated storage display: ${usagePercentage}% (${usedFormatted} / ${quotaFormatted})`); } From 1ce29c101dc6c82118c15c7a838cf72f40d26700 Mon Sep 17 00:00:00 2001 From: Edouard Vanbelle Date: Tue, 7 Apr 2026 22:48:59 +0200 Subject: [PATCH 3/4] style: apply biome CSS/JS format --- static/css/base/forms.css | 54 +- static/css/base/reset.css | 31 +- static/css/components/breadcrumb.css | 64 +- static/css/components/buttons.css | 118 +- static/css/components/cards.css | 863 +++++----- static/css/components/contextMenu.css | 88 +- static/css/components/csp-utilities.css | 242 +-- static/css/components/dialogs.css | 946 +++++------ static/css/components/fileList.css | 360 +++-- static/css/components/icons.css | 24 +- static/css/components/languageSelector.css | 162 +- static/css/components/modals.css | 432 ++--- static/css/components/multiSelect.css | 169 +- static/css/components/notifications.css | 647 ++++---- static/css/components/search.css | 54 +- static/css/components/shareDialog.css | 72 +- static/css/components/spinner.css | 90 +- static/css/components/uploadDropdown.css | 108 +- static/css/components/userMenu.css | 358 ++--- static/css/layout/content.css | 181 ++- static/css/layout/sidebar.css | 342 ++-- static/css/layout/topbar.css | 204 +-- static/css/views/admin.css | 1386 ++++++++++++++--- static/css/views/auth.css | 24 +- static/css/views/device-verify.css | 246 +-- static/css/views/favorites.css | 18 +- static/css/views/inlineViewer.css | 395 ++--- static/css/views/photos.css | 17 +- static/css/views/photosLightbox.css | 4 +- static/css/views/profile.css | 1197 +++++++++++--- static/css/views/recent.css | 14 +- static/css/views/shared.css | 458 +++--- static/css/views/trash.css | 62 +- static/js/app/authSession.js | 14 +- static/js/app/filesView.js | 61 +- static/js/app/main.js | 96 +- static/js/app/navigation.js | 148 +- static/js/app/searchView.js | 6 +- static/js/app/state.js | 3 +- static/js/app/trashView.js | 25 +- static/js/app/ui.js | 299 ++-- static/js/app/uiFileTypes.js | 186 ++- static/js/app/uiNotifications.js | 8 +- static/js/app/userMenu.js | 29 +- static/js/core/csrf.js | 54 +- static/js/core/formatters.js | 27 +- static/js/core/i18n.js | 65 +- static/js/core/icons.js | 591 +++++-- static/js/core/languageSelector.js | 59 +- static/js/core/modal.js | 478 +++--- static/js/core/notifications.js | 714 +++++---- static/js/core/sw-register.js | 21 +- static/js/core/theme-init.js | 6 +- static/js/features/auth/auth.js | 780 ++++++---- static/js/features/files/contextMenus.js | 387 +++-- static/js/features/files/fileOperations.js | 220 ++- static/js/features/files/inlineViewer.js | 837 +++++----- static/js/features/files/multiSelect.js | 1049 +++++++------ static/js/features/files/search.js | 18 +- static/js/features/files/wopiEditor.js | 29 +- static/js/features/library/favorites.js | 2 +- static/js/features/library/photos.js | 188 ++- static/js/features/library/photosLightbox.js | 13 +- static/js/features/sharing/fileSharing.js | 21 +- static/js/views/admin/admin.js | 1040 ++++++++----- .../js/views/device-verify/device-verify.js | 226 +-- static/js/views/nextcloud/error.js | 18 +- static/js/views/nextcloud/login.js | 6 +- static/js/views/nextcloud/success.js | 4 +- static/js/views/profile/profile.js | 530 ++++--- static/js/views/shared/sharedView.js | 75 +- static/locales/ar.json | 1108 ++++++------- static/locales/de.json | 1100 ++++++------- static/locales/en.json | 1108 ++++++------- static/locales/es.json | 1106 ++++++------- static/locales/fa.json | 1048 ++++++------- static/locales/fr.json | 1096 ++++++------- static/locales/hi.json | 1108 ++++++------- static/locales/it.json | 1098 ++++++------- static/locales/ja.json | 1108 ++++++------- static/locales/ko.json | 1108 ++++++------- static/locales/nl.json | 1100 ++++++------- static/locales/pt.json | 1096 ++++++------- static/locales/ru.json | 1108 ++++++------- static/locales/zh.json | 972 ++++++------ static/sw.js | 171 +- 86 files changed, 18032 insertions(+), 15166 deletions(-) diff --git a/static/css/base/forms.css b/static/css/base/forms.css index a9a67712..5a687627 100644 --- a/static/css/base/forms.css +++ b/static/css/base/forms.css @@ -1,60 +1,60 @@ .form-group { - margin-bottom: 15px; + margin-bottom: 15px; } .form-group label { - display: block; - margin-bottom: 8px; - font-weight: 500; - color: #4a5568; + display: block; + margin-bottom: 8px; + font-weight: 500; + color: #4a5568; } .form-group input, .form-group textarea { - width: 100%; - padding: 10px; - border: 1px solid #e2e8f0; - border-radius: 6px; - font-size: 14px; + width: 100%; + padding: 10px; + border: 1px solid #e2e8f0; + border-radius: 6px; + font-size: 14px; } .form-group textarea { - resize: vertical; - min-height: 80px; + resize: vertical; + min-height: 80px; } .button { - padding: 8px 16px; - border: none; - border-radius: 6px; - cursor: pointer; - font-size: 14px; - transition: background-color 0.2s; + padding: 8px 16px; + border: none; + border-radius: 6px; + cursor: pointer; + font-size: 14px; + transition: background-color 0.2s; } .primary { - background-color: #ff5e3a; - color: white; + background-color: #ff5e3a; + color: white; } .primary:hover { - background-color: #e64a29; + background-color: #e64a29; } .secondary { - background-color: #e2e8f0; - color: #4a5568; + background-color: #e2e8f0; + color: #4a5568; } .secondary:hover { - background-color: #cbd5e0; + background-color: #cbd5e0; } .danger { - background-color: #f56565; - color: white; + background-color: #f56565; + color: white; } .danger:hover { - background-color: #e53e3e; + background-color: #e53e3e; } diff --git a/static/css/base/reset.css b/static/css/base/reset.css index 9617291f..8611a912 100644 --- a/static/css/base/reset.css +++ b/static/css/base/reset.css @@ -1,24 +1,27 @@ * { - box-sizing: border-box; - margin: 0; - padding: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + box-sizing: border-box; + margin: 0; + padding: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; } body { - display: flex; - height: 100vh; - background-color: #f5f7fa; - overflow: hidden; + display: flex; + height: 100vh; + background-color: #f5f7fa; + overflow: hidden; } -html[dir='rtl'] .fa-arrow-left::before { - content: "\f061"; +html[dir="rtl"] .fa-arrow-left::before { + content: "\f061"; } -html[dir='rtl'] .fa-sign-out-alt { - -webkit-transform: rotate(180deg); - transform: rotate(180deg); +html[dir="rtl"] .fa-sign-out-alt { + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } /* Utility: hide elements without inline style="" (CSP-safe) */ -.hidden { display: none !important; } +.hidden { + /* biome-ignore lint/complexity/noImportantStyles: this case to overide the display when hiddenis selected */ + display: none !important; +} diff --git a/static/css/components/breadcrumb.css b/static/css/components/breadcrumb.css index 2d487d18..7b3d88a2 100644 --- a/static/css/components/breadcrumb.css +++ b/static/css/components/breadcrumb.css @@ -1,24 +1,26 @@ /* Breadcrumb */ .breadcrumb { - display: flex; - align-items: center; - flex-wrap: wrap; - margin-bottom: 15px; - font-size: 14px; - color: #666; - gap: 2px; + display: flex; + align-items: center; + flex-wrap: wrap; + margin-bottom: 15px; + font-size: 14px; + color: #666; + gap: 2px; } .breadcrumb-item { - padding: 2px 4px; - border-radius: 4px; - border: 2px solid transparent; - transition: background 0.15s, color 0.15s; + padding: 2px 4px; + border-radius: 4px; + border: 2px solid transparent; + transition: + background 0.15s, + color 0.15s; } .breadcrumb-link { - cursor: pointer; - color: #5a6f8a; + cursor: pointer; + color: #5a6f8a; } .breadcrumb-link.drop-target { @@ -27,37 +29,37 @@ } .breadcrumb-link:hover { - text-decoration: underline; - color: #ff5e3a; - background: rgba(255, 94, 58, 0.06); + text-decoration: underline; + color: #ff5e3a; + background: rgba(255, 94, 58, 0.06); } .breadcrumb-current { - font-weight: 600; - color: #333; - cursor: default; + font-weight: 600; + color: #333; + cursor: default; } .breadcrumb-separator { - margin: 0 4px; - color: #adb5bd; - font-size: 12px; - user-select: none; + margin: 0 4px; + color: #adb5bd; + font-size: 12px; + user-select: none; } .breadcrumb-home { - display: inline-flex; - align-items: center; - justify-content: center; - width: 24px; - height: 24px; - border-radius: 4px; + display: inline-flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + border-radius: 4px; } .breadcrumb-home i { - font-size: 12px; + font-size: 12px; } .breadcrumb-home.breadcrumb-link:hover { - background: rgba(255, 94, 58, 0.1); + background: rgba(255, 94, 58, 0.1); } diff --git a/static/css/components/buttons.css b/static/css/components/buttons.css index 42eca0ab..09b1e6ba 100644 --- a/static/css/components/buttons.css +++ b/static/css/components/buttons.css @@ -1,107 +1,107 @@ .btn { - padding: 12px 24px; - border-radius: 12px; - border: none; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - font-size: 14px; - font-weight: 500; - gap: 8px; - transition: all 0.2s ease; + padding: 12px 24px; + border-radius: 12px; + border: none; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + font-weight: 500; + gap: 8px; + transition: all 0.2s ease; } .btn i { - font-size: 15px; + font-size: 15px; } .btn-primary { - background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); - color: white; - box-shadow: 0 4px 15px rgba(255, 94, 58, 0.3); + background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); + color: white; + box-shadow: 0 4px 15px rgba(255, 94, 58, 0.3); } .btn-primary:hover { - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(255, 94, 58, 0.4); + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(255, 94, 58, 0.4); } .btn-primary:active { - transform: translateY(0); - box-shadow: 0 2px 10px rgba(255, 94, 58, 0.3); + transform: translateY(0); + box-shadow: 0 2px 10px rgba(255, 94, 58, 0.3); } .btn-secondary { - background-color: #f8fafc; - color: #4a5568; - border: 2px solid #e2e8f0; + background-color: #f8fafc; + color: #4a5568; + border: 2px solid #e2e8f0; } .btn-secondary:hover { - background-color: #edf2f7; - border-color: #cbd5e0; - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); + background-color: #edf2f7; + border-color: #cbd5e0; + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); } .btn-secondary:active { - transform: translateY(0); - background-color: #e2e8f0; + transform: translateY(0); + background-color: #e2e8f0; } .btn-danger { - background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); - color: white; - box-shadow: 0 4px 15px rgba(239, 68, 68, 0.3); + background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); + color: white; + box-shadow: 0 4px 15px rgba(239, 68, 68, 0.3); } .btn-danger:hover { - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(239, 68, 68, 0.4); + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(239, 68, 68, 0.4); } .btn-danger:active { - transform: translateY(0); - box-shadow: 0 2px 10px rgba(239, 68, 68, 0.3); + transform: translateY(0); + box-shadow: 0 2px 10px rgba(239, 68, 68, 0.3); } /* View Toggle Buttons */ .view-toggle { - display: flex; - gap: 2px; - padding: 3px; - background-color: #f0f3f7; - border-radius: 10px; - border: 1px solid #e2e8f0; + display: flex; + gap: 2px; + padding: 3px; + background-color: #f0f3f7; + border-radius: 10px; + border: 1px solid #e2e8f0; } .toggle-btn { - display: flex; - align-items: center; - justify-content: center; - width: 36px; - height: 32px; - background-color: transparent; - border: none; - border-radius: 8px; - cursor: pointer; - color: #94a3b8; - font-size: 14px; - transition: all 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 32px; + background-color: transparent; + border: none; + border-radius: 8px; + cursor: pointer; + color: #94a3b8; + font-size: 14px; + transition: all 0.2s ease; } .toggle-btn:hover { - background-color: #e2e8f0; - color: #64748b; + background-color: #e2e8f0; + color: #64748b; } .toggle-btn.active { - background-color: white; - color: #ff5e3a; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + background-color: white; + color: #ff5e3a; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } .toggle-btn i { - pointer-events: none; + pointer-events: none; } diff --git a/static/css/components/cards.css b/static/css/components/cards.css index b18af5a1..b13faaa0 100644 --- a/static/css/components/cards.css +++ b/static/css/components/cards.css @@ -1,9 +1,9 @@ /* Files grid */ .files-grid-view { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - gap: 20px; - position: relative; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 20px; + position: relative; } /* header not visible in grid mode */ @@ -13,45 +13,49 @@ /* Rubber band / lasso selection rectangle */ .selection-rect { - position: fixed; - border: 1.5px solid var(--primary-color, #e67e22); - background-color: rgba(230, 126, 34, 0.08); - pointer-events: none; - z-index: 1000; - border-radius: 3px; - display: none; + position: fixed; + border: 1.5px solid var(--primary-color, #e67e22); + background-color: rgba(230, 126, 34, 0.08); + pointer-events: none; + z-index: 1000; + border-radius: 3px; + display: none; } .files-grid-view .file-item { - background-color: white; - border-radius: 12px; - border: 2px solid #e2e8f0; - padding: 16px; - display: flex; - flex-direction: column; - align-items: center; - box-shadow: 0 1px 3px rgba(0,0,0,0.05); - cursor: pointer; - width: 100%; - min-height: 160px; - position: relative; + background-color: white; + border-radius: 12px; + border: 2px solid #e2e8f0; + padding: 16px; + display: flex; + flex-direction: column; + align-items: center; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); + cursor: pointer; + width: 100%; + min-height: 160px; + position: relative; } .files-grid-view .file-item:hover { - transform: translateY(-2px); - box-shadow: 0 5px 15px rgba(0,0,0,0.08); - border-color: #cbd5e0; + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08); + border-color: #cbd5e0; } .files-grid-view .file-item.selected { - border-color: #ff5e3a; - background: #fff8f6; - box-shadow: 0 0 0 1px rgba(255, 94, 58, 0.15), 0 4px 12px rgba(255, 94, 58, 0.1); + border-color: #ff5e3a; + background: #fff8f6; + box-shadow: + 0 0 0 1px rgba(255, 94, 58, 0.15), + 0 4px 12px rgba(255, 94, 58, 0.1); } .files-grid-view .file-item.selected:hover { - border-color: #ff5e3a; - box-shadow: 0 0 0 1px rgba(255, 94, 58, 0.2), 0 6px 18px rgba(255, 94, 58, 0.15); + border-color: #ff5e3a; + box-shadow: + 0 0 0 1px rgba(255, 94, 58, 0.2), + 0 6px 18px rgba(255, 94, 58, 0.15); } /* element hidden on grid view */ @@ -61,113 +65,113 @@ } /* Selection checkbox */ .files-grid-view .file-item .checkbox-cell { - position: absolute; - top: 10px; - left: 10px; - width: 22px; - height: 22px; - border-radius: 6px; - background: white; - display: flex; - align-items: center; - justify-content: center; - opacity: 0; - z-index: 10; - cursor: pointer; + position: absolute; + top: 10px; + left: 10px; + width: 22px; + height: 22px; + border-radius: 6px; + background: white; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + z-index: 10; + cursor: pointer; } .files-grid-view .file-item:hover .checkbox-cell { - opacity: 1; + opacity: 1; } .files-grid-view .file-item.selected .checkbox-cell { - opacity: 1; - background: #ff5e3a; - border-color: #ff5e3a; + opacity: 1; + background: #ff5e3a; + border-color: #ff5e3a; } .files-grid-view .file-item.selected .checkbox-cell i { - color: white; - font-size: 11px; + color: white; + font-size: 11px; } /* More actions button (three dots) */ .files-grid-view .file-actions { - position: absolute; - top: 8px; - right: 8px; - width: 30px; - height: 30px; - border-radius: 8px; - border: none; - background: transparent; - display: flex; - align-items: center; - justify-content: center; - opacity: 0; - z-index: 10; - cursor: pointer; - color: #64748b; - font-size: 16px; + position: absolute; + top: 8px; + right: 8px; + width: 30px; + height: 30px; + border-radius: 8px; + border: none; + background: transparent; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + z-index: 10; + cursor: pointer; + color: #64748b; + font-size: 16px; } .files-grid-view .file-item:hover .file-actions { - opacity: 1; + opacity: 1; } .files-grid-view .file-actions:hover { - background: #f1f5f9; - color: #334155; + background: #f1f5f9; + color: #334155; } /* Favorite star (mirrors file-actions button pattern) */ .files-grid-view .file-item button.favorite-star { - position: absolute; - top: 8px; - right: 38px; - width: 30px; - height: 30px; - border-radius: 8px; - border: none; - background: transparent; - display: flex; - align-items: center; - justify-content: center; - opacity: 0; - z-index: 12; - cursor: pointer; - color: #cbd5e0; - font-size: 15px; - padding: 0; - line-height: 1; + position: absolute; + top: 8px; + right: 38px; + width: 30px; + height: 30px; + border-radius: 8px; + border: none; + background: transparent; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + z-index: 12; + cursor: pointer; + color: #cbd5e0; + font-size: 15px; + padding: 0; + line-height: 1; } .files-grid-view .file-item:hover button.favorite-star { - opacity: 1; + opacity: 1; } .files-grid-view .file-item button.favorite-star:hover { - color: #fbbf24; + color: #fbbf24; } .files-grid-view .file-item button.favorite-star.active { - opacity: 1; - color: #f59e0b; + opacity: 1; + color: #f59e0b; } .files-grid-view .file-item button.favorite-star.active:hover { - color: #d97706; + color: #d97706; } .files-grid-view .file-item.dragging { - opacity: 0.5; - transform: scale(0.95); - box-shadow: none; + opacity: 0.5; + transform: scale(0.95); + box-shadow: none; } .files-grid-view .file-item.drop-target { - background-color: rgba(255, 193, 7, 0.1); - border: 2px dashed #ffc107; + background-color: rgba(255, 193, 7, 0.1); + border: 2px dashed #ffc107; } /* ensure icon centered */ @@ -181,165 +185,165 @@ List-view icons (.file-item .file-icon) are NOT affected. */ .files-grid-view .file-item .file-icon > i, .files-grid-view .file-item .file-icon > svg { - display: none !important; + display: none !important; } .file-icon.folder-icon { - width: 100px; - height: 70px; - background-color: #ffeaa7; - border-radius: 8px; - position: relative; - margin-bottom: 10px; - display: flex; - align-items: center; - justify-content: center; + width: 100px; + height: 70px; + background-color: #ffeaa7; + border-radius: 8px; + position: relative; + margin-bottom: 10px; + display: flex; + align-items: center; + justify-content: center; } .file-icon.folder-icon::before { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 20px; - background-color: #fdcb6e; - border-radius: 8px 8px 0 0; + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 20px; + background-color: #fdcb6e; + border-radius: 8px 8px 0 0; } .file-icon.pdf-icon { - width: 100px; - height: 70px; - background-color: #fee2e2; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #e53e3e; - display: flex; - align-items: center; - justify-content: center; + width: 100px; + height: 70px; + background-color: #fee2e2; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + border-top: 3px solid #e53e3e; + display: flex; + align-items: center; + justify-content: center; } .file-icon.pdf-icon::after { - content: "PDF"; - font-size: 16px; - font-weight: 700; - color: #e53e3e; - opacity: 0.65; - letter-spacing: 1px; + content: "PDF"; + font-size: 16px; + font-weight: 700; + color: #e53e3e; + opacity: 0.65; + letter-spacing: 1px; } .file-icon.doc-icon { - width: 100px; - height: 70px; - background-color: #ebf5fb; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #2b6cb0; - overflow: hidden; + width: 100px; + height: 70px; + background-color: #ebf5fb; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + border-top: 3px solid #2b6cb0; + overflow: hidden; } .file-icon.doc-icon::before { - content: ""; - position: absolute; - top: 18px; - left: 18px; - right: 18px; - height: 3px; - background-color: #2b6cb0; - opacity: 0.3; - border-radius: 2px; + content: ""; + position: absolute; + top: 18px; + left: 18px; + right: 18px; + height: 3px; + background-color: #2b6cb0; + opacity: 0.3; + border-radius: 2px; } .file-icon.doc-icon::after { - content: ""; - position: absolute; - top: 28px; - left: 18px; - right: 28px; - height: 3px; - background-color: #2b6cb0; - opacity: 0.25; - border-radius: 2px; + content: ""; + position: absolute; + top: 28px; + left: 18px; + right: 28px; + height: 3px; + background-color: #2b6cb0; + opacity: 0.25; + border-radius: 2px; } .file-icon.script-icon { - width: 100px; - height: 70px; - background-color: #e8f5e9; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #4eaa25; - display: flex; - align-items: center; - justify-content: center; + width: 100px; + height: 70px; + background-color: #e8f5e9; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + border-top: 3px solid #4eaa25; + display: flex; + align-items: center; + justify-content: center; } .file-icon.script-icon::after { - content: ">_"; - font-size: 18px; - font-weight: 700; - font-family: monospace; - color: #4eaa25; - opacity: 0.55; + content: ">_"; + font-size: 18px; + font-weight: 700; + font-family: monospace; + color: #4eaa25; + opacity: 0.55; } .file-icon.config-icon { - width: 100px; - height: 70px; - background-color: #f1f3f5; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #718096; - overflow: hidden; + width: 100px; + height: 70px; + background-color: #f1f3f5; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + border-top: 3px solid #718096; + overflow: hidden; } .file-icon.config-icon::before { - content: ""; - position: absolute; - top: 15px; - left: 16px; - width: 10px; - height: 10px; - border: 2px solid #718096; - border-radius: 50%; - opacity: 0.4; + content: ""; + position: absolute; + top: 15px; + left: 16px; + width: 10px; + height: 10px; + border: 2px solid #718096; + border-radius: 50%; + opacity: 0.4; } .file-icon.config-icon::after { - content: ""; - position: absolute; - top: 19px; - left: 34px; - right: 16px; - height: 3px; - background-color: #718096; - opacity: 0.3; - border-radius: 2px; + content: ""; + position: absolute; + top: 19px; + left: 34px; + right: 16px; + height: 3px; + background-color: #718096; + opacity: 0.3; + border-radius: 2px; } .file-icon.image-icon { - width: 100px; - height: 70px; - background-color: #74b9ff; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - overflow: hidden; + width: 100px; + height: 70px; + background-color: #74b9ff; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + overflow: hidden; } /* Thumbnail image inside file-icon (grid and list views) */ .file-icon .file-thumb { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - object-fit: cover; - z-index: 1; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-fit: cover; + z-index: 1; } /* .file-icon.image-icon::before { @@ -354,407 +358,408 @@ } */ .file-icon.video-icon { - width: 100px; - height: 70px; - background: linear-gradient(135deg, #e0e7ff 0%, #ede9fe 50%, #fce7f3 100%); - border-radius: 10px; - position: relative; - margin-bottom: 10px; - display: flex; - align-items: center; - justify-content: center; - border: 1px solid rgba(139, 92, 246, 0.15); + width: 100px; + height: 70px; + background: linear-gradient(135deg, #e0e7ff 0%, #ede9fe 50%, #fce7f3 100%); + border-radius: 10px; + position: relative; + margin-bottom: 10px; + display: flex; + align-items: center; + justify-content: center; + border: 1px solid rgba(139, 92, 246, 0.15); } .file-icon.video-icon::before { - content: ""; - width: 36px; - height: 36px; - background: linear-gradient(135deg, #8b5cf6 0%, #a855f7 100%); - border-radius: 50%; - position: absolute; - box-shadow: 0 3px 10px rgba(139, 92, 246, 0.35); + content: ""; + width: 36px; + height: 36px; + background: linear-gradient(135deg, #8b5cf6 0%, #a855f7 100%); + border-radius: 50%; + position: absolute; + box-shadow: 0 3px 10px rgba(139, 92, 246, 0.35); } .file-icon.video-icon::after { - content: ""; - width: 0; - height: 0; - border-top: 7px solid transparent; - border-bottom: 7px solid transparent; - border-left: 11px solid white; - position: absolute; - margin-left: 3px; + content: ""; + width: 0; + height: 0; + border-top: 7px solid transparent; + border-bottom: 7px solid transparent; + border-left: 11px solid white; + position: absolute; + margin-left: 3px; } .file-icon.code-icon { - width: 100px; - height: 70px; - background-color: #e2e8f0; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #556ee6; - overflow: hidden; + width: 100px; + height: 70px; + background-color: #e2e8f0; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + border-top: 3px solid #556ee6; + overflow: hidden; } .file-icon.code-icon::before, .file-icon.code-icon::after { - content: ""; - position: absolute; - left: 10px; - right: 10px; - height: 2px; - background-color: #556ee6; + content: ""; + position: absolute; + left: 10px; + right: 10px; + height: 2px; + background-color: #556ee6; } .file-icon.code-icon::before { - top: 15px; - width: 80%; + top: 15px; + width: 80%; } .file-icon.code-icon::after { - top: 25px; - width: 60%; + top: 25px; + width: 60%; } .file-icon.code-icon .code-line-1, .file-icon.code-icon .code-line-2, .file-icon.code-icon .code-line-3 { - position: absolute; - left: 10px; - height: 2px; - background-color: #a0aec0; + position: absolute; + left: 10px; + height: 2px; + background-color: #a0aec0; } .file-icon.code-icon .code-line-1 { - top: 35px; - width: 70%; + top: 35px; + width: 70%; } .file-icon.code-icon .code-line-2 { - top: 45px; - width: 85%; + top: 45px; + width: 85%; } .file-icon.code-icon .code-line-3 { - top: 55px; - width: 50%; + top: 55px; + width: 50%; } .file-icon.json-icon { - border-top-color: #ffb86c; + border-top-color: #ffb86c; } .file-icon.json-icon::before, .file-icon.json-icon::after { - background-color: #ffb86c; + background-color: #ffb86c; } .file-icon.js-icon { - border-top-color: #ffd43b; + border-top-color: #ffd43b; } .file-icon.js-icon::before, .file-icon.js-icon::after { - background-color: #ffd43b; + background-color: #ffd43b; } .file-icon.html-icon { - border-top-color: #e34c26; + border-top-color: #e34c26; } .file-icon.html-icon::before, .file-icon.html-icon::after { - background-color: #e34c26; + background-color: #e34c26; } .file-icon.css-icon { - border-top-color: #2965f1; + border-top-color: #2965f1; } .file-icon.css-icon::before, .file-icon.css-icon::after { - background-color: #2965f1; + background-color: #2965f1; } .file-icon.py-icon { - border-top-color: #3776ab; + border-top-color: #3776ab; } .file-icon.py-icon::before, .file-icon.py-icon::after { - background-color: #3776ab; + background-color: #3776ab; } .file-icon.ts-icon { - border-top-color: #3178c6; + border-top-color: #3178c6; } .file-icon.ts-icon::before, .file-icon.ts-icon::after { - background-color: #3178c6; + background-color: #3178c6; } .file-icon.rust-icon { - border-top-color: #dea584; + border-top-color: #dea584; } .file-icon.rust-icon::before, .file-icon.rust-icon::after { - background-color: #dea584; + background-color: #dea584; } .file-icon.go-icon { - border-top-color: #00add8; + border-top-color: #00add8; } .file-icon.go-icon::before, .file-icon.go-icon::after { - background-color: #00add8; + background-color: #00add8; } .file-icon.java-icon { - border-top-color: #e76f00; + border-top-color: #e76f00; } .file-icon.java-icon::before, .file-icon.java-icon::after { - background-color: #e76f00; + background-color: #e76f00; } .file-icon.c-icon { - border-top-color: #555; + border-top-color: #555; } .file-icon.c-icon::before, .file-icon.c-icon::after { - background-color: #555; + background-color: #555; } .file-icon.cs-icon { - border-top-color: #68217a; + border-top-color: #68217a; } .file-icon.cs-icon::before, .file-icon.cs-icon::after { - background-color: #68217a; + background-color: #68217a; } .file-icon.php-icon { - border-top-color: #8892be; + border-top-color: #8892be; } .file-icon.php-icon::before, .file-icon.php-icon::after { - background-color: #8892be; + background-color: #8892be; } .file-icon.ruby-icon { - border-top-color: #cc342d; + border-top-color: #cc342d; } .file-icon.ruby-icon::before, .file-icon.ruby-icon::after { - background-color: #cc342d; + background-color: #cc342d; } .file-icon.swift-icon { - border-top-color: #fa7343; + border-top-color: #fa7343; } .file-icon.swift-icon::before, .file-icon.swift-icon::after { - background-color: #fa7343; + background-color: #fa7343; } .file-icon.kotlin-icon { - border-top-color: #7f52ff; + border-top-color: #7f52ff; } .file-icon.kotlin-icon::before, .file-icon.kotlin-icon::after { - background-color: #7f52ff; + background-color: #7f52ff; } .file-icon.sql-icon { - border-top-color: #e38c00; + border-top-color: #e38c00; } .file-icon.sql-icon::before, .file-icon.sql-icon::after { - background-color: #e38c00; + background-color: #e38c00; } .file-icon.yaml-icon { - border-top-color: #cb171e; + border-top-color: #cb171e; } .file-icon.yaml-icon::before, .file-icon.yaml-icon::after { - background-color: #cb171e; + background-color: #cb171e; } .file-icon.toml-icon { - border-top-color: #9c4221; + border-top-color: #9c4221; } .file-icon.toml-icon::before, .file-icon.toml-icon::after { - background-color: #9c4221; + background-color: #9c4221; } .file-icon.md-icon { - border-top-color: #083fa1; + border-top-color: #083fa1; } .file-icon.md-icon::before, .file-icon.md-icon::after { - background-color: #083fa1; + background-color: #083fa1; } .file-icon.spreadsheet-icon { - width: 100px; - height: 70px; - background-color: #e6f4ea; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #0d904f; - overflow: hidden; - display: flex; - align-items: center; - justify-content: center; + width: 100px; + height: 70px; + background-color: #e6f4ea; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + border-top: 3px solid #0d904f; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; } .file-icon.spreadsheet-icon::before { - content: ""; - position: absolute; - top: 12px; - left: 18px; - width: 64px; - height: 44px; - background: repeating-linear-gradient(to bottom, #0d904f 0px, #0d904f 1px, transparent 1px, transparent 11px), - repeating-linear-gradient(to right, #0d904f 0px, #0d904f 1px, transparent 1px, transparent 22px); - opacity: 0.35; + content: ""; + position: absolute; + top: 12px; + left: 18px; + width: 64px; + height: 44px; + background: + repeating-linear-gradient(to bottom, #0d904f 0px, #0d904f 1px, transparent 1px, transparent 11px), + repeating-linear-gradient(to right, #0d904f 0px, #0d904f 1px, transparent 1px, transparent 22px); + opacity: 0.35; } .file-icon.presentation-icon { - width: 100px; - height: 70px; - background-color: #fef3e2; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #d04423; - overflow: hidden; - display: flex; - align-items: center; - justify-content: center; + width: 100px; + height: 70px; + background-color: #fef3e2; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + border-top: 3px solid #d04423; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; } .file-icon.presentation-icon::before { - content: ""; - position: absolute; - top: 14px; - left: 22px; - width: 56px; - height: 38px; - border: 2px solid #d04423; - border-radius: 4px; - opacity: 0.4; + content: ""; + position: absolute; + top: 14px; + left: 22px; + width: 56px; + height: 38px; + border: 2px solid #d04423; + border-radius: 4px; + opacity: 0.4; } .file-icon.presentation-icon::after { - content: ""; - position: absolute; - top: 24px; - left: 38px; - width: 0; - height: 0; - border-top: 10px solid transparent; - border-bottom: 10px solid transparent; - border-left: 14px solid #d04423; - opacity: 0.5; + content: ""; + position: absolute; + top: 24px; + left: 38px; + width: 0; + height: 0; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + border-left: 14px solid #d04423; + opacity: 0.5; } .file-icon.audio-icon { - width: 100px; - height: 70px; - background-color: #fff3e0; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #f57c00; - overflow: hidden; - display: flex; - align-items: center; - justify-content: center; + width: 100px; + height: 70px; + background-color: #fff3e0; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + border-top: 3px solid #f57c00; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; } .file-icon.audio-icon::before { - content: "♪"; - font-size: 28px; - color: #f57c00; - opacity: 0.6; + content: "♪"; + font-size: 28px; + color: #f57c00; + opacity: 0.6; } .file-icon.archive-icon { - width: 100px; - height: 70px; - background-color: #f5f0eb; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #8d6e63; - overflow: hidden; - display: flex; - align-items: center; - justify-content: center; + width: 100px; + height: 70px; + background-color: #f5f0eb; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + border-top: 3px solid #8d6e63; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; } .file-icon.archive-icon::before { - content: ""; - position: absolute; - top: 10px; - left: 45px; - width: 10px; - height: 46px; - background: repeating-linear-gradient(to bottom, #8d6e63 0px, #8d6e63 5px, #f5f0eb 5px, #f5f0eb 10px); - opacity: 0.5; + content: ""; + position: absolute; + top: 10px; + left: 45px; + width: 10px; + height: 46px; + background: repeating-linear-gradient(to bottom, #8d6e63 0px, #8d6e63 5px, #f5f0eb 5px, #f5f0eb 10px); + opacity: 0.5; } .file-icon.installer-icon { - width: 100px; - height: 70px; - background-color: #f3e8ff; - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #7c3aed; - overflow: hidden; - display: flex; - align-items: center; - justify-content: center; + width: 100px; + height: 70px; + background-color: #f3e8ff; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + border-top: 3px solid #7c3aed; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; } .file-icon.installer-icon::before { - content: "⬇"; - font-size: 24px; - color: #7c3aed; - opacity: 0.5; + content: "⬇"; + font-size: 24px; + color: #7c3aed; + opacity: 0.5; } .files-grid-view .file-item .name-cell { - font-size: 14px; - font-weight: 500; - text-align: center; - margin-bottom: 5px; - color: #2d3748; - max-width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + font-size: 14px; + font-weight: 500; + text-align: center; + margin-bottom: 5px; + color: #2d3748; + max-width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; margin-top: 8px; } @@ -769,48 +774,48 @@ } .files-grid-view .file-item .type-cell { - font-size: 12px; - color: #718096; - text-align: center; + font-size: 12px; + color: #718096; + text-align: center; } [data-theme="dark"] .files-grid-view .file-item { - background-color: #1e293b; - border-color: #334155; + background-color: #1e293b; + border-color: #334155; } [data-theme="dark"] .files-grid-view .file-item:hover { - border-color: #475569; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + border-color: #475569; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); } [data-theme="dark"] .files-grid-view .file-item.selected { - border-color: #ff5e3a; - background: #1a1520; + border-color: #ff5e3a; + background: #1a1520; } [data-theme="dark"] .files-grid-view .file-item .checkbox-cell { - background: #1e293b; - border-color: #475569; + background: #1e293b; + border-color: #475569; } [data-theme="dark"] .files-grid-view .file-actions { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .files-grid-view .file-actions:hover { - background: #334155; - color: #e2e8f0; + background: #334155; + color: #e2e8f0; } [data-theme="dark"] .files-grid-view .file-item .name-cell { - color: #e2e8f0; + color: #e2e8f0; } [data-theme="dark"] .files-grid-view .file-item .type-cell { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .files-grid-view .file-item.drop-target { - background-color: rgba(255, 193, 7, 0.05); + background-color: rgba(255, 193, 7, 0.05); } diff --git a/static/css/components/contextMenu.css b/static/css/components/contextMenu.css index fb1d598c..f159aeeb 100644 --- a/static/css/components/contextMenu.css +++ b/static/css/components/contextMenu.css @@ -1,74 +1,76 @@ /* Context menu */ .context-menu { - position: absolute; - background: white; - border: 1px solid #e2e8f0; - border-radius: 14px; - box-shadow: 0 10px 36px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.04); - padding: 6px; - min-width: 200px; - z-index: 2000; - display: none; - animation: contextMenuIn 0.15s ease-out; + position: absolute; + background: white; + border: 1px solid #e2e8f0; + border-radius: 14px; + box-shadow: + 0 10px 36px rgba(0, 0, 0, 0.12), + 0 0 0 1px rgba(0, 0, 0, 0.04); + padding: 6px; + min-width: 200px; + z-index: 2000; + display: none; + animation: contextMenuIn 0.15s ease-out; } @keyframes contextMenuIn { - from { - opacity: 0; - transform: scale(0.95); - } - to { - opacity: 1; - transform: scale(1); - } + from { + opacity: 0; + transform: scale(0.95); + } + to { + opacity: 1; + transform: scale(1); + } } .context-menu-item { - padding: 10px 14px; - cursor: pointer; - display: flex; - align-items: center; - gap: 12px; - color: #334155; - font-size: 14px; - border-radius: 8px; - transition: background 0.12s ease; + padding: 10px 14px; + cursor: pointer; + display: flex; + align-items: center; + gap: 12px; + color: #334155; + font-size: 14px; + border-radius: 8px; + transition: background 0.12s ease; } .context-menu-item:hover { - background: #f1f5f9; + background: #f1f5f9; } .context-menu-item:active { - background: #e2e8f0; + background: #e2e8f0; } .context-menu-item i { - width: 18px; - text-align: center; - font-size: 14px; - color: #64748b; + width: 18px; + text-align: center; + font-size: 14px; + color: #64748b; - [dir='rtl'] & { - margin-left: 0; - margin-right: 0; - } + [dir="rtl"] & { + margin-left: 0; + margin-right: 0; + } } .context-menu-item-danger { - color: #ef4444; + color: #ef4444; } .context-menu-item-danger:hover { - background: #fef2f2; + background: #fef2f2; } .context-menu-item-danger i { - color: #ef4444; + color: #ef4444; } .context-menu-separator { - height: 1px; - background: #f1f5f9; - margin: 4px 8px; + height: 1px; + background: #f1f5f9; + margin: 4px 8px; } diff --git a/static/css/components/csp-utilities.css b/static/css/components/csp-utilities.css index cb25807d..6b78453a 100644 --- a/static/css/components/csp-utilities.css +++ b/static/css/components/csp-utilities.css @@ -2,149 +2,211 @@ /* ── Empty state icons (large, muted) ── */ .empty-state-icon { - font-size: 48px; - color: #ddd; - margin-bottom: 16px; + font-size: 48px; + color: #ddd; + margin-bottom: 16px; } .empty-state-icon.error { - color: #f44336; + color: #f44336; } .empty-state-icon.spinner { - color: #666; + color: #666; } /* ── Dialog header icons (accent color) ── */ .dialog-header-icon { - color: #ff5e3a; + color: #ff5e3a; } /* ── Icon spacing ── */ -.icon-mr { margin-right: 5px; } -.icon-ml { margin-left: 4px; font-size: 12px; } +.icon-mr { + margin-right: 5px; +} +.icon-ml { + margin-left: 4px; + font-size: 12px; +} /* ── Success check icon ── */ -.check-icon { color: #48bb78; } +.check-icon { + color: #48bb78; +} /* ── Move dialog ── */ .move-dialog-hint { - margin: 0 0 12px; - color: #718096; - font-size: 14px; + margin: 0 0 12px; + color: #718096; + font-size: 14px; } .folder-select-container { - max-height: 220px; - overflow-y: auto; + max-height: 220px; + overflow-y: auto; } /* ── Share dialog sections ── */ .share-section { - margin: 15px 0; + margin: 15px 0; } /* ── Search spinner ── */ .search-spinner { - margin-right: 8px; + margin-right: 8px; } /* ── Search empty state text ── */ .search-empty-text { - color: var(--text-secondary, #64748b); + color: var(--text-secondary, #64748b); } /* ── Notification upload current file ── */ .notif-upload-current { - font-size: 11px; - color: #64748b; - margin: 3px 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + font-size: 11px; + color: #64748b; + margin: 3px 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } /* ── Login auth hint ── */ .auth-hint { - color: var(--text-secondary, #666); - margin-top: 4px; - display: block; + color: var(--text-secondary, #666); + margin-top: 4px; + display: block; } /* ── About modal (userMenu.js profile popup) ── */ -.about-modal-body { max-width: 380px; } -.about-modal-header { text-align: center; padding: 20px 20px 0; } +.about-modal-body { + max-width: 380px; +} +.about-modal-header { + text-align: center; + padding: 20px 20px 0; +} .about-modal-avatar { - width: 64px; - height: 64px; - border-radius: 50%; - background: linear-gradient(135deg, #3b82f6, #6366f1); - color: #fff; - display: inline-flex; - align-items: center; - justify-content: center; - font-size: 24px; - font-weight: 700; - margin-bottom: 12px; + width: 64px; + height: 64px; + border-radius: 50%; + background: linear-gradient(135deg, #3b82f6, #6366f1); + color: #fff; + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 24px; + font-weight: 700; + margin-bottom: 12px; +} +.about-modal-username { + margin: 0; + font-size: 18px; + color: #1a1a2e; +} +.about-modal-email { + margin: 4px 0 0; + font-size: 13px; + color: #64748b; } -.about-modal-username { margin: 0; font-size: 18px; color: #1a1a2e; } -.about-modal-email { margin: 4px 0 0; font-size: 13px; color: #64748b; } .about-modal-role { - display: inline-block; - margin-top: 8px; - padding: 2px 10px; - border-radius: 10px; - font-size: 11px; - font-weight: 600; + display: inline-block; + margin-top: 8px; + padding: 2px 10px; + border-radius: 10px; + font-size: 11px; + font-weight: 600; +} +.about-modal-role-admin { + background: #dbeafe; + color: #1d4ed8; +} +.about-modal-role-user { + background: #f1f5f9; + color: #64748b; +} +.about-modal-storage { + padding: 16px 20px; } -.about-modal-role-admin { background: #dbeafe; color: #1d4ed8; } -.about-modal-role-user { background: #f1f5f9; color: #64748b; } -.about-modal-storage { padding: 16px 20px; } .about-modal-storage-label { - font-size: 12px; - color: #64748b; - text-transform: uppercase; - letter-spacing: .05em; - margin-bottom: 6px; + font-size: 12px; + color: #64748b; + text-transform: uppercase; + letter-spacing: 0.05em; + margin-bottom: 6px; +} +.about-modal-storage-label i { + margin-right: 4px; } -.about-modal-storage-label i { margin-right: 4px; } .about-modal-bar-bg { - background: #f1f5f9; - border-radius: 6px; - height: 8px; - overflow: hidden; - margin-bottom: 4px; + background: #f1f5f9; + border-radius: 6px; + height: 8px; + overflow: hidden; + margin-bottom: 4px; } .about-modal-bar-fill { - height: 100%; - border-radius: 6px; - transition: width .3s; + height: 100%; + border-radius: 6px; + transition: width 0.3s; +} +.about-modal-bar-text { + font-size: 12px; + color: #64748b; + text-align: right; +} +.about-modal-footer { + padding: 0 20px 16px; + display: flex; + justify-content: center; } -.about-modal-bar-text { font-size: 12px; color: #64748b; text-align: right; } -.about-modal-footer { padding: 0 20px 16px; display: flex; justify-content: center; } .about-modal-close-btn { - padding: 8px 24px; - border: 1px solid #e2e8f0; - border-radius: 8px; - background: #fff; - color: #334155; - font-size: 13px; - font-weight: 600; - cursor: pointer; - transition: background .15s; + padding: 8px 24px; + border: 1px solid #e2e8f0; + border-radius: 8px; + background: #fff; + color: #334155; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: background 0.15s; } /* ── Dark theme overrides ── */ -[data-theme="dark"] .empty-state-icon { color: #475569; } -[data-theme="dark"] .empty-state-icon.error { color: #ef4444; } -[data-theme="dark"] .about-modal-username { color: #f1f5f9; } -[data-theme="dark"] .about-modal-email { color: #94a3b8; } -[data-theme="dark"] .about-modal-role-admin { background: #1e3a5f; color: #60a5fa; } -[data-theme="dark"] .about-modal-role-user { background: #334155; color: #94a3b8; } -[data-theme="dark"] .about-modal-storage-label { color: #94a3b8; } -[data-theme="dark"] .about-modal-bar-bg { background: #334155; } -[data-theme="dark"] .about-modal-bar-text { color: #94a3b8; } -[data-theme="dark"] .about-modal-close-btn { - background: #1e293b; - border-color: #334155; - color: #cbd5e1; +[data-theme="dark"] .empty-state-icon { + color: #475569; +} +[data-theme="dark"] .empty-state-icon.error { + color: #ef4444; +} +[data-theme="dark"] .about-modal-username { + color: #f1f5f9; +} +[data-theme="dark"] .about-modal-email { + color: #94a3b8; +} +[data-theme="dark"] .about-modal-role-admin { + background: #1e3a5f; + color: #60a5fa; +} +[data-theme="dark"] .about-modal-role-user { + background: #334155; + color: #94a3b8; +} +[data-theme="dark"] .about-modal-storage-label { + color: #94a3b8; +} +[data-theme="dark"] .about-modal-bar-bg { + background: #334155; +} +[data-theme="dark"] .about-modal-bar-text { + color: #94a3b8; +} +[data-theme="dark"] .about-modal-close-btn { + background: #1e293b; + border-color: #334155; + color: #cbd5e1; +} +[data-theme="dark"] .move-dialog-hint { + color: #94a3b8; +} +[data-theme="dark"] .search-empty-text { + color: #94a3b8; } -[data-theme="dark"] .move-dialog-hint { color: #94a3b8; } -[data-theme="dark"] .search-empty-text { color: #94a3b8; } diff --git a/static/css/components/dialogs.css b/static/css/components/dialogs.css index a8689440..a450b049 100644 --- a/static/css/components/dialogs.css +++ b/static/css/components/dialogs.css @@ -1,251 +1,261 @@ /* Dialog animations */ @keyframes modalFadeIn { - from { opacity: 0; } - to { opacity: 1; } + from { + opacity: 0; + } + to { + opacity: 1; + } } @keyframes modalSlideIn { - from { transform: scale(0.95) translateY(-10px); opacity: 0; } - to { transform: scale(1) translateY(0); opacity: 1; } + from { + transform: scale(0.95) translateY(-10px); + opacity: 0; + } + to { + transform: scale(1) translateY(0); + opacity: 1; + } } /* Dialog (Rename / Move / Confirm) — Modern Style */ .rename-dialog { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0,0,0,0.45); - display: none; - align-items: center; - justify-content: center; - z-index: 3000; - backdrop-filter: blur(2px); - animation: modalFadeIn 0.2s ease; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.45); + display: none; + align-items: center; + justify-content: center; + z-index: 3000; + backdrop-filter: blur(2px); + animation: modalFadeIn 0.2s ease; } .rename-dialog-content { - background-color: white; - border-radius: 16px; - width: 420px; - max-width: 90%; - box-shadow: 0 20px 60px rgba(0,0,0,0.25); - overflow: hidden; - animation: modalSlideIn 0.25s ease; + background-color: white; + border-radius: 16px; + width: 420px; + max-width: 90%; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25); + overflow: hidden; + animation: modalSlideIn 0.25s ease; } .rename-dialog-header { - font-size: 17px; - font-weight: 600; - color: #1a202c; - padding: 20px 24px; - border-bottom: 1px solid #e2e8f0; - display: flex; - align-items: center; - gap: 12px; + font-size: 17px; + font-weight: 600; + color: #1a202c; + padding: 20px 24px; + border-bottom: 1px solid #e2e8f0; + display: flex; + align-items: center; + gap: 12px; } .rename-dialog-body { - padding: 24px; + padding: 24px; } .rename-dialog input { - width: 100%; - padding: 12px 16px; - border: 2px solid #e2e8f0; - border-radius: 10px; - font-size: 15px; - background: #f8fafc; - color: #1a202c; - transition: all 0.15s ease; - outline: none; + width: 100%; + padding: 12px 16px; + border: 2px solid #e2e8f0; + border-radius: 10px; + font-size: 15px; + background: #f8fafc; + color: #1a202c; + transition: all 0.15s ease; + outline: none; } .rename-dialog input:focus { - border-color: #ff5e3a; - background: white; - box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); + border-color: #ff5e3a; + background: white; + box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); } .rename-dialog-buttons { - display: flex; - justify-content: flex-end; - gap: 12px; - padding: 16px 24px; - background: #f8fafc; - border-top: 1px solid #e2e8f0; + display: flex; + justify-content: flex-end; + gap: 12px; + padding: 16px 24px; + background: #f8fafc; + border-top: 1px solid #e2e8f0; } .rename-dialog-buttons .btn-outline { - background: transparent; - color: #4a5568; - border: 1px solid #cbd5e0; + background: transparent; + color: #4a5568; + border: 1px solid #cbd5e0; } .rename-dialog-buttons .btn-outline:hover { - background: #f7fafc; - border-color: #a0aec0; + background: #f7fafc; + border-color: #a0aec0; } /* Share Dialog — Modern Style */ .share-dialog { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0,0,0,0.45); - display: none; - justify-content: center; - align-items: center; - z-index: 3000; - backdrop-filter: blur(2px); - animation: modalFadeIn 0.2s ease; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.45); + display: none; + justify-content: center; + align-items: center; + z-index: 3000; + backdrop-filter: blur(2px); + animation: modalFadeIn 0.2s ease; } .share-dialog-content { - background-color: white; - border-radius: 16px; - width: 480px; - max-width: 90%; - box-shadow: 0 20px 60px rgba(0,0,0,0.25); - overflow: hidden; - animation: modalSlideIn 0.25s ease; - max-height: 85vh; - overflow-y: auto; + background-color: white; + border-radius: 16px; + width: 480px; + max-width: 90%; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25); + overflow: hidden; + animation: modalSlideIn 0.25s ease; + max-height: 85vh; + overflow-y: auto; } .share-dialog-header { - font-size: 17px; - font-weight: 600; - color: #1a202c; - padding: 20px 24px; - border-bottom: 1px solid #e2e8f0; - display: flex; - align-items: center; - gap: 12px; + font-size: 17px; + font-weight: 600; + color: #1a202c; + padding: 20px 24px; + border-bottom: 1px solid #e2e8f0; + display: flex; + align-items: center; + gap: 12px; } .share-dialog input, .share-dialog textarea { - width: 100%; - padding: 10px 14px; - border: 2px solid #e2e8f0; - border-radius: 10px; - font-size: 14px; - background: #f8fafc; - color: #1a202c; - transition: all 0.15s ease; - outline: none; + width: 100%; + padding: 10px 14px; + border: 2px solid #e2e8f0; + border-radius: 10px; + font-size: 14px; + background: #f8fafc; + color: #1a202c; + transition: all 0.15s ease; + outline: none; } .share-dialog input:focus, .share-dialog textarea:focus { - border-color: #ff5e3a; - background: white; - box-shadow: 0 0 0 3px rgba(255,94,58,0.1); + border-color: #ff5e3a; + background: white; + box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); } .share-dialog-buttons { - display: flex; - justify-content: flex-end; - gap: 12px; - padding: 16px 24px; - background: #f8fafc; - border-top: 1px solid #e2e8f0; + display: flex; + justify-content: flex-end; + gap: 12px; + padding: 16px 24px; + background: #f8fafc; + border-top: 1px solid #e2e8f0; } .shared-item-info { - padding: 12px 24px; - background: #f8fafc; - border-bottom: 1px solid #e2e8f0; - font-size: 14px; + padding: 12px 24px; + background: #f8fafc; + border-bottom: 1px solid #e2e8f0; + font-size: 14px; } .share-options { - padding: 20px 24px 0; + padding: 20px 24px 0; } .share-options h3, #existing-shares-section h3, #new-share-section h3 { - font-size: 13px; - font-weight: 600; - margin-bottom: 10px; - color: #4a5568; - text-transform: uppercase; - letter-spacing: 0.5px; + font-size: 13px; + font-weight: 600; + margin-bottom: 10px; + color: #4a5568; + text-transform: uppercase; + letter-spacing: 0.5px; } #existing-shares-section, #new-share-section { - padding: 0 24px; + padding: 0 24px; } .share-dialog .form-group { - padding: 0; + padding: 0; } /* Shared View Dialog (edit/notification dialogs inside sharedView component) */ .shared-dialog { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0,0,0,0.45); - display: none; - justify-content: center; - align-items: center; - z-index: 3000; - backdrop-filter: blur(2px); - animation: modalFadeIn 0.2s ease; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.45); + display: none; + justify-content: center; + align-items: center; + z-index: 3000; + backdrop-filter: blur(2px); + animation: modalFadeIn 0.2s ease; } .shared-dialog.active { - display: flex; + display: flex; } .shared-dialog-content { - background-color: white; - border-radius: 16px; - width: 480px; - max-width: 90%; - box-shadow: 0 20px 60px rgba(0,0,0,0.25); - overflow: hidden; - animation: modalSlideIn 0.25s ease; - max-height: 85vh; - overflow-y: auto; - padding: 0; + background-color: white; + border-radius: 16px; + width: 480px; + max-width: 90%; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25); + overflow: hidden; + animation: modalSlideIn 0.25s ease; + max-height: 85vh; + overflow-y: auto; + padding: 0; } .shared-dialog-header { - font-size: 17px; - font-weight: 600; - color: #1a202c; - padding: 20px 24px; - border-bottom: 1px solid #e2e8f0; - display: flex; - align-items: center; - gap: 12px; + font-size: 17px; + font-weight: 600; + color: #1a202c; + padding: 20px 24px; + border-bottom: 1px solid #e2e8f0; + display: flex; + align-items: center; + gap: 12px; } .shared-dialog-header .close-dialog-btn { - margin-left: auto; - background: none; - border: none; - font-size: 22px; - cursor: pointer; - color: #718096; - padding: 4px 8px; - border-radius: 6px; - transition: all 0.15s; + margin-left: auto; + background: none; + border: none; + font-size: 22px; + cursor: pointer; + color: #718096; + padding: 4px 8px; + border-radius: 6px; + transition: all 0.15s; } .shared-dialog-header .close-dialog-btn:hover { - background: #f0f0f0; - color: #1a202c; + background: #f0f0f0; + color: #1a202c; } .shared-dialog .share-link-section, @@ -253,448 +263,448 @@ .shared-dialog .share-password-section, .shared-dialog .share-expiration-section, .shared-dialog .notification-form { - padding: 16px 24px; + padding: 16px 24px; } .shared-dialog .share-link-section label, .shared-dialog .share-permissions-section h4, .shared-dialog .notification-form label { - display: block; - font-weight: 600; - margin-bottom: 8px; - color: #2d3748; - font-size: 14px; + display: block; + font-weight: 600; + margin-bottom: 8px; + color: #2d3748; + font-size: 14px; } .shared-dialog .share-link-input { - display: flex; - gap: 8px; + display: flex; + gap: 8px; } .shared-dialog .share-link-input input { - flex: 1; - padding: 8px 12px; - border: 2px solid #e2e8f0; - border-radius: 8px; - font-size: 13px; - background: #f8fafc; - color: #1a202c; + flex: 1; + padding: 8px 12px; + border: 2px solid #e2e8f0; + border-radius: 8px; + font-size: 13px; + background: #f8fafc; + color: #1a202c; } .shared-dialog .share-permissions-section label, .shared-dialog .share-password-section label, .shared-dialog .share-expiration-section label { - display: flex; - align-items: center; - gap: 8px; - margin-bottom: 8px; - font-size: 14px; - color: #4a5568; + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 8px; + font-size: 14px; + color: #4a5568; } .shared-dialog .password-input-group { - display: flex; - gap: 8px; - margin-top: 8px; + display: flex; + gap: 8px; + margin-top: 8px; } .shared-dialog .password-input-group input { - flex: 1; - padding: 8px 12px; - border: 2px solid #e2e8f0; - border-radius: 8px; - font-size: 13px; - background: #f8fafc; + flex: 1; + padding: 8px 12px; + border: 2px solid #e2e8f0; + border-radius: 8px; + font-size: 13px; + background: #f8fafc; } .shared-dialog .share-expiration-section input[type="date"] { - padding: 8px 12px; - border: 2px solid #e2e8f0; - border-radius: 8px; - font-size: 13px; - background: #f8fafc; - margin-top: 8px; + padding: 8px 12px; + border: 2px solid #e2e8f0; + border-radius: 8px; + font-size: 13px; + background: #f8fafc; + margin-top: 8px; } .shared-dialog .share-actions, .shared-dialog .notification-actions { - display: flex; - justify-content: flex-end; - gap: 12px; - padding: 16px 24px; - background: #f8fafc; - border-top: 1px solid #e2e8f0; + display: flex; + justify-content: flex-end; + gap: 12px; + padding: 16px 24px; + background: #f8fafc; + border-top: 1px solid #e2e8f0; } .shared-dialog .notification-form input, .shared-dialog .notification-form textarea { - width: 100%; - padding: 10px 14px; - border: 2px solid #e2e8f0; - border-radius: 10px; - font-size: 14px; - background: #f8fafc; - color: #1a202c; - outline: none; - transition: all 0.15s ease; - box-sizing: border-box; + width: 100%; + padding: 10px 14px; + border: 2px solid #e2e8f0; + border-radius: 10px; + font-size: 14px; + background: #f8fafc; + color: #1a202c; + outline: none; + transition: all 0.15s ease; + box-sizing: border-box; } .shared-dialog .notification-form input:focus, .shared-dialog .notification-form textarea:focus { - border-color: #ff5e3a; - background: white; - box-shadow: 0 0 0 3px rgba(255,94,58,0.1); + border-color: #ff5e3a; + background: white; + box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); } .shared-dialog .notification-form .form-group { - padding: 0; - margin-bottom: 15px; + padding: 0; + margin-bottom: 15px; } /* Move dialog breadcrumb navigation */ .move-dialog-breadcrumb { - display: none; /* Hidden by default, shown via JS when navigating into subfolders */ - align-items: center; - flex-wrap: wrap; - gap: 4px; - padding: 8px 12px; - background: #f8fafc; - border-radius: 8px; - margin-bottom: 12px; - font-size: 13px; - overflow-x: auto; + display: none; /* Hidden by default, shown via JS when navigating into subfolders */ + align-items: center; + flex-wrap: wrap; + gap: 4px; + padding: 8px 12px; + background: #f8fafc; + border-radius: 8px; + margin-bottom: 12px; + font-size: 13px; + overflow-x: auto; } .move-breadcrumb-item { - color: #4a5568; - cursor: pointer; - padding: 2px 6px; - border-radius: 4px; - transition: all 0.15s ease; - white-space: nowrap; + color: #4a5568; + cursor: pointer; + padding: 2px 6px; + border-radius: 4px; + transition: all 0.15s ease; + white-space: nowrap; } .move-breadcrumb-item:hover { - background: #e2e8f0; - color: #1a202c; + background: #e2e8f0; + color: #1a202c; } .move-breadcrumb-item.current { - color: #ff5e3a; - font-weight: 600; - cursor: default; + color: #ff5e3a; + font-weight: 600; + cursor: default; } .move-breadcrumb-separator { - color: #a0aec0; - margin: 0 2px; + color: #a0aec0; + margin: 0 2px; } /* Folder select items in move dialog */ .folder-select-item { - display: flex; - align-items: center; - gap: 10px; - padding: 10px 14px; - border-radius: 8px; - cursor: pointer; - transition: all 0.15s ease; - color: #4a5568; - font-size: 14px; + display: flex; + align-items: center; + gap: 10px; + padding: 10px 14px; + border-radius: 8px; + cursor: pointer; + transition: all 0.15s ease; + color: #4a5568; + font-size: 14px; } .folder-select-item:hover { - background-color: #f0f3f7; + background-color: #f0f3f7; } .folder-select-item.selected { - background-color: rgba(255,94,58,0.1); - color: #ff5e3a; - font-weight: 600; + background-color: rgba(255, 94, 58, 0.1); + color: #ff5e3a; + font-weight: 600; } .folder-select-item i { - color: #ffa94d; - font-size: 16px; + color: #ffa94d; + font-size: 16px; } .folder-select-item.selected i { - color: #ff5e3a; + color: #ff5e3a; } /* "Select this folder" option */ .folder-select-item.folder-select-current { - background-color: rgba(72, 187, 120, 0.1); - color: #2f855a; - font-weight: 500; + background-color: rgba(72, 187, 120, 0.1); + color: #2f855a; + font-weight: 500; } .folder-select-item.folder-select-current:hover { - background-color: rgba(72, 187, 120, 0.15); + background-color: rgba(72, 187, 120, 0.15); } .folder-select-item.folder-select-current i { - color: #48bb78; + color: #48bb78; } /* Navigate up option */ .folder-select-item.folder-navigate-up { - color: #718096; - font-style: italic; + color: #718096; + font-style: italic; } .folder-select-item.folder-navigate-up:hover { - color: #4a5568; + color: #4a5568; } .folder-select-item.folder-navigate-up i { - color: #a0aec0; + color: #a0aec0; } /* Folder navigation item (click to enter) */ .folder-select-item.folder-navigate { - justify-content: space-between; + justify-content: space-between; } .folder-select-item.folder-navigate .folder-name { - flex: 1; + flex: 1; } .folder-select-item.folder-navigate .folder-navigate-icon { - color: #a0aec0; - font-size: 12px; - opacity: 0; - transition: opacity 0.15s ease; + color: #a0aec0; + font-size: 12px; + opacity: 0; + transition: opacity 0.15s ease; } .folder-select-item.folder-navigate:hover .folder-navigate-icon { - opacity: 1; + opacity: 1; } /* Empty folder message */ .folder-select-empty { - display: flex; - align-items: center; - justify-content: center; - gap: 8px; - padding: 24px; - color: #a0aec0; - font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 24px; + color: #a0aec0; + font-size: 14px; } .folder-select-empty i { - font-size: 20px; + font-size: 20px; } /* Custom confirm dialog */ .confirm-dialog { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0,0,0,0.45); - display: none; - align-items: center; - justify-content: center; - z-index: 4000; - backdrop-filter: blur(2px); - animation: modalFadeIn 0.2s ease; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.45); + display: none; + align-items: center; + justify-content: center; + z-index: 4000; + backdrop-filter: blur(2px); + animation: modalFadeIn 0.2s ease; } .confirm-dialog.active { - display: flex; - opacity: 1; + display: flex; + opacity: 1; } .confirm-dialog-content { - background: white; - border-radius: 16px; - width: 400px; - max-width: 90%; - box-shadow: 0 20px 60px rgba(0,0,0,0.25); - overflow: hidden; - animation: modalSlideIn 0.25s ease; - text-align: center; + background: white; + border-radius: 16px; + width: 400px; + max-width: 90%; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25); + overflow: hidden; + animation: modalSlideIn 0.25s ease; + text-align: center; } .confirm-dialog-icon { - padding: 28px 24px 12px; + padding: 28px 24px 12px; } .confirm-dialog-icon i { - font-size: 40px; - color: #f56565; + font-size: 40px; + color: #f56565; } .confirm-dialog-title { - font-size: 17px; - font-weight: 600; - color: #1a202c; - padding: 0 24px 8px; + font-size: 17px; + font-weight: 600; + color: #1a202c; + padding: 0 24px 8px; } .confirm-dialog-message { - font-size: 14px; - color: #718096; - padding: 0 24px 20px; - line-height: 1.5; + font-size: 14px; + color: #718096; + padding: 0 24px 20px; + line-height: 1.5; } .confirm-dialog-buttons { - display: flex; - gap: 12px; - padding: 16px 24px; - background: #f8fafc; - border-top: 1px solid #e2e8f0; - justify-content: flex-end; + display: flex; + gap: 12px; + padding: 16px 24px; + background: #f8fafc; + border-top: 1px solid #e2e8f0; + justify-content: flex-end; } .confirm-dialog-buttons .btn-danger { - background: linear-gradient(135deg, #f56565 0%, #e53e3e 100%); - color: white; - border: none; - padding: 10px 20px; - border-radius: 10px; - font-weight: 500; - cursor: pointer; - transition: all 0.15s ease; - box-shadow: 0 2px 8px rgba(229,62,62,0.3); + background: linear-gradient(135deg, #f56565 0%, #e53e3e 100%); + color: white; + border: none; + padding: 10px 20px; + border-radius: 10px; + font-weight: 500; + cursor: pointer; + transition: all 0.15s ease; + box-shadow: 0 2px 8px rgba(229, 62, 62, 0.3); } .confirm-dialog-buttons .btn-danger:hover { - box-shadow: 0 4px 12px rgba(229,62,62,0.4); - transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(229, 62, 62, 0.4); + transform: translateY(-1px); } /* Dialog styles */ .dialog { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - display: none; - align-items: center; - justify-content: center; - z-index: 1000; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: none; + align-items: center; + justify-content: center; + z-index: 1000; } .dialog.active { - display: flex; + display: flex; } .dialog-content { - background-color: white; - border-radius: 10px; - box-shadow: 0 10px 25px rgba(0,0,0,0.1); - width: 500px; - max-width: 90%; - max-height: 90vh; - overflow-y: auto; + background-color: white; + border-radius: 10px; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); + width: 500px; + max-width: 90%; + max-height: 90vh; + overflow-y: auto; } .dialog-header { - padding: 15px 20px; - border-bottom: 1px solid #e2e8f0; - display: flex; - align-items: center; - justify-content: space-between; + padding: 15px 20px; + border-bottom: 1px solid #e2e8f0; + display: flex; + align-items: center; + justify-content: space-between; } .dialog-header h3 { - font-size: 18px; - color: #2d3748; - margin: 0; + font-size: 18px; + color: #2d3748; + margin: 0; } .close-dialog-btn { - background: none; - border: none; - font-size: 24px; - cursor: pointer; - color: #a0aec0; + background: none; + border: none; + font-size: 24px; + cursor: pointer; + color: #a0aec0; } .dialog-body { - padding: 20px; + padding: 20px; } .share-item-info { - display: flex; - align-items: center; - gap: 10px; - margin-bottom: 20px; + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 20px; } .share-link-container { - display: flex; - gap: 10px; + display: flex; + gap: 10px; } .share-link-container input { - flex-grow: 1; - padding: 10px; - border: 1px solid #e2e8f0; - border-radius: 6px; - font-size: 14px; + flex-grow: 1; + padding: 10px; + border: 1px solid #e2e8f0; + border-radius: 6px; + font-size: 14px; } [data-theme="dark"] .rename-dialog-content { - background-color: #1e293b; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); + background-color: #1e293b; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); } [data-theme="dark"] .rename-dialog-header { - color: #f1f5f9; - border-bottom-color: #334155; + color: #f1f5f9; + border-bottom-color: #334155; } [data-theme="dark"] .rename-dialog input { - background: #0f172a; - color: #e2e8f0; - border-color: #334155; + background: #0f172a; + color: #e2e8f0; + border-color: #334155; } [data-theme="dark"] .rename-dialog input:focus { - border-color: #ff5e3a; - background: #0f172a; + border-color: #ff5e3a; + background: #0f172a; } [data-theme="dark"] .rename-dialog-buttons { - background: #162032; - border-top-color: #334155; + background: #162032; + border-top-color: #334155; } [data-theme="dark"] .rename-dialog-buttons .btn-outline { - background: transparent; - color: #94a3b8; - border-color: #475569; + background: transparent; + color: #94a3b8; + border-color: #475569; } [data-theme="dark"] .rename-dialog-buttons .btn-outline:hover { - background: #334155; - border-color: #64748b; + background: #334155; + border-color: #64748b; } [data-theme="dark"] .shared-dialog-content { - background-color: #1e293b; + background-color: #1e293b; } [data-theme="dark"] .shared-dialog-header { - color: #e2e8f0; - border-bottom-color: #334155; + color: #e2e8f0; + border-bottom-color: #334155; } [data-theme="dark"] .shared-dialog-header .close-dialog-btn { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .shared-dialog-header .close-dialog-btn:hover { - background: #334155; - color: #e2e8f0; + background: #334155; + color: #e2e8f0; } [data-theme="dark"] .shared-dialog .share-link-input input, @@ -702,250 +712,250 @@ [data-theme="dark"] .shared-dialog .share-expiration-section input, [data-theme="dark"] .shared-dialog .notification-form input, [data-theme="dark"] .shared-dialog .notification-form textarea { - background: #0f172a; - border-color: #334155; - color: #e2e8f0; + background: #0f172a; + border-color: #334155; + color: #e2e8f0; } [data-theme="dark"] .shared-dialog .share-link-input input:focus, [data-theme="dark"] .shared-dialog .notification-form input:focus, [data-theme="dark"] .shared-dialog .notification-form textarea:focus { - border-color: #ff5e3a; - background: #1e293b; + border-color: #ff5e3a; + background: #1e293b; } [data-theme="dark"] .shared-dialog .share-link-section label, [data-theme="dark"] .shared-dialog .share-permissions-section h4, [data-theme="dark"] .shared-dialog .notification-form label { - color: #e2e8f0; + color: #e2e8f0; } [data-theme="dark"] .shared-dialog .share-permissions-section label, [data-theme="dark"] .shared-dialog .share-password-section label, [data-theme="dark"] .shared-dialog .share-expiration-section label { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .shared-dialog .share-actions, [data-theme="dark"] .shared-dialog .notification-actions { - background: #162032; - border-top-color: #334155; + background: #162032; + border-top-color: #334155; } [data-theme="dark"] .confirm-dialog-content { - background-color: #1e293b; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); + background-color: #1e293b; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); } [data-theme="dark"] .confirm-dialog-header { - color: #f1f5f9; + color: #f1f5f9; } [data-theme="dark"] .confirm-dialog-message { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .confirm-dialog-buttons { - background: #162032; - border-top-color: #334155; + background: #162032; + border-top-color: #334155; } [data-theme="dark"] .move-dialog-content { - background-color: #1e293b; + background-color: #1e293b; } [data-theme="dark"] .move-dialog-header { - color: #f1f5f9; - border-bottom-color: #334155; + color: #f1f5f9; + border-bottom-color: #334155; } [data-theme="dark"] .move-dialog .folder-tree { - background: #0f172a; - border-color: #334155; + background: #0f172a; + border-color: #334155; } [data-theme="dark"] .move-dialog .folder-tree-item { - color: #cbd5e1; + color: #cbd5e1; } [data-theme="dark"] .move-dialog .folder-tree-item:hover { - background: #334155; + background: #334155; } [data-theme="dark"] .move-dialog .folder-tree-item.selected { - background: rgba(255, 94, 58, 0.1); - color: #ff5e3a; + background: rgba(255, 94, 58, 0.1); + color: #ff5e3a; } [data-theme="dark"] .move-dialog-buttons { - background: #162032; - border-top-color: #334155; + background: #162032; + border-top-color: #334155; } [data-theme="dark"] .share-dialog-content { - background-color: #1e293b; + background-color: #1e293b; } [data-theme="dark"] .share-dialog-header { - color: #f1f5f9; - border-bottom-color: #334155; + color: #f1f5f9; + border-bottom-color: #334155; } [data-theme="dark"] .share-dialog-body label { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .share-dialog-body input { - background: #0f172a; - border-color: #334155; - color: #e2e8f0; + background: #0f172a; + border-color: #334155; + color: #e2e8f0; } [data-theme="dark"] .share-dialog-body input:focus { - border-color: #ff5e3a; - background: #0f172a; + border-color: #ff5e3a; + background: #0f172a; } [data-theme="dark"] .share-link-container { - background: #0f172a; - border-color: #334155; + background: #0f172a; + border-color: #334155; } [data-theme="dark"] .share-link-container input { - color: #e2e8f0; + color: #e2e8f0; } [data-theme="dark"] .share-dialog-buttons { - background: #162032; - border-top-color: #334155; + background: #162032; + border-top-color: #334155; } [data-theme="dark"] .dialog { - background-color: rgba(0, 0, 0, 0.6); + background-color: rgba(0, 0, 0, 0.6); } [data-theme="dark"] .dialog-content { - background-color: #1e293b; - color: #e2e8f0; + background-color: #1e293b; + color: #e2e8f0; } [data-theme="dark"] .dialog-header { - border-bottom-color: #334155; + border-bottom-color: #334155; } [data-theme="dark"] .dialog-header h3 { - color: #f1f5f9; + color: #f1f5f9; } [data-theme="dark"] .dialog-body label { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .dialog-body input, [data-theme="dark"] .dialog-body textarea { - background-color: #0f172a; - border-color: #334155; - color: #e2e8f0; + background-color: #0f172a; + border-color: #334155; + color: #e2e8f0; } [data-theme="dark"] .dialog-body input:focus, [data-theme="dark"] .dialog-body textarea:focus { - border-color: #ff5e3a; + border-color: #ff5e3a; } [data-theme="dark"] .close-dialog-btn { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .close-dialog-btn:hover { - color: #f1f5f9; + color: #f1f5f9; } [data-theme="dark"] .share-setting label { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .permissions-options label span { - color: #e2e8f0; + color: #e2e8f0; } [data-theme="dark"] .share-item-info { - color: #e2e8f0; + color: #e2e8f0; } /* Dark mode for move dialog breadcrumb */ [data-theme="dark"] .move-dialog-breadcrumb { - background: #0f172a; + background: #0f172a; } [data-theme="dark"] .move-breadcrumb-item { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .move-breadcrumb-item:hover { - background: #334155; - color: #e2e8f0; + background: #334155; + color: #e2e8f0; } [data-theme="dark"] .move-breadcrumb-item.current { - color: #ff5e3a; + color: #ff5e3a; } [data-theme="dark"] .move-breadcrumb-separator { - color: #475569; + color: #475569; } /* Dark mode for folder select items */ [data-theme="dark"] .folder-select-item { - color: #cbd5e1; + color: #cbd5e1; } [data-theme="dark"] .folder-select-item:hover { - background-color: #334155; + background-color: #334155; } [data-theme="dark"] .folder-select-item.selected { - background-color: rgba(255,94,58,0.15); - color: #ff5e3a; + background-color: rgba(255, 94, 58, 0.15); + color: #ff5e3a; } [data-theme="dark"] .folder-select-item i { - color: #fbbf24; + color: #fbbf24; } [data-theme="dark"] .folder-select-item.selected i { - color: #ff5e3a; + color: #ff5e3a; } [data-theme="dark"] .folder-select-item.folder-select-current { - background-color: rgba(74, 222, 128, 0.1); - color: #86efac; + background-color: rgba(74, 222, 128, 0.1); + color: #86efac; } [data-theme="dark"] .folder-select-item.folder-select-current:hover { - background-color: rgba(74, 222, 128, 0.15); + background-color: rgba(74, 222, 128, 0.15); } [data-theme="dark"] .folder-select-item.folder-select-current i { - color: #4ade80; + color: #4ade80; } [data-theme="dark"] .folder-select-item.folder-navigate-up { - color: #64748b; + color: #64748b; } [data-theme="dark"] .folder-select-item.folder-navigate-up:hover { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .folder-select-item.folder-navigate-up i { - color: #475569; + color: #475569; } [data-theme="dark"] .folder-select-item.folder-navigate .folder-navigate-icon { - color: #475569; + color: #475569; } [data-theme="dark"] .folder-select-empty { - color: #475569; + color: #475569; } diff --git a/static/css/components/fileList.css b/static/css/components/fileList.css index 783ffc3c..0103695b 100644 --- a/static/css/components/fileList.css +++ b/static/css/components/fileList.css @@ -1,369 +1,369 @@ /* File list - Improved style */ .files-list-view { - --files-list-columns: 36px minmax(200px, 2fr) 100px 110px 130px 64px; - display: flex; - flex-direction: column; - width: 100%; - border-radius: 10px; - overflow: hidden; - background-color: white; - box-shadow: 0 1px 3px rgba(0,0,0,0.05); + --files-list-columns: 36px minmax(200px, 2fr) 100px 110px 130px 64px; + display: flex; + flex-direction: column; + width: 100%; + border-radius: 10px; + overflow: hidden; + background-color: white; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); } .list-header { - display: grid; - grid-template-columns: var(--files-list-columns); - column-gap: 12px; - padding: 15px; - font-weight: 600; - color: #2d3748; - background-color: #f8f9fa; - border-bottom: 1px solid #e0e6ed; - align-items: center; + display: grid; + grid-template-columns: var(--files-list-columns); + column-gap: 12px; + padding: 15px; + font-weight: 600; + color: #2d3748; + background-color: #f8f9fa; + border-bottom: 1px solid #e0e6ed; + align-items: center; } .files-list-view .file-item { - display: grid; - grid-template-columns: var(--files-list-columns); - column-gap: 12px; - padding: 12px 15px; - border-bottom: 1px solid #f0f0f0; - align-items: center; - cursor: pointer; - background-color: white; + display: grid; + grid-template-columns: var(--files-list-columns); + column-gap: 12px; + padding: 12px 15px; + border-bottom: 1px solid #f0f0f0; + align-items: center; + cursor: pointer; + background-color: white; } .files-list-view .file-item.selected { - background-color: #fff8f6; + background-color: #fff8f6; } .files-list-view .file-item.selected:hover { - background-color: #fff0ec; + background-color: #fff0ec; } .list-header.trash-header { - grid-template-columns: minmax(180px, 1.5fr) 0.5fr 1fr 140px 100px; + grid-template-columns: minmax(180px, 1.5fr) 0.5fr 1fr 140px 100px; } .trash-item.file-item { - grid-template-columns: minmax(180px, 1.5fr) 0.5fr 1fr 140px 100px; + grid-template-columns: minmax(180px, 1.5fr) 0.5fr 1fr 140px 100px; } .files-list-view .file-item:hover { - background-color: #f0f8ff; + background-color: #f0f8ff; } .list-header > div, .files-list-view .file-item > div { - min-width: 0; + min-width: 0; } .list-header > div:nth-child(4), .files-list-view .file-item .size-cell { - justify-self: end; - text-align: right; + justify-self: end; + text-align: right; } .files-list-view .file-item .name-cell { - display: flex; - align-items: center; - gap: 12px; - min-width: 0; - overflow: hidden; + display: flex; + align-items: center; + gap: 12px; + min-width: 0; + overflow: hidden; } .files-list-view .file-item .name-cell span { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .files-list-view .file-item .file-icon { - width: 36px; - height: 36px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 8px; - font-size: 20px; - margin-bottom: 0; - flex-shrink: 0; + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 8px; + font-size: 20px; + margin-bottom: 0; + flex-shrink: 0; } .files-list-view .file-item .file-icon.folder-icon { - background-color: #ffeaa7; - position: relative; - width: 36px; - height: 36px; - margin-bottom: 0; + background-color: #ffeaa7; + position: relative; + width: 36px; + height: 36px; + margin-bottom: 0; } .files-list-view .file-item .file-icon.folder-icon::before { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 8px; - background-color: #fdcb6e; - border-radius: 8px 8px 0 0; + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 8px; + background-color: #fdcb6e; + border-radius: 8px 8px 0 0; } .files-list-view .file-item .file-icon.folder-icon i, .files-list-view .file-item .file-icon.folder-icon svg { - display: none; + display: none; } .files-list-view .file-item .file-icon.doc-icon { - background-color: #e0ecff; + background-color: #e0ecff; } .files-list-view .file-item .file-icon.doc-icon i, .files-list-view .file-item .file-icon.doc-icon svg { - color: #3171d8; - display: flex !important; + color: #3171d8; + display: flex !important; } .files-list-view .file-item .file-icon.doc-icon::before, .files-list-view .file-item .file-icon.doc-icon::after { - display: none; + display: none; } .files-list-view .file-item .file-icon.pdf-icon { - background-color: #fee2e2; + background-color: #fee2e2; } .files-list-view .file-item .file-icon.pdf-icon i, .files-list-view .file-item .file-icon.pdf-icon svg { - color: #e53e3e; - display: flex !important; + color: #e53e3e; + display: flex !important; } .files-list-view .file-item .file-icon.pdf-icon::before, .files-list-view .file-item .file-icon.pdf-icon::after { - display: none; + display: none; } .files-list-view .file-item .file-icon.image-icon { - background-color: #e0f2fe; - position: relative; - overflow: hidden; - border-radius: 4px; + background-color: #e0f2fe; + position: relative; + overflow: hidden; + border-radius: 4px; } .files-list-view .file-item .file-icon.image-icon i, .files-list-view .file-item .file-icon.image-icon svg { - color: #3b82f6; - display: flex !important; + color: #3b82f6; + display: flex !important; } .files-list-view .file-item .file-icon.image-icon::before, .files-list-view .file-item .file-icon.image-icon::after { - display: none; + display: none; } .files-list-view .file-item .file-icon.video-icon { - background: linear-gradient(135deg, #ede9fe, #fce7f3); + background: linear-gradient(135deg, #ede9fe, #fce7f3); } .files-list-view .file-item .file-icon.video-icon i, .files-list-view .file-item .file-icon.video-icon svg { - color: #8b5cf6; - display: flex !important; + color: #8b5cf6; + display: flex !important; } .files-list-view .file-item .file-icon.video-icon::before, .files-list-view .file-item .file-icon.video-icon::after { - display: none; + display: none; } .files-list-view .file-item .file-icon.audio-icon { - background-color: #fef3c7; + background-color: #fef3c7; } .files-list-view .file-item .file-icon.audio-icon i, .files-list-view .file-item .file-icon.audio-icon svg { - color: #f59e0b; - display: flex !important; + color: #f59e0b; + display: flex !important; } .files-list-view .file-item .file-icon.audio-icon::before, .files-list-view .file-item .file-icon.audio-icon::after { - display: none; + display: none; } .files-list-view .file-item .file-icon.spreadsheet-icon { - background-color: #e6f4ea; - width: 36px; - height: 36px; - margin-bottom: 0; - border-top: none; + background-color: #e6f4ea; + width: 36px; + height: 36px; + margin-bottom: 0; + border-top: none; } .files-list-view .file-item .file-icon.spreadsheet-icon i, .files-list-view .file-item .file-icon.spreadsheet-icon svg { - color: #0d904f; - display: flex !important; + color: #0d904f; + display: flex !important; } .files-list-view .file-item .file-icon.spreadsheet-icon::before, .files-list-view .file-item .file-icon.spreadsheet-icon::after { - display: none; + display: none; } .files-list-view .file-item .file-icon.presentation-icon { - background-color: #fef3e2; - width: 36px; - height: 36px; - margin-bottom: 0; - border-top: none; + background-color: #fef3e2; + width: 36px; + height: 36px; + margin-bottom: 0; + border-top: none; } .files-list-view .file-item .file-icon.presentation-icon i, .files-list-view .file-item .file-icon.presentation-icon svg { - color: #d04423; - display: flex !important; + color: #d04423; + display: flex !important; } .files-list-view .file-item .file-icon.presentation-icon::before, .files-list-view .file-item .file-icon.presentation-icon::after { - display: none; + display: none; } .files-list-view .file-item .file-icon.audio-icon { - background-color: #fff3e0; - width: 36px; - height: 36px; - margin-bottom: 0; - border-top: none; + background-color: #fff3e0; + width: 36px; + height: 36px; + margin-bottom: 0; + border-top: none; } .files-list-view .file-item .file-icon.archive-icon { - background-color: #f5f0eb; - width: 36px; - height: 36px; - margin-bottom: 0; - border-top: none; + background-color: #f5f0eb; + width: 36px; + height: 36px; + margin-bottom: 0; + border-top: none; } .files-list-view .file-item .file-icon.archive-icon i, .files-list-view .file-item .file-icon.archive-icon svg { - color: #8d6e63; - display: flex !important; + color: #8d6e63; + display: flex !important; } .files-list-view .file-item .file-icon.archive-icon::before, .files-list-view .file-item .file-icon.archive-icon::after { - display: none; + display: none; } .files-list-view .file-item .file-icon.installer-icon { - background-color: #f3e8ff; - width: 36px; - height: 36px; - margin-bottom: 0; - border-top: none; + background-color: #f3e8ff; + width: 36px; + height: 36px; + margin-bottom: 0; + border-top: none; } .files-list-view .file-item .file-icon.installer-icon i, .files-list-view .file-item .file-icon.installer-icon svg { - color: #7c3aed; - display: flex !important; + color: #7c3aed; + display: flex !important; } .files-list-view .file-item .file-icon.installer-icon::before, .files-list-view .file-item .file-icon.installer-icon::after { - display: none; + display: none; } .files-list-view .file-item .file-icon.script-icon { - background-color: #e8f5e9; + background-color: #e8f5e9; } .files-list-view .file-item .file-icon.script-icon i, .files-list-view .file-item .file-icon.script-icon svg { - color: #4eaa25; - display: flex !important; + color: #4eaa25; + display: flex !important; } .files-list-view .file-item .file-icon.script-icon::before, .files-list-view .file-item .file-icon.script-icon::after { - display: none; + display: none; } .files-list-view .file-item .file-icon.config-icon { - background-color: #f1f3f5; + background-color: #f1f3f5; } .files-list-view .file-item .file-icon.config-icon i, .files-list-view .file-item .file-icon.config-icon svg { - color: #718096; - display: flex !important; + color: #718096; + display: flex !important; } .files-list-view .file-item .file-icon.config-icon::before, .files-list-view .file-item .file-icon.config-icon::after { - display: none; + display: none; } .list-header > div:nth-child(5), .files-list-view .file-item .date-cell { - justify-self: center; - text-align: center; + justify-self: center; + text-align: center; } .files-list-view .file-item .date-cell { - color: #718096; - font-size: 14px; + color: #718096; + font-size: 14px; } .files-list-view .file-item .size-cell { - color: #718096; - font-size: 14px; - text-align: right; - font-variant-numeric: tabular-nums; + color: #718096; + font-size: 14px; + text-align: right; + font-variant-numeric: tabular-nums; } .files-list-view .file-item .type-cell { - color: #4b5563; - font-weight: 500; - font-size: 14px; + color: #4b5563; + font-weight: 500; + font-size: 14px; } .files-list-view .file-item.dragging { - opacity: 0.5; - background-color: #f9fafb; + opacity: 0.5; + background-color: #f9fafb; } .files-list-view .file-item.drop-target { - background-color: rgba(255, 193, 7, 0.1); - border: 2px dashed #ffc107; + background-color: rgba(255, 193, 7, 0.1); + border: 2px dashed #ffc107; } .files-list-view .file-item .action-cell { - align-items: center; + align-items: center; text-align: right; } .files-list-view .file-item .action-cell button { display: inline; - width: 28px; - height: 28px; - border-radius: 8px; - border: none; - background: transparent; - align-items: center; - justify-content: center; - cursor: pointer; - color: #64748b; - font-size: 16px; + width: 28px; + height: 28px; + border-radius: 8px; + border: none; + background: transparent; + align-items: center; + justify-content: center; + cursor: pointer; + color: #64748b; + font-size: 16px; } .files-list-view .file-item .action-cell button:hover { - background: #e0e5e8; - color: #334155; + background: #e0e5e8; + color: #334155; } -/* could be visible if we want */ +/* could be visible if we want */ .files-list-view .file-item .action-cell button.favorite-star { display: none; border: none; @@ -373,62 +373,60 @@ display: inline; } - [data-theme="dark"] .files-list-view { - background-color: #1e293b; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + background-color: #1e293b; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); } [data-theme="dark"] .list-header { - background-color: #162032; - color: #94a3b8; - border-bottom-color: #334155; + background-color: #162032; + color: #94a3b8; + border-bottom-color: #334155; } [data-theme="dark"] .files-list-view .file-item { - background-color: #1e293b; - border-bottom-color: #293548; + background-color: #1e293b; + border-bottom-color: #293548; } [data-theme="dark"] .files-list-view .file-item:hover { - background-color: #253345; + background-color: #253345; } [data-theme="dark"] .files-list-view .file-item.selected { - background-color: #1a1520; + background-color: #1a1520; } [data-theme="dark"] .files-list-view .file-item.selected:hover { - background-color: #231a2a; + background-color: #231a2a; } [data-theme="dark"] .files-list-view .file-item .name-cell { - color: #e2e8f0; + color: #e2e8f0; } [data-theme="dark"] .files-list-view .file-item .date-cell, [data-theme="dark"] .files-list-view .file-item .size-cell { - color: #64748b; + color: #64748b; } [data-theme="dark"] .files-list-view .file-item .type-cell { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .files-list-view .file-item.dragging { - background-color: #334155; + background-color: #334155; } [data-theme="dark"] .files-list-view .file-item.drop-target { - background-color: rgba(255, 193, 7, 0.05); + background-color: rgba(255, 193, 7, 0.05); } [data-theme="dark"] .files-list-view .file-actions { - color: #94a3b8; + color: #94a3b8; } [data-theme="dark"] .files-list-view .file-actions:hover { - background: #334155; - color: #e2e8f0; + background: #334155; + color: #e2e8f0; } - diff --git a/static/css/components/icons.css b/static/css/components/icons.css index f2ba2023..140bb8a1 100644 --- a/static/css/components/icons.css +++ b/static/css/components/icons.css @@ -1,19 +1,23 @@ /* SVG icon base styles (replaces inline