diff --git a/static/admin.html b/static/admin.html index cb0d918b..b2103b3c 100644 --- a/static/admin.html +++ b/static/admin.html @@ -6,7 +6,8 @@ OxiCloud — Admin Panel - + + diff --git a/static/css/admin.css b/static/css/admin.css index a444da70..bd5f80bc 100644 --- a/static/css/admin.css +++ b/static/css/admin.css @@ -1,299 +1 @@ -*{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{background:#f5f7fa;color:#1e293b;min-height:100vh;display:flex;flex-direction:column} - -.hidden{display:none !important} -.show-block{display:block !important} -.show-flex{display:flex !important} -.link-reset-flex{text-decoration:none;color:inherit;display:flex;align-items:center;gap:14px} -.width-zero{width:0%} -.mt-14{margin-top:14px} -.toggle-row-strong{margin-top:10px;padding:12px 0;border-top:1px solid #e2e8f0} -.icon-muted-right{color:#64748b;margin-right:6px} -.h2-space-between{justify-content:space-between} -.flex-gap-6{display:flex;gap:6px} -.oidc-discover-wrap{margin-bottom:12px} -.secret-icon{color:#059669} -.small-muted{font-weight:400;color:#94a3b8} -.summary-icon-right{margin-right:6px} -.oidc-actions{display:flex;gap:10px;margin-top:24px;justify-content:flex-end} -.modal-title-icon{color:#ff5e3a;margin-right:8px} -.quota-input-row{display:flex;gap:10px;align-items:center} -.flex-1{flex:1} -.select-qm-unit{width:90px;padding:10px 14px;border:2px solid #e2e8f0;border-radius:10px;font-size:14px;background:#f8fafc} -.form-row{display:flex;gap:14px} -.select-cu-role{width:100%;padding:10px 14px;border:2px solid #e2e8f0;border-radius:10px;font-size:14px;background:#f8fafc} -.quota-row{display:flex;gap:6px} -.select-cu-quota-unit{width:70px;padding:10px 8px;border:2px solid #e2e8f0;border-radius:10px;font-size:13px;background:#f8fafc} -.alert-no-margin{margin-top:0} -.table-loading-cell{text-align:center;padding:28px;color:#94a3b8} -.table-status-error{color:#991b1b;padding:20px} -.table-status-empty{text-align:center;padding:28px;color:#94a3b8} -.user-self-badge{color:#94a3b8;font-weight:400} -.badge-admin-icon-small{font-size:10px} -.quota-progress-fixed{width:80px} -.user-last-login-cell{font-size:12px;color:#94a3b8} - -/* ── Scrollbar ── */ -::-webkit-scrollbar{width:8px} -::-webkit-scrollbar-track{background:transparent} -::-webkit-scrollbar-thumb{background:rgba(0,0,0,.15);border-radius:4px} -::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,.25)} -*{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.15) transparent} - -/* ── Top Header Bar ── */ -.admin-header{ - background:linear-gradient(135deg,#2a3042 0%,#232838 100%); - padding:0 32px;height:64px;display:flex;align-items:center;justify-content:space-between; - box-shadow:0 2px 12px rgba(0,0,0,.15);position:sticky;top:0;z-index:100; -} -.admin-header-left{display:flex;align-items:center;gap:14px} -.admin-logo{ - width:38px;height:38px;background:linear-gradient(135deg,#ff5e3a,#ff2d55);border-radius:11px; - display:flex;align-items:center;justify-content:center; - box-shadow:0 3px 10px rgba(255,94,58,.35); -} -.admin-logo svg{width:20px;height:20px;fill:#fff} -.admin-title-text{font-size:17px;font-weight:700;color:#fff;letter-spacing:.3px} -.admin-title-separator{font-size:17px;color:rgba(255,255,255,.5);font-weight:400;margin-left:6px} -.admin-header-right a{ - color:rgba(255,255,255,.65);text-decoration:none;font-size:13px;font-weight:500; - display:flex;align-items:center;gap:6px;transition:color .2s; -} -.admin-header-right a:hover{color:#fff} - -/* ── Container ── */ -.admin-container{max-width:1080px;margin:0 auto;padding:28px 24px 60px;width:100%} - -/* ── Tabs ── */ -.admin-tabs{display:flex;gap:6px;margin-bottom:28px;background:#fff;border-radius:14px;padding:6px;box-shadow:0 1px 4px rgba(0,0,0,.06)} -.admin-tab{ - padding:10px 22px;cursor:pointer;font-weight:600;font-size:13.5px;color:#64748b; - border:none;background:none;border-radius:10px;transition:all .2s;display:flex;align-items:center;gap:8px; -} -.admin-tab:hover{color:#1e293b;background:#f8fafc} -.admin-tab.active{color:#fff;background:linear-gradient(135deg,#ff5e3a,#ff2d55);box-shadow:0 3px 12px rgba(255,94,58,.25)} -.admin-tab.active i{color:#fff} -.admin-tab i{font-size:14px;width:16px;text-align:center} -.tab-content{display:none} -.tab-content.active{display:block} - -/* ── Cards ── */ -.admin-card{background:#fff;border-radius:16px;box-shadow:0 1px 4px rgba(0,0,0,.06),0 0 0 1px rgba(0,0,0,.03);padding:28px;margin-bottom:22px} -.admin-card h2{font-size:16px;font-weight:700;margin-bottom:20px;color:#1e293b;display:flex;align-items:center;gap:10px} -.admin-card h2 i{color:#ff5e3a;font-size:17px} - -#main-content, -#ds-warn-card, -#ds-danger-card, -#registration-warning, -#oidc-form, -#secret-hint, -#password-warning, -#quota-modal, -#create-user-modal, -#reset-pw-modal{display:none} - -/* ── Stats Grid ── */ -.stats-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:22px} -.stat-card{ - padding:20px;background:#f8fafc;border-radius:14px;text-align:center; - border:1px solid #e2e8f0;transition:transform .15s,box-shadow .15s; -} -.stat-card:hover{transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,0,0,.06)} -.stat-value{font-size:1.75rem;font-weight:800;color:#1e293b} -.stat-label{font-size:11.5px;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;margin-top:4px;font-weight:600} -.stat-card.warn{border-color:#fbbf24;background:#fffbeb} -.stat-card.danger{border-color:#ef4444;background:#fef2f2} -.text-blue{color:#3b82f6!important} -.text-green{color:#059669!important} -.text-orange{color:#d97706!important} -.text-red{color:#dc2626!important} - -/* ── Progress bar ── */ -.progress-bar{width:100%;height:8px;background:#e2e8f0;border-radius:4px;overflow:hidden} -.progress-fill{height:100%;border-radius:4px;transition:width .5s ease} -.progress-fill.green{background:linear-gradient(90deg,#059669,#10b981)} -.progress-fill.orange{background:linear-gradient(90deg,#d97706,#f59e0b)} -.progress-fill.red{background:linear-gradient(90deg,#dc2626,#ef4444)} - -/* ── Table ── */ -.table-wrap{overflow-x:auto;border-radius:12px;border:1px solid #e2e8f0} -table{width:100%;border-collapse:collapse;font-size:13.5px} -th{text-align:left;padding:12px 16px;background:#f8fafc;color:#94a3b8;font-size:11px;text-transform:uppercase;letter-spacing:.06em;font-weight:700;white-space:nowrap;border-bottom:1px solid #e2e8f0} -td{padding:14px 16px;border-bottom:1px solid #f1f5f9;vertical-align:middle} -tr:last-child td{border-bottom:none} -tr:hover{background:#fafbfd} -.user-info{display:flex;flex-direction:column;gap:2px} -.user-name{font-weight:600;color:#1e293b} -.user-email{font-size:12px;color:#94a3b8} - -/* ── Badges ── */ -.badge{display:inline-flex;align-items:center;gap:4px;font-size:11px;padding:3px 10px;border-radius:20px;font-weight:600} -.badge-admin{background:#dbeafe;color:#1d4ed8} -.badge-user{background:#f1f5f9;color:#64748b} -.badge-active{background:#d1fae5;color:#065f46} -.badge-inactive{background:#fee2e2;color:#991b1b} -.badge-oidc{background:#ede9fe;color:#6d28d9} -.badge-env{background:#fef3c7;color:#92400e;font-size:10px;padding:1px 6px;margin-left:4px} - -/* ── Buttons ── */ -.btn{ - padding:8px 18px;border:none;border-radius:10px;font-size:13px;font-weight:600; - cursor:pointer;transition:all .15s;white-space:nowrap;display:inline-flex;align-items:center;gap:6px; -} -.btn-sm{padding:6px 12px;font-size:12px;border-radius:8px} -.btn-primary{background:linear-gradient(135deg,#ff5e3a,#ff2d55);color:#fff;box-shadow:0 2px 8px rgba(255,94,58,.25)} -.btn-primary:hover{box-shadow:0 4px 14px rgba(255,94,58,.35);transform:translateY(-1px)} -.btn-secondary{background:#fff;color:#334155;border:1px solid #e2e8f0} -.btn-secondary:hover{background:#f8fafc;border-color:#cbd5e1} -.btn-danger{background:#fef2f2;color:#991b1b;border:1px solid #fecaca} -.btn-danger:hover{background:#fee2e2} -.btn-success{background:#ecfdf5;color:#065f46;border:1px solid #a7f3d0} -.btn-success:hover{background:#d1fae5} -.btn:disabled{opacity:.4;cursor:not-allowed;transform:none!important} -.actions-row{display:flex;gap:6px;flex-wrap:wrap} - -/* ── Forms ── */ -.form-group{margin-bottom:16px} -.form-group label{display:block;font-size:13px;font-weight:600;margin-bottom:4px;color:#334155} -.form-group input[type="text"],.form-group input[type="password"],.form-group input[type="url"],.form-group input[type="number"],.form-group select{ - width:100%;padding:10px 14px;border:2px solid #e2e8f0;border-radius:10px;font-size:14px; - background:#f8fafc;transition:all .2s;font-family:inherit;color:#1e293b; -} -.form-group input:focus,.form-group select:focus{outline:none;border-color:#ff5e3a;background:#fff;box-shadow:0 0 0 3px rgba(255,94,58,.1)} -.form-group small{color:#94a3b8;font-size:12px;display:block;margin-top:3px} - -.toggle-row{display:flex;align-items:center;justify-content:space-between;padding:10px 0} -.toggle-row label{font-size:14px;font-weight:500;color:#334155} -.switch{position:relative;width:44px;height:24px;flex-shrink:0} -.switch input{opacity:0;width:0;height:0} -.slider{position:absolute;cursor:pointer;inset:0;background:#d1d5db;border-radius:24px;transition:.3s} -.slider:before{content:"";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background:#fff;border-radius:50%;transition:.3s;box-shadow:0 1px 3px rgba(0,0,0,.15)} -.switch input:checked+.slider{background:linear-gradient(135deg,#ff5e3a,#ff2d55)} -.switch input:checked+.slider:before{transform:translateX(20px)} - -.readonly-field{ - display:flex;align-items:center;gap:8px;background:#f8fafc;border:2px solid #e2e8f0;border-radius:10px; - padding:10px 14px;font-family:'SF Mono',Monaco,Consolas,monospace;font-size:13px;word-break:break-all;color:#334155; -} -.readonly-field button{ - flex-shrink:0;padding:6px 10px;border:1px solid #e2e8f0;border-radius:8px;background:#fff;cursor:pointer; - font-size:12px;transition:all .15s;color:#64748b; -} -.readonly-field button:hover{background:#f1f5f9;color:#334155} - -/* ── Alerts ── */ -.alert{padding:12px 16px;border-radius:10px;font-size:13px;margin-top:14px;display:none;font-weight:500} -.alert-success{background:#ecfdf5;color:#065f46;border:1px solid #a7f3d0;display:block} -.alert-error{background:#fef2f2;color:#991b1b;border:1px solid #fecaca;display:block} -.alert-info{background:#eff6ff;color:#1e40af;border:1px solid #bfdbfe;display:block} -.warning{background:#fffbeb;border:1px solid #fde68a;border-radius:10px;padding:10px 14px;font-size:13px;color:#92400e;margin-top:8px;display:flex;align-items:center;gap:6px;font-weight:500} - -/* ── Discovery ── */ -.discovery-result{margin:12px 0;padding:14px;border-radius:10px;font-size:13px} -.discovery-result.ok{background:#ecfdf5;border:1px solid #a7f3d0;color:#065f46} -.discovery-result.fail{background:#fef2f2;border:1px solid #fecaca;color:#991b1b} -.discovery-result dt{font-weight:700;margin-top:6px} -.discovery-result dd{margin-left:0;word-break:break-all} - -/* ── Details ── */ -details{margin-top:14px;border-top:1px solid #e2e8f0;padding-top:12px} -details summary{cursor:pointer;font-weight:600;font-size:14px;color:#64748b;padding:6px 0;user-select:none;transition:color .2s} -details summary:hover{color:#ff5e3a} -details[open] summary{margin-bottom:14px;color:#ff5e3a} - -/* ── Modal ── */ -.modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.45);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;z-index:1000} -.modal{background:#fff;border-radius:20px;padding:28px;width:420px;max-width:90vw;box-shadow:0 20px 60px rgba(0,0,0,.2);animation:modalIn .2s ease-out} -@keyframes modalIn{from{opacity:0;transform:scale(.95) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}} -.modal h3{margin-bottom:18px;font-size:17px;color:#1e293b;display:flex;align-items:center} -.modal-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:18px} - -/* ── Quota bar inline ── */ -.quota-bar{display:flex;align-items:center;gap:10px} -.quota-bar .progress-bar{flex:1;height:6px} -.quota-text{font-size:12px;color:#94a3b8;white-space:nowrap} - -/* ── Access / Loading ── */ -#access-denied{display:none;text-align:center;padding:80px 20px} -#access-denied .access-icon{width:80px;height:80px;background:#fef2f2;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 20px} -#access-denied .access-icon i{font-size:32px;color:#ef4444} -#access-denied h2{color:#991b1b;margin-bottom:8px;font-size:20px} -#access-denied p{color:#64748b;margin-bottom:20px;font-size:14px} -#access-denied a{display:inline-flex;align-items:center;gap:6px;padding:10px 24px;background:linear-gradient(135deg,#ff5e3a,#ff2d55);color:#fff;text-decoration:none;border-radius:10px;font-weight:600;font-size:14px;box-shadow:0 3px 12px rgba(255,94,58,.3);transition:all .2s} -#access-denied a:hover{transform:translateY(-1px);box-shadow:0 5px 18px rgba(255,94,58,.4)} -#loading{text-align:center;padding:80px;color:#94a3b8;font-size:15px} -#loading i{font-size:32px;color:#ff5e3a;display:block;margin-bottom:12px;animation:spin 1s linear infinite} -@keyframes spin{to{transform:rotate(360deg)}} - -/* ── Pagination ── */ -.pagination{display:flex;align-items:center;justify-content:space-between;margin-top:14px;font-size:13px;color:#94a3b8;padding:0 4px} -.pagination button{padding:6px 14px} - -/* ── Dark Mode ── */ -[data-theme="dark"] body{background:#0f172a;color:#e2e8f0} -[data-theme="dark"] ::-webkit-scrollbar-thumb{background:rgba(255,255,255,.15)} -[data-theme="dark"] *{scrollbar-color:rgba(255,255,255,.15) transparent} -[data-theme="dark"] .admin-tabs{background:#1e293b;box-shadow:0 1px 4px rgba(0,0,0,.2)} -[data-theme="dark"] .admin-tab{color:#94a3b8} -[data-theme="dark"] .admin-tab:hover{color:#f1f5f9;background:#162032} -[data-theme="dark"] .admin-card{background:#1e293b;box-shadow:0 1px 4px rgba(0,0,0,.2),0 0 0 1px rgba(255,255,255,.03)} -[data-theme="dark"] .admin-card h2{color:#f1f5f9} -[data-theme="dark"] .stat-card{background:#162032;border-color:#334155} -[data-theme="dark"] .stat-card:hover{box-shadow:0 4px 12px rgba(0,0,0,.15)} -[data-theme="dark"] .stat-value{color:#f1f5f9} -[data-theme="dark"] .stat-label{color:#64748b} -[data-theme="dark"] .stat-card.warn{border-color:#92400e;background:#422006} -[data-theme="dark"] .stat-card.danger{border-color:#991b1b;background:#3b1111} -[data-theme="dark"] .progress-bar{background:#334155} -[data-theme="dark"] .table-wrap{border-color:#334155} -[data-theme="dark"] th{background:#162032;color:#64748b;border-bottom-color:#334155} -[data-theme="dark"] td{border-bottom-color:#334155;color:#e2e8f0} -[data-theme="dark"] tr:hover{background:#162032} -[data-theme="dark"] .user-name{color:#f1f5f9} -[data-theme="dark"] .user-email{color:#64748b} -[data-theme="dark"] .badge-admin{background:#1e3a5f;color:#60a5fa} -[data-theme="dark"] .badge-user{background:#334155;color:#94a3b8} -[data-theme="dark"] .badge-active{background:#052e16;color:#86efac} -[data-theme="dark"] .badge-inactive{background:#3b1111;color:#fca5a5} -[data-theme="dark"] .badge-oidc{background:#2e1065;color:#c4b5fd} -[data-theme="dark"] .btn-secondary{background:#1e293b;color:#e2e8f0;border-color:#334155} -[data-theme="dark"] .btn-secondary:hover{background:#334155;border-color:#475569} -[data-theme="dark"] .btn-danger{background:#3b1111;color:#fca5a5;border-color:#991b1b} -[data-theme="dark"] .btn-danger:hover{background:#4a1515} -[data-theme="dark"] .btn-success{background:#052e16;color:#86efac;border-color:#065f46} -[data-theme="dark"] .btn-success:hover{background:#064e27} -[data-theme="dark"] .form-group label{color:#94a3b8} -[data-theme="dark"] .form-group input[type="text"], -[data-theme="dark"] .form-group input[type="password"], -[data-theme="dark"] .form-group input[type="url"], -[data-theme="dark"] .form-group input[type="number"], -[data-theme="dark"] .form-group select{background:#0f172a;border-color:#334155;color:#e2e8f0} -[data-theme="dark"] .form-group input:focus, -[data-theme="dark"] .form-group select:focus{border-color:#ff5e3a;background:#0f172a;box-shadow:0 0 0 3px rgba(255,94,58,.15)} -[data-theme="dark"] .form-group small{color:#64748b} -[data-theme="dark"] .toggle-row label{color:#94a3b8} -[data-theme="dark"] .slider{background:#475569} -[data-theme="dark"] .readonly-field{background:#0f172a;border-color:#334155;color:#e2e8f0} -[data-theme="dark"] .readonly-field button{background:#1e293b;border-color:#334155;color:#94a3b8} -[data-theme="dark"] .readonly-field button:hover{background:#334155;color:#f1f5f9} -[data-theme="dark"] .warning{background:#422006;border-color:#92400e;color:#fbbf24} -[data-theme="dark"] .alert-success{background:#052e16;color:#86efac;border-color:#065f46} -[data-theme="dark"] .alert-error{background:#3b1111;color:#fca5a5;border-color:#991b1b} -[data-theme="dark"] .alert-info{background:#0c2d48;color:#93c5fd;border-color:#1d4ed8} -[data-theme="dark"] .discovery-result.ok{background:#052e16;border-color:#065f46;color:#86efac} -[data-theme="dark"] .discovery-result.fail{background:#3b1111;border-color:#991b1b;color:#fca5a5} -[data-theme="dark"] details{border-top-color:#334155} -[data-theme="dark"] details summary{color:#94a3b8} -[data-theme="dark"] details summary:hover{color:#ff5e3a} -[data-theme="dark"] details[open] summary{color:#ff5e3a} -[data-theme="dark"] .modal{background:#1e293b;box-shadow:0 20px 60px rgba(0,0,0,.4)} -[data-theme="dark"] .modal h3{color:#f1f5f9} -[data-theme="dark"] .modal-overlay{background:rgba(0,0,0,.6);backdrop-filter:blur(4px)} -[data-theme="dark"] .quota-text{color:#64748b} -[data-theme="dark"] .pagination{color:#64748b} -[data-theme="dark"] #access-denied h2{color:#fca5a5} -[data-theme="dark"] #access-denied p{color:#94a3b8} -[data-theme="dark"] #access-denied .access-icon{background:#3b1111} -[data-theme="dark"] #loading{color:#64748b} -[data-theme="dark"] .toggle-row{border-top-color:#334155} +@import url("./views/admin.css"); diff --git a/static/css/auth.css b/static/css/auth.css index 4f406106..3245a760 100644 --- a/static/css/auth.css +++ b/static/css/auth.css @@ -1,585 +1 @@ -/* Auth styles for OxiCloud */ -.auth-container { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: 100vh; - width: 100%; - background-color: #f5f7fa; -} - -.auth-panel { - width: 400px; - max-width: 90%; - margin: 0 auto; - background-color: white; - border-radius: 10px; - box-shadow: 0 5px 20px rgba(0,0,0,0.1); - padding: 30px; - text-align: center; -} - -.auth-logo { - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 20px; -} - -.auth-logo-icon { - width: 50px; - height: 50px; - background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); - border-radius: 12px; - display: flex; - align-items: center; - justify-content: center; - margin-right: 10px; - box-shadow: 0 4px 12px rgba(255, 94, 58, 0.3); -} - -.auth-logo-icon svg { - width: 30px; - height: 30px; - fill: white; -} - -.auth-logo-text { - font-size: 24px; - font-weight: bold; - color: #2a3042; -} - -.auth-title { - font-size: 20px; - font-weight: bold; - margin-bottom: 25px; - color: #2a3042; -} - -.auth-form { - width: 100%; - text-align: left; - - [dir='rtl'] & { - text-align: right; - } -} - -.auth-input-group { - margin-bottom: 20px; -} - -.auth-label { - display: block; - margin-bottom: 8px; - font-size: 14px; - color: #4b5563; - font-weight: 500; -} - -.auth-input { - width: 100%; - padding: 12px 15px; - border-radius: 8px; - border: 1px solid #e2e8f0; - font-size: 14px; - background-color: #f9fafb; - transition: border-color 0.2s; -} - -.auth-input:focus { - outline: none; - border-color: #ff5e3a; - box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); -} - -.auth-button { - width: 100%; - padding: 12px 15px; - border-radius: 10px; - background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); - color: white; - font-weight: bold; - border: none; - cursor: pointer; - font-size: 16px; - transition: all 0.3s ease; - margin-top: 10px; - box-shadow: 0 4px 12px rgba(255, 94, 58, 0.3); -} - -.auth-button:hover { - transform: translateY(-1px); - box-shadow: 0 6px 20px rgba(255, 94, 58, 0.4); - filter: brightness(1.05); -} - -.auth-button:active { - transform: translateY(0); - box-shadow: 0 2px 8px rgba(255, 94, 58, 0.3); -} - -.auth-button:disabled { - background-color: #f9a799; - cursor: not-allowed; -} - -/* SSO / OIDC button */ -.auth-button-oidc { - background: linear-gradient(135deg, #2d3748 0%, #4a5568 100%); - box-shadow: 0 4px 12px rgba(45, 55, 72, 0.3); - display: flex; - align-items: center; - justify-content: center; - gap: 10px; -} - -.auth-button-oidc:hover { - box-shadow: 0 6px 20px rgba(45, 55, 72, 0.4); -} - -.auth-button-oidc i { - font-size: 14px; -} - -/* Divider between password and SSO login */ -.auth-divider { - display: flex; - align-items: center; - margin: 20px 0; - color: #a0aec0; - font-size: 13px; -} - -.auth-divider::before, -.auth-divider::after { - content: ''; - flex: 1; - height: 1px; - background: #e2e8f0; -} - -.auth-divider span { - padding: 0 12px; -} - -/* OIDC-only mode: hide password form */ -.auth-form.hidden { - display: none; -} - -.auth-toggle { - margin-top: 20px; - font-size: 14px; - color: #718096; -} - -.auth-toggle-link { - color: #ff5e3a; - cursor: pointer; - text-decoration: none; - font-weight: 500; -} - -.auth-toggle-link:hover { - text-decoration: underline; -} - -.auth-error { - background-color: #fee2e2; - color: #b91c1c; - padding: 10px 15px; - border-radius: 8px; - margin-bottom: 20px; - font-size: 14px; - display: none; -} - -.auth-success { - background-color: #dcfce7; - color: #15803d; - padding: 10px 15px; - border-radius: 8px; - margin-bottom: 20px; - font-size: 14px; - display: none; -} - -/* Admin setup panel styles */ -.admin-setup-panel { - display: none; -} - -.setup-steps { - margin-bottom: 25px; - display: flex; - justify-content: space-between; -} - -.setup-step { - display: flex; - flex-direction: column; - align-items: center; - width: 30%; -} - -.step-number { - width: 30px; - height: 30px; - background-color: #e2e8f0; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - color: #64748b; - font-weight: bold; - margin-bottom: 5px; -} - -.step-number.active { - background-color: #ff5e3a; - color: white; -} - -.step-title { - font-size: 12px; - color: #64748b; -} - -.step-title.active { - color: #1e293b; - font-weight: 500; -} - -/* Language selector panel styles */ -.language-selector-panel { - text-align: center; -} - -.language-subtitle { - color: #64748b; - font-size: 16px; - margin-bottom: 24px; -} - -/* ====== Compact Language Picker ====== */ -.lang-picker { - position: relative; - margin-bottom: 24px; - text-align: left; -} - -.lang-picker-selected { - display: flex; - align-items: center; - padding: 14px 18px; - border: 2px solid #e2e8f0; - border-radius: 12px; - cursor: pointer; - background-color: #f9fafb; - transition: all 0.2s ease; - user-select: none; -} - -.lang-picker-selected:hover { - border-color: #ff5e3a; - background-color: #fff; -} - -.lang-picker.open .lang-picker-selected { - border-color: #ff5e3a; - background-color: #fff; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); -} - -.lang-picker-flag { - font-size: 26px; - margin-right: 14px; - flex-shrink: 0; -} - -.lang-picker-name { - font-size: 16px; - font-weight: 600; - color: #1e293b; - flex: 1; -} - -.lang-picker-arrow { - color: #94a3b8; - font-size: 13px; - transition: transform 0.2s ease; - flex-shrink: 0; -} - -.lang-picker.open .lang-picker-arrow { - transform: rotate(180deg); -} - -/* Dropdown */ -.lang-picker-dropdown { - display: none; - position: absolute; - top: 100%; - left: 0; - right: 0; - background: #fff; - border: 2px solid #ff5e3a; - border-top: 1px solid #f1f5f9; - border-bottom-left-radius: 12px; - border-bottom-right-radius: 12px; - box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12); - z-index: 100; - overflow: hidden; -} - -.lang-picker.open .lang-picker-dropdown { - display: block; - animation: langPickerSlideDown 0.2s ease; -} - -@keyframes langPickerSlideDown { - from { opacity: 0; transform: translateY(-4px); } - to { opacity: 1; transform: translateY(0); } -} - -/* Search inside dropdown */ -.lang-picker-search { - position: relative; - padding: 10px 14px; - border-bottom: 1px solid #f1f5f9; -} - -.lang-picker-search i { - position: absolute; - left: 26px; - top: 50%; - transform: translateY(-50%); - color: #94a3b8; - font-size: 13px; -} - -.lang-picker-search input { - width: 100%; - padding: 8px 12px 8px 32px; - border: 1px solid #e2e8f0; - border-radius: 8px; - font-size: 14px; - outline: none; - box-sizing: border-box; - transition: border-color 0.2s; -} - -.lang-picker-search input:focus { - border-color: #ff5e3a; -} - -/* Scrollable list */ -.lang-picker-list { - max-height: 240px; - overflow-y: auto; - padding: 6px; -} - -.lang-picker-list::-webkit-scrollbar { - width: 6px; -} - -.lang-picker-list::-webkit-scrollbar-track { - background: transparent; -} - -.lang-picker-list::-webkit-scrollbar-thumb { - background: #cbd5e1; - border-radius: 3px; -} - -.lang-picker-list::-webkit-scrollbar-thumb:hover { - background: #94a3b8; -} - -/* Language item in dropdown */ -.lang-picker-item { - display: flex; - align-items: center; - gap: 10px; - padding: 10px 12px; - border-radius: 8px; - cursor: pointer; - transition: all 0.12s ease; -} - -.lang-picker-item:hover { - background: #f8fafc; -} - -.lang-picker-item.selected { - background: #fff5f3; -} - -.lang-picker-item-flag { - font-size: 22px; - flex-shrink: 0; -} - -.lang-picker-item-name { - font-size: 15px; - font-weight: 500; - color: #1e293b; -} - -.lang-picker-item-english { - font-size: 13px; - color: #94a3b8; - margin-left: auto; -} - -.lang-picker-item-check { - color: #ff5e3a; - font-size: 13px; - flex-shrink: 0; -} - -.lang-picker-empty { - text-align: center; - color: #94a3b8; - padding: 20px; - font-size: 14px; -} - -@media (max-width: 480px) { - .auth-panel { - width: 90%; - padding: 20px; - } - - .lang-picker-selected { - padding: 12px 14px; - } - - .lang-picker-list { - max-height: 200px; - } -} - -/* ============================================================ - DARK MODE — Auth Pages - ============================================================ */ -[data-theme="dark"] .auth-container { - background-color: #0f172a; -} -[data-theme="dark"] .auth-panel { - background-color: #1e293b; - box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3); -} -[data-theme="dark"] .auth-logo-text { - color: #f1f5f9; -} -[data-theme="dark"] .auth-title { - color: #f1f5f9; -} -[data-theme="dark"] .auth-label { - color: #94a3b8; -} -[data-theme="dark"] .auth-input { - background-color: #0f172a; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .auth-input:focus { - border-color: #ff5e3a; - background-color: #0f172a; - box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.15); -} -[data-theme="dark"] .auth-input::placeholder { - color: #64748b; -} -[data-theme="dark"] .auth-error { - background-color: #3b1111; - color: #fca5a5; -} -[data-theme="dark"] .auth-success { - background-color: #052e16; - color: #86efac; -} -[data-theme="dark"] .auth-toggle { - color: #94a3b8; -} -[data-theme="dark"] .auth-divider { - color: #64748b; -} -[data-theme="dark"] .auth-divider::before, -[data-theme="dark"] .auth-divider::after { - background: #334155; -} -[data-theme="dark"] .language-subtitle { - color: #94a3b8; -} -[data-theme="dark"] .lang-picker-selected { - background-color: #0f172a; - border-color: #334155; -} -[data-theme="dark"] .lang-picker-selected:hover { - border-color: #ff5e3a; - background-color: #162032; -} -[data-theme="dark"] .lang-picker.open .lang-picker-selected { - border-color: #ff5e3a; - background-color: #162032; -} -[data-theme="dark"] .lang-picker-name { - color: #f1f5f9; -} -[data-theme="dark"] .lang-picker-arrow { - color: #64748b; -} -[data-theme="dark"] .lang-picker-dropdown { - background: #1e293b; - border-color: #ff5e3a; - border-top-color: #334155; - box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3); -} -[data-theme="dark"] .lang-picker-search { - border-bottom-color: #334155; -} -[data-theme="dark"] .lang-picker-search input { - background-color: #0f172a; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .lang-picker-search input:focus { - border-color: #ff5e3a; -} -[data-theme="dark"] .lang-picker-search input::placeholder { - color: #64748b; -} -[data-theme="dark"] .lang-picker-list::-webkit-scrollbar-thumb { - background: #475569; -} -[data-theme="dark"] .lang-picker-item:hover { - background: #162032; -} -[data-theme="dark"] .lang-picker-item.selected { - background: #2a1a15; -} -[data-theme="dark"] .lang-picker-item-name { - color: #f1f5f9; -} -[data-theme="dark"] .lang-picker-item-english { - color: #64748b; -} -[data-theme="dark"] .lang-picker-empty { - color: #64748b; -} -/* Setup steps */ -[data-theme="dark"] .step-number { - background-color: #334155; - color: #94a3b8; -} -[data-theme="dark"] .step-title { - color: #94a3b8; -} +@import url("./views/auth.css"); diff --git a/static/css/base/forms.css b/static/css/base/forms.css new file mode 100644 index 00000000..a9a67712 --- /dev/null +++ b/static/css/base/forms.css @@ -0,0 +1,60 @@ +.form-group { + margin-bottom: 15px; +} + +.form-group label { + 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; +} + +.form-group textarea { + resize: vertical; + min-height: 80px; +} + +.button { + padding: 8px 16px; + border: none; + border-radius: 6px; + cursor: pointer; + font-size: 14px; + transition: background-color 0.2s; +} + +.primary { + background-color: #ff5e3a; + color: white; +} + +.primary:hover { + background-color: #e64a29; +} + +.secondary { + background-color: #e2e8f0; + color: #4a5568; +} + +.secondary:hover { + background-color: #cbd5e0; +} + +.danger { + background-color: #f56565; + color: white; +} + +.danger:hover { + background-color: #e53e3e; +} diff --git a/static/css/base/reset.css b/static/css/base/reset.css new file mode 100644 index 00000000..56125332 --- /dev/null +++ b/static/css/base/reset.css @@ -0,0 +1,22 @@ +* { + 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; +} + +html[dir='rtl'] .fa-arrow-left::before { + content: "\f061"; +} + +html[dir='rtl'] .fa-sign-out-alt { + -webkit-transform: rotate(180deg); + transform: rotate(180deg); +} diff --git a/static/css/base/variables.css b/static/css/base/variables.css new file mode 100644 index 00000000..341516b4 --- /dev/null +++ b/static/css/base/variables.css @@ -0,0 +1,9 @@ +:root { + --color-bg-page: #f5f7fa; + --color-bg-surface: #ffffff; + --color-border: #e2e8f0; + --color-text: #2d3748; + --color-text-muted: #718096; + --color-accent: #ff5e3a; + --color-accent-hover: #e04520; +} diff --git a/static/css/components/breadcrumb.css b/static/css/components/breadcrumb.css new file mode 100644 index 00000000..8c4304a7 --- /dev/null +++ b/static/css/components/breadcrumb.css @@ -0,0 +1,40 @@ +/* Breadcrumb */ +.breadcrumb { + 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; + transition: background 0.15s, color 0.15s; +} + +.breadcrumb-link { + cursor: pointer; + color: #5a6f8a; +} + +.breadcrumb-link:hover { + text-decoration: underline; + color: #ff5e3a; + background: rgba(255, 94, 58, 0.06); +} + +.breadcrumb-current { + font-weight: 600; + color: #333; + cursor: default; +} + +.breadcrumb-separator { + margin: 0 4px; + color: #adb5bd; + font-size: 12px; + user-select: none; +} diff --git a/static/css/components/buttons.css b/static/css/components/buttons.css new file mode 100644 index 00000000..e7c1308e --- /dev/null +++ b/static/css/components/buttons.css @@ -0,0 +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; +} + +.btn i { + 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); +} + +.btn-primary:hover { + 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); +} + +.btn-secondary { + 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); +} + +.btn-secondary:active { + 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); +} + +.btn-danger:hover { + 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); +} + +/* View Toggle Buttons */ +.view-toggle { + display: flex; + gap: 6px; + padding: 4px; + background-color: #f0f3f7; + border-radius: 12px; + border: 1px solid #e2e8f0; +} + +.toggle-btn { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 36px; + background-color: transparent; + border: none; + border-radius: 8px; + cursor: pointer; + color: #64748b; + font-size: 16px; + transition: all 0.2s ease; +} + +.toggle-btn:hover { + background-color: #e2e8f0; + color: #4a5568; +} + +.toggle-btn.active { + background-color: white; + color: #ff5e3a; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); +} + +.toggle-btn i { + pointer-events: none; +} diff --git a/static/css/components/cards.css b/static/css/components/cards.css new file mode 100644 index 00000000..681d1acd --- /dev/null +++ b/static/css/components/cards.css @@ -0,0 +1,785 @@ +/* Files grid */ +.files-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 240px)); + gap: 20px; + justify-content: start; + position: relative; +} + +/* 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; +} + +.file-card { + 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; + transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s; + width: 100%; + min-height: 160px; + position: relative; +} + +.file-card:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(0,0,0,0.08); + border-color: #cbd5e0; +} + +.file-card.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); +} + +.file-card.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); +} + +/* Selection checkbox */ +.file-card-checkbox { + position: absolute; + top: 10px; + left: 10px; + width: 22px; + height: 22px; + border-radius: 6px; + border: 2px solid #cbd5e0; + background: white; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 0.15s, background 0.15s, border-color 0.15s; + z-index: 10; + cursor: pointer; +} + +.file-card:hover .file-card-checkbox { + opacity: 1; +} + +.file-card.selected .file-card-checkbox { + opacity: 1; + background: #ff5e3a; + border-color: #ff5e3a; +} + +.file-card.selected .file-card-checkbox i { + color: white; + font-size: 11px; +} + +/* More actions button (three dots) */ +.file-card-more { + 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; + transition: opacity 0.15s, background 0.15s; + z-index: 10; + cursor: pointer; + color: #64748b; + font-size: 16px; +} + +.file-card:hover .file-card-more { + opacity: 1; +} + +.file-card-more:hover { + background: #f1f5f9; + color: #334155; +} + +/* Favorite star (mirrors file-card-more button pattern) */ +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; + transition: opacity 0.15s, color 0.15s, background 0.15s; + z-index: 12; + cursor: pointer; + color: #cbd5e0; + font-size: 15px; + padding: 0; + line-height: 1; +} + +.file-card:hover .favorite-star { + opacity: 1; +} + +.favorite-star:hover { + color: #fbbf24; +} + +.favorite-star.active { + opacity: 1; + color: #f59e0b; +} + +.favorite-star.active:hover { + color: #d97706; +} + +.file-card.dragging { + opacity: 0.5; + transform: scale(0.95); + box-shadow: none; +} + +.file-card.drop-target { + background-color: rgba(255, 193, 7, 0.1); + border: 2px dashed #ffc107; +} + +/* Hide FontAwesome / SVG icons inside grid card thumbnails — the decorative + CSS shapes (::before / ::after) already convey the file type visually. + Icons.js replaces with , so we target both. + List-view icons (.file-item .file-icon) are NOT affected. */ +.file-card .file-icon > i, +.file-card .file-icon > svg { + 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; +} + +.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; +} + +.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; +} + +.file-icon.pdf-icon::after { + 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; +} + +.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; +} + +.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; +} + +.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; +} + +.file-icon.script-icon::after { + 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; +} + +.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; +} + +.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; +} + +.file-icon.image-icon { + width: 100px; + height: 70px; + background-color: #74b9ff; + border-radius: 4px; + position: relative; + margin-bottom: 10px; + overflow: hidden; +} + +.file-icon.image-icon::before { + content: ""; + position: absolute; + top: 10px; + left: 15px; + width: 20px; + height: 20px; + background-color: #ffda79; + border-radius: 50%; +} + +.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); +} + +.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); +} + +.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; +} + +.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; +} + +.file-icon.code-icon::before, +.file-icon.code-icon::after { + content: ""; + position: absolute; + left: 10px; + right: 10px; + height: 2px; + background-color: #556ee6; +} + +.file-icon.code-icon::before { + top: 15px; + width: 80%; +} + +.file-icon.code-icon::after { + 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; +} + +.file-icon.code-icon .code-line-1 { + top: 35px; + width: 70%; +} + +.file-icon.code-icon .code-line-2 { + top: 45px; + width: 85%; +} + +.file-icon.code-icon .code-line-3 { + top: 55px; + width: 50%; +} + +.file-icon.json-icon { + border-top-color: #ffb86c; +} + +.file-icon.json-icon::before, +.file-icon.json-icon::after { + background-color: #ffb86c; +} + +.file-icon.js-icon { + border-top-color: #ffd43b; +} + +.file-icon.js-icon::before, +.file-icon.js-icon::after { + background-color: #ffd43b; +} + +.file-icon.html-icon { + border-top-color: #e34c26; +} + +.file-icon.html-icon::before, +.file-icon.html-icon::after { + background-color: #e34c26; +} + +.file-icon.css-icon { + border-top-color: #2965f1; +} + +.file-icon.css-icon::before, +.file-icon.css-icon::after { + background-color: #2965f1; +} + +.file-icon.py-icon { + border-top-color: #3776ab; +} + +.file-icon.py-icon::before, +.file-icon.py-icon::after { + background-color: #3776ab; +} + +.file-icon.ts-icon { + border-top-color: #3178c6; +} + +.file-icon.ts-icon::before, +.file-icon.ts-icon::after { + background-color: #3178c6; +} + +.file-icon.rust-icon { + border-top-color: #dea584; +} + +.file-icon.rust-icon::before, +.file-icon.rust-icon::after { + background-color: #dea584; +} + +.file-icon.go-icon { + border-top-color: #00add8; +} + +.file-icon.go-icon::before, +.file-icon.go-icon::after { + background-color: #00add8; +} + +.file-icon.java-icon { + border-top-color: #e76f00; +} + +.file-icon.java-icon::before, +.file-icon.java-icon::after { + background-color: #e76f00; +} + +.file-icon.c-icon { + border-top-color: #555; +} + +.file-icon.c-icon::before, +.file-icon.c-icon::after { + background-color: #555; +} + +.file-icon.cs-icon { + border-top-color: #68217a; +} + +.file-icon.cs-icon::before, +.file-icon.cs-icon::after { + background-color: #68217a; +} + +.file-icon.php-icon { + border-top-color: #8892be; +} + +.file-icon.php-icon::before, +.file-icon.php-icon::after { + background-color: #8892be; +} + +.file-icon.ruby-icon { + border-top-color: #cc342d; +} + +.file-icon.ruby-icon::before, +.file-icon.ruby-icon::after { + background-color: #cc342d; +} + +.file-icon.swift-icon { + border-top-color: #fa7343; +} + +.file-icon.swift-icon::before, +.file-icon.swift-icon::after { + background-color: #fa7343; +} + +.file-icon.kotlin-icon { + border-top-color: #7f52ff; +} + +.file-icon.kotlin-icon::before, +.file-icon.kotlin-icon::after { + background-color: #7f52ff; +} + +.file-icon.sql-icon { + border-top-color: #e38c00; +} + +.file-icon.sql-icon::before, +.file-icon.sql-icon::after { + background-color: #e38c00; +} + +.file-icon.yaml-icon { + border-top-color: #cb171e; +} + +.file-icon.yaml-icon::before, +.file-icon.yaml-icon::after { + background-color: #cb171e; +} + +.file-icon.toml-icon { + border-top-color: #9c4221; +} + +.file-icon.toml-icon::before, +.file-icon.toml-icon::after { + background-color: #9c4221; +} + +.file-icon.md-icon { + border-top-color: #083fa1; +} + +.file-icon.md-icon::before, +.file-icon.md-icon::after { + 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; +} + +.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; +} + +.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; +} + +.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; +} + +.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; +} + +.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; +} + +.file-icon.audio-icon::before { + 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; +} + +.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; +} + +.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; +} + +.file-icon.installer-icon::before { + content: "⬇"; + font-size: 24px; + color: #7c3aed; + opacity: 0.5; +} + +.file-name { + 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; +} + +.file-info { + font-size: 12px; + color: #718096; + text-align: center; +} + +[data-theme="dark"] .file-card { + background-color: #1e293b; + border-color: #334155; +} + +[data-theme="dark"] .file-card:hover { + border-color: #475569; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +[data-theme="dark"] .file-card.selected { + border-color: #ff5e3a; + background: #1a1520; +} + +[data-theme="dark"] .file-card-checkbox { + background: #1e293b; + border-color: #475569; +} + +[data-theme="dark"] .file-card-more { + color: #94a3b8; +} + +[data-theme="dark"] .file-card-more:hover { + background: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] .file-name { + color: #e2e8f0; +} + +[data-theme="dark"] .file-info { + color: #94a3b8; +} + +[data-theme="dark"] .file-card.drop-target { + background-color: rgba(255, 193, 7, 0.05); +} diff --git a/static/css/components/contextMenu.css b/static/css/components/contextMenu.css new file mode 100644 index 00000000..fb1d598c --- /dev/null +++ b/static/css/components/contextMenu.css @@ -0,0 +1,74 @@ +/* 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; +} + +@keyframes contextMenuIn { + 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; +} + +.context-menu-item:hover { + background: #f1f5f9; +} + +.context-menu-item:active { + background: #e2e8f0; +} + +.context-menu-item i { + width: 18px; + text-align: center; + font-size: 14px; + color: #64748b; + + [dir='rtl'] & { + margin-left: 0; + margin-right: 0; + } +} + +.context-menu-item-danger { + color: #ef4444; +} + +.context-menu-item-danger:hover { + background: #fef2f2; +} + +.context-menu-item-danger i { + color: #ef4444; +} + +.context-menu-separator { + height: 1px; + background: #f1f5f9; + margin: 4px 8px; +} diff --git a/static/css/components/dialogs.css b/static/css/components/dialogs.css new file mode 100644 index 00000000..2b89e032 --- /dev/null +++ b/static/css/components/dialogs.css @@ -0,0 +1,749 @@ +/* Dialog animations */ +@keyframes modalFadeIn { + 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; } +} + +/* 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; +} + +.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; +} + +.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; +} + +.rename-dialog-body { + 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; +} + +.rename-dialog input:focus { + 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; +} + +/* 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; +} + +.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; +} + +.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; +} + +.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; +} + +.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); +} + +.share-dialog-buttons { + 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; +} + +.share-options { + 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; +} + +#existing-shares-section, +#new-share-section { + padding: 0 24px; +} + +.share-dialog .form-group { + 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; +} + +.shared-dialog.active { + 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; +} + +.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; +} + +.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; +} + +.shared-dialog-header .close-dialog-btn:hover { + background: #f0f0f0; + color: #1a202c; +} + +.shared-dialog .share-link-section, +.shared-dialog .share-permissions-section, +.shared-dialog .share-password-section, +.shared-dialog .share-expiration-section, +.shared-dialog .notification-form { + 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; +} + +.shared-dialog .share-link-input { + 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; +} + +.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; +} + +.shared-dialog .password-input-group { + 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; +} + +.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; +} + +.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; +} + +.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; +} + +.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); +} + +.shared-dialog .notification-form .form-group { + padding: 0; + margin-bottom: 15px; +} + +/* 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; +} + +.folder-select-item:hover { + background-color: #f0f3f7; +} + +.folder-select-item.selected { + background-color: rgba(255,94,58,0.1); + color: #ff5e3a; + font-weight: 600; +} + +.folder-select-item i { + color: #ffa94d; + font-size: 16px; +} + +.folder-select-item.selected i { + color: #ff5e3a; +} + +/* 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; +} + +.confirm-dialog.active { + 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; +} + +.confirm-dialog-icon { + padding: 28px 24px 12px; +} + +.confirm-dialog-icon i { + font-size: 40px; + color: #f56565; +} + +.confirm-dialog-title { + 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; +} + +.confirm-dialog-buttons { + 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); +} + +.confirm-dialog-buttons .btn-danger:hover { + 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; +} + +.dialog.active { + 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; +} + +.dialog-header { + 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; +} + +.close-dialog-btn { + background: none; + border: none; + font-size: 24px; + cursor: pointer; + color: #a0aec0; +} + +.dialog-body { + padding: 20px; +} + +.share-item-info { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 20px; +} + +.share-link-container { + display: flex; + gap: 10px; +} + +.share-link-container input { + 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); +} + +[data-theme="dark"] .rename-dialog-header { + color: #f1f5f9; + border-bottom-color: #334155; +} + +[data-theme="dark"] .rename-dialog input { + background: #0f172a; + color: #e2e8f0; + border-color: #334155; +} + +[data-theme="dark"] .rename-dialog input:focus { + border-color: #ff5e3a; + background: #0f172a; +} + +[data-theme="dark"] .rename-dialog-buttons { + background: #162032; + border-top-color: #334155; +} + +[data-theme="dark"] .shared-dialog-content { + background-color: #1e293b; +} + +[data-theme="dark"] .shared-dialog-header { + color: #e2e8f0; + border-bottom-color: #334155; +} + +[data-theme="dark"] .shared-dialog-header .close-dialog-btn { + color: #94a3b8; +} + +[data-theme="dark"] .shared-dialog-header .close-dialog-btn:hover { + background: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] .shared-dialog .share-link-input input, +[data-theme="dark"] .shared-dialog .password-input-group input, +[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; +} + +[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; +} + +[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; +} + +[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; +} + +[data-theme="dark"] .shared-dialog .share-actions, +[data-theme="dark"] .shared-dialog .notification-actions { + 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); +} + +[data-theme="dark"] .confirm-dialog-header { + color: #f1f5f9; +} + +[data-theme="dark"] .confirm-dialog-message { + color: #94a3b8; +} + +[data-theme="dark"] .confirm-dialog-buttons { + background: #162032; + border-top-color: #334155; +} + +[data-theme="dark"] .move-dialog-content { + background-color: #1e293b; +} + +[data-theme="dark"] .move-dialog-header { + color: #f1f5f9; + border-bottom-color: #334155; +} + +[data-theme="dark"] .move-dialog .folder-tree { + background: #0f172a; + border-color: #334155; +} + +[data-theme="dark"] .move-dialog .folder-tree-item { + color: #cbd5e1; +} + +[data-theme="dark"] .move-dialog .folder-tree-item:hover { + background: #334155; +} + +[data-theme="dark"] .move-dialog .folder-tree-item.selected { + background: rgba(255, 94, 58, 0.1); + color: #ff5e3a; +} + +[data-theme="dark"] .move-dialog-buttons { + background: #162032; + border-top-color: #334155; +} + +[data-theme="dark"] .share-dialog-content { + background-color: #1e293b; +} + +[data-theme="dark"] .share-dialog-header { + color: #f1f5f9; + border-bottom-color: #334155; +} + +[data-theme="dark"] .share-dialog-body label { + color: #94a3b8; +} + +[data-theme="dark"] .share-dialog-body input { + background: #0f172a; + border-color: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] .share-dialog-body input:focus { + border-color: #ff5e3a; + background: #0f172a; +} + +[data-theme="dark"] .share-link-container { + background: #0f172a; + border-color: #334155; +} + +[data-theme="dark"] .share-link-container input { + color: #e2e8f0; +} + +[data-theme="dark"] .share-dialog-buttons { + background: #162032; + border-top-color: #334155; +} + +[data-theme="dark"] .dialog { + background-color: rgba(0, 0, 0, 0.6); +} + +[data-theme="dark"] .dialog-content { + background-color: #1e293b; + color: #e2e8f0; +} + +[data-theme="dark"] .dialog-header { + border-bottom-color: #334155; +} + +[data-theme="dark"] .dialog-header h3 { + color: #f1f5f9; +} + +[data-theme="dark"] .dialog-body label { + color: #94a3b8; +} + +[data-theme="dark"] .dialog-body input, +[data-theme="dark"] .dialog-body textarea { + 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; +} + +[data-theme="dark"] .close-dialog-btn { + color: #94a3b8; +} + +[data-theme="dark"] .close-dialog-btn:hover { + color: #f1f5f9; +} + +[data-theme="dark"] .share-setting label { + color: #94a3b8; +} + +[data-theme="dark"] .permissions-options label span { + color: #e2e8f0; +} + +[data-theme="dark"] .share-item-info { + color: #e2e8f0; +} diff --git a/static/css/components/fileList.css b/static/css/components/fileList.css new file mode 100644 index 00000000..88b6548a --- /dev/null +++ b/static/css/components/fileList.css @@ -0,0 +1,379 @@ +/* File list - Improved style */ +.files-list-view { + --files-list-columns: 36px minmax(200px, 2fr) 100px 110px 160px; + 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); + padding: 15px; + font-weight: 600; + color: #2d3748; + background-color: #f8f9fa; + border-bottom: 1px solid #e0e6ed; + align-items: center; +} + +.file-item { + display: grid; + grid-template-columns: var(--files-list-columns); + padding: 12px 15px; + border-bottom: 1px solid #f0f0f0; + align-items: center; + cursor: pointer; + transition: background-color 0.2s; + background-color: white; +} + +.file-item.selected { + background-color: #fff8f6; +} + +.file-item.selected:hover { + background-color: #fff0ec; +} + +.list-header.trash-header { + 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; +} + +.file-item:hover { + background-color: #f0f8ff; +} + +.list-header > div, +.file-item > div { + min-width: 0; +} + +.list-header > div:nth-child(4), +.file-item .size-cell { + justify-self: end; + text-align: right; +} + +.file-item .name-cell { + display: flex; + align-items: center; + gap: 12px; + min-width: 0; + overflow: hidden; +} + +.file-item .name-cell span { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.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; +} + +.file-item .file-icon.folder-icon { + background-color: #ffeaa7; + position: relative; + width: 36px; + height: 36px; + margin-bottom: 0; +} + +.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; +} + +.file-item .file-icon.folder-icon i, +.file-item .file-icon.folder-icon svg { + display: none; +} + +.file-item .file-icon.doc-icon { + background-color: #e0ecff; +} + +.file-item .file-icon.doc-icon i, +.file-item .file-icon.doc-icon svg { + color: #3171d8; + display: flex !important; +} + +.file-item .file-icon.doc-icon::before, +.file-item .file-icon.doc-icon::after { + display: none; +} + +.file-item .file-icon.pdf-icon { + background-color: #fee2e2; +} + +.file-item .file-icon.pdf-icon i, +.file-item .file-icon.pdf-icon svg { + color: #e53e3e; + display: flex !important; +} + +.file-item .file-icon.pdf-icon::before, +.file-item .file-icon.pdf-icon::after { + display: none; +} + +.file-item .file-icon.image-icon { + background-color: #e0f2fe; +} + +.file-item .file-icon.image-icon i, +.file-item .file-icon.image-icon svg { + color: #3b82f6; + display: flex !important; +} + +.file-item .file-icon.image-icon::before, +.file-item .file-icon.image-icon::after { + display: none; +} + +.file-item .file-icon.video-icon { + background: linear-gradient(135deg, #ede9fe, #fce7f3); +} + +.file-item .file-icon.video-icon i, +.file-item .file-icon.video-icon svg { + color: #8b5cf6; + display: flex !important; +} + +.file-item .file-icon.video-icon::before, +.file-item .file-icon.video-icon::after { + display: none; +} + +.file-item .file-icon.audio-icon { + background-color: #fef3c7; +} + +.file-item .file-icon.audio-icon i, +.file-item .file-icon.audio-icon svg { + color: #f59e0b; + display: flex !important; +} + +.file-item .file-icon.audio-icon::before, +.file-item .file-icon.audio-icon::after { + display: none; +} + +.file-item .file-icon.spreadsheet-icon { + background-color: #e6f4ea; + width: 36px; + height: 36px; + margin-bottom: 0; + border-top: none; +} + +.file-item .file-icon.spreadsheet-icon i, +.file-item .file-icon.spreadsheet-icon svg { + color: #0d904f; + display: flex !important; +} + +.file-item .file-icon.spreadsheet-icon::before, +.file-item .file-icon.spreadsheet-icon::after { + display: none; +} + +.file-item .file-icon.presentation-icon { + background-color: #fef3e2; + width: 36px; + height: 36px; + margin-bottom: 0; + border-top: none; +} + +.file-item .file-icon.presentation-icon i, +.file-item .file-icon.presentation-icon svg { + color: #d04423; + display: flex !important; +} + +.file-item .file-icon.presentation-icon::before, +.file-item .file-icon.presentation-icon::after { + display: none; +} + +.file-item .file-icon.audio-icon { + background-color: #fff3e0; + width: 36px; + height: 36px; + margin-bottom: 0; + border-top: none; +} + +.file-item .file-icon.archive-icon { + background-color: #f5f0eb; + width: 36px; + height: 36px; + margin-bottom: 0; + border-top: none; +} + +.file-item .file-icon.archive-icon i, +.file-item .file-icon.archive-icon svg { + color: #8d6e63; + display: flex !important; +} + +.file-item .file-icon.archive-icon::before, +.file-item .file-icon.archive-icon::after { + display: none; +} + +.file-item .file-icon.installer-icon { + background-color: #f3e8ff; + width: 36px; + height: 36px; + margin-bottom: 0; + border-top: none; +} + +.file-item .file-icon.installer-icon i, +.file-item .file-icon.installer-icon svg { + color: #7c3aed; + display: flex !important; +} + +.file-item .file-icon.installer-icon::before, +.file-item .file-icon.installer-icon::after { + display: none; +} + +.file-item .file-icon.script-icon { + background-color: #e8f5e9; +} + +.file-item .file-icon.script-icon i, +.file-item .file-icon.script-icon svg { + color: #4eaa25; + display: flex !important; +} + +.file-item .file-icon.script-icon::before, +.file-item .file-icon.script-icon::after { + display: none; +} + +.file-item .file-icon.config-icon { + background-color: #f1f3f5; +} + +.file-item .file-icon.config-icon i, +.file-item .file-icon.config-icon svg { + color: #718096; + display: flex !important; +} + +.file-item .file-icon.config-icon::before, +.file-item .file-icon.config-icon::after { + display: none; +} + +.file-item .date-cell { + color: #718096; + font-size: 14px; +} + +.file-item .size-cell { + color: #718096; + font-size: 14px; + text-align: right; +} + +.file-item .type-cell { + color: #4b5563; + font-weight: 500; + font-size: 14px; +} + +.file-item.dragging { + opacity: 0.5; + background-color: #f9fafb; +} + +.file-item.drop-target { + background-color: rgba(255, 193, 7, 0.1); + border: 2px dashed #ffc107; +} + +[data-theme="dark"] .files-list-view { + 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; +} + +[data-theme="dark"] .file-item { + background-color: #1e293b; + border-bottom-color: #293548; +} + +[data-theme="dark"] .file-item:hover { + background-color: #253345; +} + +[data-theme="dark"] .file-item.selected { + background-color: #1a1520; +} + +[data-theme="dark"] .file-item.selected:hover { + background-color: #231a2a; +} + +[data-theme="dark"] .file-item .name-cell { + color: #e2e8f0; +} + +[data-theme="dark"] .file-item .date-cell, +[data-theme="dark"] .file-item .size-cell { + color: #64748b; +} + +[data-theme="dark"] .file-item .type-cell { + color: #94a3b8; +} + +[data-theme="dark"] .file-item.dragging { + background-color: #334155; +} + +[data-theme="dark"] .file-item.drop-target { + background-color: rgba(255, 193, 7, 0.05); +} diff --git a/static/css/components/languageSelector.css b/static/css/components/languageSelector.css new file mode 100644 index 00000000..17e16dff --- /dev/null +++ b/static/css/components/languageSelector.css @@ -0,0 +1,138 @@ +/* Language Selector - Custom Dropdown */ +.language-selector { + position: relative; + margin-right: 15px; +} + +.language-selector-toggle { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 14px; + background-color: #f0f3f7; + border: 1px solid #e2e8f0; + border-radius: 50px; + cursor: pointer; + font-size: 14px; + font-weight: 500; + color: #4a5568; + transition: all 0.2s ease; + user-select: none; +} + +.language-selector-toggle:hover { + background-color: #e2e8f0; + border-color: #cbd5e0; +} + +.language-selector-toggle i { + font-size: 14px; + color: #718096; +} + +.language-selector-toggle .lang-code { + font-weight: 600; + color: #2d3748; +} + +.language-selector-toggle .dropdown-arrow { + font-size: 10px; + color: #718096; + transition: transform 0.2s ease; + margin-left: 2px; +} + +.language-selector.open .dropdown-arrow { + transform: rotate(180deg); +} + +.language-selector-dropdown { + position: absolute; + top: calc(100% + 8px); + right: 0; + min-width: 160px; + background-color: white; + border-radius: 12px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); + border: 1px solid #e2e8f0; + opacity: 0; + visibility: hidden; + transform: translateY(-10px); + transition: all 0.2s ease; + z-index: 1000; + overflow: hidden; +} + +.language-selector.open .language-selector-dropdown { + opacity: 1; + visibility: visible; + transform: translateY(0); +} + +.language-option { + display: flex; + align-items: center; + gap: 10px; + padding: 12px 16px; + cursor: pointer; + font-size: 14px; + color: #4a5568; + transition: background-color 0.15s ease; +} + +.language-option:hover { + background-color: #f7fafc; +} + +.language-option.active { + background-color: #fff5f3; + color: #ff5e3a; +} + +.language-option .lang-flag { + font-size: 18px; + line-height: 1; +} + +.language-option .lang-name { + flex: 1; +} + +.language-option .lang-check { + color: #ff5e3a; + font-size: 12px; + opacity: 0; +} + +.language-option.active .lang-check { + opacity: 1; +} + +[data-theme="dark"] .language-selector-toggle { + background-color: #1e293b; + border-color: #334155; + color: #cbd5e1; +} + +[data-theme="dark"] .language-selector-toggle:hover { + background-color: #334155; +} + +[data-theme="dark"] .language-selector-dropdown { + background-color: #1e293b; + border-color: #334155; + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5); +} + +[data-theme="dark"] .language-option { + color: #cbd5e1; +} + +[data-theme="dark"] .language-option:hover { + background-color: #334155; +} + +[data-theme="dark"] .language-option.active { + background-color: rgba(255, 94, 58, 0.1); + color: #ff5e3a; +} diff --git a/static/css/components/modals.css b/static/css/components/modals.css new file mode 100644 index 00000000..def2a218 --- /dev/null +++ b/static/css/components/modals.css @@ -0,0 +1,381 @@ +/* About Modal */ +.about-modal-overlay { + display: none; + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(4px); + z-index: 3000; + justify-content: center; + align-items: center; +} + +.about-modal-overlay.show { + display: flex; +} + +.about-modal { + background: white; + border-radius: 20px; + padding: 40px; + max-width: 400px; + width: 90%; + text-align: center; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2); + animation: userMenuIn 0.25s ease-out; +} + +.about-modal-logo { + width: 72px; + height: 72px; + background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); + border-radius: 20px; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto 20px; + box-shadow: 0 8px 24px rgba(255, 94, 58, 0.3); +} + +.about-modal-logo i { + font-size: 32px; + color: white; +} + +.about-modal h2 { + font-size: 22px; + font-weight: 700; + color: #1e293b; + margin-bottom: 6px; +} + +.about-modal .about-version { + font-size: 13px; + color: #94a3b8; + margin-bottom: 20px; +} + +.about-modal .about-description { + font-size: 14px; + color: #64748b; + line-height: 1.6; + margin-bottom: 24px; +} + +.about-modal .about-tech { + display: flex; + justify-content: center; + gap: 12px; + flex-wrap: wrap; + margin-bottom: 24px; +} + +.about-modal .about-tech-badge { + padding: 4px 12px; + background: #f8fafc; + border: 1px solid #e2e8f0; + border-radius: 20px; + font-size: 12px; + color: #64748b; + font-weight: 500; +} + +.about-modal .about-links { + display: flex; + justify-content: center; + gap: 16px; + margin-bottom: 24px; +} + +.about-modal .about-link { + display: flex; + align-items: center; + gap: 6px; + font-size: 13px; + color: #ff5e3a; + text-decoration: none; + font-weight: 500; + transition: opacity 0.2s; +} + +.about-modal .about-link:hover { + opacity: 0.8; +} + +.about-modal .about-close-btn { + padding: 10px 32px; + background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); + color: white; + border: none; + border-radius: 10px; + font-size: 14px; + font-weight: 600; + cursor: pointer; + transition: transform 0.2s, box-shadow 0.2s; + box-shadow: 0 4px 15px rgba(255, 94, 58, 0.3); +} + +.about-modal .about-close-btn:hover { + transform: translateY(-1px); + box-shadow: 0 6px 20px rgba(255, 94, 58, 0.4); +} + +/* Modern Modal Overlay */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: none; + justify-content: center; + align-items: center; + z-index: 3000; + opacity: 0; + transition: opacity 0.2s ease; +} + +.modal-overlay.active { + display: flex; + opacity: 1; +} + +.modal-container { + background-color: white; + border-radius: 16px; + width: 420px; + max-width: 90%; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); + transform: scale(0.9) translateY(-20px); + transition: transform 0.2s ease; + overflow: hidden; +} + +.modal-overlay.active .modal-container { + transform: scale(1) translateY(0); +} + +.modal-header { + display: flex; + align-items: center; + padding: 20px 24px; + border-bottom: 1px solid #e2e8f0; + position: relative; +} + +.modal-icon { + width: 44px; + height: 44px; + background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + margin-right: 14px; + flex-shrink: 0; + + [dir='rtl'] & { + margin-left: 14px; + margin-right: unset; + } +} + +.modal-icon i { + color: white; + font-size: 20px; +} + +.modal-header h3 { + font-size: 18px; + font-weight: 600; + color: #1a202c; + margin: 0; + flex: 1; +} + +.modal-close-btn { + position: absolute; + top: 16px; + right: 16px; + width: 32px; + height: 32px; + border: none; + background: #f0f3f7; + border-radius: 8px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + color: #64748b; + transition: all 0.15s ease; + + [dir='rtl'] & { + left: 16px; + right: unset; + } +} + +.modal-close-btn:hover { + background: #e2e8f0; + color: #1a202c; +} + +.modal-body { + padding: 24px; +} + +.modal-body label { + display: block; + font-size: 14px; + font-weight: 500; + color: #4a5568; + margin-bottom: 8px; +} + +.modal-input { + width: 100%; + padding: 12px 16px; + font-size: 15px; + border: 2px solid #e2e8f0; + border-radius: 10px; + background: #f8fafc; + color: #1a202c; + transition: all 0.15s ease; + outline: none; +} + +.modal-input:focus { + border-color: #ff5e3a; + background: white; + box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); +} + +.modal-input::placeholder { + color: #a0aec0; +} + +.modal-footer { + display: flex; + justify-content: flex-end; + gap: 12px; + padding: 16px 24px; + background: #f8fafc; + border-top: 1px solid #e2e8f0; +} + +.modal-footer .btn { + padding: 10px 20px; + font-size: 14px; + font-weight: 500; + border-radius: 10px; + cursor: pointer; + transition: all 0.15s ease; +} + +.modal-footer .btn-secondary { + background: white; + border: 1px solid #e2e8f0; + color: #4a5568; +} + +.modal-footer .btn-secondary:hover { + background: #f0f3f7; + border-color: #cbd5e0; +} + +.modal-footer .btn-primary { + background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); + border: none; + color: white; + box-shadow: 0 2px 8px rgba(255, 94, 58, 0.3); +} + +.modal-footer .btn-primary:hover { + box-shadow: 0 4px 12px rgba(255, 94, 58, 0.4); + transform: translateY(-1px); +} + +.modal-footer .btn-primary:active { + transform: translateY(0); +} + +[data-theme="dark"] .about-modal { + background: #1e293b; +} + +[data-theme="dark"] .about-modal h2 { + color: #f1f5f9; +} + +[data-theme="dark"] .about-modal .about-version, +[data-theme="dark"] .about-modal .about-description { + color: #94a3b8; +} + +[data-theme="dark"] .about-modal .about-tech-badge { + background: #334155; + border-color: #475569; + color: #cbd5e1; +} + +[data-theme="dark"] .modal-overlay { + background-color: rgba(0, 0, 0, 0.7); +} + +[data-theme="dark"] .modal-container { + background-color: #1e293b; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); +} + +[data-theme="dark"] .modal-header { + border-bottom-color: #334155; +} + +[data-theme="dark"] .modal-header h3 { + color: #f1f5f9; +} + +[data-theme="dark"] .modal-close-btn { + background: #334155; + color: #94a3b8; +} + +[data-theme="dark"] .modal-close-btn:hover { + background: #475569; + color: #e2e8f0; +} + +[data-theme="dark"] .modal-body label { + color: #94a3b8; +} + +[data-theme="dark"] .modal-input { + border-color: #334155; + background: #0f172a; + color: #e2e8f0; +} + +[data-theme="dark"] .modal-input:focus { + border-color: #ff5e3a; + background: #0f172a; +} + +[data-theme="dark"] .modal-input::placeholder { + color: #475569; +} + +[data-theme="dark"] .modal-footer { + background: #162032; + border-top-color: #334155; +} + +[data-theme="dark"] .modal-footer .btn-secondary { + background: #334155; + border-color: #475569; + color: #cbd5e1; +} + +[data-theme="dark"] .modal-footer .btn-secondary:hover { + background: #475569; +} diff --git a/static/css/components/multiSelect.css b/static/css/components/multiSelect.css new file mode 100644 index 00000000..1b39ce1c --- /dev/null +++ b/static/css/components/multiSelect.css @@ -0,0 +1,153 @@ +/* Multi-Select – checkboxes & batch action bar */ +.list-header-checkbox, +.list-item-checkbox { + display: flex; + align-items: center; + justify-content: center; +} + +.list-header-checkbox input[type="checkbox"], +.list-item-checkbox input[type="checkbox"] { + width: 17px; + height: 17px; + cursor: pointer; + accent-color: #ff5e3a; + border-radius: 4px; +} + +.list-header.selection-mode { + grid-template-columns: 36px 1fr; + background-color: #1e293b; + color: #fff; + border-bottom-color: #334155; +} + +.list-header.selection-mode .list-header-checkbox input[type="checkbox"] { + accent-color: #ff5e3a; +} + +.batch-selection-info { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + min-width: 0; +} + +.batch-action-bar { + display: flex; + align-items: center; + justify-content: space-between; + background: #1e293b; + color: #fff; + padding: 10px 20px; + border-radius: 12px; + margin: 0 0 12px; + opacity: 0; + max-height: 0; + overflow: hidden; + transform: translateY(-8px); + transition: opacity 0.2s, max-height 0.25s, transform 0.2s, margin 0.2s, padding 0.2s; + pointer-events: none; +} + +.batch-action-bar.visible { + opacity: 1; + max-height: 60px; + transform: translateY(0); + pointer-events: auto; + padding: 10px 20px; + margin: 0 0 12px; +} + +.batch-bar-left { + display: flex; + align-items: center; + gap: 12px; +} + +.batch-bar-close { + background: none; + border: none; + color: rgba(255,255,255,0.7); + cursor: pointer; + font-size: 14px; + padding: 4px 6px; + border-radius: 6px; + transition: background 0.15s, color 0.15s; +} + +.batch-bar-close:hover { + background: rgba(255,255,255,0.1); + color: #fff; +} + +.batch-bar-count { + font-size: 14px; + font-weight: 600; + white-space: nowrap; +} + +.batch-bar-actions { + display: flex; + align-items: center; + gap: 6px; +} + +.batch-btn { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 7px 14px; + border: none; + border-radius: 8px; + background: rgba(255,255,255,0.1); + color: #fff; + font-size: 13px; + font-weight: 500; + cursor: pointer; + transition: background 0.15s; + white-space: nowrap; +} + +.batch-btn:hover { + background: rgba(255,255,255,0.2); +} + +.batch-btn-danger { + background: rgba(239,68,68,0.25); + color: #fca5a5; +} + +.batch-btn-danger:hover { + background: rgba(239,68,68,0.4); + color: #fff; +} + +@media (max-width: 640px) { + .batch-btn span { + display: none; + } + + .batch-btn { + padding: 7px 10px; + } +} + +[data-theme="dark"] .list-header-checkbox input, +[data-theme="dark"] .list-item-checkbox input, +[data-theme="dark"] .file-card-checkbox input { + accent-color: #ff5e3a; +} + +[data-theme="dark"] .batch-action-bar { + background-color: #1e293b; + border-color: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] .list-header.selection-mode { + background-color: #0f172a; + border-bottom-color: #334155; + color: #e2e8f0; +} diff --git a/static/css/components/notifications.css b/static/css/components/notifications.css new file mode 100644 index 00000000..628b16fe --- /dev/null +++ b/static/css/components/notifications.css @@ -0,0 +1,577 @@ +/* Notification */ +.notification { + position: absolute; + top: 70px; + right: 20px; + background-color: white; + width: 250px; + border-radius: 8px; + box-shadow: 0 5px 15px rgba(0,0,0,0.1); + padding: 15px; + border-left: 4px solid #ff5e3a; + z-index: 1000; + display: none; + + [dir='rtl'] & { + left: 20px; + border-right: 4px solid #ff5e3a; + right: unset; + border-left: unset; + } +} + +.notification-title { + font-weight: bold; + font-size: 14px; + margin-bottom: 5px; + color: #2d3748; +} + +.notification-message { + font-size: 12px; + color: #718096; +} + +/* Notification banner */ +.notification-banner { + position: fixed; + top: 20px; + right: 20px; + padding: 15px 20px; + background-color: white; + border-radius: 8px; + box-shadow: 0 4px 12px rgba(0,0,0,0.1); + display: flex; + align-items: center; + justify-content: space-between; + max-width: 400px; + z-index: 2000; + transform: translateY(-100px); + opacity: 0; + transition: transform 0.3s, opacity 0.3s; +} + +.notification-banner.active { + transform: translateY(0); + opacity: 1; +} + +.notification-banner.success { + border-left: 4px solid #48bb78; +} + +.notification-banner.error { + border-left: 4px solid #f56565; +} + +.close-notification-btn { + background: none; + border: none; + font-size: 18px; + cursor: pointer; + color: #a0aec0; + margin-left: 10px; +} + +/* Notification Bell */ +.notif-wrapper { + position: relative; +} + +.notif-bell-btn { + background: none; + border: none; + cursor: pointer; + font-size: 18px; + color: #64748b; + width: 40px; + height: 40px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s ease; + position: relative; +} + +.notif-bell-btn:hover { + background: rgba(255, 94, 58, 0.08); + color: #ff5e3a; +} + +.notif-bell-btn.active { + color: #ff5e3a; + background: rgba(255, 94, 58, 0.1); +} + +.notif-badge { + position: absolute; + top: 4px; + right: 4px; + min-width: 16px; + height: 16px; + line-height: 16px; + border-radius: 8px; + background: #ff3b30; + color: #fff; + font-size: 10px; + font-weight: 700; + text-align: center; + padding: 0 4px; + pointer-events: none; +} + +@keyframes bellRing { + 0%, 100% { transform: rotate(0deg); } + 15% { transform: rotate(14deg); } + 30% { transform: rotate(-14deg); } + 45% { transform: rotate(8deg); } + 60% { transform: rotate(-8deg); } + 75% { transform: rotate(3deg); } +} + +.notif-bell-btn.ring i { + animation: bellRing 0.6s ease; +} + +.notif-panel { + display: none; + position: absolute; + top: calc(100% + 10px); + right: -40px; + width: 380px; + max-height: 480px; + background: #fff; + border-radius: 16px; + box-shadow: 0 12px 40px rgba(0,0,0,0.15), 0 0 0 1px rgba(0,0,0,0.05); + z-index: 2000; + overflow: hidden; + animation: notifPanelIn 0.2s ease-out; +} + +.notif-wrapper.open .notif-panel { + display: flex; + flex-direction: column; +} + +@keyframes notifPanelIn { + from { opacity: 0; transform: translateY(-8px) scale(0.97); } + to { opacity: 1; transform: translateY(0) scale(1); } +} + +.notif-panel-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 14px 16px; + border-bottom: 1px solid #f0f0f0; +} + +.notif-panel-title { + font-weight: 600; + font-size: 15px; + color: #1e293b; +} + +.notif-clear-btn { + background: none; + border: none; + cursor: pointer; + color: #94a3b8; + font-size: 14px; + padding: 4px 8px; + border-radius: 6px; + transition: all 0.15s; +} + +.notif-clear-btn:hover { + color: #ff5e3a; + background: rgba(255, 94, 58, 0.08); +} + +.notif-panel-body { + flex: 1; + overflow-y: auto; + max-height: 400px; +} + +.notif-empty { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px 20px; + color: #94a3b8; + gap: 8px; +} + +.notif-empty i { + font-size: 28px; + opacity: 0.5; +} + +.notif-empty span { + font-size: 14px; +} + +.notif-item { + display: flex; + align-items: flex-start; + padding: 12px 16px; + gap: 12px; + border-bottom: 1px solid #f5f5f5; + transition: background 0.15s; + cursor: default; +} + +.notif-item:last-child { + border-bottom: none; +} + +.notif-item:hover { + background: #f8fafc; +} + +.notif-item-icon { + width: 32px; + height: 32px; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + font-size: 14px; +} + +.notif-item-icon.upload { + background: rgba(255, 94, 58, 0.1); + color: #ff5e3a; +} + +.notif-item-icon.success { + background: rgba(52, 199, 89, 0.1); + color: #34c759; +} + +.notif-item-icon.error { + background: rgba(255, 59, 48, 0.1); + color: #ff3b30; +} + +.notif-item-body { + flex: 1; + min-width: 0; +} + +.notif-item-title { + font-size: 13px; + font-weight: 600; + color: #1e293b; + margin-bottom: 2px; +} + +.notif-item-text { + font-size: 12px; + color: #64748b; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.notif-item-time { + font-size: 11px; + color: #94a3b8; + margin-top: 3px; +} + +.notif-upload-progress { + margin-top: 6px; +} + +.notif-upload-bar { + height: 3px; + background: #eee; + border-radius: 2px; + overflow: hidden; +} + +.notif-upload-fill { + height: 100%; + background: #ff5e3a; + width: 0%; + transition: width 0.2s ease; + border-radius: 2px; +} + +.notif-upload-fill.done { + background: #34c759; +} + +.notif-upload-fill.error { + background: #ff3b30; +} + +.notif-upload-detail { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 3px; +} + +.notif-upload-pct, +.notif-upload-stats { + font-size: 11px; + color: #94a3b8; +} + +/* Upload Progress Toast (legacy — hidden, kept for compat) */ +.upload-toast { + position: fixed; + bottom: 24px; + right: 24px; + width: 360px; + max-height: 400px; + background: #fff; + border-radius: 12px; + box-shadow: 0 8px 30px rgba(0,0,0,0.15); + z-index: 10000; + display: none; + flex-direction: column; + overflow: hidden; + font-family: inherit; + animation: uploadToastSlideIn 0.3s ease-out; +} + +.upload-toast.visible { + display: flex; +} + +@keyframes uploadToastSlideIn { + from { transform: translateY(20px); opacity: 0; } + to { transform: translateY(0); opacity: 1; } +} + +.upload-toast-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 16px; + background: #ff5e3a; + color: #fff; +} + +.upload-toast-title { + font-weight: 600; + font-size: 14px; +} + +.upload-toast-close { + background: none; + border: none; + color: #fff; + font-size: 20px; + cursor: pointer; + line-height: 1; + padding: 0 4px; + opacity: 0.8; +} + +.upload-toast-close:hover { + opacity: 1; +} + +.upload-toast-body { + flex: 1; + overflow-y: auto; + padding: 8px 0; + max-height: 260px; +} + +.upload-toast-file { + display: flex; + align-items: center; + padding: 6px 16px; + gap: 10px; +} + +.upload-toast-file-icon { + font-size: 16px; + color: #999; + flex-shrink: 0; + width: 20px; + text-align: center; +} + +.upload-toast-file-icon.done { + color: #34c759; +} + +.upload-toast-file-icon.error { + color: #ff3b30; +} + +.upload-toast-file-info { + flex: 1; + min-width: 0; +} + +.upload-toast-file-name { + font-size: 13px; + color: #333; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.upload-toast-file-bar { + height: 3px; + background: #eee; + border-radius: 2px; + margin-top: 4px; + overflow: hidden; +} + +.upload-toast-file-fill { + height: 100%; + background: #ff5e3a; + width: 0%; + transition: width 0.2s ease; + border-radius: 2px; +} + +.upload-toast-file-fill.done { + background: #34c759; +} + +.upload-toast-file-fill.error { + background: #ff3b30; +} + +.upload-toast-file-pct { + font-size: 12px; + color: #999; + flex-shrink: 0; + width: 38px; + text-align: right; +} + +.upload-toast-footer { + padding: 10px 16px; + border-top: 1px solid #f0f0f0; +} + +.upload-toast-overall-bar { + height: 4px; + background: #eee; + border-radius: 2px; + overflow: hidden; + margin-bottom: 6px; +} + +.upload-toast-overall-fill { + height: 100%; + background: #ff5e3a; + width: 0%; + transition: width 0.25s ease; + border-radius: 2px; +} + +.upload-toast-stats { + font-size: 12px; + color: #888; +} + +[data-theme="dark"] .notification { + background-color: #1e293b; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); +} + +[data-theme="dark"] .notification-title { + color: #f1f5f9; +} + +[data-theme="dark"] .notification-message { + color: #94a3b8; +} + +[data-theme="dark"] .notification-banner { + background-color: #1e293b; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); +} + +[data-theme="dark"] .notif-bell-btn { + color: #94a3b8; +} + +[data-theme="dark"] .notif-bell-btn:hover, +[data-theme="dark"] .notif-bell-btn.active { + color: #ff5e3a; + background: rgba(255, 94, 58, 0.15); +} + +[data-theme="dark"] .notif-panel { + background: #1e293b; + box-shadow: 0 12px 40px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.06); +} + +[data-theme="dark"] .notif-panel-header { + border-bottom-color: #334155; +} + +[data-theme="dark"] .notif-panel-title { + color: #f1f5f9; +} + +[data-theme="dark"] .notif-clear-btn { + color: #64748b; +} + +[data-theme="dark"] .notif-clear-btn:hover { + color: #ff5e3a; + background: rgba(255, 94, 58, 0.12); +} + +[data-theme="dark"] .notif-empty { + color: #64748b; +} + +[data-theme="dark"] .notif-item { + border-bottom-color: #1a2536; +} + +[data-theme="dark"] .notif-item:hover { + background: #162032; +} + +[data-theme="dark"] .notif-item-title { + color: #e2e8f0; +} + +[data-theme="dark"] .notif-item-text { + color: #94a3b8; +} + +[data-theme="dark"] .notif-upload-bar { + background: #334155; +} + +[data-theme="dark"] .upload-toast { + background: #1e293b; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); +} + +[data-theme="dark"] .upload-toast-file-name { + color: #e2e8f0; +} + +[data-theme="dark"] .upload-toast-file-bar { + background: #334155; +} + +[data-theme="dark"] .upload-toast-file-pct { + color: #64748b; +} + +[data-theme="dark"] .upload-toast-footer { + border-top-color: #334155; +} diff --git a/static/css/components/search.css b/static/css/components/search.css new file mode 100644 index 00000000..4fd77759 --- /dev/null +++ b/static/css/components/search.css @@ -0,0 +1,45 @@ +/* Styles for search results */ +.search-results-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 0; + margin-bottom: 15px; + border-bottom: 1px solid #eee; + width: 100%; + flex-wrap: wrap; + gap: 8px; +} + +.search-results-header h3 { + margin: 0; + font-size: 16px; + color: #555; +} + +.search-results-header .search-time { + font-size: 12px; + font-weight: normal; + color: #999; +} + +.search-controls { + display: flex; + align-items: center; + gap: 8px; +} + +.search-sort-select { + padding: 4px 8px; + border: 1px solid #ddd; + border-radius: 4px; + font-size: 13px; + background: #fff; + color: #333; + cursor: pointer; + outline: none; +} + +.search-sort-select:focus { + border-color: var(--primary-color, #4a90d9); +} diff --git a/static/css/components/shareDialog.css b/static/css/components/shareDialog.css new file mode 100644 index 00000000..441b1e1f --- /dev/null +++ b/static/css/components/shareDialog.css @@ -0,0 +1,68 @@ +.permission-options { + display: flex; + gap: 15px; + margin-top: 5px; +} + +.permission-option { + display: flex; + align-items: center; + gap: 5px; +} + +.existing-share-item { + background-color: #f8f9fa; + border-radius: 4px; + padding: 10px; + margin-bottom: 10px; +} + +.share-url { + font-size: 12px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin-bottom: 5px; + color: #1565c0; +} + +.share-info { + font-size: 11px; + display: flex; + gap: 15px; + margin-bottom: 10px; + color: #757575; +} + +.share-protected { + color: #1565c0; +} + +.share-expiration { + color: #b71c1c; +} + +.share-actions { + display: flex; + gap: 5px; + justify-content: flex-end; +} + +.share-link-actions { + display: flex; + gap: 10px; + margin-top: 5px; +} + +.btn-small { + font-size: 12px; + padding: 5px 10px; +} + +#notification-message { + width: 100%; + padding: 10px; + border: 1px solid #ddd; + border-radius: 4px; + resize: vertical; +} diff --git a/static/css/components/spinner.css b/static/css/components/spinner.css new file mode 100644 index 00000000..d1c35908 --- /dev/null +++ b/static/css/components/spinner.css @@ -0,0 +1,76 @@ +/* Loading spinner overlay */ +.files-loading-spinner { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 80px 20px; + gap: 16px; + grid-column: 1 / -1; +} + +.files-loading-spinner .spinner { + width: 36px; + height: 36px; + border: 3px solid #e2e8f0; + border-top-color: #ff5e3a; + border-radius: 50%; + animation: spin 0.7s linear infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.files-loading-spinner span { + font-size: 14px; + color: #a0aec0; + font-weight: 500; +} + +.dropzone { + border: 2px dashed #ddd; + border-radius: 8px; + padding: 20px; + text-align: center; + margin: 20px 0; + color: #666; + display: none; +} + +.dropzone.active { + border-color: #ff5e3a; + background-color: rgba(255, 94, 58, 0.05); +} + +.upload-progress { + margin-top: 15px; + width: 100%; + display: none; +} + +.progress-bar { + background-color: #f0f0f0; + height: 6px; + border-radius: 3px; + overflow: hidden; +} + +.progress-fill { + height: 100%; + background-color: #ff5e3a; + width: 0%; + transition: width 0.3s; +} + +[data-theme="dark"] .dropzone { + border-color: #475569; + color: #94a3b8; + background-color: #0f172a; +} + +[data-theme="dark"] .progress-bar { + background-color: #334155; +} diff --git a/static/css/components/uploadDropdown.css b/static/css/components/uploadDropdown.css new file mode 100644 index 00000000..ed0f89d9 --- /dev/null +++ b/static/css/components/uploadDropdown.css @@ -0,0 +1,97 @@ +/* Upload Dropdown */ +.upload-dropdown { + position: relative; + display: inline-block; +} + +.upload-dropdown .btn-primary { + display: flex; + align-items: center; + gap: 6px; +} + +.upload-dropdown-menu { + display: none; + position: absolute; + top: calc(100% + 6px); + left: 0; + min-width: 200px; + background: white; + border-radius: 12px; + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15); + border: 1px solid #e2e8f0; + z-index: 1000; + overflow: hidden; + animation: dropdownFadeIn 0.15s ease-out; +} + +.upload-dropdown-menu.show { + display: block; +} + +@keyframes dropdownFadeIn { + from { + opacity: 0; + transform: translateY(-8px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.upload-dropdown-item { + display: flex; + align-items: center; + gap: 12px; + width: 100%; + padding: 12px 16px; + border: none; + background: none; + color: #334155; + font-size: 14px; + cursor: pointer; + transition: background 0.15s ease; + text-align: left; +} + +.upload-dropdown-item:hover { + background: #f1f5f9; +} + +.upload-dropdown-item:active { + background: #e2e8f0; +} + +.upload-dropdown-item i { + width: 20px; + text-align: center; + color: #64748b; + font-size: 15px; +} + +.upload-dropdown-item:first-child { + border-bottom: 1px solid #f1f5f9; +} + +[data-theme="dark"] .upload-dropdown-menu { + background: #1e293b; + border-color: #334155; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); +} + +[data-theme="dark"] .upload-dropdown-item { + color: #cbd5e1; +} + +[data-theme="dark"] .upload-dropdown-item:hover { + background: #334155; +} + +[data-theme="dark"] .upload-dropdown-item:active { + background: #475569; +} + +[data-theme="dark"] .upload-dropdown-item i { + color: #94a3b8; +} diff --git a/static/css/components/userMenu.css b/static/css/components/userMenu.css new file mode 100644 index 00000000..a783862b --- /dev/null +++ b/static/css/components/userMenu.css @@ -0,0 +1,340 @@ +/* User Menu */ +.user-menu-wrapper { + position: relative; +} + +.user-avatar-btn { + background: none; + border: 2px solid transparent; + border-radius: 50%; + padding: 2px; + cursor: pointer; + transition: all 0.25s ease; + display: flex; + align-items: center; + justify-content: center; +} + +.user-avatar-btn:hover { + border-color: rgba(255, 94, 58, 0.4); + transform: scale(1.05); +} + +.user-avatar-btn:hover .user-avatar { + box-shadow: 0 0 0 2px rgba(255, 94, 58, 0.2); +} + +.user-menu-wrapper.open .user-avatar-btn { + border-color: #ff5e3a; +} + +.user-avatar { + width: 38px; + height: 38px; + background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-weight: 700; + font-size: 14px; + letter-spacing: 0.5px; + user-select: none; +} + +.user-menu { + display: none; + position: absolute; + top: calc(100% + 10px); + right: 0; + width: 300px; + background: white; + border-radius: 16px; + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.05); + z-index: 2000; + overflow: hidden; + animation: userMenuIn 0.2s ease-out; +} + +.user-menu-wrapper.open .user-menu { + display: block; +} + +@keyframes userMenuIn { + from { + opacity: 0; + transform: translateY(-8px) scale(0.97); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +.user-menu-header { + display: flex; + align-items: center; + gap: 14px; + padding: 20px 20px 16px; + background: linear-gradient(135deg, #fef5f3 0%, #fdf2f8 100%); + border-bottom: 1px solid #fce7e1; +} + +.user-menu-avatar { + width: 48px; + height: 48px; + min-width: 48px; + background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-weight: 700; + font-size: 17px; + letter-spacing: 0.5px; + box-shadow: 0 4px 12px rgba(255, 94, 58, 0.3); +} + +.user-menu-info { + overflow: hidden; +} + +.user-menu-name { + font-weight: 600; + font-size: 15px; + color: #1e293b; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.user-menu-email { + font-size: 12.5px; + color: #94a3b8; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-top: 2px; +} + +.user-menu-storage { + padding: 14px 20px; +} + +.user-menu-storage-label { + display: flex; + align-items: center; + gap: 8px; + font-size: 12px; + font-weight: 600; + color: #64748b; + text-transform: uppercase; + letter-spacing: 0.5px; + margin-bottom: 8px; +} + +.user-menu-storage-label i { + font-size: 11px; + color: #94a3b8; +} + +.user-menu-storage-bar { + height: 6px; + background: #f1f5f9; + border-radius: 3px; + overflow: hidden; + margin-bottom: 6px; +} + +.user-menu-storage-fill { + height: 100%; + background: linear-gradient(90deg, #ff5e3a, #ff2d55); + border-radius: 3px; + width: 0%; + transition: width 0.5s ease; +} + +.user-menu-storage-text { + font-size: 11.5px; + color: #94a3b8; +} + +.user-menu-divider { + height: 1px; + background: #f1f5f9; + margin: 4px 0; +} + +.user-menu-item { + display: flex; + align-items: center; + gap: 12px; + width: 100%; + padding: 12px 20px; + border: none; + background: none; + color: #334155; + font-size: 14px; + cursor: pointer; + transition: background 0.15s ease; + text-align: left; +} + +.user-menu-item:hover { + background: #f8fafc; +} + +.user-menu-item i { + width: 20px; + text-align: center; + font-size: 15px; + color: #64748b; +} + +.user-menu-item .theme-toggle-pill { + margin-left: auto; + width: 40px; + height: 22px; + background: #e2e8f0; + border-radius: 11px; + position: relative; + transition: background 0.3s ease; +} + +.user-menu-item .theme-toggle-pill.active { + background: #ff5e3a; +} + +.user-menu-item .theme-toggle-knob { + width: 18px; + height: 18px; + background: white; + border-radius: 50%; + position: absolute; + top: 2px; + left: 2px; + transition: transform 0.3s ease; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15); +} + +.user-menu-item .theme-toggle-pill.active .theme-toggle-knob { + transform: translateX(18px); +} + +.user-menu-admin { + color: #1d4ed8; +} + +.user-menu-admin i { + color: #3b82f6; +} + +.user-menu-admin:hover { + background: #eff6ff; +} + +.user-menu-role-badge { + padding: 0 20px 4px; +} + +.role-badge { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 11px; + font-weight: 600; + padding: 2px 10px; + border-radius: 10px; +} + +.role-badge-admin { + background: #dbeafe; + color: #1d4ed8; +} + +.role-badge i { + font-size: 10px; +} + +.user-menu-logout { + color: #ef4444; + margin-bottom: 4px; +} + +.user-menu-logout i { + color: #ef4444; +} + +.user-menu-logout:hover { + background: #fef2f2; +} + +[data-theme="dark"] .user-menu { + background: #1e293b; + border-color: #334155; + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5); +} + +[data-theme="dark"] .user-menu-header { + background: linear-gradient(135deg, #1a2332 0%, #1e2940 100%); + border-bottom-color: #334155; +} + +[data-theme="dark"] .user-menu-name { + color: #f1f5f9; +} + +[data-theme="dark"] .user-menu-email { + color: #64748b; +} + +[data-theme="dark"] .user-menu-storage-label { + color: #94a3b8; +} + +[data-theme="dark"] .user-menu-storage-bar { + background: #334155; +} + +[data-theme="dark"] .user-menu-storage-text { + color: #64748b; +} + +[data-theme="dark"] .user-menu-divider { + background: #334155; +} + +[data-theme="dark"] .user-menu-item { + color: #cbd5e1; +} + +[data-theme="dark"] .user-menu-item:hover { + background: #334155; +} + +[data-theme="dark"] .user-menu-item i { + color: #94a3b8; +} + +[data-theme="dark"] .theme-toggle-pill { + background: #475569; +} + +[data-theme="dark"] .user-menu-admin { + color: #60a5fa; +} + +[data-theme="dark"] .user-menu-admin:hover { + background: rgba(59, 130, 246, 0.1); +} + +[data-theme="dark"] .role-badge-admin { + background: rgba(59, 130, 246, 0.15); + color: #60a5fa; +} + +[data-theme="dark"] .user-menu-logout:hover { + background: rgba(239, 68, 68, 0.1); +} diff --git a/static/css/favorites.css b/static/css/favorites.css index d729af2e..95739df6 100644 --- a/static/css/favorites.css +++ b/static/css/favorites.css @@ -1,126 +1 @@ -/* Styles for the favorites feature */ - -/* Favorite indicator */ -.favorite-indicator { - position: absolute; - top: 10px; - right: 10px; - width: 25px; - height: 25px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - color: #ccc; - cursor: pointer; - z-index: 5; - transition: all 0.2s ease; - - [dir='rtl'] & { - left: 10px; - right: unset; - } -} - -.favorite-indicator:hover { - transform: scale(1.1); -} - -.favorite-indicator.active { - color: #ffc107; - text-shadow: 0 0 5px rgba(255, 193, 7, 0.5); -} - -/* Styles for the favorites view items */ -.favorite-item { - position: relative; -} - -/* Adjustments for grid view */ -.file-card.favorite-item { - border-left: 3px solid #ffc107; - - [dir='rtl'] & { - border-right: 3px solid #ffc107; - border-left: unset; - } -} - -/* Adjustments for list view */ -.list-header.favorites-header { - grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; -} - -.file-item.favorite-item { - position: relative; - grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; -} - -.file-item.favorite-item .favorite-indicator { - position: relative; - top: 0; - right: 0; - width: 30px; - height: 30px; -} - -/* Styles for the favorites-specific empty state */ -.favorites-empty-state { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 50px 20px; - text-align: center; - color: #6c757d; -} - -.favorites-empty-state i { - font-size: 48px; - color: #ffc107; - margin-bottom: 20px; - opacity: 0.6; -} - -.favorites-empty-state p { - margin-bottom: 10px; - max-width: 400px; -} - -/* Animation for the favorite star */ -@keyframes favorite-pulse { - 0% { transform: scale(1); } - 50% { transform: scale(1.2); } - 100% { transform: scale(1); } -} - -.favorite-indicator.active { - animation: favorite-pulse 0.3s ease; -} - -/* ── Star badge on file/folder cards (normal view) ── */ - -/* Grid view: keep interactive star button behavior from style.css */ -.file-card .favorite-star { - pointer-events: auto; - z-index: 12; -} - -.file-card .favorite-star.active i, -.file-card .favorite-star.active svg { - animation: favorite-pulse 0.3s ease; -} - -/* List view: small star next to the name */ -.favorite-star-inline { - color: #ffc107; - font-size: 11px; - margin-left: 6px; - vertical-align: middle; - filter: drop-shadow(0 0 1px rgba(255, 193, 7, 0.4)); - - [dir='rtl'] & { - margin-left: 0; - margin-right: 6px; - } -} \ No newline at end of file +@import url("./views/favorites.css"); diff --git a/static/css/inlineViewer.css b/static/css/inlineViewer.css index 2dcb0bc9..943bafa3 100644 --- a/static/css/inlineViewer.css +++ b/static/css/inlineViewer.css @@ -1,226 +1 @@ -/* OxiCloud Inline Viewer Styles */ - -.inline-viewer-modal { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 9999; - background-color: rgba(0, 0, 0, 0.85); - display: none; - opacity: 0; - transition: opacity 0.3s ease; - pointer-events: none; -} - -.inline-viewer-modal.active { - display: flex !important; - opacity: 1; - align-items: center; - justify-content: center; - pointer-events: all; -} - -.inline-viewer-content { - width: 90%; - height: 90%; - max-width: 1200px; - background-color: #fff; - border-radius: 8px; - overflow: hidden; - display: flex; - flex-direction: column; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); -} - -.inline-viewer-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 12px 16px; - background-color: #f8f9fa; - border-bottom: 1px solid #e2e8f0; -} - -.inline-viewer-title { - font-size: 18px; - font-weight: 500; - color: #2d3748; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.inline-viewer-close { - background: none; - border: none; - font-size: 18px; - cursor: pointer; - color: #718096; - width: 36px; - height: 36px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - transition: background-color 0.2s; -} - -.inline-viewer-close:hover { - background-color: #e2e8f0; - color: #4a5568; -} - -.inline-viewer-container { - flex-grow: 1; - overflow: auto; - background-color: #f0f3f7; - display: flex; - align-items: center; - justify-content: center; - position: relative; -} - -.inline-viewer-toolbar { - display: flex; - justify-content: space-between; - align-items: center; - padding: 12px 16px; - background-color: #f8f9fa; - border-top: 1px solid #e2e8f0; -} - -.inline-viewer-download { - background-color: #ff5e3a; - color: white; - border: none; - border-radius: 4px; - padding: 8px 16px; - font-size: 14px; - font-weight: 500; - cursor: pointer; - display: flex; - align-items: center; - gap: 8px; - transition: background-color 0.2s; -} - -.inline-viewer-download:hover { - background-color: #e74c3c; -} - -.inline-viewer-controls { - display: flex; - gap: 8px; -} - -.inline-viewer-controls button { - background-color: #f1f5f9; - border: 1px solid #cbd5e1; - border-radius: 4px; - width: 36px; - height: 36px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - color: #64748b; - transition: all 0.2s; -} - -.inline-viewer-controls button:hover { - background-color: #e2e8f0; - color: #334155; -} - -/* Image viewer */ -.inline-viewer-image { - max-width: 100%; - max-height: 100%; - object-fit: contain; - transform-origin: center; - transition: transform 0.2s ease; -} - -/* PDF viewer */ -.inline-viewer-pdf, -.inline-viewer-pdf-fallback { - width: 100%; - height: 100%; - border: none; -} - -/* Only show fallback if object fails */ -.inline-viewer-pdf + .inline-viewer-pdf-fallback { - display: none; -} - -.inline-viewer-pdf:not([data]), -.inline-viewer-pdf[data=""] + .inline-viewer-pdf-fallback { - display: block; -} - -/* Loading indicator */ -.inline-viewer-loader { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - font-size: 36px; - color: #64748b; -} - -/* Error and unsupported message */ -.inline-viewer-message { - padding: 32px; - text-align: center; - max-width: 400px; -} - -.inline-viewer-icon { - font-size: 64px; - color: #cbd5e1; - margin-bottom: 24px; -} - -.inline-viewer-text { - color: #64748b; - line-height: 1.6; -} - -.inline-viewer-text p { - margin: 0 0 16px; -} - -/* Text viewer */ -.inline-viewer-text-content { - width: 100%; - height: 100%; - margin: 0; - padding: 16px 24px; - font-family: 'Courier New', Consolas, Monaco, monospace; - font-size: 14px; - line-height: 1.6; - color: #2d3748; - background-color: #fff; - overflow: auto; - white-space: pre-wrap; - word-wrap: break-word; - box-sizing: border-box; - text-align: left; - tab-size: 4; -} - -/* Responsive adjustments */ -@media (max-width: 768px) { - .inline-viewer-content { - width: 100%; - height: 100%; - border-radius: 0; - } - - .inline-viewer-controls { - display: none; - } -} \ No newline at end of file +@import url("./views/inlineViewer.css"); diff --git a/static/css/layout/content.css b/static/css/layout/content.css new file mode 100644 index 00000000..061954d6 --- /dev/null +++ b/static/css/layout/content.css @@ -0,0 +1,38 @@ +/* Content area */ +.content-area { + flex-grow: 1; + padding: 20px; + overflow-y: scroll; + scrollbar-gutter: stable; +} + +.page-title { + font-size: 24px; + font-weight: bold; + margin-bottom: 20px; + color: #2d3748; +} + +.actions-bar { + display: flex; + justify-content: space-between; + margin-bottom: 20px; +} + +.action-buttons { + display: flex; + gap: 12px; +} + +.empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px; + text-align: center; + color: #888; + width: 100%; + height: 300px; + grid-column: 1 / -1; +} diff --git a/static/css/layout/sidebar.css b/static/css/layout/sidebar.css new file mode 100644 index 00000000..24ca927c --- /dev/null +++ b/static/css/layout/sidebar.css @@ -0,0 +1,177 @@ +/* Sidebar */ +.sidebar { + width: 250px; + background: linear-gradient(180deg, #2a3042 0%, #232838 100%); + color: #fff; + display: flex; + flex-direction: column; + height: 100%; + flex-shrink: 0; + box-shadow: 2px 0 12px rgba(0,0,0,0.15); +} + +.logo-container { + padding: 22px 20px; + display: flex; + align-items: center; + border-bottom: 1px solid rgba(255,255,255,0.07); + margin-bottom: 8px; +} + +.logo { + width: 40px; + height: 40px; + background: linear-gradient(135deg, #ff5e3a 0%, #ff8a5c 100%); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + margin-right: 12px; + box-shadow: 0 3px 10px rgba(255,94,58,0.35); + transition: transform 0.2s, box-shadow 0.2s; + + [dir='rtl'] & { + margin-left: 12px; + margin-right: unset; + } +} + +.logo:hover { + transform: scale(1.05); + box-shadow: 0 4px 14px rgba(255,94,58,0.45); +} + +.logo svg { + width: 22px; + height: 22px; + fill: white; +} + +.app-name { + font-size: 19px; + font-weight: 700; + color: white; + letter-spacing: 0.3px; +} + +.nav-menu { + display: flex; + flex-direction: column; + flex-grow: 1; + padding: 8px 12px; + gap: 2px; +} + +.nav-item { + display: flex; + align-items: center; + padding: 11px 14px; + border-radius: 10px; + cursor: pointer; + color: rgba(255,255,255,0.65); + font-size: 14.5px; + font-weight: 500; + transition: all 0.2s ease; + position: relative; + border-left: 3px solid transparent; + + [dir='rtl'] & { + border-left: none; + border-right: 3px solid transparent; + } +} + +.nav-item:hover { + background-color: rgba(255,255,255,0.06); + color: rgba(255,255,255,0.9); +} + +.nav-item.active { + background-color: rgba(255,94,58,0.12); + color: #fff; + border-left-color: #ff5e3a; + font-weight: 600; + + [dir='rtl'] & { + border-left-color: transparent; + border-right-color: #ff5e3a; + } +} + +.nav-item i, +.nav-item .oxi-icon { + margin-right: 14px; + width: 20px; + height: 20px; + text-align: center; + font-size: 16px; + transition: color 0.2s, transform 0.2s; + flex-shrink: 0; + + [dir='rtl'] & { + margin-left: 14px; + margin-right: unset; + } +} + +/* Colored icons per section */ +.nav-item:nth-child(1) i, .nav-item:nth-child(1) .oxi-icon { color: #ffa94d; } /* Files - orange */ +.nav-item:nth-child(2) i, .nav-item:nth-child(2) .oxi-icon { color: #74b9ff; } /* Shared - blue */ +.nav-item:nth-child(3) i, .nav-item:nth-child(3) .oxi-icon { color: #81ecec; } /* Recent - teal */ +.nav-item:nth-child(4) i, .nav-item:nth-child(4) .oxi-icon { color: #ffd43b; } /* Favorites - gold */ +.nav-item:nth-child(5) i, .nav-item:nth-child(5) .oxi-icon { color: #ff7675; } /* Trash - red */ + +.nav-item.active:nth-child(1) i, .nav-item.active:nth-child(1) .oxi-icon { color: #ff5e3a; } +.nav-item.active:nth-child(2) i, .nav-item.active:nth-child(2) .oxi-icon { color: #0984e3; } +.nav-item.active:nth-child(3) i, .nav-item.active:nth-child(3) .oxi-icon { color: #00cec9; } +.nav-item.active:nth-child(4) i, .nav-item.active:nth-child(4) .oxi-icon { color: #f0c800; } +.nav-item.active:nth-child(5) i, .nav-item.active:nth-child(5) .oxi-icon { color: #e74c3c; } + +.nav-item:hover i, +.nav-item:hover .oxi-icon { + transform: scale(1.1); +} + +/* Storage indicator */ +.storage-container { + margin: auto 12px 16px 12px; + background: rgba(255,255,255,0.05); + border: 1px solid rgba(255,255,255,0.07); + border-radius: 12px; + padding: 16px; +} + +.storage-title { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + margin-bottom: 12px; + font-size: 13px; + font-weight: 600; + color: rgba(255,255,255,0.8); + letter-spacing: 0.3px; +} + +.storage-bar { + height: 6px; + background-color: rgba(255,255,255,0.1); + border-radius: 3px; + overflow: hidden; + margin-bottom: 10px; +} + +.storage-fill { + height: 100%; + background: linear-gradient(90deg, #ff5e3a 0%, #ff8a5c 100%); + border-radius: 3px; + width: 0%; + transition: width 0.8s ease; +} + +.storage-info { + text-align: center; + font-size: 11.5px; + color: rgba(255,255,255,0.5); + font-weight: 400; +} diff --git a/static/css/layout/topbar.css b/static/css/layout/topbar.css new file mode 100644 index 00000000..1b470074 --- /dev/null +++ b/static/css/layout/topbar.css @@ -0,0 +1,127 @@ +/* Main content */ +.main-content { + flex-grow: 1; + display: flex; + flex-direction: column; + overflow: hidden; +} + +/* Top bar */ +.top-bar { + height: 70px; + min-height: 70px; + max-height: 70px; + background-color: white; + border-bottom: 1px solid #e6e6e6; + display: flex; + align-items: center; + padding: 0 30px; + justify-content: space-between; + flex-shrink: 0; +} + +.search-container { + flex-grow: 1; + max-width: 600px; + position: relative; + margin-right: 20px; + display: flex; + align-items: center; + + [dir='rtl'] & { + margin-left: 20px; + margin-right: unset; + } +} + +.search-container input { + width: 100%; + padding: 12px 50px 12px 44px; + border-radius: 12px; + border: 2px solid #e2e8f0; + background-color: #f8fafc; + font-size: 14px; + height: 46px; + color: #1a202c; + transition: all 0.2s ease; +} + +.search-container input:hover { + border-color: #cbd5e0; + background-color: #fff; +} + +.search-container input:focus { + outline: none; + border-color: #ff5e3a; + background-color: #fff; + box-shadow: 0 0 0 4px rgba(255, 94, 58, 0.1); +} + +.search-container input::placeholder { + color: #a0aec0; +} + +.search-icon { + position: absolute; + left: 16px; + top: 50%; + transform: translateY(-50%); + color: #a0aec0; + font-size: 16px; + pointer-events: none; + transition: color 0.2s ease; + + [dir='rtl'] & { + right: 16px; + left: unset; + } +} + +.search-container input:focus + .search-icon, +.search-container:focus-within .search-icon { + color: #ff5e3a; +} + +.search-button { + position: absolute; + right: 6px; + top: 50%; + transform: translateY(-50%); + background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); + color: white; + border: none; + border-radius: 10px; + width: 36px; + height: 36px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s ease; + box-shadow: 0 2px 8px rgba(255, 94, 58, 0.3); + + [dir='rtl'] & { + left: 6px; + right: unset; + } +} + +.search-button:hover { + transform: translateY(-50%) scale(1.05); + box-shadow: 0 4px 12px rgba(255, 94, 58, 0.4); +} + +.search-button:active { + transform: translateY(-50%) scale(0.98); +} + +.search-button i { + font-size: 14px; +} + +.user-controls { + display: flex; + align-items: center; + gap: 12px; +} diff --git a/static/css/main.css b/static/css/main.css new file mode 100644 index 00000000..2248769b --- /dev/null +++ b/static/css/main.css @@ -0,0 +1,29 @@ +/* Base */ +@import url("./base/variables.css"); +@import url("./base/reset.css"); +@import url("./base/forms.css"); + +/* Layout */ +@import url("./layout/sidebar.css"); +@import url("./layout/topbar.css"); +@import url("./layout/content.css"); + +/* Components */ +@import url("./components/breadcrumb.css"); +@import url("./components/buttons.css"); +@import url("./components/cards.css"); +@import url("./components/fileList.css"); +@import url("./components/contextMenu.css"); +@import url("./components/dialogs.css"); +@import url("./components/modals.css"); +@import url("./components/shareDialog.css"); +@import url("./components/uploadDropdown.css"); +@import url("./components/notifications.css"); +@import url("./components/userMenu.css"); +@import url("./components/languageSelector.css"); +@import url("./components/multiSelect.css"); +@import url("./components/spinner.css"); +@import url("./components/search.css"); + +/* Theme */ +@import url("./themes/dark.css"); diff --git a/static/css/profile.css b/static/css/profile.css index a9966e17..65a43e34 100644 --- a/static/css/profile.css +++ b/static/css/profile.css @@ -1,148 +1 @@ -*{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{background:#f5f7fa;color:#1e293b;min-height:100vh;display:flex;flex-direction:column} - -.link-reset-flex{text-decoration:none;color:inherit;display:flex;align-items:center;gap:14px} -.width-zero{width:0%} - -#main-content{display:none} - -/* ── Scrollbar ── */ -::-webkit-scrollbar{width:8px} -::-webkit-scrollbar-track{background:transparent} -::-webkit-scrollbar-thumb{background:rgba(0,0,0,.15);border-radius:4px} -*{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.15) transparent} - -/* ── Header ── */ -.profile-header{ - background:linear-gradient(135deg,#2a3042 0%,#232838 100%); - padding:0 32px;height:64px;display:flex;align-items:center;justify-content:space-between; - box-shadow:0 2px 12px rgba(0,0,0,.15);position:sticky;top:0;z-index:100; -} -.profile-header-left{display:flex;align-items:center;gap:14px} -.profile-logo{ - width:38px;height:38px;background:linear-gradient(135deg,#ff5e3a,#ff2d55);border-radius:11px; - display:flex;align-items:center;justify-content:center; - box-shadow:0 3px 10px rgba(255,94,58,.35); -} -.profile-logo svg{width:20px;height:20px;fill:#fff} -.profile-title-text{font-size:17px;font-weight:700;color:#fff;letter-spacing:.3px} -.profile-title-separator{font-size:17px;color:rgba(255,255,255,.5);font-weight:400;margin-left:6px} -.profile-header-right a{ - color:rgba(255,255,255,.65);text-decoration:none;font-size:13px;font-weight:500; - display:flex;align-items:center;gap:6px;transition:color .2s; -} -.profile-header-right a:hover{color:#fff} - -/* ── Container ── */ -.profile-container{max-width:720px;margin:0 auto;padding:32px 24px 60px;width:100%} - -/* ── Card ── */ -.profile-card{background:#fff;border-radius:16px;box-shadow:0 1px 4px rgba(0,0,0,.06),0 0 0 1px rgba(0,0,0,.03);padding:32px;margin-bottom:22px} -.profile-card h2{font-size:16px;font-weight:700;margin-bottom:20px;color:#1e293b;display:flex;align-items:center;gap:10px} -.profile-card h2 i{color:#ff5e3a;font-size:17px} - -/* ── Avatar Section ── */ -.avatar-section{display:flex;align-items:center;gap:24px;margin-bottom:8px} -.avatar-large{ - width:88px;height:88px;border-radius:50%; - background:linear-gradient(135deg,#ff5e3a,#ff2d55); - display:flex;align-items:center;justify-content:center; - color:#fff;font-size:32px;font-weight:700;letter-spacing:1px; - box-shadow:0 6px 20px rgba(255,94,58,.3);flex-shrink:0; -} -.avatar-info h1{font-size:22px;font-weight:700;color:#1e293b;margin-bottom:4px} -.avatar-info .email{font-size:14px;color:#64748b;margin-bottom:8px} -.avatar-info .role-badge{ - display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600; - padding:4px 12px;border-radius:20px; -} -.role-badge-admin{background:#dbeafe;color:#1d4ed8} -.role-badge-user{background:#f1f5f9;color:#64748b} - -/* ── Info Grid ── */ -.info-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px} -@media(max-width:560px){.info-grid{grid-template-columns:1fr}} -.info-item{padding:16px;background:#f8fafc;border-radius:12px;border:1px solid #e2e8f0} -.info-item .info-label{font-size:11.5px;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;font-weight:700;margin-bottom:4px;display:flex;align-items:center;gap:6px} -.info-item .info-label i{font-size:12px;color:#cbd5e1} -.info-item .info-value{font-size:15px;font-weight:600;color:#1e293b} - -/* ── Storage ── */ -.storage-section{margin-top:4px} -.storage-stats{display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px;margin-bottom:16px} -@media(max-width:560px){.storage-stats{grid-template-columns:1fr}} -.storage-stat{text-align:center;padding:16px;background:#f8fafc;border-radius:12px;border:1px solid #e2e8f0} -.storage-stat .stat-value{font-size:1.5rem;font-weight:800;color:#1e293b} -.storage-stat .stat-label{font-size:11px;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;font-weight:600;margin-top:2px} -.storage-bar-wrap{margin-top:4px} -.storage-bar{height:10px;background:#e2e8f0;border-radius:5px;overflow:hidden} -.storage-fill{height:100%;border-radius:5px;transition:width .6s ease} -.storage-fill.green{background:linear-gradient(90deg,#059669,#10b981)} -.storage-fill.orange{background:linear-gradient(90deg,#d97706,#f59e0b)} -.storage-fill.red{background:linear-gradient(90deg,#dc2626,#ef4444)} -.storage-text{font-size:12px;color:#94a3b8;text-align:right;margin-top:6px} - -/* ── Change Password ── */ -.form-group{margin-bottom:16px} -.form-group label{display:block;font-size:13px;font-weight:600;margin-bottom:4px;color:#334155} -.form-group input{ - width:100%;padding:10px 14px;border:2px solid #e2e8f0;border-radius:10px;font-size:14px; - background:#f8fafc;transition:all .2s;font-family:inherit;color:#1e293b; -} -.form-group input:focus{outline:none;border-color:#ff5e3a;background:#fff;box-shadow:0 0 0 3px rgba(255,94,58,.1)} -.form-group small{color:#94a3b8;font-size:12px;display:block;margin-top:3px} - -.btn{ - padding:10px 22px;border:none;border-radius:10px;font-size:14px;font-weight:600; - cursor:pointer;transition:all .15s;white-space:nowrap;display:inline-flex;align-items:center;gap:6px; -} -.btn-primary{background:linear-gradient(135deg,#ff5e3a,#ff2d55);color:#fff;box-shadow:0 2px 8px rgba(255,94,58,.25)} -.btn-primary:hover{box-shadow:0 4px 14px rgba(255,94,58,.35);transform:translateY(-1px)} -.btn-primary:disabled{opacity:.4;cursor:not-allowed;transform:none!important} - -.alert{padding:12px 16px;border-radius:10px;font-size:13px;margin-top:14px;font-weight:500} -.alert-success{background:#ecfdf5;color:#065f46;border:1px solid #a7f3d0} -.alert-error{background:#fef2f2;color:#991b1b;border:1px solid #fecaca} - -/* ── Loading / Error ── */ -#loading{text-align:center;padding:80px;color:#94a3b8;font-size:15px} -#loading i{font-size:32px;color:#ff5e3a;display:block;margin-bottom:12px;animation:spin 1s linear infinite} -@keyframes spin{to{transform:rotate(360deg)}} -#auth-error{display:none;text-align:center;padding:80px 20px} -#auth-error .err-icon{width:80px;height:80px;background:#fef2f2;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 20px} -#auth-error .err-icon i{font-size:32px;color:#ef4444} -#auth-error h2{color:#991b1b;margin-bottom:8px;font-size:20px} -#auth-error p{color:#64748b;margin-bottom:20px;font-size:14px} -#auth-error a{display:inline-flex;align-items:center;gap:6px;padding:10px 24px;background:linear-gradient(135deg,#ff5e3a,#ff2d55);color:#fff;text-decoration:none;border-radius:10px;font-weight:600;font-size:14px;box-shadow:0 3px 12px rgba(255,94,58,.3);transition:all .2s} -#auth-error a:hover{transform:translateY(-1px);box-shadow:0 5px 18px rgba(255,94,58,.4)} - -/* ── Dark Mode ── */ -[data-theme="dark"] body{background:#0f172a;color:#e2e8f0} -[data-theme="dark"] ::-webkit-scrollbar-thumb{background:rgba(255,255,255,.15)} -[data-theme="dark"] *{scrollbar-color:rgba(255,255,255,.15) transparent} -[data-theme="dark"] .profile-card{background:#1e293b;box-shadow:0 1px 4px rgba(0,0,0,.2),0 0 0 1px rgba(255,255,255,.03)} -[data-theme="dark"] .profile-card h2{color:#f1f5f9} -[data-theme="dark"] .avatar-info h1{color:#f1f5f9} -[data-theme="dark"] .avatar-info .email{color:#94a3b8} -[data-theme="dark"] .role-badge-admin{background:#1e3a5f;color:#60a5fa} -[data-theme="dark"] .role-badge-user{background:#334155;color:#94a3b8} -[data-theme="dark"] .info-item{background:#162032;border-color:#334155} -[data-theme="dark"] .info-item .info-label{color:#64748b} -[data-theme="dark"] .info-item .info-label i{color:#475569} -[data-theme="dark"] .info-item .info-value{color:#f1f5f9} -[data-theme="dark"] .storage-stat{background:#162032;border-color:#334155} -[data-theme="dark"] .storage-stat .stat-value{color:#f1f5f9} -[data-theme="dark"] .storage-stat .stat-label{color:#64748b} -[data-theme="dark"] .storage-bar{background:#334155} -[data-theme="dark"] .storage-text{color:#64748b} -[data-theme="dark"] .form-group label{color:#94a3b8} -[data-theme="dark"] .form-group input{background:#0f172a;border-color:#334155;color:#e2e8f0} -[data-theme="dark"] .form-group input:focus{border-color:#ff5e3a;background:#0f172a;box-shadow:0 0 0 3px rgba(255,94,58,.15)} -[data-theme="dark"] .form-group small{color:#64748b} -[data-theme="dark"] .alert-success{background:#052e16;color:#86efac;border-color:#065f46} -[data-theme="dark"] .alert-error{background:#3b1111;color:#fca5a5;border-color:#991b1b} -[data-theme="dark"] #auth-error{background:transparent} -[data-theme="dark"] #auth-error .err-icon{background:#3b1111} -[data-theme="dark"] #auth-error h2{color:#fca5a5} -[data-theme="dark"] #auth-error p{color:#94a3b8} -[data-theme="dark"] #loading{color:#64748b} +@import url("./views/profile.css"); diff --git a/static/css/recent.css b/static/css/recent.css index 008907f0..17e536a5 100644 --- a/static/css/recent.css +++ b/static/css/recent.css @@ -1,92 +1 @@ -/* Styles for the recent files feature */ - -/* Recent indicator */ -.recent-indicator { - position: absolute; - top: 10px; - right: 10px; - width: 25px; - height: 25px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - color: #6c757d; - z-index: 5; - - [dir='rtl'] & { - left: 10px; - right: unset; - } -} - -/* Styles for the recent view items */ -.recent-item { - position: relative; -} - -/* Adjustments for grid view */ -.file-card.recent-item { - border-left: 3px solid #6c757d; - - [dir='rtl'] & { - border-right: 3px solid #6c757d; - border-left: unset; - } -} - -/* Adjustments for list view */ -.list-header.recent-header { - grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; -} - -.file-item.recent-item { - position: relative; - grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; -} - -.file-item.recent-item .recent-indicator { - position: relative; - top: 0; - right: 0; - width: 30px; - height: 30px; -} - -/* Styles for the recent-specific empty state */ -.recents-empty-state { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 50px 20px; - text-align: center; - color: #6c757d; -} - -.recents-empty-state i { - font-size: 48px; - color: #6c757d; - margin-bottom: 20px; - opacity: 0.6; -} - -.recents-empty-state p { - margin-bottom: 10px; - max-width: 400px; -} - -/* Tooltip for access time */ -.recent-item .file-info { - cursor: help; -} - -/* Animation for recent files */ -.recent-item { - animation: recent-fade-in 0.3s ease; -} - -@keyframes recent-fade-in { - from { opacity: 0; transform: translateY(10px); } - to { opacity: 1; transform: translateY(0); } -} \ No newline at end of file +@import url("./views/recent.css"); diff --git a/static/css/style.css b/static/css/style.css index a97d45f8..c72e85e1 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -1,5115 +1 @@ -/* Reset and base styles */ -* { - 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; -} - -/* Custom scrollbar styling */ -::-webkit-scrollbar { - width: 8px; -} - -::-webkit-scrollbar-track { - background: transparent; -} - -::-webkit-scrollbar-thumb { - background-color: rgba(0, 0, 0, 0.2); - border-radius: 4px; -} - -::-webkit-scrollbar-thumb:hover { - background-color: rgba(0, 0, 0, 0.3); -} - -/* Firefox scrollbar */ -* { - scrollbar-width: thin; - scrollbar-color: rgba(0, 0, 0, 0.2) transparent; -} - -/* Global select styling */ -select { - padding: 8px 32px 8px 12px; - border: 1px solid #e2e8f0; - border-radius: 8px; - background-color: white; - font-size: 14px; - color: #2d3748; - cursor: pointer; - appearance: none; - -webkit-appearance: none; - -moz-appearance: none; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23718096' d='M6 8L1 3h10z'/%3E%3C/svg%3E"); - background-repeat: no-repeat; - background-position: right 10px center; - transition: border-color 0.15s ease, box-shadow 0.15s ease; - font-family: inherit; -} - -select:hover { - border-color: #cbd5e0; -} - -select:focus { - outline: none; - border-color: #ff5e3a; - box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); -} - -/* Sidebar */ -.sidebar { - width: 250px; - background: linear-gradient(180deg, #2a3042 0%, #232838 100%); - color: #fff; - display: flex; - flex-direction: column; - height: 100%; - flex-shrink: 0; - box-shadow: 2px 0 12px rgba(0,0,0,0.15); -} - -.logo-container { - padding: 22px 20px; - display: flex; - align-items: center; - border-bottom: 1px solid rgba(255,255,255,0.07); - margin-bottom: 8px; -} - -.logo { - width: 40px; - height: 40px; - background: linear-gradient(135deg, #ff5e3a 0%, #ff8a5c 100%); - border-radius: 12px; - display: flex; - align-items: center; - justify-content: center; - margin-right: 12px; - box-shadow: 0 3px 10px rgba(255,94,58,0.35); - transition: transform 0.2s, box-shadow 0.2s; - - [dir='rtl'] & { - margin-left: 12px; - margin-right: unset; - } -} - -.logo:hover { - transform: scale(1.05); - box-shadow: 0 4px 14px rgba(255,94,58,0.45); -} - -.logo svg { - width: 22px; - height: 22px; - fill: white; -} - -.app-name { - font-size: 19px; - font-weight: 700; - color: white; - letter-spacing: 0.3px; -} - -.nav-menu { - display: flex; - flex-direction: column; - flex-grow: 1; - padding: 8px 12px; - gap: 2px; -} - -.nav-item { - display: flex; - align-items: center; - padding: 11px 14px; - border-radius: 10px; - cursor: pointer; - color: rgba(255,255,255,0.65); - font-size: 14.5px; - font-weight: 500; - transition: all 0.2s ease; - position: relative; - border-left: 3px solid transparent; - - [dir='rtl'] & { - border-left: none; - border-right: 3px solid transparent; - } -} - -.nav-item:hover { - background-color: rgba(255,255,255,0.06); - color: rgba(255,255,255,0.9); -} - -.nav-item.active { - background-color: rgba(255,94,58,0.12); - color: #fff; - border-left-color: #ff5e3a; - font-weight: 600; - - [dir='rtl'] & { - border-left-color: transparent; - border-right-color: #ff5e3a; - } -} - -.nav-item i, -.nav-item .oxi-icon { - margin-right: 14px; - width: 20px; - height: 20px; - text-align: center; - font-size: 16px; - transition: color 0.2s, transform 0.2s; - flex-shrink: 0; - - [dir='rtl'] & { - margin-left: 14px; - margin-right: unset; - } -} - -/* Colored icons per section */ -.nav-item:nth-child(1) i, .nav-item:nth-child(1) .oxi-icon { color: #ffa94d; } /* Files - orange */ -.nav-item:nth-child(2) i, .nav-item:nth-child(2) .oxi-icon { color: #74b9ff; } /* Shared - blue */ -.nav-item:nth-child(3) i, .nav-item:nth-child(3) .oxi-icon { color: #81ecec; } /* Recent - teal */ -.nav-item:nth-child(4) i, .nav-item:nth-child(4) .oxi-icon { color: #ffd43b; } /* Favorites - gold */ -.nav-item:nth-child(5) i, .nav-item:nth-child(5) .oxi-icon { color: #ff7675; } /* Trash - red */ - -.nav-item.active:nth-child(1) i, .nav-item.active:nth-child(1) .oxi-icon { color: #ff5e3a; } -.nav-item.active:nth-child(2) i, .nav-item.active:nth-child(2) .oxi-icon { color: #0984e3; } -.nav-item.active:nth-child(3) i, .nav-item.active:nth-child(3) .oxi-icon { color: #00cec9; } -.nav-item.active:nth-child(4) i, .nav-item.active:nth-child(4) .oxi-icon { color: #f0c800; } -.nav-item.active:nth-child(5) i, .nav-item.active:nth-child(5) .oxi-icon { color: #e74c3c; } - -.nav-item:hover i, -.nav-item:hover .oxi-icon { - transform: scale(1.1); -} - -/* Storage indicator */ -.storage-container { - margin: auto 12px 16px 12px; - background: rgba(255,255,255,0.05); - border: 1px solid rgba(255,255,255,0.07); - border-radius: 12px; - padding: 16px; -} - -.storage-title { - display: flex; - align-items: center; - justify-content: center; - gap: 6px; - margin-bottom: 12px; - font-size: 13px; - font-weight: 600; - color: rgba(255,255,255,0.8); - letter-spacing: 0.3px; -} - -.storage-bar { - height: 6px; - background-color: rgba(255,255,255,0.1); - border-radius: 3px; - overflow: hidden; - margin-bottom: 10px; -} - -.storage-fill { - height: 100%; - background: linear-gradient(90deg, #ff5e3a 0%, #ff8a5c 100%); - border-radius: 3px; - width: 0%; - transition: width 0.8s ease; -} - -.storage-info { - text-align: center; - font-size: 11.5px; - color: rgba(255,255,255,0.5); - font-weight: 400; -} - -/* Main content */ -.main-content { - flex-grow: 1; - display: flex; - flex-direction: column; - overflow: hidden; -} - -/* Top bar */ -.top-bar { - height: 70px; - min-height: 70px; - max-height: 70px; - background-color: white; - border-bottom: 1px solid #e6e6e6; - display: flex; - align-items: center; - padding: 0 30px; - justify-content: space-between; - flex-shrink: 0; -} - -.search-container { - flex-grow: 1; - max-width: 600px; - position: relative; - margin-right: 20px; - display: flex; - align-items: center; - - [dir='rtl'] & { - margin-left: 20px; - margin-right: unset; - } -} - -.search-container input { - width: 100%; - padding: 12px 50px 12px 44px; - border-radius: 12px; - border: 2px solid #e2e8f0; - background-color: #f8fafc; - font-size: 14px; - height: 46px; - color: #1a202c; - transition: all 0.2s ease; -} - -.search-container input:hover { - border-color: #cbd5e0; - background-color: #fff; -} - -.search-container input:focus { - outline: none; - border-color: #ff5e3a; - background-color: #fff; - box-shadow: 0 0 0 4px rgba(255, 94, 58, 0.1); -} - -.search-container input::placeholder { - color: #a0aec0; -} - -.search-icon { - position: absolute; - left: 16px; - top: 50%; - transform: translateY(-50%); - color: #a0aec0; - font-size: 16px; - pointer-events: none; - transition: color 0.2s ease; - - [dir='rtl'] & { - right: 16px; - left: unset; - } -} - -.search-container input:focus + .search-icon, -.search-container:focus-within .search-icon { - color: #ff5e3a; -} - -.search-button { - position: absolute; - right: 6px; - top: 50%; - transform: translateY(-50%); - background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); - color: white; - border: none; - border-radius: 10px; - width: 36px; - height: 36px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - transition: all 0.2s ease; - box-shadow: 0 2px 8px rgba(255, 94, 58, 0.3); - - [dir='rtl'] & { - left: 6px; - right: unset; - } -} - -.search-button:hover { - transform: translateY(-50%) scale(1.05); - box-shadow: 0 4px 12px rgba(255, 94, 58, 0.4); -} - -.search-button:active { - transform: translateY(-50%) scale(0.98); -} - -.search-button i { - font-size: 14px; -} - -/* Styles for search results */ -.search-results-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 10px 0; - margin-bottom: 15px; - border-bottom: 1px solid #eee; - width: 100%; - flex-wrap: wrap; - gap: 8px; -} - -.search-results-header h3 { - margin: 0; - font-size: 16px; - color: #555; -} - -.search-results-header .search-time { - font-size: 12px; - font-weight: normal; - color: #999; -} - -.search-controls { - display: flex; - align-items: center; - gap: 8px; -} - -.search-sort-select { - padding: 4px 8px; - border: 1px solid #ddd; - border-radius: 4px; - font-size: 13px; - background: #fff; - color: #333; - cursor: pointer; - outline: none; -} - -.search-sort-select:focus { - border-color: var(--primary-color, #4a90d9); -} - -.empty-state { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 40px; - text-align: center; - color: #888; - width: 100%; -} - -.user-controls { - display: flex; - align-items: center; - gap: 12px; -} - -/* User Menu */ -.user-menu-wrapper { - position: relative; -} - -.user-avatar-btn { - background: none; - border: 2px solid transparent; - border-radius: 50%; - padding: 2px; - cursor: pointer; - transition: all 0.25s ease; - display: flex; - align-items: center; - justify-content: center; -} - -.user-avatar-btn:hover { - border-color: rgba(255, 94, 58, 0.4); - transform: scale(1.05); -} - -.user-avatar-btn:hover .user-avatar { - box-shadow: 0 0 0 2px rgba(255, 94, 58, 0.2); -} - -.user-menu-wrapper.open .user-avatar-btn { - border-color: #ff5e3a; -} - -.user-avatar { - width: 38px; - height: 38px; - background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-weight: 700; - font-size: 14px; - letter-spacing: 0.5px; - user-select: none; -} - -.user-menu { - display: none; - position: absolute; - top: calc(100% + 10px); - right: 0; - width: 300px; - background: white; - border-radius: 16px; - box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.05); - z-index: 2000; - overflow: hidden; - animation: userMenuIn 0.2s ease-out; -} - -.user-menu-wrapper.open .user-menu { - display: block; -} - -@keyframes userMenuIn { - from { - opacity: 0; - transform: translateY(-8px) scale(0.97); - } - to { - opacity: 1; - transform: translateY(0) scale(1); - } -} - -.user-menu-header { - display: flex; - align-items: center; - gap: 14px; - padding: 20px 20px 16px; - background: linear-gradient(135deg, #fef5f3 0%, #fdf2f8 100%); - border-bottom: 1px solid #fce7e1; -} - -.user-menu-avatar { - width: 48px; - height: 48px; - min-width: 48px; - background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-weight: 700; - font-size: 17px; - letter-spacing: 0.5px; - box-shadow: 0 4px 12px rgba(255, 94, 58, 0.3); -} - -.user-menu-info { - overflow: hidden; -} - -.user-menu-name { - font-weight: 600; - font-size: 15px; - color: #1e293b; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.user-menu-email { - font-size: 12.5px; - color: #94a3b8; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin-top: 2px; -} - -.user-menu-storage { - padding: 14px 20px; -} - -.user-menu-storage-label { - display: flex; - align-items: center; - gap: 8px; - font-size: 12px; - font-weight: 600; - color: #64748b; - text-transform: uppercase; - letter-spacing: 0.5px; - margin-bottom: 8px; -} - -.user-menu-storage-label i { - font-size: 11px; - color: #94a3b8; -} - -.user-menu-storage-bar { - height: 6px; - background: #f1f5f9; - border-radius: 3px; - overflow: hidden; - margin-bottom: 6px; -} - -.user-menu-storage-fill { - height: 100%; - background: linear-gradient(90deg, #ff5e3a, #ff2d55); - border-radius: 3px; - width: 0%; - transition: width 0.5s ease; -} - -.user-menu-storage-text { - font-size: 11.5px; - color: #94a3b8; -} - -.user-menu-divider { - height: 1px; - background: #f1f5f9; - margin: 4px 0; -} - -.user-menu-item { - display: flex; - align-items: center; - gap: 12px; - width: 100%; - padding: 12px 20px; - border: none; - background: none; - color: #334155; - font-size: 14px; - cursor: pointer; - transition: background 0.15s ease; - text-align: left; -} - -.user-menu-item:hover { - background: #f8fafc; -} - -.user-menu-item i { - width: 20px; - text-align: center; - font-size: 15px; - color: #64748b; -} - -.user-menu-item .theme-toggle-pill { - margin-left: auto; - width: 40px; - height: 22px; - background: #e2e8f0; - border-radius: 11px; - position: relative; - transition: background 0.3s ease; -} - -.user-menu-item .theme-toggle-pill.active { - background: #ff5e3a; -} - -.user-menu-item .theme-toggle-knob { - width: 18px; - height: 18px; - background: white; - border-radius: 50%; - position: absolute; - top: 2px; - left: 2px; - transition: transform 0.3s ease; - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15); -} - -.user-menu-item .theme-toggle-pill.active .theme-toggle-knob { - transform: translateX(18px); -} - -.user-menu-admin { - color: #1d4ed8; -} - -.user-menu-admin i { - color: #3b82f6; -} - -.user-menu-admin:hover { - background: #eff6ff; -} - -.user-menu-role-badge { - padding: 0 20px 4px; -} - -.role-badge { - display: inline-flex; - align-items: center; - gap: 4px; - font-size: 11px; - font-weight: 600; - padding: 2px 10px; - border-radius: 10px; -} - -.role-badge-admin { - background: #dbeafe; - color: #1d4ed8; -} - -.role-badge i { - font-size: 10px; -} - -.user-menu-logout { - color: #ef4444; - margin-bottom: 4px; -} - -.user-menu-logout i { - color: #ef4444; -} - -.user-menu-logout:hover { - background: #fef2f2; -} - -/* About Modal */ -.about-modal-overlay { - display: none; - position: fixed; - inset: 0; - background: rgba(0, 0, 0, 0.5); - backdrop-filter: blur(4px); - z-index: 3000; - justify-content: center; - align-items: center; -} - -.about-modal-overlay.show { - display: flex; -} - -.about-modal { - background: white; - border-radius: 20px; - padding: 40px; - max-width: 400px; - width: 90%; - text-align: center; - box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2); - animation: userMenuIn 0.25s ease-out; -} - -.about-modal-logo { - width: 72px; - height: 72px; - background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); - border-radius: 20px; - display: flex; - align-items: center; - justify-content: center; - margin: 0 auto 20px; - box-shadow: 0 8px 24px rgba(255, 94, 58, 0.3); -} - -.about-modal-logo i { - font-size: 32px; - color: white; -} - -.about-modal h2 { - font-size: 22px; - font-weight: 700; - color: #1e293b; - margin-bottom: 6px; -} - -.about-modal .about-version { - font-size: 13px; - color: #94a3b8; - margin-bottom: 20px; -} - -.about-modal .about-description { - font-size: 14px; - color: #64748b; - line-height: 1.6; - margin-bottom: 24px; -} - -.about-modal .about-tech { - display: flex; - justify-content: center; - gap: 12px; - flex-wrap: wrap; - margin-bottom: 24px; -} - -.about-modal .about-tech-badge { - padding: 4px 12px; - background: #f8fafc; - border: 1px solid #e2e8f0; - border-radius: 20px; - font-size: 12px; - color: #64748b; - font-weight: 500; -} - -.about-modal .about-links { - display: flex; - justify-content: center; - gap: 16px; - margin-bottom: 24px; -} - -.about-modal .about-link { - display: flex; - align-items: center; - gap: 6px; - font-size: 13px; - color: #ff5e3a; - text-decoration: none; - font-weight: 500; - transition: opacity 0.2s; -} - -.about-modal .about-link:hover { - opacity: 0.8; -} - -.about-modal .about-close-btn { - padding: 10px 32px; - background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); - color: white; - border: none; - border-radius: 10px; - font-size: 14px; - font-weight: 600; - cursor: pointer; - transition: transform 0.2s, box-shadow 0.2s; - box-shadow: 0 4px 15px rgba(255, 94, 58, 0.3); -} - -.about-modal .about-close-btn:hover { - transform: translateY(-1px); - box-shadow: 0 6px 20px rgba(255, 94, 58, 0.4); -} - -/* Language Selector - Custom Dropdown */ -.language-selector { - position: relative; - margin-right: 15px; -} - -.language-selector-toggle { - display: flex; - align-items: center; - gap: 8px; - padding: 8px 14px; - background-color: #f0f3f7; - border: 1px solid #e2e8f0; - border-radius: 50px; - cursor: pointer; - font-size: 14px; - font-weight: 500; - color: #4a5568; - transition: all 0.2s ease; - user-select: none; -} - -.language-selector-toggle:hover { - background-color: #e2e8f0; - border-color: #cbd5e0; -} - -.language-selector-toggle i { - font-size: 14px; - color: #718096; -} - -.language-selector-toggle .lang-code { - font-weight: 600; - color: #2d3748; -} - -.language-selector-toggle .dropdown-arrow { - font-size: 10px; - color: #718096; - transition: transform 0.2s ease; - margin-left: 2px; -} - -.language-selector.open .dropdown-arrow { - transform: rotate(180deg); -} - -.language-selector-dropdown { - position: absolute; - top: calc(100% + 8px); - right: 0; - min-width: 160px; - background-color: white; - border-radius: 12px; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); - border: 1px solid #e2e8f0; - opacity: 0; - visibility: hidden; - transform: translateY(-10px); - transition: all 0.2s ease; - z-index: 1000; - overflow: hidden; -} - -.language-selector.open .language-selector-dropdown { - opacity: 1; - visibility: visible; - transform: translateY(0); -} - -.language-option { - display: flex; - align-items: center; - gap: 10px; - padding: 12px 16px; - cursor: pointer; - font-size: 14px; - color: #4a5568; - transition: background-color 0.15s ease; -} - -.language-option:hover { - background-color: #f7fafc; -} - -.language-option.active { - background-color: #fff5f3; - color: #ff5e3a; -} - -.language-option .lang-flag { - font-size: 18px; - line-height: 1; -} - -.language-option .lang-name { - flex: 1; -} - -.language-option .lang-check { - color: #ff5e3a; - font-size: 12px; - opacity: 0; -} - -.language-option.active .lang-check { - opacity: 1; -} - -/* Content area */ -.content-area { - flex-grow: 1; - padding: 20px; - overflow-y: scroll; - scrollbar-gutter: stable; -} - -.page-title { - font-size: 24px; - font-weight: bold; - margin-bottom: 20px; - color: #2d3748; -} - -.actions-bar { - display: flex; - justify-content: space-between; - margin-bottom: 20px; -} - -.action-buttons { - display: flex; - gap: 12px; -} - -.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; -} - -.btn i { - 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); -} - -.btn-primary:hover { - 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); -} - -/* Upload Dropdown */ -.upload-dropdown { - position: relative; - display: inline-block; -} - -.upload-dropdown .btn-primary { - display: flex; - align-items: center; - gap: 6px; -} - -.upload-dropdown-menu { - display: none; - position: absolute; - top: calc(100% + 6px); - left: 0; - min-width: 200px; - background: white; - border-radius: 12px; - box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15); - border: 1px solid #e2e8f0; - z-index: 1000; - overflow: hidden; - animation: dropdownFadeIn 0.15s ease-out; -} - -.upload-dropdown-menu.show { - display: block; -} - -@keyframes dropdownFadeIn { - from { - opacity: 0; - transform: translateY(-8px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.upload-dropdown-item { - display: flex; - align-items: center; - gap: 12px; - width: 100%; - padding: 12px 16px; - border: none; - background: none; - color: #334155; - font-size: 14px; - cursor: pointer; - transition: background 0.15s ease; - text-align: left; -} - -.upload-dropdown-item:hover { - background: #f1f5f9; -} - -.upload-dropdown-item:active { - background: #e2e8f0; -} - -.upload-dropdown-item i { - width: 20px; - text-align: center; - color: #64748b; - font-size: 15px; -} - -.upload-dropdown-item:first-child { - border-bottom: 1px solid #f1f5f9; -} - -.btn-secondary { - 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); -} - -.btn-secondary:active { - 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); -} - -.btn-danger:hover { - 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); -} - -/* View Toggle Buttons */ -.view-toggle { - display: flex; - gap: 6px; - padding: 4px; - background-color: #f0f3f7; - border-radius: 12px; - border: 1px solid #e2e8f0; -} - -.toggle-btn { - display: flex; - align-items: center; - justify-content: center; - width: 40px; - height: 36px; - background-color: transparent; - border: none; - border-radius: 8px; - cursor: pointer; - color: #64748b; - font-size: 16px; - transition: all 0.2s ease; -} - -.toggle-btn:hover { - background-color: #e2e8f0; - color: #4a5568; -} - -.toggle-btn.active { - background-color: white; - color: #ff5e3a; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); -} - -.toggle-btn i { - pointer-events: none; -} - -/* Files grid */ -.files-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(200px, 240px)); - gap: 20px; - justify-content: start; - position: relative; -} - -/* 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; -} - -.file-card { - 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; - transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s; - width: 100%; - min-height: 160px; - position: relative; -} - -.file-card:hover { - transform: translateY(-2px); - box-shadow: 0 5px 15px rgba(0,0,0,0.08); - border-color: #cbd5e0; -} - -.file-card.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); -} - -.file-card.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); -} - -/* Selection checkbox */ -.file-card-checkbox { - position: absolute; - top: 10px; - left: 10px; - width: 22px; - height: 22px; - border-radius: 6px; - border: 2px solid #cbd5e0; - background: white; - display: flex; - align-items: center; - justify-content: center; - opacity: 0; - transition: opacity 0.15s, background 0.15s, border-color 0.15s; - z-index: 10; - cursor: pointer; -} - -.file-card:hover .file-card-checkbox { - opacity: 1; -} - -.file-card.selected .file-card-checkbox { - opacity: 1; - background: #ff5e3a; - border-color: #ff5e3a; -} - -.file-card.selected .file-card-checkbox i { - color: white; - font-size: 11px; -} - -/* More actions button (three dots) */ -.file-card-more { - 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; - transition: opacity 0.15s, background 0.15s; - z-index: 10; - cursor: pointer; - color: #64748b; - font-size: 16px; -} - -.file-card:hover .file-card-more { - opacity: 1; -} - -.file-card-more:hover { - background: #f1f5f9; - color: #334155; -} - -/* Favorite star (mirrors file-card-more button pattern) */ -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; - transition: opacity 0.15s, color 0.15s, background 0.15s; - z-index: 12; - cursor: pointer; - color: #cbd5e0; - font-size: 15px; - padding: 0; - line-height: 1; -} - -.file-card:hover .favorite-star { - opacity: 1; -} - -.favorite-star:hover { - color: #fbbf24; -} - -.favorite-star.active { - opacity: 1; - color: #f59e0b; -} - -.favorite-star.active:hover { - color: #d97706; -} - -.file-card.dragging { - opacity: 0.5; - transform: scale(0.95); - box-shadow: none; -} - -.file-card.drop-target { - background-color: rgba(255, 193, 7, 0.1); - border: 2px dashed #ffc107; -} - -/* Hide FontAwesome / SVG icons inside grid card thumbnails — the decorative - CSS shapes (::before / ::after) already convey the file type visually. - Icons.js replaces with , so we target both. - List-view icons (.file-item .file-icon) are NOT affected. */ -.file-card .file-icon > i, -.file-card .file-icon > svg { - display: none !important; -} - -/* Styles for folders as in the mockup */ -.file-icon.folder-icon { - width: 100px; - height: 70px; - background-color: #ffeaa7; /* Light yellow color */ - 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; /* Darker yellow color for the tab */ - border-radius: 8px 8px 0 0; -} - -/* Style for PDF files */ -.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; -} -.file-icon.pdf-icon::after { - content: "PDF"; - font-size: 16px; - font-weight: 700; - color: #e53e3e; - opacity: 0.65; - letter-spacing: 1px; -} - -/* Style for document files (doc, docx, txt, rtf, odt) */ -.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; -} -.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; -} -.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; -} - -/* Style for shell/script files */ -.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; -} -.file-icon.script-icon::after { - content: ">_"; - font-size: 18px; - font-weight: 700; - font-family: monospace; - color: #4eaa25; - opacity: 0.55; -} - -/* Style for config files */ -.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; -} -.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; -} -.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; -} - -/* Style for images */ -.file-icon.image-icon { - width: 100px; - height: 70px; - background-color: #74b9ff; /* Light blue background */ - border-radius: 4px; - position: relative; - margin-bottom: 10px; - overflow: hidden; -} - -.file-icon.image-icon::before { - content: ""; - position: absolute; - top: 10px; - left: 15px; - width: 20px; - height: 20px; - background-color: #ffda79; /* Yellow circle like a sun */ - border-radius: 50%; -} - -/* Style for videos */ -.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); -} - -.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); -} - -.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; -} - -/* Styles for code files */ -.file-icon.code-icon { - width: 100px; - height: 70px; - background-color: #e2e8f0; /* Light gray background */ - border-radius: 4px; - position: relative; - margin-bottom: 10px; - border-top: 3px solid #556ee6; /* Blue top border */ - overflow: hidden; -} - -/* Lines that simulate code */ -.file-icon.code-icon::before, -.file-icon.code-icon::after { - content: ""; - position: absolute; - left: 10px; - right: 10px; - height: 2px; - background-color: #556ee6; /* Blue color for code */ -} - -.file-icon.code-icon::before { - top: 15px; - width: 80%; -} - -.file-icon.code-icon::after { - top: 25px; - width: 60%; -} - -/* Add additional lines to simulate code */ -.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; /* Gray color for code */ -} - -.file-icon.code-icon .code-line-1 { - top: 35px; - width: 70%; -} - -.file-icon.code-icon .code-line-2 { - top: 45px; - width: 85%; -} - -.file-icon.code-icon .code-line-3 { - top: 55px; - width: 50%; -} - -/* Specific colors for different code file types */ -.file-icon.json-icon { - border-top-color: #ffb86c; /* Orange for JSON */ -} - -.file-icon.json-icon::before, -.file-icon.json-icon::after { - background-color: #ffb86c; -} - -.file-icon.js-icon { - border-top-color: #ffd43b; /* Yellow for JavaScript */ -} - -.file-icon.js-icon::before, -.file-icon.js-icon::after { - background-color: #ffd43b; -} - -.file-icon.html-icon { - border-top-color: #e34c26; /* Red for HTML */ -} - -.file-icon.html-icon::before, -.file-icon.html-icon::after { - background-color: #e34c26; -} - -.file-icon.css-icon { - border-top-color: #2965f1; /* Blue for CSS */ -} - -.file-icon.css-icon::before, -.file-icon.css-icon::after { - background-color: #2965f1; -} - -.file-icon.py-icon { - border-top-color: #3776ab; /* Dark blue for Python */ -} - -.file-icon.py-icon::before, -.file-icon.py-icon::after { - background-color: #3776ab; -} - -/* TypeScript */ -.file-icon.ts-icon { border-top-color: #3178c6; } -.file-icon.ts-icon::before, .file-icon.ts-icon::after { background-color: #3178c6; } - -/* Rust */ -.file-icon.rust-icon { border-top-color: #dea584; } -.file-icon.rust-icon::before, .file-icon.rust-icon::after { background-color: #dea584; } - -/* Go */ -.file-icon.go-icon { border-top-color: #00add8; } -.file-icon.go-icon::before, .file-icon.go-icon::after { background-color: #00add8; } - -/* Java */ -.file-icon.java-icon { border-top-color: #e76f00; } -.file-icon.java-icon::before, .file-icon.java-icon::after { background-color: #e76f00; } - -/* C / C++ */ -.file-icon.c-icon { border-top-color: #555; } -.file-icon.c-icon::before, .file-icon.c-icon::after { background-color: #555; } - -/* C# */ -.file-icon.cs-icon { border-top-color: #68217a; } -.file-icon.cs-icon::before, .file-icon.cs-icon::after { background-color: #68217a; } - -/* PHP */ -.file-icon.php-icon { border-top-color: #8892be; } -.file-icon.php-icon::before, .file-icon.php-icon::after { background-color: #8892be; } - -/* Ruby */ -.file-icon.ruby-icon { border-top-color: #cc342d; } -.file-icon.ruby-icon::before, .file-icon.ruby-icon::after { background-color: #cc342d; } - -/* Swift */ -.file-icon.swift-icon { border-top-color: #fa7343; } -.file-icon.swift-icon::before, .file-icon.swift-icon::after { background-color: #fa7343; } - -/* Kotlin */ -.file-icon.kotlin-icon { border-top-color: #7f52ff; } -.file-icon.kotlin-icon::before, .file-icon.kotlin-icon::after { background-color: #7f52ff; } - -/* SQL */ -.file-icon.sql-icon { border-top-color: #e38c00; } -.file-icon.sql-icon::before, .file-icon.sql-icon::after { background-color: #e38c00; } - -/* YAML / YML */ -.file-icon.yaml-icon { border-top-color: #cb171e; } -.file-icon.yaml-icon::before, .file-icon.yaml-icon::after { background-color: #cb171e; } - -/* TOML */ -.file-icon.toml-icon { border-top-color: #9c4221; } -.file-icon.toml-icon::before, .file-icon.toml-icon::after { background-color: #9c4221; } - -/* Markdown */ -.file-icon.md-icon { border-top-color: #083fa1; } -.file-icon.md-icon::before, .file-icon.md-icon::after { background-color: #083fa1; } - -/* Shell / Script */ -.file-icon.script-icon { border-top-color: #4eaa25; } -.file-icon.script-icon::before, .file-icon.script-icon::after { background-color: #4eaa25; } - -/* Config files */ -.file-icon.config-icon { border-top-color: #718096; } -.file-icon.config-icon::before, .file-icon.config-icon::after { background-color: #718096; } - -/* Spreadsheet (xlsx, xls, csv, ods) */ -.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; -} -.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; -} - -/* Presentation (pptx, ppt, odp, key) */ -.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; -} -.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; -} -.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; -} - -/* Audio files */ -.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; -} -.file-icon.audio-icon::before { - content: "♪"; - font-size: 28px; - color: #f57c00; - opacity: 0.6; -} - -/* Archive (zip, rar, tar, gz, 7z) */ -.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; -} -.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; -} - -/* Installer (exe, msi, dmg, deb, rpm, appimage) */ -.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; -} -.file-icon.installer-icon::before { - content: "⬇"; - font-size: 24px; - color: #7c3aed; - opacity: 0.5; -} - -/* List view icon colors for new types */ -.file-item .file-icon.spreadsheet-icon { background-color: #e6f4ea; width: 36px; height: 36px; margin-bottom: 0; border-top: none; } -.file-item .file-icon.spreadsheet-icon i, -.file-item .file-icon.spreadsheet-icon svg { color: #0d904f; display: flex !important; } -.file-item .file-icon.spreadsheet-icon::before, -.file-item .file-icon.spreadsheet-icon::after { display: none; } - -.file-item .file-icon.presentation-icon { background-color: #fef3e2; width: 36px; height: 36px; margin-bottom: 0; border-top: none; } -.file-item .file-icon.presentation-icon i, -.file-item .file-icon.presentation-icon svg { color: #d04423; display: flex !important; } -.file-item .file-icon.presentation-icon::before, -.file-item .file-icon.presentation-icon::after { display: none; } - -.file-item .file-icon.audio-icon { background-color: #fff3e0; width: 36px; height: 36px; margin-bottom: 0; border-top: none; } -.file-item .file-icon.audio-icon i, -.file-item .file-icon.audio-icon svg { color: #f57c00; display: flex !important; } -.file-item .file-icon.audio-icon::before, -.file-item .file-icon.audio-icon::after { display: none; } - -.file-item .file-icon.archive-icon { background-color: #f5f0eb; width: 36px; height: 36px; margin-bottom: 0; border-top: none; } -.file-item .file-icon.archive-icon i, -.file-item .file-icon.archive-icon svg { color: #8d6e63; display: flex !important; } -.file-item .file-icon.archive-icon::before, -.file-item .file-icon.archive-icon::after { display: none; } - -.file-item .file-icon.installer-icon { background-color: #f3e8ff; width: 36px; height: 36px; margin-bottom: 0; border-top: none; } -.file-item .file-icon.installer-icon i, -.file-item .file-icon.installer-icon svg { color: #7c3aed; display: flex !important; } -.file-item .file-icon.installer-icon::before, -.file-item .file-icon.installer-icon::after { display: none; } - -.file-item .file-icon.script-icon { background-color: #e8f5e9; } -.file-item .file-icon.script-icon i, -.file-item .file-icon.script-icon svg { color: #4eaa25; display: flex !important; } -.file-item .file-icon.script-icon::before, -.file-item .file-icon.script-icon::after { display: none; } - -.file-item .file-icon.config-icon { background-color: #f1f3f5; } -.file-item .file-icon.config-icon i, -.file-item .file-icon.config-icon svg { color: #718096; display: flex !important; } -.file-item .file-icon.config-icon::before, -.file-item .file-icon.config-icon::after { display: none; } - -.file-name { - 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; -} - -.file-info { - font-size: 12px; - color: #718096; - text-align: center; -} - -/* File list - Improved style */ -.files-list-view { - 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: 36px minmax(200px, 2fr) 100px 110px 160px; - padding: 15px; - font-weight: 600; - color: #2d3748; - background-color: #f8f9fa; - border-bottom: 1px solid #e0e6ed; - align-items: center; -} - -.file-item { - display: grid; - grid-template-columns: 36px minmax(200px, 2fr) 100px 110px 160px; - padding: 12px 15px; - border-bottom: 1px solid #f0f0f0; - align-items: center; - cursor: pointer; - transition: background-color 0.2s; - background-color: white; -} - -.file-item.selected { - background-color: #fff8f6; -} - -.file-item.selected:hover { - background-color: #fff0ec; -} - -/* For trash mode, adjust columns (5 cols: name, type, path, date, actions) */ -.list-header.trash-header { - 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; -} - -.file-item:hover { - background-color: #f0f8ff; -} - -.file-item .name-cell { - display: flex; - align-items: center; - gap: 12px; - min-width: 0; - overflow: hidden; -} - -.file-item .name-cell span { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.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; -} - -.file-item .file-icon.folder-icon { - background-color: #ffeaa7; - position: relative; - width: 36px; - height: 36px; - margin-bottom: 0; -} - -.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; -} - -.file-item .file-icon.folder-icon i, -.file-item .file-icon.folder-icon svg { - display: none; -} - -/* List view: show FA/SVG icons, hide grid-only decorative pseudo-elements */ -.file-item .file-icon.doc-icon { - background-color: #e0ecff; -} -.file-item .file-icon.doc-icon i, -.file-item .file-icon.doc-icon svg { - color: #3171d8; - display: flex !important; -} -.file-item .file-icon.doc-icon::before, -.file-item .file-icon.doc-icon::after { - display: none; -} - -/* Specific icons for files in list view */ -.file-item .file-icon.pdf-icon { - background-color: #fee2e2; -} - -.file-item .file-icon.pdf-icon i, -.file-item .file-icon.pdf-icon svg { - color: #e53e3e; - display: flex !important; -} -.file-item .file-icon.pdf-icon::before, -.file-item .file-icon.pdf-icon::after { - display: none; -} - -.file-item .file-icon.image-icon { - background-color: #e0f2fe; -} - -.file-item .file-icon.image-icon i, -.file-item .file-icon.image-icon svg { - color: #3b82f6; - display: flex !important; -} -.file-item .file-icon.image-icon::before, -.file-item .file-icon.image-icon::after { - display: none; -} - -.file-item .file-icon.video-icon { - background: linear-gradient(135deg, #ede9fe, #fce7f3); -} - -.file-item .file-icon.video-icon i, -.file-item .file-icon.video-icon svg { - color: #8b5cf6; - display: flex !important; -} -.file-item .file-icon.video-icon::before, -.file-item .file-icon.video-icon::after { - display: none; -} - -.file-item .file-icon.audio-icon { - background-color: #fef3c7; -} - -.file-item .file-icon.audio-icon i, -.file-item .file-icon.audio-icon svg { - color: #f59e0b; - display: flex !important; -} -.file-item .file-icon.audio-icon::before, -.file-item .file-icon.audio-icon::after { - display: none; -} - -.file-item .date-cell { - color: #718096; - font-size: 14px; -} - -.file-item .size-cell { - color: #718096; - font-size: 14px; - text-align: right; -} - -.file-item .type-cell { - color: #4b5563; - font-weight: 500; - font-size: 14px; -} - -.file-item.dragging { - opacity: 0.5; - background-color: #f9fafb; -} - -.file-item.drop-target { - background-color: rgba(255, 193, 7, 0.1); - border: 2px dashed #ffc107; -} - -/* Breadcrumb */ -.breadcrumb { - display: flex; - align-items: center; - margin-bottom: 15px; - font-size: 14px; - color: #666; -} - -.breadcrumb-item { - cursor: pointer; -} - -.breadcrumb-item:hover { - text-decoration: underline; -} - -.breadcrumb-separator { - margin: 0 8px; -} - -/* 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; -} - -@keyframes contextMenuIn { - 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; -} - -.context-menu-item:hover { - background: #f1f5f9; -} - -.context-menu-item:active { - background: #e2e8f0; -} - -.context-menu-item i { - width: 18px; - text-align: center; - font-size: 14px; - color: #64748b; - - [dir='rtl'] & { - margin-left: 0; - margin-right: 0; - } -} - -.context-menu-item-danger { - color: #ef4444; -} - -.context-menu-item-danger:hover { - background: #fef2f2; -} - -.context-menu-item-danger i { - color: #ef4444; -} - -.context-menu-separator { - height: 1px; - background: #f1f5f9; - margin: 4px 8px; -} - -/* 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; -} - -@keyframes modalFadeIn { - 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; } -} - -.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; -} - -.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; -} - -.rename-dialog-body { - 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; -} - -.rename-dialog input:focus { - 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; -} - -/* Dropzone */ -.dropzone { - border: 2px dashed #ddd; - border-radius: 8px; - padding: 20px; - text-align: center; - margin: 20px 0; - color: #666; - display: none; -} - -.dropzone.active { - border-color: #ff5e3a; - background-color: rgba(255, 94, 58, 0.05); -} - -.upload-progress { - margin-top: 15px; - width: 100%; - display: none; -} - -.progress-bar { - background-color: #f0f0f0; - height: 6px; - border-radius: 3px; - overflow: hidden; -} - -.progress-fill { - height: 100%; - background-color: #ff5e3a; - width: 0%; - transition: width 0.3s; -} - -/* Notification */ -.notification { - position: absolute; - top: 70px; - right: 20px; - background-color: white; - width: 250px; - border-radius: 8px; - box-shadow: 0 5px 15px rgba(0,0,0,0.1); - padding: 15px; - border-left: 4px solid #ff5e3a; - z-index: 1000; - display: none; - - [dir='rtl'] & { - left: 20px; - border-right: 4px solid #ff5e3a; - right: unset; - border-left: unset; - } -} - -.notification-title { - font-weight: bold; - font-size: 14px; - margin-bottom: 5px; - color: #2d3748; -} - -.notification-message { - font-size: 12px; - color: #718096; -} - -/* Modern Modal Overlay */ -.modal-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - display: none; - justify-content: center; - align-items: center; - z-index: 3000; - opacity: 0; - transition: opacity 0.2s ease; -} - -.modal-overlay.active { - display: flex; - opacity: 1; -} - -.modal-container { - background-color: white; - border-radius: 16px; - width: 420px; - max-width: 90%; - box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); - transform: scale(0.9) translateY(-20px); - transition: transform 0.2s ease; - overflow: hidden; -} - -.modal-overlay.active .modal-container { - transform: scale(1) translateY(0); -} - -.modal-header { - display: flex; - align-items: center; - padding: 20px 24px; - border-bottom: 1px solid #e2e8f0; - position: relative; -} - -.modal-icon { - width: 44px; - height: 44px; - background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); - border-radius: 12px; - display: flex; - align-items: center; - justify-content: center; - margin-right: 14px; - flex-shrink: 0; - - [dir='rtl'] & { - margin-left: 14px; - margin-right: unset; - } -} - -.modal-icon i { - color: white; - font-size: 20px; -} - -.modal-header h3 { - font-size: 18px; - font-weight: 600; - color: #1a202c; - margin: 0; - flex: 1; -} - -.modal-close-btn { - position: absolute; - top: 16px; - right: 16px; - width: 32px; - height: 32px; - border: none; - background: #f0f3f7; - border-radius: 8px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - color: #64748b; - transition: all 0.15s ease; - - [dir='rtl'] & { - left: 16px; - right: unset; - } -} - -.modal-close-btn:hover { - background: #e2e8f0; - color: #1a202c; -} - -.modal-body { - padding: 24px; -} - -.modal-body label { - display: block; - font-size: 14px; - font-weight: 500; - color: #4a5568; - margin-bottom: 8px; -} - -.modal-input { - width: 100%; - padding: 12px 16px; - font-size: 15px; - border: 2px solid #e2e8f0; - border-radius: 10px; - background: #f8fafc; - color: #1a202c; - transition: all 0.15s ease; - outline: none; -} - -.modal-input:focus { - border-color: #ff5e3a; - background: white; - box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); -} - -.modal-input::placeholder { - color: #a0aec0; -} - -.modal-footer { - display: flex; - justify-content: flex-end; - gap: 12px; - padding: 16px 24px; - background: #f8fafc; - border-top: 1px solid #e2e8f0; -} - -.modal-footer .btn { - padding: 10px 20px; - font-size: 14px; - font-weight: 500; - border-radius: 10px; - cursor: pointer; - transition: all 0.15s ease; -} - -.modal-footer .btn-secondary { - background: white; - border: 1px solid #e2e8f0; - color: #4a5568; -} - -.modal-footer .btn-secondary:hover { - background: #f0f3f7; - border-color: #cbd5e0; -} - -.modal-footer .btn-primary { - background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); - border: none; - color: white; - box-shadow: 0 2px 8px rgba(255, 94, 58, 0.3); -} - -.modal-footer .btn-primary:hover { - box-shadow: 0 4px 12px rgba(255, 94, 58, 0.4); - transform: translateY(-1px); -} - -.modal-footer .btn-primary:active { - transform: translateY(0); -} - -/* 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; -} - -.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; -} - -.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; -} - -.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; -} - -.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); -} - -.share-dialog-buttons { - display: flex; - justify-content: flex-end; - gap: 12px; - padding: 16px 24px; - background: #f8fafc; - border-top: 1px solid #e2e8f0; -} - -/* Share dialog specific styles */ -.shared-item-info { - padding: 12px 24px; - background: #f8fafc; - border-bottom: 1px solid #e2e8f0; - font-size: 14px; -} - -.share-options { - 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; -} - -#existing-shares-section, #new-share-section { - padding: 0 24px; -} - -.form-group { - margin-bottom: 15px; - padding: 0 24px; -} - -.share-dialog .form-group { - 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; -} - -.shared-dialog.active { - 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; -} - -.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; -} - -.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; -} - -.shared-dialog-header .close-dialog-btn:hover { - background: #f0f0f0; - color: #1a202c; -} - -.shared-dialog .share-link-section, -.shared-dialog .share-permissions-section, -.shared-dialog .share-password-section, -.shared-dialog .share-expiration-section, -.shared-dialog .notification-form { - 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; -} - -.shared-dialog .share-link-input { - 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; -} - -.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; -} - -.shared-dialog .password-input-group { - 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; -} - -.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; -} - -.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; -} - -.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; -} - -.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); -} - -.shared-dialog .notification-form .form-group { - padding: 0; - margin-bottom: 15px; -} - -/* Dark mode for shared-dialog */ -[data-theme="dark"] .shared-dialog-content { - background-color: #1e293b; -} - -[data-theme="dark"] .shared-dialog-header { - color: #e2e8f0; - border-bottom-color: #334155; -} - -[data-theme="dark"] .shared-dialog-header .close-dialog-btn { - color: #94a3b8; -} - -[data-theme="dark"] .shared-dialog-header .close-dialog-btn:hover { - background: #334155; - color: #e2e8f0; -} - -[data-theme="dark"] .shared-dialog .share-link-input input, -[data-theme="dark"] .shared-dialog .password-input-group input, -[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; -} - -[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; -} - -[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; -} - -[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; -} - -[data-theme="dark"] .shared-dialog .share-actions, -[data-theme="dark"] .shared-dialog .notification-actions { - background: #162032; - border-top-color: #334155; -} - -/* 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; -} - -.folder-select-item:hover { - background-color: #f0f3f7; -} - -.folder-select-item.selected { - background-color: rgba(255,94,58,0.1); - color: #ff5e3a; - font-weight: 600; -} - -.folder-select-item i { - color: #ffa94d; - font-size: 16px; -} - -.folder-select-item.selected i { - color: #ff5e3a; -} - -/* 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; -} - -.confirm-dialog.active { - 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; -} - -.confirm-dialog-icon { - padding: 28px 24px 12px; -} - -.confirm-dialog-icon i { - font-size: 40px; - color: #f56565; -} - -.confirm-dialog-title { - 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; -} - -.confirm-dialog-buttons { - 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); -} - -.confirm-dialog-buttons .btn-danger:hover { - box-shadow: 0 4px 12px rgba(229,62,62,0.4); - transform: translateY(-1px); -} - -/* Loading spinner overlay */ -.files-loading-spinner { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 80px 20px; - gap: 16px; - grid-column: 1 / -1; -} - -.files-loading-spinner .spinner { - width: 36px; - height: 36px; - border: 3px solid #e2e8f0; - border-top-color: #ff5e3a; - border-radius: 50%; - animation: spin 0.7s linear infinite; -} - -@keyframes spin { - to { transform: rotate(360deg); } -} - -.files-loading-spinner span { - font-size: 14px; - color: #a0aec0; - font-weight: 500; -} - -.form-group label { - display: block; - margin-bottom: 5px; - font-weight: 500; -} - -.permission-options { - display: flex; - gap: 15px; - margin-top: 5px; -} - -.permission-option { - display: flex; - align-items: center; - gap: 5px; -} - -.existing-share-item { - background-color: #f8f9fa; - border-radius: 4px; - padding: 10px; - margin-bottom: 10px; -} - -.share-url { - font-size: 12px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - margin-bottom: 5px; - color: #1565c0; -} - -.share-info { - font-size: 11px; - display: flex; - gap: 15px; - margin-bottom: 10px; - color: #757575; -} - -.share-protected { - color: #1565c0; -} - -.share-expiration { - color: #b71c1c; -} - -.share-actions { - display: flex; - gap: 5px; - justify-content: flex-end; -} - -.share-link-actions { - display: flex; - gap: 10px; - margin-top: 5px; -} - -.btn-small { - font-size: 12px; - padding: 5px 10px; -} - -#notification-message { - width: 100%; - padding: 10px; - border: 1px solid #ddd; - border-radius: 4px; - resize: vertical; -} - -/* Shared Resources Page Styles */ -/* Header styles for shared page */ -header { - background-color: white; - border-bottom: 1px solid #e6e6e6; - padding: 15px 20px; -} - -.header-container { - display: flex; - justify-content: space-between; - align-items: center; - max-width: 1280px; - margin: 0 auto; -} - -.header-actions { - display: flex; - align-items: center; - gap: 15px; -} - -.header-button { - padding: 8px 15px; - background-color: #f0f3f7; - border: none; - border-radius: 6px; - cursor: pointer; - font-size: 14px; - transition: background-color 0.2s; -} - -.header-button:hover { - background-color: #e6e9ed; -} - -/* Shared page container */ -.shared-page-container { - max-width: 1280px; - margin: 20px auto; - padding: 0 20px; -} - -.shared-header { - margin-bottom: 25px; -} - -.shared-header h2 { - font-size: 24px; - color: #2d3748; - margin-bottom: 8px; -} - -.shared-header p { - color: #718096; - font-size: 16px; -} - -/* Filters and search */ -.shared-filters { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 25px; - flex-wrap: wrap; - gap: 15px; -} - -.filter-group { - display: flex; - align-items: center; - gap: 10px; -} - -.filter-group label { - font-size: 14px; - color: #4a5568; - font-weight: 500; -} - -.filter-group select { - padding: 8px 32px 8px 12px; - border: 1px solid #e2e8f0; - border-radius: 8px; - background-color: white; - font-size: 14px; - color: #2d3748; - cursor: pointer; - appearance: none; - -webkit-appearance: none; - -moz-appearance: none; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23718096' d='M6 8L1 3h10z'/%3E%3C/svg%3E"); - background-repeat: no-repeat; - background-position: right 10px center; - transition: border-color 0.15s ease, box-shadow 0.15s ease; - - [dir='rtl'] & { - background-position: left 10px center; - } -} - -.filter-group select:hover { - border-color: #cbd5e0; -} - -.filter-group select:focus { - outline: none; - border-color: #ff5e3a; - box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); -} - -.search-box { - display: flex; - gap: 10px; -} - -.search-box input { - padding: 8px 15px; - border: 1px solid #e2e8f0; - border-radius: 6px; - font-size: 14px; - width: 250px; -} - -.search-box button { - padding: 8px 15px; - background-color: #ff5e3a; - color: white; - border: none; - border-radius: 6px; - cursor: pointer; - transition: background-color 0.2s; -} - -.search-box button:hover { - background-color: #e64a29; -} - -/* Shared items list */ -.shared-list-container { - background-color: white; - border-radius: 10px; - box-shadow: 0 1px 3px rgba(0,0,0,0.05); - overflow: hidden; -} - -.shared-list { - width: 100%; - border-collapse: collapse; -} - -.shared-list thead th { - padding: 15px; - text-align: left; - font-weight: 600; - color: #2d3748; - background-color: #f8f9fa; - border-bottom: 1px solid #e0e6ed; -} - -.shared-list tbody td { - padding: 15px; - border-bottom: 1px solid #f0f0f0; - vertical-align: middle; -} - -.shared-item-name { - display: flex; - align-items: center; - gap: 10px; -} - -.shared-item-actions { - display: flex; - gap: 10px; -} - -.action-btn { - width: 32px; - height: 32px; - border: 1px solid #e2e8f0; - border-radius: 6px; - background-color: white; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - transition: all 0.2s; -} - -.action-btn:hover { - background-color: #f0f8ff; - border-color: #90cdf4; -} - -.action-icon { - font-size: 14px; -} - -/* Empty state */ -.empty-state { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 60px 20px; - background-color: white; - border-radius: 10px; - box-shadow: 0 1px 3px rgba(0,0,0,0.05); -} - -.empty-state-icon { - font-size: 40px; - margin-bottom: 20px; - color: #a0aec0; -} - -.empty-state h3 { - font-size: 18px; - color: #2d3748; - margin-bottom: 10px; -} - -.empty-state p { - color: #718096; - margin-bottom: 20px; - text-align: center; -} - -/* 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; -} - -.dialog.active { - 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; -} - -.dialog-header { - 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; -} - -.close-dialog-btn { - background: none; - border: none; - font-size: 24px; - cursor: pointer; - color: #a0aec0; -} - -.dialog-body { - padding: 20px; -} - -/* Share dialog specific styles */ -.share-item-info { - display: flex; - align-items: center; - gap: 10px; - margin-bottom: 20px; -} - -.item-icon { - font-size: 24px; -} - -.item-name { - font-size: 16px; - font-weight: 500; - color: #2d3748; -} - -.share-link-section { - margin-bottom: 20px; -} - -.share-link-container { - display: flex; - gap: 10px; -} - -.share-link-container input { - flex-grow: 1; - padding: 10px; - border: 1px solid #e2e8f0; - border-radius: 6px; - font-size: 14px; -} - -.share-link-container button { - padding: 0 15px; - background-color: #4a5568; - color: white; - border: none; - border-radius: 6px; - cursor: pointer; - transition: background-color 0.2s; -} - -.share-link-container button:hover { - background-color: #2d3748; -} - -.share-settings { - margin-bottom: 20px; -} - -.share-setting { - margin-bottom: 15px; -} - -.share-setting label { - display: block; - margin-bottom: 8px; - font-weight: 500; - color: #4a5568; -} - -.permissions-options { - display: flex; - gap: 20px; -} - -.permissions-options label { - font-weight: normal; - display: flex; - align-items: center; - gap: 5px; -} - -.password-setting, .expiration-setting { - display: flex; - align-items: center; - gap: 10px; -} - -.password-setting input[type="checkbox"], .expiration-setting input[type="checkbox"] { - width: auto; -} - -.password-setting input[type="password"], .expiration-setting input[type="date"] { - flex-grow: 1; - padding: 8px 10px; - border: 1px solid #e2e8f0; - border-radius: 6px; - font-size: 14px; -} - -.password-setting button { - padding: 8px 12px; - background-color: #4a5568; - color: white; - border: none; - border-radius: 6px; - cursor: pointer; - font-size: 12px; - transition: background-color 0.2s; -} - -.password-setting button:hover { - background-color: #2d3748; -} - -.share-actions { - display: flex; - justify-content: flex-end; - gap: 10px; -} - -/* Form styles */ -.form-group { - margin-bottom: 15px; -} - -.form-group label { - 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; -} - -.form-group textarea { - resize: vertical; - min-height: 80px; -} - -/* Button styles */ -.button { - padding: 8px 16px; - border: none; - border-radius: 6px; - cursor: pointer; - font-size: 14px; - transition: background-color 0.2s; -} - -.primary { - background-color: #ff5e3a; - color: white; -} - -.primary:hover { - background-color: #e64a29; -} - -.secondary { - background-color: #e2e8f0; - color: #4a5568; -} - -.secondary:hover { - background-color: #cbd5e0; -} - -.danger { - background-color: #f56565; - color: white; -} - -.danger:hover { - background-color: #e53e3e; -} - -/* Notification banner */ -.notification-banner { - position: fixed; - top: 20px; - right: 20px; - padding: 15px 20px; - background-color: white; - border-radius: 8px; - box-shadow: 0 4px 12px rgba(0,0,0,0.1); - display: flex; - align-items: center; - justify-content: space-between; - max-width: 400px; - z-index: 2000; - transform: translateY(-100px); - opacity: 0; - transition: transform 0.3s, opacity 0.3s; -} - -.notification-banner.active { - transform: translateY(0); - opacity: 1; -} - -.notification-banner.success { - border-left: 4px solid #48bb78; -} - -.notification-banner.error { - border-left: 4px solid #f56565; -} - -.close-notification-btn { - background: none; - border: none; - font-size: 18px; - cursor: pointer; - color: #a0aec0; - margin-left: 10px; -} - -/* Folder selection for move dialog */ -.folder-select-item { - padding: 8px 10px; - margin-bottom: 5px; - border-radius: 4px; - cursor: pointer; - display: flex; - align-items: center; -} - -.folder-select-item:hover { - background-color: #f0f8ff; -} - -.folder-select-item.selected { - background-color: #e6f7ff; - border-left: 3px solid #1890ff; - - [dir='rtl'] & { - border-right: 3px solid #1890ff; - border-left: unset; - } -} - -.folder-select-item i { - margin-right: 8px; - color: #ffc107; - - [dir='rtl'] & { - margin-left: 8px; - margin-right: unset; - } -} - -/* Styles for trash */ -.trash-item { - position: relative; -} - -.trash-actions { - position: absolute; - top: 10px; - right: 10px; - display: none; - gap: 8px; -} - -.file-card.trash-item:hover .trash-actions, -.file-item.trash-item:hover .actions-cell { - display: flex; -} - -.trash-actions button, -.actions-cell button { - background: #fff; - border: 1px solid #ddd; - border-radius: 4px; - padding: 4px 8px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - width: 30px; - height: 30px; - transition: all 0.2s; -} - -.trash-actions button:hover, -.actions-cell button:hover { - background: #f0f0f0; -} - -.btn-restore { - color: #4CAF50; -} - -.btn-delete { - color: #f44336; -} - -.actions-cell { - display: flex; - gap: 8px; - justify-content: flex-start; - align-items: center; -} - -.empty-state { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: 300px; - width: 100%; - color: #666; - grid-column: 1 / -1; -} - -/* Danger button for emptying trash */ -.btn-danger { - background-color: #f44336; - color: white; -} - -/* Responsive */ -@media (max-width: 768px) { - .sidebar { - width: 64px; - padding: 0; - } - - .logo-container { - justify-content: center; - padding: 16px 0; - } - - .logo { - margin-right: 0; - } - - .app-name, .storage-title, .storage-info { - display: none; - } - - .nav-menu { - padding: 8px 8px; - } - - .nav-item { - justify-content: center; - padding: 12px 0; - border-left-width: 0; - border-bottom: 3px solid transparent; - } - - .nav-item.active { - border-left-color: transparent; - border-bottom-color: #ff5e3a; - } - - .nav-item i { - margin-right: 0; - font-size: 18px; - } - - .nav-item span { - display: none; - } - - .storage-container { - margin: auto 8px 12px 8px; - padding: 10px 6px; - } - - /* Responsive styles for shared page */ - .shared-filters { - flex-direction: column; - align-items: flex-start; - } - - .shared-list thead th:nth-child(4), - .shared-list thead th:nth-child(5), - .shared-list tbody td:nth-child(4), - .shared-list tbody td:nth-child(5) { - display: none; - } - - .dialog-content { - width: 95%; - } -} - -/* Specific styles for the Shared page */ -.page-description { - color: #718096; - font-size: 16px; - margin-top: -15px; - margin-bottom: 25px; -} - -/* Improvements for the Shared page filters */ -.shared-filters { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 25px; - flex-wrap: wrap; - gap: 15px; - background-color: white; - border-radius: 10px; - padding: 15px; - box-shadow: 0 1px 3px rgba(0,0,0,0.05); -} - -.filter-group { - display: flex; - align-items: center; - gap: 10px; -} - -.filter-group label { - font-size: 14px; - color: #4a5568; - font-weight: 500; -} - -.filter-group select { - padding: 8px 12px; - border: 1px solid #e2e8f0; - border-radius: 6px; - background-color: white; - font-size: 14px; - min-width: 120px; -} - -.search-box { - display: flex; - gap: 10px; -} - -.search-box input { - padding: 8px 15px; - border: 1px solid #e2e8f0; - border-radius: 6px; - font-size: 14px; - width: 250px; -} - -/* Improvements in the shared items table */ -.shared-list-container { - background-color: white; - border-radius: 10px; - box-shadow: 0 1px 3px rgba(0,0,0,0.05); - overflow: hidden; - margin-bottom: 25px; -} - -.shared-list { - width: 100%; - border-collapse: collapse; -} - -.shared-list thead th { - padding: 15px; - text-align: left; - font-weight: 600; - color: #2d3748; - background-color: #f8f9fa; - border-bottom: 1px solid #e0e6ed; -} - -.shared-list tbody td { - padding: 15px; - border-bottom: 1px solid #f0f0f0; - vertical-align: middle; -} - -/* Improved empty state */ -.empty-state { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 60px 20px; - background-color: white; - border-radius: 10px; - box-shadow: 0 1px 3px rgba(0,0,0,0.05); - text-align: center; -} - -.empty-state-icon { - font-size: 48px; - margin-bottom: 20px; - color: #ffc107; -} - -.empty-state h3 { - font-size: 18px; - color: #2d3748; - margin-bottom: 10px; -} - -.empty-state p { - color: #718096; - margin-bottom: 20px; - text-align: center; -} - -.button.primary { - padding: 8px 16px; - border: none; - border-radius: 6px; - cursor: pointer; - font-size: 14px; - background-color: #ff5e3a; - color: white; - text-decoration: none; - display: inline-block; - transition: background-color 0.2s; -} - -.button.primary:hover { - background-color: #e64a29; -} - -html[dir='rtl'] .fa-arrow-left::before { - content: "\f061"; -} - -html[dir='rtl'] .fa-sign-out-alt { - -webkit-transform: rotate(180deg); - transform: rotate(180deg); -} - -/* ============================================================================ - Notification Bell - ============================================================================ */ -.notif-wrapper { - position: relative; -} - -.notif-bell-btn { - background: none; - border: none; - cursor: pointer; - font-size: 18px; - color: #64748b; - width: 40px; - height: 40px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - transition: all 0.2s ease; - position: relative; -} -.notif-bell-btn:hover { - background: rgba(255, 94, 58, 0.08); - color: #ff5e3a; -} -.notif-bell-btn.active { - color: #ff5e3a; - background: rgba(255, 94, 58, 0.1); -} - -/* Badge counter on bell */ -.notif-badge { - position: absolute; - top: 4px; - right: 4px; - min-width: 16px; - height: 16px; - line-height: 16px; - border-radius: 8px; - background: #ff3b30; - color: #fff; - font-size: 10px; - font-weight: 700; - text-align: center; - padding: 0 4px; - pointer-events: none; -} - -/* Animated wiggle for new notifications */ -@keyframes bellRing { - 0%, 100% { transform: rotate(0deg); } - 15% { transform: rotate(14deg); } - 30% { transform: rotate(-14deg); } - 45% { transform: rotate(8deg); } - 60% { transform: rotate(-8deg); } - 75% { transform: rotate(3deg); } -} -.notif-bell-btn.ring i { - animation: bellRing 0.6s ease; -} - -/* Dropdown panel */ -.notif-panel { - display: none; - position: absolute; - top: calc(100% + 10px); - right: -40px; - width: 380px; - max-height: 480px; - background: #fff; - border-radius: 16px; - box-shadow: 0 12px 40px rgba(0,0,0,0.15), 0 0 0 1px rgba(0,0,0,0.05); - z-index: 2000; - overflow: hidden; - animation: notifPanelIn 0.2s ease-out; -} -.notif-wrapper.open .notif-panel { - display: flex; - flex-direction: column; -} - -@keyframes notifPanelIn { - from { opacity: 0; transform: translateY(-8px) scale(0.97); } - to { opacity: 1; transform: translateY(0) scale(1); } -} - -.notif-panel-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 14px 16px; - border-bottom: 1px solid #f0f0f0; -} -.notif-panel-title { - font-weight: 600; - font-size: 15px; - color: #1e293b; -} -.notif-clear-btn { - background: none; - border: none; - cursor: pointer; - color: #94a3b8; - font-size: 14px; - padding: 4px 8px; - border-radius: 6px; - transition: all 0.15s; -} -.notif-clear-btn:hover { - color: #ff5e3a; - background: rgba(255, 94, 58, 0.08); -} - -.notif-panel-body { - flex: 1; - overflow-y: auto; - max-height: 400px; -} -.notif-empty { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 40px 20px; - color: #94a3b8; - gap: 8px; -} -.notif-empty i { - font-size: 28px; - opacity: 0.5; -} -.notif-empty span { - font-size: 14px; -} - -/* Individual notification items */ -.notif-item { - display: flex; - align-items: flex-start; - padding: 12px 16px; - gap: 12px; - border-bottom: 1px solid #f5f5f5; - transition: background 0.15s; - cursor: default; -} -.notif-item:last-child { - border-bottom: none; -} -.notif-item:hover { - background: #f8fafc; -} -.notif-item-icon { - width: 32px; - height: 32px; - border-radius: 8px; - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; - font-size: 14px; -} -.notif-item-icon.upload { - background: rgba(255, 94, 58, 0.1); - color: #ff5e3a; -} -.notif-item-icon.success { - background: rgba(52, 199, 89, 0.1); - color: #34c759; -} -.notif-item-icon.error { - background: rgba(255, 59, 48, 0.1); - color: #ff3b30; -} -.notif-item-body { - flex: 1; - min-width: 0; -} -.notif-item-title { - font-size: 13px; - font-weight: 600; - color: #1e293b; - margin-bottom: 2px; -} -.notif-item-text { - font-size: 12px; - color: #64748b; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.notif-item-time { - font-size: 11px; - color: #94a3b8; - margin-top: 3px; -} - -/* Upload progress inside notification */ -.notif-upload-progress { - margin-top: 6px; -} -.notif-upload-bar { - height: 3px; - background: #eee; - border-radius: 2px; - overflow: hidden; -} -.notif-upload-fill { - height: 100%; - background: #ff5e3a; - width: 0%; - transition: width 0.2s ease; - border-radius: 2px; -} -.notif-upload-fill.done { - background: #34c759; -} -.notif-upload-fill.error { - background: #ff3b30; -} -.notif-upload-detail { - display: flex; - justify-content: space-between; - align-items: center; - margin-top: 3px; -} -.notif-upload-pct { - font-size: 11px; - color: #94a3b8; -} -.notif-upload-stats { - font-size: 11px; - color: #94a3b8; -} - -/* ============================================================================ - Upload Progress Toast (legacy — hidden, kept for compat) - ============================================================================ */ -.upload-toast { - position: fixed; - bottom: 24px; - right: 24px; - width: 360px; - max-height: 400px; - background: #fff; - border-radius: 12px; - box-shadow: 0 8px 30px rgba(0,0,0,0.15); - z-index: 10000; - display: none; - flex-direction: column; - overflow: hidden; - font-family: inherit; - animation: uploadToastSlideIn 0.3s ease-out; -} -.upload-toast.visible { - display: flex; -} -@keyframes uploadToastSlideIn { - from { transform: translateY(20px); opacity: 0; } - to { transform: translateY(0); opacity: 1; } -} -.upload-toast-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 12px 16px; - background: #ff5e3a; - color: #fff; -} -.upload-toast-title { - font-weight: 600; - font-size: 14px; -} -.upload-toast-close { - background: none; - border: none; - color: #fff; - font-size: 20px; - cursor: pointer; - line-height: 1; - padding: 0 4px; - opacity: 0.8; -} -.upload-toast-close:hover { opacity: 1; } - -.upload-toast-body { - flex: 1; - overflow-y: auto; - padding: 8px 0; - max-height: 260px; -} -.upload-toast-file { - display: flex; - align-items: center; - padding: 6px 16px; - gap: 10px; -} -.upload-toast-file-icon { - font-size: 16px; - color: #999; - flex-shrink: 0; - width: 20px; - text-align: center; -} -.upload-toast-file-icon.done { color: #34c759; } -.upload-toast-file-icon.error { color: #ff3b30; } -.upload-toast-file-info { - flex: 1; - min-width: 0; -} -.upload-toast-file-name { - font-size: 13px; - color: #333; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.upload-toast-file-bar { - height: 3px; - background: #eee; - border-radius: 2px; - margin-top: 4px; - overflow: hidden; -} -.upload-toast-file-fill { - height: 100%; - background: #ff5e3a; - width: 0%; - transition: width 0.2s ease; - border-radius: 2px; -} -.upload-toast-file-fill.done { background: #34c759; } -.upload-toast-file-fill.error { background: #ff3b30; } -.upload-toast-file-pct { - font-size: 12px; - color: #999; - flex-shrink: 0; - width: 38px; - text-align: right; -} - -.upload-toast-footer { - padding: 10px 16px; - border-top: 1px solid #f0f0f0; -} -.upload-toast-overall-bar { - height: 4px; - background: #eee; - border-radius: 2px; - overflow: hidden; - margin-bottom: 6px; -} -.upload-toast-overall-fill { - height: 100%; - background: #ff5e3a; - width: 0%; - transition: width 0.25s ease; - border-radius: 2px; -} -.upload-toast-stats { - font-size: 12px; - color: #888; -} - -/* ═══════════════════════════════════════════════════════════ - Multi-Select – checkboxes & batch action bar - ═══════════════════════════════════════════════════════════ */ - -/* -- List-view checkbox column -- */ -.list-header-checkbox, -.list-item-checkbox { - display: flex; - align-items: center; - justify-content: center; -} - -.list-header-checkbox input[type="checkbox"], -.list-item-checkbox input[type="checkbox"] { - width: 17px; - height: 17px; - cursor: pointer; - accent-color: #ff5e3a; - border-radius: 4px; -} - -/* Sync checkbox state visually with .selected */ -.file-item.selected .item-checkbox { - /* Checked via JS */ -} - -/* ── Selection-mode header (replaces Name/Type/Size/Modified) ── */ -.list-header.selection-mode { - grid-template-columns: 36px 1fr; - background-color: #1e293b; - color: #fff; - border-bottom-color: #334155; -} - -.list-header.selection-mode .list-header-checkbox input[type="checkbox"] { - accent-color: #ff5e3a; -} - -.batch-selection-info { - display: flex; - align-items: center; - justify-content: space-between; - gap: 16px; - min-width: 0; -} - -/* -- Batch action bar (grid view floating bar) -- */ -.batch-action-bar { - display: flex; - align-items: center; - justify-content: space-between; - background: #1e293b; - color: #fff; - padding: 10px 20px; - border-radius: 12px; - margin: 0 0 12px; - opacity: 0; - max-height: 0; - overflow: hidden; - transform: translateY(-8px); - transition: opacity 0.2s, max-height 0.25s, transform 0.2s, margin 0.2s, padding 0.2s; - pointer-events: none; -} - -.batch-action-bar.visible { - opacity: 1; - max-height: 60px; - transform: translateY(0); - pointer-events: auto; - padding: 10px 20px; - margin: 0 0 12px; -} - -.batch-bar-left { - display: flex; - align-items: center; - gap: 12px; -} - -.batch-bar-close { - background: none; - border: none; - color: rgba(255,255,255,0.7); - cursor: pointer; - font-size: 14px; - padding: 4px 6px; - border-radius: 6px; - transition: background 0.15s, color 0.15s; -} - -.batch-bar-close:hover { - background: rgba(255,255,255,0.1); - color: #fff; -} - -.batch-bar-count { - font-size: 14px; - font-weight: 600; - white-space: nowrap; -} - -.batch-bar-actions { - display: flex; - align-items: center; - gap: 6px; -} - -.batch-btn { - display: inline-flex; - align-items: center; - gap: 6px; - padding: 7px 14px; - border: none; - border-radius: 8px; - background: rgba(255,255,255,0.1); - color: #fff; - font-size: 13px; - font-weight: 500; - cursor: pointer; - transition: background 0.15s; - white-space: nowrap; -} - -.batch-btn:hover { - background: rgba(255,255,255,0.2); -} - -.batch-btn-danger { - background: rgba(239,68,68,0.25); - color: #fca5a5; -} - -.batch-btn-danger:hover { - background: rgba(239,68,68,0.4); - color: #fff; -} - -/* Responsive: hide button text on small screens */ -@media (max-width: 640px) { - .batch-btn span { - display: none; - } - .batch-btn { - padding: 7px 10px; - } -} - -/* ============================================================ - DARK MODE - ============================================================ */ - -[data-theme="dark"] body { - background-color: #0f172a; -} - -/* Scrollbars */ -[data-theme="dark"] ::-webkit-scrollbar-thumb { - background-color: rgba(255, 255, 255, 0.15); -} -[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { - background-color: rgba(255, 255, 255, 0.25); -} -[data-theme="dark"] * { - scrollbar-color: rgba(255, 255, 255, 0.15) transparent; -} - -/* Selects */ -[data-theme="dark"] select { - background-color: #1e293b; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] select:hover { - border-color: #475569; -} -[data-theme="dark"] select:focus { - border-color: #ff5e3a; - background-color: #1e293b; -} - -/* Sidebar — already dark, minor tweaks */ -[data-theme="dark"] .sidebar { - background: linear-gradient(180deg, #0f172a 0%, #0c1322 100%); -} - -/* Top bar */ -[data-theme="dark"] .top-bar { - background-color: #1e293b; - border-bottom-color: #334155; -} - -/* Search container */ -[data-theme="dark"] .search-container input { - background-color: #1e293b; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .search-container input:hover { - background-color: #1e293b; - border-color: #475569; -} -[data-theme="dark"] .search-container input:focus { - background-color: #1e293b; - border-color: #ff5e3a; -} -[data-theme="dark"] .search-container input::placeholder { - color: #64748b; -} -[data-theme="dark"] .search-icon { - color: #64748b; -} - -/* User menu dropdown */ -[data-theme="dark"] .user-menu { - background: #1e293b; - border-color: #334155; - box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5); -} -[data-theme="dark"] .user-menu-header { - background: linear-gradient(135deg, #1a2332 0%, #1e2940 100%); - border-bottom-color: #334155; -} -[data-theme="dark"] .user-menu-name { - color: #f1f5f9; -} -[data-theme="dark"] .user-menu-email { - color: #64748b; -} -[data-theme="dark"] .user-menu-storage-label { - color: #94a3b8; -} -[data-theme="dark"] .user-menu-storage-bar { - background: #334155; -} -[data-theme="dark"] .user-menu-storage-text { - color: #64748b; -} -[data-theme="dark"] .user-menu-divider { - background: #334155; -} -[data-theme="dark"] .user-menu-item { - color: #cbd5e1; -} -[data-theme="dark"] .user-menu-item:hover { - background: #334155; -} -[data-theme="dark"] .user-menu-item i { - color: #94a3b8; -} -[data-theme="dark"] .theme-toggle-pill { - background: #475569; -} -[data-theme="dark"] .user-menu-admin { - color: #60a5fa; -} -[data-theme="dark"] .user-menu-admin:hover { - background: rgba(59, 130, 246, 0.1); -} -[data-theme="dark"] .role-badge-admin { - background: rgba(59, 130, 246, 0.15); - color: #60a5fa; -} -[data-theme="dark"] .user-menu-logout:hover { - background: rgba(239, 68, 68, 0.1); -} - -/* About modal */ -[data-theme="dark"] .about-modal { - background: #1e293b; -} -[data-theme="dark"] .about-modal h2 { - color: #f1f5f9; -} -[data-theme="dark"] .about-modal .about-version { - color: #94a3b8; -} -[data-theme="dark"] .about-modal .about-description { - color: #94a3b8; -} -[data-theme="dark"] .about-modal .about-tech-badge { - background: #334155; - border-color: #475569; - color: #cbd5e1; -} - -/* Language selector */ -[data-theme="dark"] .language-selector-toggle { - background-color: #1e293b; - border-color: #334155; - color: #cbd5e1; -} -[data-theme="dark"] .language-selector-toggle:hover { - background-color: #334155; -} -[data-theme="dark"] .language-selector-dropdown { - background-color: #1e293b; - border-color: #334155; - box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5); -} -[data-theme="dark"] .language-option { - color: #cbd5e1; -} -[data-theme="dark"] .language-option:hover { - background-color: #334155; -} -[data-theme="dark"] .language-option.active { - background-color: rgba(255, 94, 58, 0.1); - color: #ff5e3a; -} - -/* Content area / page title */ -[data-theme="dark"] .page-title { - color: #f1f5f9; -} - -/* Breadcrumb */ -[data-theme="dark"] .breadcrumb { - color: #94a3b8; -} -[data-theme="dark"] .breadcrumb a { - color: #94a3b8; -} -[data-theme="dark"] .breadcrumb a:hover { - color: #ff5e3a; -} - -/* Action bar buttons */ -[data-theme="dark"] .btn-secondary { - background-color: #1e293b; - color: #cbd5e1; - border-color: #334155; -} -[data-theme="dark"] .btn-secondary:hover { - background-color: #334155; - border-color: #475569; -} -[data-theme="dark"] .btn-secondary:active { - background-color: #475569; -} - -/* Upload dropdown */ -[data-theme="dark"] .upload-dropdown-menu { - background: #1e293b; - border-color: #334155; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); -} -[data-theme="dark"] .upload-dropdown-item { - color: #cbd5e1; -} -[data-theme="dark"] .upload-dropdown-item:hover { - background: #334155; -} -[data-theme="dark"] .upload-dropdown-item:active { - background: #475569; -} -[data-theme="dark"] .upload-dropdown-item i { - color: #94a3b8; -} - -/* View toggle */ -[data-theme="dark"] .view-toggle { - background-color: #1e293b; - border-color: #334155; -} -[data-theme="dark"] .toggle-btn { - color: #94a3b8; -} -[data-theme="dark"] .toggle-btn:hover { - background-color: #334155; -} -[data-theme="dark"] .toggle-btn.active { - background-color: #334155; - color: #ff5e3a; -} - -/* File cards (grid view) */ -[data-theme="dark"] .file-card { - background-color: #1e293b; - border-color: #334155; -} -[data-theme="dark"] .file-card:hover { - border-color: #475569; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); -} -[data-theme="dark"] .file-card.selected { - border-color: #ff5e3a; - background: #1a1520; -} -[data-theme="dark"] .file-card-checkbox { - background: #1e293b; - border-color: #475569; -} -[data-theme="dark"] .file-card-more { - color: #94a3b8; -} -[data-theme="dark"] .file-card-more:hover { - background: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .file-card-name { - color: #e2e8f0; -} -[data-theme="dark"] .file-card-type { - color: #94a3b8; -} -[data-theme="dark"] .file-card.drop-target { - background-color: rgba(255, 193, 7, 0.05); -} - -/* File list (table view) */ -[data-theme="dark"] .files-list-view { - 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; -} -[data-theme="dark"] .file-item { - background-color: #1e293b; - border-bottom-color: #293548; -} -[data-theme="dark"] .file-item:hover { - background-color: #253345; -} -[data-theme="dark"] .file-item.selected { - background-color: #1a1520; -} -[data-theme="dark"] .file-item.selected:hover { - background-color: #231a2a; -} -[data-theme="dark"] .file-item .name-cell { - color: #e2e8f0; -} -[data-theme="dark"] .file-item .date-cell { - color: #64748b; -} -[data-theme="dark"] .file-item .size-cell { - color: #64748b; -} -[data-theme="dark"] .file-item .type-cell { - color: #94a3b8; -} -[data-theme="dark"] .file-item.dragging { - background-color: #334155; -} -[data-theme="dark"] .file-item.drop-target { - background-color: rgba(255, 193, 7, 0.05); -} - -/* Context menu */ -[data-theme="dark"] .context-menu { - background: #1e293b; - border-color: #334155; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); -} -[data-theme="dark"] .context-menu-item { - color: #cbd5e1; -} -[data-theme="dark"] .context-menu-item:hover { - background: #334155; -} -[data-theme="dark"] .context-menu-item:active { - background: #475569; -} -[data-theme="dark"] .context-menu-item i { - color: #94a3b8; -} -[data-theme="dark"] .context-menu-item-danger:hover { - background: rgba(239, 68, 68, 0.1); -} -[data-theme="dark"] .context-menu-separator { - background: #334155; -} - -/* Rename dialog */ -[data-theme="dark"] .rename-dialog-content { - 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; -} -[data-theme="dark"] .rename-dialog input { - background: #0f172a; - color: #e2e8f0; - border-color: #334155; -} -[data-theme="dark"] .rename-dialog input:focus { - border-color: #ff5e3a; - background: #0f172a; -} -[data-theme="dark"] .rename-dialog-buttons { - background: #162032; - border-top-color: #334155; -} - -/* Modal dialogs */ -[data-theme="dark"] .modal-overlay { - background-color: rgba(0, 0, 0, 0.7); -} -[data-theme="dark"] .modal-container { - background-color: #1e293b; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); -} -[data-theme="dark"] .modal-header { - border-bottom-color: #334155; -} -[data-theme="dark"] .modal-header h3 { - color: #f1f5f9; -} -[data-theme="dark"] .modal-close-btn { - background: #334155; - color: #94a3b8; -} -[data-theme="dark"] .modal-close-btn:hover { - background: #475569; - color: #e2e8f0; -} -[data-theme="dark"] .modal-body label { - color: #94a3b8; -} -[data-theme="dark"] .modal-input { - border-color: #334155; - background: #0f172a; - color: #e2e8f0; -} -[data-theme="dark"] .modal-input:focus { - border-color: #ff5e3a; - background: #0f172a; -} -[data-theme="dark"] .modal-input::placeholder { - color: #475569; -} -[data-theme="dark"] .modal-footer { - background: #162032; - border-top-color: #334155; -} -[data-theme="dark"] .modal-footer .btn-secondary { - background: #334155; - border-color: #475569; - color: #cbd5e1; -} -[data-theme="dark"] .modal-footer .btn-secondary:hover { - background: #475569; -} - -/* Notifications */ -[data-theme="dark"] .notification { - background-color: #1e293b; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); -} -[data-theme="dark"] .notification-title { - color: #f1f5f9; -} -[data-theme="dark"] .notification-message { - color: #94a3b8; -} -[data-theme="dark"] .notification-banner { - background-color: #1e293b; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); -} - -/* Upload toast */ -[data-theme="dark"] .upload-toast { - background: #1e293b; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); -} -[data-theme="dark"] .upload-toast-file-name { - color: #e2e8f0; -} -[data-theme="dark"] .upload-toast-file-bar { - background: #334155; -} -[data-theme="dark"] .upload-toast-file-pct { - color: #64748b; -} -[data-theme="dark"] .upload-toast-footer { - border-top-color: #334155; -} - -/* Notification bell */ -[data-theme="dark"] .notif-bell-btn { - color: #94a3b8; -} -[data-theme="dark"] .notif-bell-btn:hover, -[data-theme="dark"] .notif-bell-btn.active { - color: #ff5e3a; - background: rgba(255, 94, 58, 0.15); -} -[data-theme="dark"] .notif-panel { - background: #1e293b; - box-shadow: 0 12px 40px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.06); -} -[data-theme="dark"] .notif-panel-header { - border-bottom-color: #334155; -} -[data-theme="dark"] .notif-panel-title { - color: #f1f5f9; -} -[data-theme="dark"] .notif-clear-btn { - color: #64748b; -} -[data-theme="dark"] .notif-clear-btn:hover { - color: #ff5e3a; - background: rgba(255, 94, 58, 0.12); -} -[data-theme="dark"] .notif-empty { - color: #64748b; -} -[data-theme="dark"] .notif-item { - border-bottom-color: #1a2536; -} -[data-theme="dark"] .notif-item:hover { - background: #162032; -} -[data-theme="dark"] .notif-item-title { - color: #e2e8f0; -} -[data-theme="dark"] .notif-item-text { - color: #94a3b8; -} -[data-theme="dark"] .notif-upload-bar { - background: #334155; -} - -/* Dropzone */ -[data-theme="dark"] .dropzone { - border-color: #475569; - color: #94a3b8; - background-color: #0f172a; -} - -/* Progress bar */ -[data-theme="dark"] .progress-bar { - background-color: #334155; -} - -/* Empty state */ -[data-theme="dark"] .empty-state { - background-color: #1e293b; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - color: #64748b; -} -[data-theme="dark"] .empty-state i { - color: #334155 !important; -} -[data-theme="dark"] .empty-state p { - color: #64748b; -} - -/* Confirm dialog */ -[data-theme="dark"] .confirm-dialog-content { - background-color: #1e293b; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); -} -[data-theme="dark"] .confirm-dialog-header { - color: #f1f5f9; -} -[data-theme="dark"] .confirm-dialog-message { - color: #94a3b8; -} -[data-theme="dark"] .confirm-dialog-buttons { - background: #162032; - border-top-color: #334155; -} - -/* Move dialog / folder tree */ -[data-theme="dark"] .move-dialog-content { - background-color: #1e293b; -} -[data-theme="dark"] .move-dialog-header { - color: #f1f5f9; - border-bottom-color: #334155; -} -[data-theme="dark"] .move-dialog .folder-tree { - background: #0f172a; - border-color: #334155; -} -[data-theme="dark"] .move-dialog .folder-tree-item { - color: #cbd5e1; -} -[data-theme="dark"] .move-dialog .folder-tree-item:hover { - background: #334155; -} -[data-theme="dark"] .move-dialog .folder-tree-item.selected { - background: rgba(255, 94, 58, 0.1); - color: #ff5e3a; -} -[data-theme="dark"] .move-dialog-buttons { - background: #162032; - border-top-color: #334155; -} - -/* Share dialog */ -[data-theme="dark"] .share-dialog-content { - background-color: #1e293b; -} -[data-theme="dark"] .share-dialog-header { - color: #f1f5f9; - border-bottom-color: #334155; -} -[data-theme="dark"] .share-dialog-body label { - color: #94a3b8; -} -[data-theme="dark"] .share-dialog-body input { - background: #0f172a; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .share-dialog-body input:focus { - border-color: #ff5e3a; - background: #0f172a; -} -[data-theme="dark"] .share-link-container { - background: #0f172a; - border-color: #334155; -} -[data-theme="dark"] .share-link-container input { - color: #e2e8f0; -} -[data-theme="dark"] .share-dialog-buttons { - background: #162032; - border-top-color: #334155; -} - -/* Checkbox accent */ -[data-theme="dark"] .list-header-checkbox input, -[data-theme="dark"] .list-item-checkbox input, -[data-theme="dark"] .file-card-checkbox input { - accent-color: #ff5e3a; -} - -/* Search results header */ -[data-theme="dark"] .search-results-header h3 { - color: #f1f5f9; -} - -/* ── Shared View Dark Mode ── */ -[data-theme="dark"] .shared-filters { - background-color: #1e293b; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); -} -[data-theme="dark"] .filter-group label { - color: #94a3b8; -} -[data-theme="dark"] .filter-group select { - background-color: #1e293b; - border-color: #334155; - color: #e2e8f0; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2394a3b8' d='M6 8L1 3h10z'/%3E%3C/svg%3E"); -} -[data-theme="dark"] .filter-group select:focus { - border-color: #ff5e3a; - box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.15); -} -[data-theme="dark"] .search-box input { - background-color: #1e293b; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .search-box input::placeholder { - color: #64748b; -} -[data-theme="dark"] .shared-list-container { - background-color: #1e293b; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); -} -[data-theme="dark"] .shared-list thead th { - background-color: #162032; - color: #94a3b8; - border-bottom-color: #334155; -} -[data-theme="dark"] .shared-list tbody td { - border-bottom-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .shared-list tbody tr:hover { - background-color: #162032; -} -[data-theme="dark"] .page-description { - color: #94a3b8; -} -[data-theme="dark"] .empty-state h3 { - color: #f1f5f9; -} -[data-theme="dark"] .empty-state p { - color: #94a3b8; -} -[data-theme="dark"] .empty-state .button.primary { - background: linear-gradient(135deg, #ff5e3a, #ff2d55); - color: #fff; -} -/* Shared view action buttons */ -[data-theme="dark"] .shared-list .action-btn { - color: #94a3b8; -} -[data-theme="dark"] .shared-list .action-btn:hover { - color: #ff5e3a; -} -/* Share dialog dark mode (shared view specific) */ -[data-theme="dark"] .dialog { - background-color: rgba(0, 0, 0, 0.6); -} -[data-theme="dark"] .dialog-content { - background-color: #1e293b; - color: #e2e8f0; -} -[data-theme="dark"] .dialog-header { - border-bottom-color: #334155; -} -[data-theme="dark"] .dialog-header h3 { - color: #f1f5f9; -} -[data-theme="dark"] .dialog-body label { - color: #94a3b8; -} -[data-theme="dark"] .dialog-body input, -[data-theme="dark"] .dialog-body textarea { - 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; -} -[data-theme="dark"] .close-dialog-btn { - color: #94a3b8; -} -[data-theme="dark"] .close-dialog-btn:hover { - color: #f1f5f9; -} -[data-theme="dark"] .notification-banner { - background-color: #1e293b; - color: #e2e8f0; - border-color: #334155; -} -[data-theme="dark"] .share-setting label { - color: #94a3b8; -} -[data-theme="dark"] .permissions-options label span { - color: #e2e8f0; -} -[data-theme="dark"] .share-item-info { - color: #e2e8f0; -} -/* Batch bar dark mode */ -[data-theme="dark"] .batch-action-bar { - background-color: #1e293b; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .list-header.selection-mode { - background-color: #0f172a; - border-bottom-color: #334155; - color: #e2e8f0; -} -/* Search results dark mode */ -[data-theme="dark"] .search-results-header { - color: #f1f5f9; - border-bottom-color: #334155; -} -[data-theme="dark"] .search-results-header h3 { - color: #f1f5f9; -} -[data-theme="dark"] .search-results-header .search-time { - color: #64748b; -} -[data-theme="dark"] .search-results-header .btn-secondary { - background: #1e293b; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .search-results-header .btn-secondary:hover { - background: #334155; -} -[data-theme="dark"] .search-sort-select { - background: #1e293b; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .search-sort-select:focus { - border-color: #ff5e3a; -} - -/* Trash & action buttons dark mode */ -[data-theme="dark"] .trash-actions button, -[data-theme="dark"] .actions-cell button { - background: #1e293b; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .trash-actions button:hover, -[data-theme="dark"] .actions-cell button:hover { - background: #334155; -} -[data-theme="dark"] .action-btn { - background-color: #1e293b; - border-color: #334155; - color: #e2e8f0; -} -[data-theme="dark"] .action-btn:hover { - background-color: #334155; - border-color: #475569; -} - -/* Header dark mode (shared page) */ -[data-theme="dark"] header { - background-color: #1e293b; - border-bottom-color: #334155; -} \ No newline at end of file +@import url("./main.css"); diff --git a/static/css/themes/dark.css b/static/css/themes/dark.css new file mode 100644 index 00000000..7f33b829 --- /dev/null +++ b/static/css/themes/dark.css @@ -0,0 +1,194 @@ +[data-theme="dark"] { + --color-bg-page: #0f172a; + --color-bg-surface: #1e293b; + --color-border: #334155; + --color-text: #e2e8f0; + --color-text-muted: #94a3b8; + --color-accent: #ff5e3a; + --color-accent-hover: #ff7a5c; +} + +[data-theme="dark"] body { + background-color: #0f172a; +} + +[data-theme="dark"] ::-webkit-scrollbar-thumb { + background-color: rgba(255, 255, 255, 0.15); +} + +[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { + background-color: rgba(255, 255, 255, 0.25); +} + +[data-theme="dark"] * { + scrollbar-color: rgba(255, 255, 255, 0.15) transparent; +} + +[data-theme="dark"] select { + background-color: #1e293b; + border-color: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] select:hover { + border-color: #475569; +} + +[data-theme="dark"] select:focus { + border-color: #ff5e3a; + background-color: #1e293b; +} + +[data-theme="dark"] .sidebar { + background: linear-gradient(180deg, #0f172a 0%, #0c1322 100%); +} + +[data-theme="dark"] .top-bar { + background-color: #1e293b; + border-bottom-color: #334155; +} + +[data-theme="dark"] .search-container input { + background-color: #1e293b; + border-color: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] .search-container input:hover { + background-color: #1e293b; + border-color: #475569; +} + +[data-theme="dark"] .search-container input:focus { + background-color: #1e293b; + border-color: #ff5e3a; +} + +[data-theme="dark"] .search-container input::placeholder { + color: #64748b; +} + +[data-theme="dark"] .search-icon { + color: #64748b; +} + +[data-theme="dark"] .page-title { + color: #f1f5f9; +} + +[data-theme="dark"] .breadcrumb { + color: #94a3b8; +} + +[data-theme="dark"] .breadcrumb-link { + color: #94a3b8; +} + +[data-theme="dark"] .breadcrumb-link:hover { + color: #ff5e3a; + background: rgba(255, 94, 58, 0.1); +} + +[data-theme="dark"] .breadcrumb-current { + color: #e2e8f0; +} + +[data-theme="dark"] .breadcrumb-separator { + color: #64748b; +} + +[data-theme="dark"] .btn-secondary { + background-color: #1e293b; + color: #cbd5e1; + border-color: #334155; +} + +[data-theme="dark"] .btn-secondary:hover { + background-color: #334155; + border-color: #475569; +} + +[data-theme="dark"] .btn-secondary:active { + background-color: #475569; +} + +[data-theme="dark"] .view-toggle { + background-color: #1e293b; + border-color: #334155; +} + +[data-theme="dark"] .toggle-btn { + color: #94a3b8; +} + +[data-theme="dark"] .toggle-btn:hover { + background-color: #334155; +} + +[data-theme="dark"] .toggle-btn.active { + background-color: #334155; + color: #ff5e3a; +} + +[data-theme="dark"] .context-menu { + background: #1e293b; + border-color: #334155; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); +} + +[data-theme="dark"] .context-menu-item { + color: #cbd5e1; +} + +[data-theme="dark"] .context-menu-item:hover { + background: #334155; +} + +[data-theme="dark"] .context-menu-item:active { + background: #475569; +} + +[data-theme="dark"] .context-menu-item i { + color: #94a3b8; +} + +[data-theme="dark"] .context-menu-item-danger:hover { + background: rgba(239, 68, 68, 0.1); +} + +[data-theme="dark"] .context-menu-separator { + background: #334155; +} + +[data-theme="dark"] .search-results-header h3 { + color: #f1f5f9; +} + +[data-theme="dark"] .search-results-header { + color: #f1f5f9; + border-bottom-color: #334155; +} + +[data-theme="dark"] .search-results-header .search-time { + color: #64748b; +} + +[data-theme="dark"] .search-results-header .btn-secondary { + background: #1e293b; + border-color: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] .search-results-header .btn-secondary:hover { + background: #334155; +} + +[data-theme="dark"] .search-sort-select { + background: #1e293b; + border-color: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] .search-sort-select:focus { + border-color: #ff5e3a; +} diff --git a/static/css/views/admin.css b/static/css/views/admin.css new file mode 100644 index 00000000..a444da70 --- /dev/null +++ b/static/css/views/admin.css @@ -0,0 +1,299 @@ +*{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{background:#f5f7fa;color:#1e293b;min-height:100vh;display:flex;flex-direction:column} + +.hidden{display:none !important} +.show-block{display:block !important} +.show-flex{display:flex !important} +.link-reset-flex{text-decoration:none;color:inherit;display:flex;align-items:center;gap:14px} +.width-zero{width:0%} +.mt-14{margin-top:14px} +.toggle-row-strong{margin-top:10px;padding:12px 0;border-top:1px solid #e2e8f0} +.icon-muted-right{color:#64748b;margin-right:6px} +.h2-space-between{justify-content:space-between} +.flex-gap-6{display:flex;gap:6px} +.oidc-discover-wrap{margin-bottom:12px} +.secret-icon{color:#059669} +.small-muted{font-weight:400;color:#94a3b8} +.summary-icon-right{margin-right:6px} +.oidc-actions{display:flex;gap:10px;margin-top:24px;justify-content:flex-end} +.modal-title-icon{color:#ff5e3a;margin-right:8px} +.quota-input-row{display:flex;gap:10px;align-items:center} +.flex-1{flex:1} +.select-qm-unit{width:90px;padding:10px 14px;border:2px solid #e2e8f0;border-radius:10px;font-size:14px;background:#f8fafc} +.form-row{display:flex;gap:14px} +.select-cu-role{width:100%;padding:10px 14px;border:2px solid #e2e8f0;border-radius:10px;font-size:14px;background:#f8fafc} +.quota-row{display:flex;gap:6px} +.select-cu-quota-unit{width:70px;padding:10px 8px;border:2px solid #e2e8f0;border-radius:10px;font-size:13px;background:#f8fafc} +.alert-no-margin{margin-top:0} +.table-loading-cell{text-align:center;padding:28px;color:#94a3b8} +.table-status-error{color:#991b1b;padding:20px} +.table-status-empty{text-align:center;padding:28px;color:#94a3b8} +.user-self-badge{color:#94a3b8;font-weight:400} +.badge-admin-icon-small{font-size:10px} +.quota-progress-fixed{width:80px} +.user-last-login-cell{font-size:12px;color:#94a3b8} + +/* ── Scrollbar ── */ +::-webkit-scrollbar{width:8px} +::-webkit-scrollbar-track{background:transparent} +::-webkit-scrollbar-thumb{background:rgba(0,0,0,.15);border-radius:4px} +::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,.25)} +*{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.15) transparent} + +/* ── Top Header Bar ── */ +.admin-header{ + background:linear-gradient(135deg,#2a3042 0%,#232838 100%); + padding:0 32px;height:64px;display:flex;align-items:center;justify-content:space-between; + box-shadow:0 2px 12px rgba(0,0,0,.15);position:sticky;top:0;z-index:100; +} +.admin-header-left{display:flex;align-items:center;gap:14px} +.admin-logo{ + width:38px;height:38px;background:linear-gradient(135deg,#ff5e3a,#ff2d55);border-radius:11px; + display:flex;align-items:center;justify-content:center; + box-shadow:0 3px 10px rgba(255,94,58,.35); +} +.admin-logo svg{width:20px;height:20px;fill:#fff} +.admin-title-text{font-size:17px;font-weight:700;color:#fff;letter-spacing:.3px} +.admin-title-separator{font-size:17px;color:rgba(255,255,255,.5);font-weight:400;margin-left:6px} +.admin-header-right a{ + color:rgba(255,255,255,.65);text-decoration:none;font-size:13px;font-weight:500; + display:flex;align-items:center;gap:6px;transition:color .2s; +} +.admin-header-right a:hover{color:#fff} + +/* ── Container ── */ +.admin-container{max-width:1080px;margin:0 auto;padding:28px 24px 60px;width:100%} + +/* ── Tabs ── */ +.admin-tabs{display:flex;gap:6px;margin-bottom:28px;background:#fff;border-radius:14px;padding:6px;box-shadow:0 1px 4px rgba(0,0,0,.06)} +.admin-tab{ + padding:10px 22px;cursor:pointer;font-weight:600;font-size:13.5px;color:#64748b; + border:none;background:none;border-radius:10px;transition:all .2s;display:flex;align-items:center;gap:8px; +} +.admin-tab:hover{color:#1e293b;background:#f8fafc} +.admin-tab.active{color:#fff;background:linear-gradient(135deg,#ff5e3a,#ff2d55);box-shadow:0 3px 12px rgba(255,94,58,.25)} +.admin-tab.active i{color:#fff} +.admin-tab i{font-size:14px;width:16px;text-align:center} +.tab-content{display:none} +.tab-content.active{display:block} + +/* ── Cards ── */ +.admin-card{background:#fff;border-radius:16px;box-shadow:0 1px 4px rgba(0,0,0,.06),0 0 0 1px rgba(0,0,0,.03);padding:28px;margin-bottom:22px} +.admin-card h2{font-size:16px;font-weight:700;margin-bottom:20px;color:#1e293b;display:flex;align-items:center;gap:10px} +.admin-card h2 i{color:#ff5e3a;font-size:17px} + +#main-content, +#ds-warn-card, +#ds-danger-card, +#registration-warning, +#oidc-form, +#secret-hint, +#password-warning, +#quota-modal, +#create-user-modal, +#reset-pw-modal{display:none} + +/* ── Stats Grid ── */ +.stats-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:22px} +.stat-card{ + padding:20px;background:#f8fafc;border-radius:14px;text-align:center; + border:1px solid #e2e8f0;transition:transform .15s,box-shadow .15s; +} +.stat-card:hover{transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,0,0,.06)} +.stat-value{font-size:1.75rem;font-weight:800;color:#1e293b} +.stat-label{font-size:11.5px;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;margin-top:4px;font-weight:600} +.stat-card.warn{border-color:#fbbf24;background:#fffbeb} +.stat-card.danger{border-color:#ef4444;background:#fef2f2} +.text-blue{color:#3b82f6!important} +.text-green{color:#059669!important} +.text-orange{color:#d97706!important} +.text-red{color:#dc2626!important} + +/* ── Progress bar ── */ +.progress-bar{width:100%;height:8px;background:#e2e8f0;border-radius:4px;overflow:hidden} +.progress-fill{height:100%;border-radius:4px;transition:width .5s ease} +.progress-fill.green{background:linear-gradient(90deg,#059669,#10b981)} +.progress-fill.orange{background:linear-gradient(90deg,#d97706,#f59e0b)} +.progress-fill.red{background:linear-gradient(90deg,#dc2626,#ef4444)} + +/* ── Table ── */ +.table-wrap{overflow-x:auto;border-radius:12px;border:1px solid #e2e8f0} +table{width:100%;border-collapse:collapse;font-size:13.5px} +th{text-align:left;padding:12px 16px;background:#f8fafc;color:#94a3b8;font-size:11px;text-transform:uppercase;letter-spacing:.06em;font-weight:700;white-space:nowrap;border-bottom:1px solid #e2e8f0} +td{padding:14px 16px;border-bottom:1px solid #f1f5f9;vertical-align:middle} +tr:last-child td{border-bottom:none} +tr:hover{background:#fafbfd} +.user-info{display:flex;flex-direction:column;gap:2px} +.user-name{font-weight:600;color:#1e293b} +.user-email{font-size:12px;color:#94a3b8} + +/* ── Badges ── */ +.badge{display:inline-flex;align-items:center;gap:4px;font-size:11px;padding:3px 10px;border-radius:20px;font-weight:600} +.badge-admin{background:#dbeafe;color:#1d4ed8} +.badge-user{background:#f1f5f9;color:#64748b} +.badge-active{background:#d1fae5;color:#065f46} +.badge-inactive{background:#fee2e2;color:#991b1b} +.badge-oidc{background:#ede9fe;color:#6d28d9} +.badge-env{background:#fef3c7;color:#92400e;font-size:10px;padding:1px 6px;margin-left:4px} + +/* ── Buttons ── */ +.btn{ + padding:8px 18px;border:none;border-radius:10px;font-size:13px;font-weight:600; + cursor:pointer;transition:all .15s;white-space:nowrap;display:inline-flex;align-items:center;gap:6px; +} +.btn-sm{padding:6px 12px;font-size:12px;border-radius:8px} +.btn-primary{background:linear-gradient(135deg,#ff5e3a,#ff2d55);color:#fff;box-shadow:0 2px 8px rgba(255,94,58,.25)} +.btn-primary:hover{box-shadow:0 4px 14px rgba(255,94,58,.35);transform:translateY(-1px)} +.btn-secondary{background:#fff;color:#334155;border:1px solid #e2e8f0} +.btn-secondary:hover{background:#f8fafc;border-color:#cbd5e1} +.btn-danger{background:#fef2f2;color:#991b1b;border:1px solid #fecaca} +.btn-danger:hover{background:#fee2e2} +.btn-success{background:#ecfdf5;color:#065f46;border:1px solid #a7f3d0} +.btn-success:hover{background:#d1fae5} +.btn:disabled{opacity:.4;cursor:not-allowed;transform:none!important} +.actions-row{display:flex;gap:6px;flex-wrap:wrap} + +/* ── Forms ── */ +.form-group{margin-bottom:16px} +.form-group label{display:block;font-size:13px;font-weight:600;margin-bottom:4px;color:#334155} +.form-group input[type="text"],.form-group input[type="password"],.form-group input[type="url"],.form-group input[type="number"],.form-group select{ + width:100%;padding:10px 14px;border:2px solid #e2e8f0;border-radius:10px;font-size:14px; + background:#f8fafc;transition:all .2s;font-family:inherit;color:#1e293b; +} +.form-group input:focus,.form-group select:focus{outline:none;border-color:#ff5e3a;background:#fff;box-shadow:0 0 0 3px rgba(255,94,58,.1)} +.form-group small{color:#94a3b8;font-size:12px;display:block;margin-top:3px} + +.toggle-row{display:flex;align-items:center;justify-content:space-between;padding:10px 0} +.toggle-row label{font-size:14px;font-weight:500;color:#334155} +.switch{position:relative;width:44px;height:24px;flex-shrink:0} +.switch input{opacity:0;width:0;height:0} +.slider{position:absolute;cursor:pointer;inset:0;background:#d1d5db;border-radius:24px;transition:.3s} +.slider:before{content:"";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background:#fff;border-radius:50%;transition:.3s;box-shadow:0 1px 3px rgba(0,0,0,.15)} +.switch input:checked+.slider{background:linear-gradient(135deg,#ff5e3a,#ff2d55)} +.switch input:checked+.slider:before{transform:translateX(20px)} + +.readonly-field{ + display:flex;align-items:center;gap:8px;background:#f8fafc;border:2px solid #e2e8f0;border-radius:10px; + padding:10px 14px;font-family:'SF Mono',Monaco,Consolas,monospace;font-size:13px;word-break:break-all;color:#334155; +} +.readonly-field button{ + flex-shrink:0;padding:6px 10px;border:1px solid #e2e8f0;border-radius:8px;background:#fff;cursor:pointer; + font-size:12px;transition:all .15s;color:#64748b; +} +.readonly-field button:hover{background:#f1f5f9;color:#334155} + +/* ── Alerts ── */ +.alert{padding:12px 16px;border-radius:10px;font-size:13px;margin-top:14px;display:none;font-weight:500} +.alert-success{background:#ecfdf5;color:#065f46;border:1px solid #a7f3d0;display:block} +.alert-error{background:#fef2f2;color:#991b1b;border:1px solid #fecaca;display:block} +.alert-info{background:#eff6ff;color:#1e40af;border:1px solid #bfdbfe;display:block} +.warning{background:#fffbeb;border:1px solid #fde68a;border-radius:10px;padding:10px 14px;font-size:13px;color:#92400e;margin-top:8px;display:flex;align-items:center;gap:6px;font-weight:500} + +/* ── Discovery ── */ +.discovery-result{margin:12px 0;padding:14px;border-radius:10px;font-size:13px} +.discovery-result.ok{background:#ecfdf5;border:1px solid #a7f3d0;color:#065f46} +.discovery-result.fail{background:#fef2f2;border:1px solid #fecaca;color:#991b1b} +.discovery-result dt{font-weight:700;margin-top:6px} +.discovery-result dd{margin-left:0;word-break:break-all} + +/* ── Details ── */ +details{margin-top:14px;border-top:1px solid #e2e8f0;padding-top:12px} +details summary{cursor:pointer;font-weight:600;font-size:14px;color:#64748b;padding:6px 0;user-select:none;transition:color .2s} +details summary:hover{color:#ff5e3a} +details[open] summary{margin-bottom:14px;color:#ff5e3a} + +/* ── Modal ── */ +.modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.45);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;z-index:1000} +.modal{background:#fff;border-radius:20px;padding:28px;width:420px;max-width:90vw;box-shadow:0 20px 60px rgba(0,0,0,.2);animation:modalIn .2s ease-out} +@keyframes modalIn{from{opacity:0;transform:scale(.95) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}} +.modal h3{margin-bottom:18px;font-size:17px;color:#1e293b;display:flex;align-items:center} +.modal-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:18px} + +/* ── Quota bar inline ── */ +.quota-bar{display:flex;align-items:center;gap:10px} +.quota-bar .progress-bar{flex:1;height:6px} +.quota-text{font-size:12px;color:#94a3b8;white-space:nowrap} + +/* ── Access / Loading ── */ +#access-denied{display:none;text-align:center;padding:80px 20px} +#access-denied .access-icon{width:80px;height:80px;background:#fef2f2;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 20px} +#access-denied .access-icon i{font-size:32px;color:#ef4444} +#access-denied h2{color:#991b1b;margin-bottom:8px;font-size:20px} +#access-denied p{color:#64748b;margin-bottom:20px;font-size:14px} +#access-denied a{display:inline-flex;align-items:center;gap:6px;padding:10px 24px;background:linear-gradient(135deg,#ff5e3a,#ff2d55);color:#fff;text-decoration:none;border-radius:10px;font-weight:600;font-size:14px;box-shadow:0 3px 12px rgba(255,94,58,.3);transition:all .2s} +#access-denied a:hover{transform:translateY(-1px);box-shadow:0 5px 18px rgba(255,94,58,.4)} +#loading{text-align:center;padding:80px;color:#94a3b8;font-size:15px} +#loading i{font-size:32px;color:#ff5e3a;display:block;margin-bottom:12px;animation:spin 1s linear infinite} +@keyframes spin{to{transform:rotate(360deg)}} + +/* ── Pagination ── */ +.pagination{display:flex;align-items:center;justify-content:space-between;margin-top:14px;font-size:13px;color:#94a3b8;padding:0 4px} +.pagination button{padding:6px 14px} + +/* ── Dark Mode ── */ +[data-theme="dark"] body{background:#0f172a;color:#e2e8f0} +[data-theme="dark"] ::-webkit-scrollbar-thumb{background:rgba(255,255,255,.15)} +[data-theme="dark"] *{scrollbar-color:rgba(255,255,255,.15) transparent} +[data-theme="dark"] .admin-tabs{background:#1e293b;box-shadow:0 1px 4px rgba(0,0,0,.2)} +[data-theme="dark"] .admin-tab{color:#94a3b8} +[data-theme="dark"] .admin-tab:hover{color:#f1f5f9;background:#162032} +[data-theme="dark"] .admin-card{background:#1e293b;box-shadow:0 1px 4px rgba(0,0,0,.2),0 0 0 1px rgba(255,255,255,.03)} +[data-theme="dark"] .admin-card h2{color:#f1f5f9} +[data-theme="dark"] .stat-card{background:#162032;border-color:#334155} +[data-theme="dark"] .stat-card:hover{box-shadow:0 4px 12px rgba(0,0,0,.15)} +[data-theme="dark"] .stat-value{color:#f1f5f9} +[data-theme="dark"] .stat-label{color:#64748b} +[data-theme="dark"] .stat-card.warn{border-color:#92400e;background:#422006} +[data-theme="dark"] .stat-card.danger{border-color:#991b1b;background:#3b1111} +[data-theme="dark"] .progress-bar{background:#334155} +[data-theme="dark"] .table-wrap{border-color:#334155} +[data-theme="dark"] th{background:#162032;color:#64748b;border-bottom-color:#334155} +[data-theme="dark"] td{border-bottom-color:#334155;color:#e2e8f0} +[data-theme="dark"] tr:hover{background:#162032} +[data-theme="dark"] .user-name{color:#f1f5f9} +[data-theme="dark"] .user-email{color:#64748b} +[data-theme="dark"] .badge-admin{background:#1e3a5f;color:#60a5fa} +[data-theme="dark"] .badge-user{background:#334155;color:#94a3b8} +[data-theme="dark"] .badge-active{background:#052e16;color:#86efac} +[data-theme="dark"] .badge-inactive{background:#3b1111;color:#fca5a5} +[data-theme="dark"] .badge-oidc{background:#2e1065;color:#c4b5fd} +[data-theme="dark"] .btn-secondary{background:#1e293b;color:#e2e8f0;border-color:#334155} +[data-theme="dark"] .btn-secondary:hover{background:#334155;border-color:#475569} +[data-theme="dark"] .btn-danger{background:#3b1111;color:#fca5a5;border-color:#991b1b} +[data-theme="dark"] .btn-danger:hover{background:#4a1515} +[data-theme="dark"] .btn-success{background:#052e16;color:#86efac;border-color:#065f46} +[data-theme="dark"] .btn-success:hover{background:#064e27} +[data-theme="dark"] .form-group label{color:#94a3b8} +[data-theme="dark"] .form-group input[type="text"], +[data-theme="dark"] .form-group input[type="password"], +[data-theme="dark"] .form-group input[type="url"], +[data-theme="dark"] .form-group input[type="number"], +[data-theme="dark"] .form-group select{background:#0f172a;border-color:#334155;color:#e2e8f0} +[data-theme="dark"] .form-group input:focus, +[data-theme="dark"] .form-group select:focus{border-color:#ff5e3a;background:#0f172a;box-shadow:0 0 0 3px rgba(255,94,58,.15)} +[data-theme="dark"] .form-group small{color:#64748b} +[data-theme="dark"] .toggle-row label{color:#94a3b8} +[data-theme="dark"] .slider{background:#475569} +[data-theme="dark"] .readonly-field{background:#0f172a;border-color:#334155;color:#e2e8f0} +[data-theme="dark"] .readonly-field button{background:#1e293b;border-color:#334155;color:#94a3b8} +[data-theme="dark"] .readonly-field button:hover{background:#334155;color:#f1f5f9} +[data-theme="dark"] .warning{background:#422006;border-color:#92400e;color:#fbbf24} +[data-theme="dark"] .alert-success{background:#052e16;color:#86efac;border-color:#065f46} +[data-theme="dark"] .alert-error{background:#3b1111;color:#fca5a5;border-color:#991b1b} +[data-theme="dark"] .alert-info{background:#0c2d48;color:#93c5fd;border-color:#1d4ed8} +[data-theme="dark"] .discovery-result.ok{background:#052e16;border-color:#065f46;color:#86efac} +[data-theme="dark"] .discovery-result.fail{background:#3b1111;border-color:#991b1b;color:#fca5a5} +[data-theme="dark"] details{border-top-color:#334155} +[data-theme="dark"] details summary{color:#94a3b8} +[data-theme="dark"] details summary:hover{color:#ff5e3a} +[data-theme="dark"] details[open] summary{color:#ff5e3a} +[data-theme="dark"] .modal{background:#1e293b;box-shadow:0 20px 60px rgba(0,0,0,.4)} +[data-theme="dark"] .modal h3{color:#f1f5f9} +[data-theme="dark"] .modal-overlay{background:rgba(0,0,0,.6);backdrop-filter:blur(4px)} +[data-theme="dark"] .quota-text{color:#64748b} +[data-theme="dark"] .pagination{color:#64748b} +[data-theme="dark"] #access-denied h2{color:#fca5a5} +[data-theme="dark"] #access-denied p{color:#94a3b8} +[data-theme="dark"] #access-denied .access-icon{background:#3b1111} +[data-theme="dark"] #loading{color:#64748b} +[data-theme="dark"] .toggle-row{border-top-color:#334155} diff --git a/static/css/views/auth.css b/static/css/views/auth.css new file mode 100644 index 00000000..4f406106 --- /dev/null +++ b/static/css/views/auth.css @@ -0,0 +1,585 @@ +/* Auth styles for OxiCloud */ +.auth-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + width: 100%; + background-color: #f5f7fa; +} + +.auth-panel { + width: 400px; + max-width: 90%; + margin: 0 auto; + background-color: white; + border-radius: 10px; + box-shadow: 0 5px 20px rgba(0,0,0,0.1); + padding: 30px; + text-align: center; +} + +.auth-logo { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 20px; +} + +.auth-logo-icon { + width: 50px; + height: 50px; + background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + margin-right: 10px; + box-shadow: 0 4px 12px rgba(255, 94, 58, 0.3); +} + +.auth-logo-icon svg { + width: 30px; + height: 30px; + fill: white; +} + +.auth-logo-text { + font-size: 24px; + font-weight: bold; + color: #2a3042; +} + +.auth-title { + font-size: 20px; + font-weight: bold; + margin-bottom: 25px; + color: #2a3042; +} + +.auth-form { + width: 100%; + text-align: left; + + [dir='rtl'] & { + text-align: right; + } +} + +.auth-input-group { + margin-bottom: 20px; +} + +.auth-label { + display: block; + margin-bottom: 8px; + font-size: 14px; + color: #4b5563; + font-weight: 500; +} + +.auth-input { + width: 100%; + padding: 12px 15px; + border-radius: 8px; + border: 1px solid #e2e8f0; + font-size: 14px; + background-color: #f9fafb; + transition: border-color 0.2s; +} + +.auth-input:focus { + outline: none; + border-color: #ff5e3a; + box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); +} + +.auth-button { + width: 100%; + padding: 12px 15px; + border-radius: 10px; + background: linear-gradient(135deg, #ff5e3a 0%, #ff2d55 100%); + color: white; + font-weight: bold; + border: none; + cursor: pointer; + font-size: 16px; + transition: all 0.3s ease; + margin-top: 10px; + box-shadow: 0 4px 12px rgba(255, 94, 58, 0.3); +} + +.auth-button:hover { + transform: translateY(-1px); + box-shadow: 0 6px 20px rgba(255, 94, 58, 0.4); + filter: brightness(1.05); +} + +.auth-button:active { + transform: translateY(0); + box-shadow: 0 2px 8px rgba(255, 94, 58, 0.3); +} + +.auth-button:disabled { + background-color: #f9a799; + cursor: not-allowed; +} + +/* SSO / OIDC button */ +.auth-button-oidc { + background: linear-gradient(135deg, #2d3748 0%, #4a5568 100%); + box-shadow: 0 4px 12px rgba(45, 55, 72, 0.3); + display: flex; + align-items: center; + justify-content: center; + gap: 10px; +} + +.auth-button-oidc:hover { + box-shadow: 0 6px 20px rgba(45, 55, 72, 0.4); +} + +.auth-button-oidc i { + font-size: 14px; +} + +/* Divider between password and SSO login */ +.auth-divider { + display: flex; + align-items: center; + margin: 20px 0; + color: #a0aec0; + font-size: 13px; +} + +.auth-divider::before, +.auth-divider::after { + content: ''; + flex: 1; + height: 1px; + background: #e2e8f0; +} + +.auth-divider span { + padding: 0 12px; +} + +/* OIDC-only mode: hide password form */ +.auth-form.hidden { + display: none; +} + +.auth-toggle { + margin-top: 20px; + font-size: 14px; + color: #718096; +} + +.auth-toggle-link { + color: #ff5e3a; + cursor: pointer; + text-decoration: none; + font-weight: 500; +} + +.auth-toggle-link:hover { + text-decoration: underline; +} + +.auth-error { + background-color: #fee2e2; + color: #b91c1c; + padding: 10px 15px; + border-radius: 8px; + margin-bottom: 20px; + font-size: 14px; + display: none; +} + +.auth-success { + background-color: #dcfce7; + color: #15803d; + padding: 10px 15px; + border-radius: 8px; + margin-bottom: 20px; + font-size: 14px; + display: none; +} + +/* Admin setup panel styles */ +.admin-setup-panel { + display: none; +} + +.setup-steps { + margin-bottom: 25px; + display: flex; + justify-content: space-between; +} + +.setup-step { + display: flex; + flex-direction: column; + align-items: center; + width: 30%; +} + +.step-number { + width: 30px; + height: 30px; + background-color: #e2e8f0; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + color: #64748b; + font-weight: bold; + margin-bottom: 5px; +} + +.step-number.active { + background-color: #ff5e3a; + color: white; +} + +.step-title { + font-size: 12px; + color: #64748b; +} + +.step-title.active { + color: #1e293b; + font-weight: 500; +} + +/* Language selector panel styles */ +.language-selector-panel { + text-align: center; +} + +.language-subtitle { + color: #64748b; + font-size: 16px; + margin-bottom: 24px; +} + +/* ====== Compact Language Picker ====== */ +.lang-picker { + position: relative; + margin-bottom: 24px; + text-align: left; +} + +.lang-picker-selected { + display: flex; + align-items: center; + padding: 14px 18px; + border: 2px solid #e2e8f0; + border-radius: 12px; + cursor: pointer; + background-color: #f9fafb; + transition: all 0.2s ease; + user-select: none; +} + +.lang-picker-selected:hover { + border-color: #ff5e3a; + background-color: #fff; +} + +.lang-picker.open .lang-picker-selected { + border-color: #ff5e3a; + background-color: #fff; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.1); +} + +.lang-picker-flag { + font-size: 26px; + margin-right: 14px; + flex-shrink: 0; +} + +.lang-picker-name { + font-size: 16px; + font-weight: 600; + color: #1e293b; + flex: 1; +} + +.lang-picker-arrow { + color: #94a3b8; + font-size: 13px; + transition: transform 0.2s ease; + flex-shrink: 0; +} + +.lang-picker.open .lang-picker-arrow { + transform: rotate(180deg); +} + +/* Dropdown */ +.lang-picker-dropdown { + display: none; + position: absolute; + top: 100%; + left: 0; + right: 0; + background: #fff; + border: 2px solid #ff5e3a; + border-top: 1px solid #f1f5f9; + border-bottom-left-radius: 12px; + border-bottom-right-radius: 12px; + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12); + z-index: 100; + overflow: hidden; +} + +.lang-picker.open .lang-picker-dropdown { + display: block; + animation: langPickerSlideDown 0.2s ease; +} + +@keyframes langPickerSlideDown { + from { opacity: 0; transform: translateY(-4px); } + to { opacity: 1; transform: translateY(0); } +} + +/* Search inside dropdown */ +.lang-picker-search { + position: relative; + padding: 10px 14px; + border-bottom: 1px solid #f1f5f9; +} + +.lang-picker-search i { + position: absolute; + left: 26px; + top: 50%; + transform: translateY(-50%); + color: #94a3b8; + font-size: 13px; +} + +.lang-picker-search input { + width: 100%; + padding: 8px 12px 8px 32px; + border: 1px solid #e2e8f0; + border-radius: 8px; + font-size: 14px; + outline: none; + box-sizing: border-box; + transition: border-color 0.2s; +} + +.lang-picker-search input:focus { + border-color: #ff5e3a; +} + +/* Scrollable list */ +.lang-picker-list { + max-height: 240px; + overflow-y: auto; + padding: 6px; +} + +.lang-picker-list::-webkit-scrollbar { + width: 6px; +} + +.lang-picker-list::-webkit-scrollbar-track { + background: transparent; +} + +.lang-picker-list::-webkit-scrollbar-thumb { + background: #cbd5e1; + border-radius: 3px; +} + +.lang-picker-list::-webkit-scrollbar-thumb:hover { + background: #94a3b8; +} + +/* Language item in dropdown */ +.lang-picker-item { + display: flex; + align-items: center; + gap: 10px; + padding: 10px 12px; + border-radius: 8px; + cursor: pointer; + transition: all 0.12s ease; +} + +.lang-picker-item:hover { + background: #f8fafc; +} + +.lang-picker-item.selected { + background: #fff5f3; +} + +.lang-picker-item-flag { + font-size: 22px; + flex-shrink: 0; +} + +.lang-picker-item-name { + font-size: 15px; + font-weight: 500; + color: #1e293b; +} + +.lang-picker-item-english { + font-size: 13px; + color: #94a3b8; + margin-left: auto; +} + +.lang-picker-item-check { + color: #ff5e3a; + font-size: 13px; + flex-shrink: 0; +} + +.lang-picker-empty { + text-align: center; + color: #94a3b8; + padding: 20px; + font-size: 14px; +} + +@media (max-width: 480px) { + .auth-panel { + width: 90%; + padding: 20px; + } + + .lang-picker-selected { + padding: 12px 14px; + } + + .lang-picker-list { + max-height: 200px; + } +} + +/* ============================================================ + DARK MODE — Auth Pages + ============================================================ */ +[data-theme="dark"] .auth-container { + background-color: #0f172a; +} +[data-theme="dark"] .auth-panel { + background-color: #1e293b; + box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3); +} +[data-theme="dark"] .auth-logo-text { + color: #f1f5f9; +} +[data-theme="dark"] .auth-title { + color: #f1f5f9; +} +[data-theme="dark"] .auth-label { + color: #94a3b8; +} +[data-theme="dark"] .auth-input { + background-color: #0f172a; + border-color: #334155; + color: #e2e8f0; +} +[data-theme="dark"] .auth-input:focus { + border-color: #ff5e3a; + background-color: #0f172a; + box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.15); +} +[data-theme="dark"] .auth-input::placeholder { + color: #64748b; +} +[data-theme="dark"] .auth-error { + background-color: #3b1111; + color: #fca5a5; +} +[data-theme="dark"] .auth-success { + background-color: #052e16; + color: #86efac; +} +[data-theme="dark"] .auth-toggle { + color: #94a3b8; +} +[data-theme="dark"] .auth-divider { + color: #64748b; +} +[data-theme="dark"] .auth-divider::before, +[data-theme="dark"] .auth-divider::after { + background: #334155; +} +[data-theme="dark"] .language-subtitle { + color: #94a3b8; +} +[data-theme="dark"] .lang-picker-selected { + background-color: #0f172a; + border-color: #334155; +} +[data-theme="dark"] .lang-picker-selected:hover { + border-color: #ff5e3a; + background-color: #162032; +} +[data-theme="dark"] .lang-picker.open .lang-picker-selected { + border-color: #ff5e3a; + background-color: #162032; +} +[data-theme="dark"] .lang-picker-name { + color: #f1f5f9; +} +[data-theme="dark"] .lang-picker-arrow { + color: #64748b; +} +[data-theme="dark"] .lang-picker-dropdown { + background: #1e293b; + border-color: #ff5e3a; + border-top-color: #334155; + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3); +} +[data-theme="dark"] .lang-picker-search { + border-bottom-color: #334155; +} +[data-theme="dark"] .lang-picker-search input { + background-color: #0f172a; + border-color: #334155; + color: #e2e8f0; +} +[data-theme="dark"] .lang-picker-search input:focus { + border-color: #ff5e3a; +} +[data-theme="dark"] .lang-picker-search input::placeholder { + color: #64748b; +} +[data-theme="dark"] .lang-picker-list::-webkit-scrollbar-thumb { + background: #475569; +} +[data-theme="dark"] .lang-picker-item:hover { + background: #162032; +} +[data-theme="dark"] .lang-picker-item.selected { + background: #2a1a15; +} +[data-theme="dark"] .lang-picker-item-name { + color: #f1f5f9; +} +[data-theme="dark"] .lang-picker-item-english { + color: #64748b; +} +[data-theme="dark"] .lang-picker-empty { + color: #64748b; +} +/* Setup steps */ +[data-theme="dark"] .step-number { + background-color: #334155; + color: #94a3b8; +} +[data-theme="dark"] .step-title { + color: #94a3b8; +} diff --git a/static/css/views/favorites.css b/static/css/views/favorites.css new file mode 100644 index 00000000..d729af2e --- /dev/null +++ b/static/css/views/favorites.css @@ -0,0 +1,126 @@ +/* Styles for the favorites feature */ + +/* Favorite indicator */ +.favorite-indicator { + position: absolute; + top: 10px; + right: 10px; + width: 25px; + height: 25px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + color: #ccc; + cursor: pointer; + z-index: 5; + transition: all 0.2s ease; + + [dir='rtl'] & { + left: 10px; + right: unset; + } +} + +.favorite-indicator:hover { + transform: scale(1.1); +} + +.favorite-indicator.active { + color: #ffc107; + text-shadow: 0 0 5px rgba(255, 193, 7, 0.5); +} + +/* Styles for the favorites view items */ +.favorite-item { + position: relative; +} + +/* Adjustments for grid view */ +.file-card.favorite-item { + border-left: 3px solid #ffc107; + + [dir='rtl'] & { + border-right: 3px solid #ffc107; + border-left: unset; + } +} + +/* Adjustments for list view */ +.list-header.favorites-header { + grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; +} + +.file-item.favorite-item { + position: relative; + grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; +} + +.file-item.favorite-item .favorite-indicator { + position: relative; + top: 0; + right: 0; + width: 30px; + height: 30px; +} + +/* Styles for the favorites-specific empty state */ +.favorites-empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 50px 20px; + text-align: center; + color: #6c757d; +} + +.favorites-empty-state i { + font-size: 48px; + color: #ffc107; + margin-bottom: 20px; + opacity: 0.6; +} + +.favorites-empty-state p { + margin-bottom: 10px; + max-width: 400px; +} + +/* Animation for the favorite star */ +@keyframes favorite-pulse { + 0% { transform: scale(1); } + 50% { transform: scale(1.2); } + 100% { transform: scale(1); } +} + +.favorite-indicator.active { + animation: favorite-pulse 0.3s ease; +} + +/* ── Star badge on file/folder cards (normal view) ── */ + +/* Grid view: keep interactive star button behavior from style.css */ +.file-card .favorite-star { + pointer-events: auto; + z-index: 12; +} + +.file-card .favorite-star.active i, +.file-card .favorite-star.active svg { + animation: favorite-pulse 0.3s ease; +} + +/* List view: small star next to the name */ +.favorite-star-inline { + color: #ffc107; + font-size: 11px; + margin-left: 6px; + vertical-align: middle; + filter: drop-shadow(0 0 1px rgba(255, 193, 7, 0.4)); + + [dir='rtl'] & { + margin-left: 0; + margin-right: 6px; + } +} \ No newline at end of file diff --git a/static/css/views/inlineViewer.css b/static/css/views/inlineViewer.css new file mode 100644 index 00000000..2dcb0bc9 --- /dev/null +++ b/static/css/views/inlineViewer.css @@ -0,0 +1,226 @@ +/* OxiCloud Inline Viewer Styles */ + +.inline-viewer-modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 9999; + background-color: rgba(0, 0, 0, 0.85); + display: none; + opacity: 0; + transition: opacity 0.3s ease; + pointer-events: none; +} + +.inline-viewer-modal.active { + display: flex !important; + opacity: 1; + align-items: center; + justify-content: center; + pointer-events: all; +} + +.inline-viewer-content { + width: 90%; + height: 90%; + max-width: 1200px; + background-color: #fff; + border-radius: 8px; + overflow: hidden; + display: flex; + flex-direction: column; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); +} + +.inline-viewer-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 16px; + background-color: #f8f9fa; + border-bottom: 1px solid #e2e8f0; +} + +.inline-viewer-title { + font-size: 18px; + font-weight: 500; + color: #2d3748; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.inline-viewer-close { + background: none; + border: none; + font-size: 18px; + cursor: pointer; + color: #718096; + width: 36px; + height: 36px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: background-color 0.2s; +} + +.inline-viewer-close:hover { + background-color: #e2e8f0; + color: #4a5568; +} + +.inline-viewer-container { + flex-grow: 1; + overflow: auto; + background-color: #f0f3f7; + display: flex; + align-items: center; + justify-content: center; + position: relative; +} + +.inline-viewer-toolbar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 16px; + background-color: #f8f9fa; + border-top: 1px solid #e2e8f0; +} + +.inline-viewer-download { + background-color: #ff5e3a; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + display: flex; + align-items: center; + gap: 8px; + transition: background-color 0.2s; +} + +.inline-viewer-download:hover { + background-color: #e74c3c; +} + +.inline-viewer-controls { + display: flex; + gap: 8px; +} + +.inline-viewer-controls button { + background-color: #f1f5f9; + border: 1px solid #cbd5e1; + border-radius: 4px; + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + color: #64748b; + transition: all 0.2s; +} + +.inline-viewer-controls button:hover { + background-color: #e2e8f0; + color: #334155; +} + +/* Image viewer */ +.inline-viewer-image { + max-width: 100%; + max-height: 100%; + object-fit: contain; + transform-origin: center; + transition: transform 0.2s ease; +} + +/* PDF viewer */ +.inline-viewer-pdf, +.inline-viewer-pdf-fallback { + width: 100%; + height: 100%; + border: none; +} + +/* Only show fallback if object fails */ +.inline-viewer-pdf + .inline-viewer-pdf-fallback { + display: none; +} + +.inline-viewer-pdf:not([data]), +.inline-viewer-pdf[data=""] + .inline-viewer-pdf-fallback { + display: block; +} + +/* Loading indicator */ +.inline-viewer-loader { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 36px; + color: #64748b; +} + +/* Error and unsupported message */ +.inline-viewer-message { + padding: 32px; + text-align: center; + max-width: 400px; +} + +.inline-viewer-icon { + font-size: 64px; + color: #cbd5e1; + margin-bottom: 24px; +} + +.inline-viewer-text { + color: #64748b; + line-height: 1.6; +} + +.inline-viewer-text p { + margin: 0 0 16px; +} + +/* Text viewer */ +.inline-viewer-text-content { + width: 100%; + height: 100%; + margin: 0; + padding: 16px 24px; + font-family: 'Courier New', Consolas, Monaco, monospace; + font-size: 14px; + line-height: 1.6; + color: #2d3748; + background-color: #fff; + overflow: auto; + white-space: pre-wrap; + word-wrap: break-word; + box-sizing: border-box; + text-align: left; + tab-size: 4; +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .inline-viewer-content { + width: 100%; + height: 100%; + border-radius: 0; + } + + .inline-viewer-controls { + display: none; + } +} \ No newline at end of file diff --git a/static/css/views/profile.css b/static/css/views/profile.css new file mode 100644 index 00000000..a9966e17 --- /dev/null +++ b/static/css/views/profile.css @@ -0,0 +1,148 @@ +*{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{background:#f5f7fa;color:#1e293b;min-height:100vh;display:flex;flex-direction:column} + +.link-reset-flex{text-decoration:none;color:inherit;display:flex;align-items:center;gap:14px} +.width-zero{width:0%} + +#main-content{display:none} + +/* ── Scrollbar ── */ +::-webkit-scrollbar{width:8px} +::-webkit-scrollbar-track{background:transparent} +::-webkit-scrollbar-thumb{background:rgba(0,0,0,.15);border-radius:4px} +*{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.15) transparent} + +/* ── Header ── */ +.profile-header{ + background:linear-gradient(135deg,#2a3042 0%,#232838 100%); + padding:0 32px;height:64px;display:flex;align-items:center;justify-content:space-between; + box-shadow:0 2px 12px rgba(0,0,0,.15);position:sticky;top:0;z-index:100; +} +.profile-header-left{display:flex;align-items:center;gap:14px} +.profile-logo{ + width:38px;height:38px;background:linear-gradient(135deg,#ff5e3a,#ff2d55);border-radius:11px; + display:flex;align-items:center;justify-content:center; + box-shadow:0 3px 10px rgba(255,94,58,.35); +} +.profile-logo svg{width:20px;height:20px;fill:#fff} +.profile-title-text{font-size:17px;font-weight:700;color:#fff;letter-spacing:.3px} +.profile-title-separator{font-size:17px;color:rgba(255,255,255,.5);font-weight:400;margin-left:6px} +.profile-header-right a{ + color:rgba(255,255,255,.65);text-decoration:none;font-size:13px;font-weight:500; + display:flex;align-items:center;gap:6px;transition:color .2s; +} +.profile-header-right a:hover{color:#fff} + +/* ── Container ── */ +.profile-container{max-width:720px;margin:0 auto;padding:32px 24px 60px;width:100%} + +/* ── Card ── */ +.profile-card{background:#fff;border-radius:16px;box-shadow:0 1px 4px rgba(0,0,0,.06),0 0 0 1px rgba(0,0,0,.03);padding:32px;margin-bottom:22px} +.profile-card h2{font-size:16px;font-weight:700;margin-bottom:20px;color:#1e293b;display:flex;align-items:center;gap:10px} +.profile-card h2 i{color:#ff5e3a;font-size:17px} + +/* ── Avatar Section ── */ +.avatar-section{display:flex;align-items:center;gap:24px;margin-bottom:8px} +.avatar-large{ + width:88px;height:88px;border-radius:50%; + background:linear-gradient(135deg,#ff5e3a,#ff2d55); + display:flex;align-items:center;justify-content:center; + color:#fff;font-size:32px;font-weight:700;letter-spacing:1px; + box-shadow:0 6px 20px rgba(255,94,58,.3);flex-shrink:0; +} +.avatar-info h1{font-size:22px;font-weight:700;color:#1e293b;margin-bottom:4px} +.avatar-info .email{font-size:14px;color:#64748b;margin-bottom:8px} +.avatar-info .role-badge{ + display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600; + padding:4px 12px;border-radius:20px; +} +.role-badge-admin{background:#dbeafe;color:#1d4ed8} +.role-badge-user{background:#f1f5f9;color:#64748b} + +/* ── Info Grid ── */ +.info-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px} +@media(max-width:560px){.info-grid{grid-template-columns:1fr}} +.info-item{padding:16px;background:#f8fafc;border-radius:12px;border:1px solid #e2e8f0} +.info-item .info-label{font-size:11.5px;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;font-weight:700;margin-bottom:4px;display:flex;align-items:center;gap:6px} +.info-item .info-label i{font-size:12px;color:#cbd5e1} +.info-item .info-value{font-size:15px;font-weight:600;color:#1e293b} + +/* ── Storage ── */ +.storage-section{margin-top:4px} +.storage-stats{display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px;margin-bottom:16px} +@media(max-width:560px){.storage-stats{grid-template-columns:1fr}} +.storage-stat{text-align:center;padding:16px;background:#f8fafc;border-radius:12px;border:1px solid #e2e8f0} +.storage-stat .stat-value{font-size:1.5rem;font-weight:800;color:#1e293b} +.storage-stat .stat-label{font-size:11px;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;font-weight:600;margin-top:2px} +.storage-bar-wrap{margin-top:4px} +.storage-bar{height:10px;background:#e2e8f0;border-radius:5px;overflow:hidden} +.storage-fill{height:100%;border-radius:5px;transition:width .6s ease} +.storage-fill.green{background:linear-gradient(90deg,#059669,#10b981)} +.storage-fill.orange{background:linear-gradient(90deg,#d97706,#f59e0b)} +.storage-fill.red{background:linear-gradient(90deg,#dc2626,#ef4444)} +.storage-text{font-size:12px;color:#94a3b8;text-align:right;margin-top:6px} + +/* ── Change Password ── */ +.form-group{margin-bottom:16px} +.form-group label{display:block;font-size:13px;font-weight:600;margin-bottom:4px;color:#334155} +.form-group input{ + width:100%;padding:10px 14px;border:2px solid #e2e8f0;border-radius:10px;font-size:14px; + background:#f8fafc;transition:all .2s;font-family:inherit;color:#1e293b; +} +.form-group input:focus{outline:none;border-color:#ff5e3a;background:#fff;box-shadow:0 0 0 3px rgba(255,94,58,.1)} +.form-group small{color:#94a3b8;font-size:12px;display:block;margin-top:3px} + +.btn{ + padding:10px 22px;border:none;border-radius:10px;font-size:14px;font-weight:600; + cursor:pointer;transition:all .15s;white-space:nowrap;display:inline-flex;align-items:center;gap:6px; +} +.btn-primary{background:linear-gradient(135deg,#ff5e3a,#ff2d55);color:#fff;box-shadow:0 2px 8px rgba(255,94,58,.25)} +.btn-primary:hover{box-shadow:0 4px 14px rgba(255,94,58,.35);transform:translateY(-1px)} +.btn-primary:disabled{opacity:.4;cursor:not-allowed;transform:none!important} + +.alert{padding:12px 16px;border-radius:10px;font-size:13px;margin-top:14px;font-weight:500} +.alert-success{background:#ecfdf5;color:#065f46;border:1px solid #a7f3d0} +.alert-error{background:#fef2f2;color:#991b1b;border:1px solid #fecaca} + +/* ── Loading / Error ── */ +#loading{text-align:center;padding:80px;color:#94a3b8;font-size:15px} +#loading i{font-size:32px;color:#ff5e3a;display:block;margin-bottom:12px;animation:spin 1s linear infinite} +@keyframes spin{to{transform:rotate(360deg)}} +#auth-error{display:none;text-align:center;padding:80px 20px} +#auth-error .err-icon{width:80px;height:80px;background:#fef2f2;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 20px} +#auth-error .err-icon i{font-size:32px;color:#ef4444} +#auth-error h2{color:#991b1b;margin-bottom:8px;font-size:20px} +#auth-error p{color:#64748b;margin-bottom:20px;font-size:14px} +#auth-error a{display:inline-flex;align-items:center;gap:6px;padding:10px 24px;background:linear-gradient(135deg,#ff5e3a,#ff2d55);color:#fff;text-decoration:none;border-radius:10px;font-weight:600;font-size:14px;box-shadow:0 3px 12px rgba(255,94,58,.3);transition:all .2s} +#auth-error a:hover{transform:translateY(-1px);box-shadow:0 5px 18px rgba(255,94,58,.4)} + +/* ── Dark Mode ── */ +[data-theme="dark"] body{background:#0f172a;color:#e2e8f0} +[data-theme="dark"] ::-webkit-scrollbar-thumb{background:rgba(255,255,255,.15)} +[data-theme="dark"] *{scrollbar-color:rgba(255,255,255,.15) transparent} +[data-theme="dark"] .profile-card{background:#1e293b;box-shadow:0 1px 4px rgba(0,0,0,.2),0 0 0 1px rgba(255,255,255,.03)} +[data-theme="dark"] .profile-card h2{color:#f1f5f9} +[data-theme="dark"] .avatar-info h1{color:#f1f5f9} +[data-theme="dark"] .avatar-info .email{color:#94a3b8} +[data-theme="dark"] .role-badge-admin{background:#1e3a5f;color:#60a5fa} +[data-theme="dark"] .role-badge-user{background:#334155;color:#94a3b8} +[data-theme="dark"] .info-item{background:#162032;border-color:#334155} +[data-theme="dark"] .info-item .info-label{color:#64748b} +[data-theme="dark"] .info-item .info-label i{color:#475569} +[data-theme="dark"] .info-item .info-value{color:#f1f5f9} +[data-theme="dark"] .storage-stat{background:#162032;border-color:#334155} +[data-theme="dark"] .storage-stat .stat-value{color:#f1f5f9} +[data-theme="dark"] .storage-stat .stat-label{color:#64748b} +[data-theme="dark"] .storage-bar{background:#334155} +[data-theme="dark"] .storage-text{color:#64748b} +[data-theme="dark"] .form-group label{color:#94a3b8} +[data-theme="dark"] .form-group input{background:#0f172a;border-color:#334155;color:#e2e8f0} +[data-theme="dark"] .form-group input:focus{border-color:#ff5e3a;background:#0f172a;box-shadow:0 0 0 3px rgba(255,94,58,.15)} +[data-theme="dark"] .form-group small{color:#64748b} +[data-theme="dark"] .alert-success{background:#052e16;color:#86efac;border-color:#065f46} +[data-theme="dark"] .alert-error{background:#3b1111;color:#fca5a5;border-color:#991b1b} +[data-theme="dark"] #auth-error{background:transparent} +[data-theme="dark"] #auth-error .err-icon{background:#3b1111} +[data-theme="dark"] #auth-error h2{color:#fca5a5} +[data-theme="dark"] #auth-error p{color:#94a3b8} +[data-theme="dark"] #loading{color:#64748b} diff --git a/static/css/views/recent.css b/static/css/views/recent.css new file mode 100644 index 00000000..008907f0 --- /dev/null +++ b/static/css/views/recent.css @@ -0,0 +1,92 @@ +/* Styles for the recent files feature */ + +/* Recent indicator */ +.recent-indicator { + position: absolute; + top: 10px; + right: 10px; + width: 25px; + height: 25px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + color: #6c757d; + z-index: 5; + + [dir='rtl'] & { + left: 10px; + right: unset; + } +} + +/* Styles for the recent view items */ +.recent-item { + position: relative; +} + +/* Adjustments for grid view */ +.file-card.recent-item { + border-left: 3px solid #6c757d; + + [dir='rtl'] & { + border-right: 3px solid #6c757d; + border-left: unset; + } +} + +/* Adjustments for list view */ +.list-header.recent-header { + grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; +} + +.file-item.recent-item { + position: relative; + grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; +} + +.file-item.recent-item .recent-indicator { + position: relative; + top: 0; + right: 0; + width: 30px; + height: 30px; +} + +/* Styles for the recent-specific empty state */ +.recents-empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 50px 20px; + text-align: center; + color: #6c757d; +} + +.recents-empty-state i { + font-size: 48px; + color: #6c757d; + margin-bottom: 20px; + opacity: 0.6; +} + +.recents-empty-state p { + margin-bottom: 10px; + max-width: 400px; +} + +/* Tooltip for access time */ +.recent-item .file-info { + cursor: help; +} + +/* Animation for recent files */ +.recent-item { + animation: recent-fade-in 0.3s ease; +} + +@keyframes recent-fade-in { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} \ No newline at end of file diff --git a/static/css/views/shared.css b/static/css/views/shared.css new file mode 100644 index 00000000..521a0723 --- /dev/null +++ b/static/css/views/shared.css @@ -0,0 +1,420 @@ +.page-description { + color: #718096; + font-size: 16px; + margin-top: -15px; + margin-bottom: 25px; +} + +.shared-page-container { + max-width: 1280px; + margin: 20px auto; + padding: 0 20px; +} + +.shared-header { + margin-bottom: 25px; +} + +.shared-header h2 { + font-size: 24px; + color: #2d3748; + margin-bottom: 8px; +} + +.shared-header p { + color: #718096; + font-size: 16px; +} + +/* In-app Shared view (index.html dynamic container) */ +.shared-view-container .shared-header { + margin-bottom: 20px; +} + +.shared-view-container .shared-filters { + display: flex; + align-items: center; + justify-content: flex-start; + gap: 12px; + flex-wrap: wrap; + margin-bottom: 0; + padding: 15px; + background-color: #f8f9fa; + box-shadow: 0 1px 3px rgba(0,0,0,0.05); + border-radius: 10px 10px 0 0; + border-bottom: 1px solid #e0e6ed; + font-weight: 600; + color: #2d3748; +} + +.shared-view-container .shared-custom-select { + position: relative; +} + +.shared-view-container .shared-select-toggle { + display: flex; + align-items: center; + gap: 10px; + width: 100%; + padding: 10px 40px 10px 16px; + border-radius: 12px; + border: 2px solid #e2e8f0; + background-color: #f8fafc; + font-size: 14px; + font-weight: 500; + color: #1a202c; + cursor: pointer; + min-width: 170px; + height: 44px; + transition: all 0.2s ease; + text-align: left; +} + +.shared-view-container .shared-select-toggle:hover { + border-color: #cbd5e0; + background-color: #fff; +} + +.shared-view-container .shared-custom-select.open .shared-select-toggle { + border-color: #ff5e3a; + background-color: #fff; + box-shadow: 0 0 0 4px rgba(255, 94, 58, 0.1); +} + +.shared-view-container .shared-select-arrow { + position: absolute; + right: 14px; + top: 50%; + transform: translateY(-50%); + font-size: 10px; + color: #718096; + transition: transform 0.2s ease; + pointer-events: none; +} + +.shared-view-container .shared-custom-select.open .shared-select-arrow { + transform: translateY(-50%) rotate(180deg); +} + +.shared-view-container .shared-select-dropdown { + position: absolute; + top: calc(100% + 6px); + left: 0; + min-width: 100%; + background-color: white; + border-radius: 12px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); + border: 1px solid #e2e8f0; + opacity: 0; + visibility: hidden; + transform: translateY(-10px); + transition: all 0.2s ease; + z-index: 1000; + overflow: hidden; +} + +.shared-view-container .shared-custom-select.open .shared-select-dropdown { + opacity: 1; + visibility: visible; + transform: translateY(0); +} + +.shared-view-container .shared-select-option { + display: flex; + align-items: center; + padding: 12px 16px; + cursor: pointer; + font-size: 14px; + font-weight: 400; + color: #4a5568; + transition: background-color 0.15s ease; +} + +.shared-view-container .shared-select-option:hover { + background-color: #f7fafc; +} + +.shared-view-container .shared-select-option.active { + background-color: #fff5f3; + color: #ff5e3a; + font-weight: 500; +} + +.shared-filters { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0; + flex-wrap: wrap; + gap: 15px; + background-color: #f8f9fa; + border-radius: 10px 10px 0 0; + padding: 15px; + border-bottom: 1px solid #e0e6ed; + box-shadow: 0 1px 3px rgba(0,0,0,0.05); + font-weight: 600; + color: #2d3748; +} + +.filter-group { + display: flex; + align-items: center; + gap: 10px; +} + +.filter-group label { + font-size: 14px; + color: #4a5568; + font-weight: 500; +} + +.filter-group select { + padding: 8px 12px; + border: 1px solid #e2e8f0; + border-radius: 6px; + background-color: white; + font-size: 14px; + min-width: 120px; +} + +.search-box { + display: flex; + gap: 10px; +} + +.search-box input { + padding: 8px 15px; + border: 1px solid #e2e8f0; + border-radius: 6px; + font-size: 14px; + width: 250px; +} + +.shared-list-container { + background-color: white; + border-radius: 0 0 10px 10px; + box-shadow: 0 1px 3px rgba(0,0,0,0.05); + overflow: hidden; + margin-bottom: 25px; +} + +.shared-list, +.shared-table { + width: 100%; + border-collapse: collapse; +} + +.shared-list thead th, +.shared-table thead th { + padding: 15px; + text-align: left; + font-weight: 600; + color: #2d3748; + background-color: #f8f9fa; + border-bottom: 1px solid #e0e6ed; +} + +.shared-list tbody td, +.shared-table tbody td { + padding: 15px; + border-bottom: 1px solid #f0f0f0; + vertical-align: middle; +} + +.shared-item-name { + display: flex; + align-items: center; + gap: 10px; +} + +.shared-item-actions { + display: flex; + gap: 10px; +} + +.shared-list .action-btn, +.shared-table .action-btn { + width: 32px; + height: 32px; + border: 1px solid #e2e8f0; + border-radius: 6px; + background-color: white; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all 0.2s; +} + +.shared-list .action-btn:hover, +.shared-table .action-btn:hover { + background-color: #f0f8ff; + border-color: #90cdf4; +} + +.action-icon { + font-size: 14px; +} + +#empty-shared-state.empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 50px 20px; + background-color: transparent; + border-radius: 0; + box-shadow: none; + text-align: center; + color: #6c757d; +} + +#empty-shared-state p { + margin-bottom: 10px; + max-width: 400px; +} + +@media (max-width: 768px) { + .shared-filters { + flex-direction: column; + align-items: flex-start; + } + + .shared-list thead th:nth-child(4), + .shared-list thead th:nth-child(5), + .shared-list tbody td:nth-child(4), + .shared-list tbody td:nth-child(5), + .shared-table thead th:nth-child(4), + .shared-table thead th:nth-child(5), + .shared-table tbody td:nth-child(4), + .shared-table tbody td:nth-child(5) { + display: none; + } +} + +[data-theme="dark"] .shared-filters { + background-color: #162032; + color: #94a3b8; + border-bottom-color: #334155; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); +} + +[data-theme="dark"] .shared-view-container .shared-select-toggle { + background-color: #1e293b; + border-color: #334155; + color: #cbd5e1; +} + +[data-theme="dark"] .shared-view-container .shared-filters { + background-color: #162032; + color: #94a3b8; + border-bottom-color: #334155; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); +} + +[data-theme="dark"] .shared-view-container .shared-select-toggle:hover { + background-color: #334155; + border-color: #475569; +} + +[data-theme="dark"] .shared-view-container .shared-custom-select.open .shared-select-toggle { + border-color: #ff5e3a; + box-shadow: 0 0 0 4px rgba(255, 94, 58, 0.15); + background-color: #1e293b; +} + +[data-theme="dark"] .shared-view-container .shared-select-arrow { + color: #94a3b8; +} + +[data-theme="dark"] .shared-view-container .shared-select-dropdown { + background-color: #1e293b; + border-color: #334155; + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5); +} + +[data-theme="dark"] .shared-view-container .shared-select-option { + color: #cbd5e1; +} + +[data-theme="dark"] .shared-view-container .shared-select-option:hover { + background-color: #334155; +} + +[data-theme="dark"] .shared-view-container .shared-select-option.active { + background-color: rgba(255, 94, 58, 0.1); + color: #ff5e3a; +} + +[data-theme="dark"] .filter-group label { + color: #94a3b8; +} + +[data-theme="dark"] .filter-group select { + background-color: #1e293b; + border-color: #334155; + color: #e2e8f0; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2394a3b8' d='M6 8L1 3h10z'/%3E%3C/svg%3E"); +} + +[data-theme="dark"] .filter-group select:focus { + border-color: #ff5e3a; + box-shadow: 0 0 0 3px rgba(255, 94, 58, 0.15); +} + +[data-theme="dark"] .search-box input { + background-color: #1e293b; + border-color: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] .search-box input::placeholder { + color: #64748b; +} + +[data-theme="dark"] .shared-list-container { + background-color: #1e293b; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); +} + +[data-theme="dark"] .shared-list thead th, +[data-theme="dark"] .shared-table thead th { + background-color: #162032; + color: #94a3b8; + border-bottom-color: #334155; +} + +[data-theme="dark"] .shared-list tbody td, +[data-theme="dark"] .shared-table tbody td { + border-bottom-color: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] .shared-list tbody tr:hover, +[data-theme="dark"] .shared-table tbody tr:hover { + background-color: #162032; +} + +[data-theme="dark"] .page-description { + color: #94a3b8; +} + +[data-theme="dark"] #empty-shared-state.empty-state { + background-color: transparent; + box-shadow: none; + color: #64748b; +} + +[data-theme="dark"] #empty-shared-state p { + color: #94a3b8; +} + +[data-theme="dark"] .shared-list .action-btn, +[data-theme="dark"] .shared-table .action-btn { + color: #94a3b8; +} + +[data-theme="dark"] .shared-list .action-btn:hover, +[data-theme="dark"] .shared-table .action-btn:hover { + color: #ff5e3a; +} diff --git a/static/css/views/trash.css b/static/css/views/trash.css new file mode 100644 index 00000000..f1e29111 --- /dev/null +++ b/static/css/views/trash.css @@ -0,0 +1,68 @@ +.trash-item { + position: relative; +} + +.trash-actions { + position: absolute; + top: 10px; + right: 10px; + display: none; + gap: 8px; +} + +.file-card.trash-item:hover .trash-actions, +.file-item.trash-item:hover .actions-cell { + display: flex; +} + +.trash-actions button, +.actions-cell button { + background: #fff; + border: 1px solid #ddd; + border-radius: 4px; + padding: 4px 8px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + width: 30px; + height: 30px; + transition: all 0.2s; +} + +.trash-actions button:hover, +.actions-cell button:hover { + background: #f0f0f0; +} + +.btn-restore { + color: #4caf50; +} + +.btn-delete { + color: #f44336; +} + +.actions-cell { + display: flex; + gap: 8px; + justify-content: flex-start; + align-items: center; +} + +.btn-danger { + background-color: #f44336; + color: white; +} + +[data-theme="dark"] .trash-actions button, +[data-theme="dark"] .actions-cell button { + background: #1e293b; + border-color: #334155; + color: #e2e8f0; +} + +[data-theme="dark"] .trash-actions button:hover, +[data-theme="dark"] .actions-cell button:hover { + background: #334155; +} diff --git a/static/index.html b/static/index.html index feb71bd1..2457b0ab 100644 --- a/static/index.html +++ b/static/index.html @@ -8,10 +8,12 @@ - - - - + + + + + + diff --git a/static/js/app/authSession.js b/static/js/app/authSession.js index b910a57f..ca969c1e 100644 --- a/static/js/app/authSession.js +++ b/static/js/app/authSession.js @@ -205,17 +205,20 @@ async function resolveHomeFolder() { app.userHomeFolderId = home.id; app.userHomeFolderName = home.name; app.currentPath = home.id; - window.ui.updateBreadcrumb(home.name); + app.breadcrumbPath = []; + window.ui.updateBreadcrumb(); console.log(`Home folder resolved: ${home.name} (${home.id})`); } else { console.warn('No root folders found for user'); app.currentPath = ''; - window.ui.updateBreadcrumb(''); + app.breadcrumbPath = []; + window.ui.updateBreadcrumb(); } } catch (error) { console.error('Error resolving home folder:', error); app.currentPath = ''; - window.ui.updateBreadcrumb(''); + app.breadcrumbPath = []; + window.ui.updateBreadcrumb(); } } diff --git a/static/js/app/filesView.js b/static/js/app/filesView.js index 6232f427..2e45dc07 100644 --- a/static/js/app/filesView.js +++ b/static/js/app/filesView.js @@ -36,7 +36,8 @@ async function loadFiles(options = {}) { if (app.userHomeFolderId) { url = `/api/folders/${app.userHomeFolderId}/listing?t=${timestamp}`; app.currentPath = app.userHomeFolderId; - window.ui.updateBreadcrumb(app.userHomeFolderName || 'Home'); + app.breadcrumbPath = []; + window.ui.updateBreadcrumb(); console.log(`Loading user folder: ${app.userHomeFolderName} (${app.userHomeFolderId})`); } else { url = `/api/folders?t=${timestamp}`; diff --git a/static/js/app/main.js b/static/js/app/main.js index c2414302..789c6171 100644 --- a/static/js/app/main.js +++ b/static/js/app/main.js @@ -52,6 +52,14 @@ const ACTIONS_BAR_TEMPLATES = { Empty trash +
+ + +
`, favorites: `
@@ -537,8 +545,9 @@ window.setActionsBarMode = setActionsBarMode; // Set up global selectFolder function for navigation window.selectFolder = (id, name) => { + app.breadcrumbPath.push({ id, name }); app.currentPath = id; - ui.updateBreadcrumb(name); + ui.updateBreadcrumb(); window.loadFiles(); }; diff --git a/static/js/app/navigation.js b/static/js/app/navigation.js index 38ade27e..445a8a9a 100644 --- a/static/js/app/navigation.js +++ b/static/js/app/navigation.js @@ -76,7 +76,8 @@ function switchToFilesView() { if (window.app.userHomeFolderId) { window.app.currentPath = window.app.userHomeFolderId; - window.ui.updateBreadcrumb(window.app.userHomeFolderName || 'Home'); + window.app.breadcrumbPath = []; + window.ui.updateBreadcrumb(); } else { window.app.currentPath = ''; } diff --git a/static/js/app/state.js b/static/js/app/state.js index 6a8dfb07..c515a093 100644 --- a/static/js/app/state.js +++ b/static/js/app/state.js @@ -19,7 +19,8 @@ window.app = { isSearchMode: false, shareDialogItem: null, shareDialogItemType: null, - notificationShareUrl: null + notificationShareUrl: null, + breadcrumbPath: [] // Array of {id, name} tracking folder navigation hierarchy }; window.appElements = { diff --git a/static/js/app/ui.js b/static/js/app/ui.js index 5e2e5727..7dc48e51 100644 --- a/static/js/app/ui.js +++ b/static/js/app/ui.js @@ -472,75 +472,72 @@ const ui = { }, /** - * Update breadcrumb navigation - * @param {string} folderName - Name of the current folder + * Update breadcrumb navigation from the breadcrumbPath array. + * Renders: Home > folder1 > folder2 > ... + * Each segment is clickable to navigate back to that level. */ - updateBreadcrumb(folderName) { + updateBreadcrumb() { const breadcrumb = document.querySelector('.breadcrumb'); breadcrumb.innerHTML = ''; - - // Get user info to help determine home folder - const USER_DATA_KEY = 'oxicloud_user'; - const userData = JSON.parse(localStorage.getItem(USER_DATA_KEY) || '{}'); - const username = userData.username || ''; - - // Create the home item - for users, this is their personal folder - const homeItem = document.createElement('span'); - homeItem.className = 'breadcrumb-item'; - + + const self = this; + const path = window.app.breadcrumbPath; // [{id, name}, ...] + // Helper function to safely get translation text const getTranslatedText = (key, defaultValue) => { if (!window.i18n || !window.i18n.t) return defaultValue; return window.i18n.t(key); }; - - // First determine if the current view is the user's home folder - const isUserHomeFolder = username && window.app.userHomeFolderName && - window.app.userHomeFolderName.includes(username) && - folderName === window.app.userHomeFolderName; - - // Set appropriate text for home item - if (isUserHomeFolder) { - // If the current folder is the user's home folder, label it as "Home" - homeItem.textContent = getTranslatedText('breadcrumb.home', 'Home'); - } else if (folderName && folderName.startsWith('My Folder')) { - // If viewing a root folder but not the user's home folder, use its full name - homeItem.textContent = folderName; - } else { - // Default - use "Home" label - homeItem.textContent = getTranslatedText('breadcrumb.home', 'Home'); - - // For searching, we might have a custom breadcrumb text - if (folderName && folderName.startsWith('Search:')) { - // We're in search mode - don't add click handler - breadcrumb.appendChild(homeItem); - return; - } - } - - // Add click handler - but only if we have a user home folder to return to - if (window.app.userHomeFolderId) { + + // -- Home item (always present) -- + const homeItem = document.createElement('span'); + homeItem.className = 'breadcrumb-item'; + homeItem.textContent = getTranslatedText('breadcrumb.home', 'Home'); + + // If we have deeper segments, Home is clickable + if (path.length > 0 && window.app.userHomeFolderId) { + homeItem.classList.add('breadcrumb-link'); homeItem.addEventListener('click', () => { + window.app.breadcrumbPath = []; window.app.currentPath = window.app.userHomeFolderId; - this.updateBreadcrumb(window.app.userHomeFolderName || 'Home'); + self.updateBreadcrumb(); window.loadFiles(); }); + } else { + homeItem.classList.add('breadcrumb-current'); } - breadcrumb.appendChild(homeItem); - // If we have a subfolder, add it to the breadcrumb - if (folderName && !folderName.startsWith('Mi Carpeta') && !folderName.startsWith('Search:')) { + // -- Intermediate + current segments -- + path.forEach((segment, index) => { + const isLast = index === path.length - 1; + + // Separator const separator = document.createElement('span'); separator.className = 'breadcrumb-separator'; separator.textContent = '>'; breadcrumb.appendChild(separator); - const folderItem = document.createElement('span'); - folderItem.className = 'breadcrumb-item'; - folderItem.textContent = folderName; - breadcrumb.appendChild(folderItem); - } + // Segment item + const item = document.createElement('span'); + item.className = 'breadcrumb-item'; + item.textContent = segment.name; + + if (!isLast) { + // Intermediate segment: clickable – truncate path to this level + item.classList.add('breadcrumb-link'); + item.addEventListener('click', () => { + window.app.breadcrumbPath = path.slice(0, index + 1); + window.app.currentPath = segment.id; + self.updateBreadcrumb(); + window.loadFiles(); + }); + } else { + // Last segment: current location, not clickable + item.classList.add('breadcrumb-current'); + } + breadcrumb.appendChild(item); + }); }, /** @@ -733,8 +730,11 @@ const ui = { }; const navigateFolder = (card) => { - window.app.currentPath = card.dataset.folderId; - self.updateBreadcrumb(card.dataset.folderName); + const folderId = card.dataset.folderId; + const folderName = card.dataset.folderName; + window.app.breadcrumbPath.push({ id: folderId, name: folderName }); + window.app.currentPath = folderId; + self.updateBreadcrumb(); window.loadFiles(); }; diff --git a/static/js/core/icons.js b/static/js/core/icons.js index 3c114643..8d76ac3d 100644 --- a/static/js/core/icons.js +++ b/static/js/core/icons.js @@ -200,6 +200,9 @@ function replaceIconsInElement(container) { // Copy inline style if present if (el.style.cssText) svg.style.cssText = el.style.cssText; + // Preserve id attribute if present + if (el.id) svg.id = el.id; + const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); path.setAttribute("fill", "currentColor"); path.setAttribute("d", d); diff --git a/static/js/core/modal.js b/static/js/core/modal.js index 99b638a2..debf04ec 100644 --- a/static/js/core/modal.js +++ b/static/js/core/modal.js @@ -87,8 +87,18 @@ const Modal = { cancelText = null } = options; - // Set modal content - this.icon.className = `fas ${icon}`; + // Set modal content - update the icon + const iconContainer = document.querySelector('.modal-icon'); + if (iconContainer) { + // Replace contents with a fresh that icons.js will convert + iconContainer.innerHTML = ``; + this.icon = document.getElementById('modal-icon'); + // Let icons.js convert it to SVG + if (window.replaceIconsInElement) { + window.replaceIconsInElement(iconContainer); + this.icon = document.getElementById('modal-icon'); + } + } this.title.textContent = title; this.label.textContent = label; this.input.placeholder = placeholder; diff --git a/static/js/views/shared/sharedView.js b/static/js/views/shared/sharedView.js index 53e1771c..70a60f22 100644 --- a/static/js/views/shared/sharedView.js +++ b/static/js/views/shared/sharedView.js @@ -69,24 +69,35 @@ const sharedView = { container.innerHTML = `
- - +
+ +
+
All
+
Files
+
Folders
+
+
+
+ +
+
Sort by date
+
Sort by name
+
Sort by expiration
+
+