:root { color-scheme: light; --background: hsl(36 33% 97%); --foreground: hsl(222 33% 15%); --card: hsl(0 0% 100%); --line: hsl(32 18% 84%); --line-strong: hsl(32 18% 76%); --primary: hsl(198 78% 37%); --primary-soft: hsl(198 52% 90%); --cyan: hsl(192 85% 55%); --pink: hsl(338 82% 62%); --text-muted: hsl(220 13% 40%); --shadow-1: 0 1px 2px 0 rgb(23 32 46 / 0.06); --shadow-2: 0 12px 30px -12px rgb(23 32 46 / 0.22); } .dark { color-scheme: dark; --background: hsl(222 35% 10%); --foreground: hsl(38 20% 92%); --card: hsl(221 31% 13%); --line: hsl(219 18% 25%); --line-strong: hsl(219 18% 33%); --primary: hsl(194 76% 62%); --primary-soft: hsl(210 34% 24%); --cyan: hsl(192 85% 55%); --pink: hsl(338 82% 62%); --text-muted: hsl(218 17% 72%); --shadow-1: 0 1px 2px 0 rgb(2 8 18 / 0.35); --shadow-2: 0 12px 30px -12px rgb(2 8 18 / 0.55); } * { box-sizing: border-box; } body { margin: 0; color: var(--foreground); font-family: "Avenir Next", "Segoe UI", "Noto Sans", sans-serif; background: var(--background); min-height: 100vh; } body::before { content: ""; position: fixed; inset: 0; pointer-events: none; background-image: linear-gradient(112deg, hsl(198 78% 37% / 0.14) 0%, hsl(192 85% 55% / 0.11) 28%, transparent 56%), linear-gradient(248deg, hsl(338 82% 62% / 0.11) 0%, transparent 46%), repeating-linear-gradient(135deg, hsl(222 33% 15% / 0.035) 0 1px, transparent 1px 11px); opacity: 1; } main { position: relative; max-width: 1050px; margin: 0 auto; padding: 28px 22px 40px; } h1, h2, h3 { font-family: "Baskerville", "Times New Roman", serif; letter-spacing: 0.01em; } .top-nav { position: sticky; top: 0; z-index: 3; display: flex; justify-content: space-between; align-items: center; gap: 18px; padding: 14px 22px; border-bottom: 1px solid hsl(198 78% 37% / 0.25); background: hsl(36 33% 97% / 0.72); backdrop-filter: blur(10px); box-shadow: var(--shadow-1); } .brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--foreground); } .brand img { border-radius: 8px; box-shadow: 0 8px 24px -10px rgb(23 32 46 / 0.35); } .brand-name { background: linear-gradient(90deg, var(--primary), var(--cyan), var(--pink)); -webkit-background-clip: text; background-clip: text; color: transparent; font-size: 1.02rem; font-weight: 800; letter-spacing: 0.06em; } .brand-subtitle { margin-left: -4px; text-transform: uppercase; letter-spacing: 0.12em; font-size: 0.68rem; color: var(--text-muted); font-weight: 700; } .links { display: flex; gap: 14px; } .links-wrap { display: flex; align-items: center; gap: 10px; } a { color: var(--primary); text-decoration: none; font-weight: 700; } .links a { padding: 7px 10px; border-radius: 8px; } .links a:hover { background: hsl(198 52% 90% / 0.65); color: hsl(222 33% 15%); } table { width: 100%; border-collapse: collapse; background: hsl(0 0% 100% / 0.95); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; box-shadow: var(--shadow-2); } th, td { padding: 10px; border-bottom: 1px solid hsl(32 18% 86%); text-align: left; } th { color: hsl(222 33% 18%); background: hsl(36 30% 95%); } code, pre { font-family: "JetBrains Mono", "SF Mono", monospace; } pre { margin: 10px 0 0; white-space: pre-wrap; word-break: break-all; background: hsl(36 24% 93%); border: 1px solid var(--line); border-radius: 8px; padding: 10px; } form.inline { display: inline; } input, select, button { border-radius: 8px; padding: 8px 10px; margin: 4px 8px 4px 0; border: 1px solid var(--line-strong); background: white; color: var(--foreground); } button { border: 1px solid hsl(198 78% 37% / 0.45); background: linear-gradient(95deg, hsl(198 78% 37% / 0.12), hsl(192 85% 55% / 0.15)); color: hsl(222 33% 16%); cursor: pointer; font-weight: 700; } button:hover { box-shadow: 0 6px 20px -10px hsl(198 78% 37% / 0.5); } .theme-toggle { min-width: 66px; } .cancel-btn { background: linear-gradient(95deg, hsl(2 72% 48% / 0.15), hsl(338 82% 62% / 0.2)); border-color: hsl(2 72% 48% / 0.5); } .scan-btn { background: linear-gradient(95deg, hsl(142 60% 45% / 0.15), hsl(142 60% 55% / 0.2)); border-color: hsl(142 60% 45% / 0.5); padding: 4px 12px; font-size: 0.85rem; } .delete-btn { background: linear-gradient(95deg, hsl(2 72% 48% / 0.15), hsl(338 82% 62% / 0.2)); border-color: hsl(2 72% 48% / 0.5); padding: 4px 12px; font-size: 0.85rem; } .full-rebuild-btn { background: linear-gradient(95deg, hsl(280 60% 45% / 0.15), hsl(280 60% 55% / 0.2)); border-color: hsl(280 60% 45% / 0.5); } .status-pending { color: hsl(45 93% 35%); } .status-running { color: hsl(198 78% 37%); font-weight: 700; } .status-completed { color: hsl(142 60% 35%); } .status-failed { color: hsl(2 72% 45%); } .status-cancelled { color: hsl(220 13% 40%); } .error-hint { display: inline-block; margin-left: 6px; width: 16px; height: 16px; line-height: 16px; text-align: center; border-radius: 50%; background: hsl(2 72% 48%); color: white; font-size: 11px; font-weight: bold; cursor: help; } .card { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 16px; margin: 16px 0; box-shadow: var(--shadow-2); } .dark .top-nav { background: hsl(222 35% 10% / 0.72); border-bottom-color: hsl(194 76% 62% / 0.3); } .dark .links a:hover { background: hsl(210 34% 24% / 0.8); color: hsl(38 20% 92%); } .dark table { background: hsl(221 31% 13% / 0.95); } .dark th { color: hsl(38 20% 92%); background: hsl(221 24% 17%); } .dark th, .dark td { border-bottom-color: hsl(219 18% 22%); } .dark input, .dark select, .dark button { background: hsl(221 31% 13%); color: hsl(38 20% 92%); } .dark pre { background: hsl(221 24% 17%); } @media (max-width: 720px) { .top-nav { flex-direction: column; align-items: flex-start; } .links-wrap { width: 100%; justify-content: space-between; } .links { flex-wrap: wrap; } .brand span { font-size: 14px; } main { padding: 18px 14px 30px; } } /* Books page styles */ .search-form { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; } .search-input { flex: 1; min-width: 200px; } .results-info { color: var(--text-muted); margin: 16px 0; font-size: 0.95rem; } .books-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 24px; margin: 24px 0; } .book-card { display: flex; flex-direction: column; text-decoration: none; color: var(--foreground); background: var(--card); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; transition: transform 0.2s ease, box-shadow 0.2s ease; box-shadow: var(--shadow-1); } .book-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); } .book-cover { position: relative; aspect-ratio: 2/3; background: linear-gradient(135deg, hsl(36 24% 93%), hsl(36 24% 88%)); overflow: hidden; } .cover-image { width: 100%; height: 100%; object-fit: cover; } .book-info { padding: 12px; flex: 1; display: flex; flex-direction: column; gap: 4px; } .book-title { font-size: 0.95rem; font-weight: 700; margin: 0; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-family: "Avenir Next", "Segoe UI", sans-serif; letter-spacing: normal; } .book-author { font-size: 0.85rem; color: var(--text-muted); margin: 0; } .book-series { font-size: 0.8rem; color: var(--primary); margin: 0; } .book-meta { display: flex; gap: 8px; margin-top: auto; padding-top: 8px; } .book-kind { font-size: 0.7rem; padding: 2px 6px; border-radius: 4px; font-weight: 700; background: hsl(198 52% 90%); color: hsl(198 78% 37%); } .book-kind.cbz { background: hsl(142 60% 90%); color: hsl(142 60% 35%); } .book-kind.cbr { background: hsl(45 93% 90%); color: hsl(45 93% 35%); } .book-kind.pdf { background: hsl(2 72% 90%); color: hsl(2 72% 45%); } .book-lang { font-size: 0.7rem; padding: 2px 6px; border-radius: 4px; background: var(--line); color: var(--text-muted); } .pagination { display: flex; justify-content: center; margin: 32px 0; } .empty-state { text-align: center; padding: 48px 24px; color: var(--text-muted); } /* Book detail page */ .breadcrumb { margin-bottom: 24px; } .breadcrumb a { color: var(--text-muted); font-size: 0.9rem; } .breadcrumb a:hover { color: var(--primary); } .book-detail { display: grid; grid-template-columns: 300px 1fr; gap: 32px; align-items: start; } @media (max-width: 720px) { .book-detail { grid-template-columns: 1fr; } } .book-detail-cover { border-radius: 12px; overflow: hidden; box-shadow: var(--shadow-2); } .detail-cover-image { width: 100%; height: auto; display: block; } .book-detail-info h1 { margin: 0 0 16px 0; font-size: 1.8rem; line-height: 1.2; } .detail-author { font-size: 1.1rem; color: var(--text-muted); margin: 0 0 16px 0; } .detail-series { font-size: 1rem; color: var(--primary); margin: 0 0 24px 0; } .detail-series .volume { margin-left: 12px; padding: 4px 10px; background: var(--primary-soft); border-radius: 6px; font-size: 0.85rem; color: var(--foreground); } .detail-meta { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 20px; box-shadow: var(--shadow-1); } .meta-row { display: flex; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line); } .meta-row:last-child { border-bottom: none; } .meta-label { font-weight: 700; color: var(--text-muted); min-width: 100px; } .book-id { font-size: 0.85rem; color: var(--text-muted); } .dark .book-cover { background: linear-gradient(135deg, hsl(221 24% 20%), hsl(221 24% 15%)); } .dark .book-kind { background: hsl(198 52% 25%); color: hsl(198 78% 75%); } .dark .book-kind.cbz { background: hsl(142 60% 25%); color: hsl(142 60% 65%); } .dark .book-kind.cbr { background: hsl(45 93% 25%); color: hsl(45 93% 65%); } .dark .book-kind.pdf { background: hsl(2 72% 25%); color: hsl(2 72% 65%); } /* Library info styles */ .library-info { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 16px 20px; margin: 16px 0 24px 0; box-shadow: var(--shadow-1); } .library-info p { margin: 0; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; } .library-info code { font-size: 0.9rem; } .library-info .separator { color: var(--line-strong); font-weight: 300; } .status-enabled { color: hsl(142 60% 45%); font-weight: 700; } .status-disabled { color: hsl(220 13% 40%); font-weight: 700; } .book-count-link { color: var(--primary); text-decoration: none; font-weight: 700; padding: 2px 8px; border-radius: 6px; transition: background 0.2s ease; } .book-count-link:hover { background: var(--primary-soft); } .series-count-link { color: var(--primary); text-decoration: none; font-weight: 700; padding: 2px 8px; border-radius: 6px; transition: background 0.2s ease; } .series-count-link:hover { background: var(--primary-soft); } .dark .status-enabled { color: hsl(142 60% 65%); } .dark .status-disabled { color: hsl(218 17% 72%); } /* Series grid styles */ .series-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 24px; margin: 24px 0; } .series-card { display: flex; flex-direction: column; text-decoration: none; color: var(--foreground); background: var(--card); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; transition: transform 0.2s ease, box-shadow 0.2s ease; box-shadow: var(--shadow-1); } .series-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); } .series-cover { position: relative; aspect-ratio: 2/3; background: linear-gradient(135deg, hsl(36 24% 93%), hsl(36 24% 88%)); overflow: hidden; } .series-cover-image { width: 100%; height: 100%; object-fit: cover; } .series-info { padding: 12px; flex: 1; display: flex; flex-direction: column; gap: 4px; } .series-name { font-size: 0.95rem; font-weight: 700; margin: 0; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-family: "Avenir Next", "Segoe UI", sans-serif; letter-spacing: normal; } .series-count { font-size: 0.85rem; color: var(--text-muted); margin: 0; margin-top: auto; } .dark .series-cover { background: linear-gradient(135deg, hsl(221 24% 20%), hsl(221 24% 15%)); } /* Status badges */ .status-ok { color: hsl(142 60% 45%); font-weight: 700; } .status-error { color: hsl(2 72% 48%); font-weight: 700; } .status-pending { color: hsl(45 93% 47%); font-weight: 700; } .file-path { font-size: 0.8rem; word-break: break-all; max-width: 400px; display: inline-block; } /* Job Progress Component */ .job-progress { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 16px; margin: 8px 0; } .progress-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; } .status-badge { padding: 4px 10px; border-radius: 6px; font-size: 0.8rem; font-weight: 700; text-transform: uppercase; } .status-badge.status-pending { background: hsl(45 93% 90%); color: hsl(45 93% 35%); } .status-badge.status-running { background: hsl(198 52% 90%); color: hsl(198 78% 37%); } .status-badge.status-success { background: hsl(142 60% 90%); color: hsl(142 60% 35%); } .status-badge.status-failed { background: hsl(2 72% 90%); color: hsl(2 72% 45%); } .status-badge.status-cancelled { background: hsl(220 13% 90%); color: hsl(220 13% 40%); } .complete-badge { padding: 4px 10px; border-radius: 6px; font-size: 0.75rem; font-weight: 700; background: hsl(142 60% 90%); color: hsl(142 60% 35%); } .progress-bar-container { position: relative; height: 24px; background: var(--line); border-radius: 12px; overflow: hidden; margin-bottom: 12px; } .progress-bar-fill { height: 100%; background: linear-gradient(90deg, hsl(198 78% 37%), hsl(192 85% 55%)); border-radius: 12px; transition: width 0.3s ease; } .progress-percent { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); font-size: 0.8rem; font-weight: 700; color: var(--foreground); } .progress-stats { display: flex; justify-content: space-between; align-items: center; font-size: 0.9rem; color: var(--text-muted); } .current-file { font-size: 0.8rem; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .progress-detailed-stats { display: flex; gap: 16px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); font-size: 0.85rem; } .error-count { color: hsl(2 72% 48%); font-weight: 700; } .progress-row { background: hsl(198 52% 95%); } .progress-row td { padding: 0; } .toggle-progress-btn { margin-left: 8px; padding: 2px 8px; font-size: 0.75rem; background: transparent; border: 1px solid var(--line); } /* Jobs Indicator */ .jobs-indicator-container { position: relative; } .jobs-indicator { position: relative; display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; padding: 0; border-radius: 8px; background: transparent; border: 1px solid var(--line); color: var(--foreground); cursor: pointer; transition: all 0.2s ease; } .jobs-indicator:hover { background: hsl(198 52% 90% / 0.5); } .jobs-indicator.active { border-color: hsl(198 78% 37% / 0.5); } .jobs-badge { position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px; padding: 0 5px; background: hsl(2 72% 48%); color: white; font-size: 0.7rem; font-weight: 700; border-radius: 9px; display: flex; align-items: center; justify-content: center; } .jobs-pulse { position: absolute; bottom: 2px; left: 2px; width: 8px; height: 8px; background: hsl(142 60% 45%); border-radius: 50%; animation: pulse 2s infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .jobs-dropdown { position: absolute; top: 100%; right: 0; margin-top: 8px; min-width: 320px; max-width: 400px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-2); z-index: 100; padding: 16px; } .jobs-dropdown-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--line); } .jobs-dropdown-header a { font-size: 0.85rem; } .jobs-empty { text-align: center; color: var(--text-muted); padding: 16px; } .jobs-list { list-style: none; margin: 0; padding: 0; max-height: 300px; overflow-y: auto; } .job-item { padding: 12px; border-bottom: 1px solid var(--line); } .job-item:last-child { border-bottom: none; } .job-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } .job-id { font-size: 0.75rem; color: var(--text-muted); } .job-status { font-size: 0.7rem; padding: 2px 6px; border-radius: 4px; font-weight: 700; text-transform: uppercase; } .job-status.status-pending { background: hsl(45 93% 90%); color: hsl(45 93% 35%); } .job-status.status-running { background: hsl(198 52% 90%); color: hsl(198 78% 37%); } .job-mini-progress { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; } .job-progress-bar { flex: 1; height: 6px; background: hsl(198 78% 37%); border-radius: 3px; } .job-mini-progress span { font-size: 0.75rem; color: var(--text-muted); min-width: 35px; } .job-file { margin: 0; font-size: 0.75rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .progress-loading, .progress-error { padding: 16px; text-align: center; color: var(--text-muted); } .progress-error { color: hsl(2 72% 48%); } /* Dark mode overrides for new components */ .dark .status-badge.status-pending { background: hsl(45 93% 25%); color: hsl(45 93% 65%); } .dark .status-badge.status-running { background: hsl(198 52% 25%); color: hsl(198 78% 75%); } .dark .status-badge.status-success { background: hsl(142 60% 25%); color: hsl(142 60% 65%); } .dark .status-badge.status-failed { background: hsl(2 72% 25%); color: hsl(2 72% 65%); } .dark .status-badge.status-cancelled { background: hsl(220 13% 25%); color: hsl(220 13% 65%); } .dark .complete-badge { background: hsl(142 60% 25%); color: hsl(142 60% 65%); } .dark .progress-row { background: hsl(198 52% 15%); } .dark .jobs-indicator:hover { background: hsl(210 34% 24% / 0.5); } .dark .job-status.status-pending { background: hsl(45 93% 25%); color: hsl(45 93% 65%); } .dark .job-status.status-running { background: hsl(198 52% 25%); color: hsl(198 78% 75%); } /* Dark mode status colors for job list - couleurs plus soutenues */ .dark .status-running { color: hsl(192 85% 55%); font-weight: 700; text-shadow: 0 0 10px hsl(192 85% 55% / 0.3); } .dark .status-pending { color: hsl(45 100% 55%); font-weight: 600; } .dark .status-completed { color: hsl(142 70% 55%); font-weight: 600; } .dark .status-failed { color: hsl(2 80% 60%); font-weight: 600; } .dark .status-cancelled { color: hsl(220 20% 65%); } /* Progress bar visibility fix */ .job-progress { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 16px; margin: 8px 0; min-height: 120px; } .progress-bar-container { position: relative; height: 24px; background: hsl(220 13% 90%); border-radius: 12px; overflow: hidden; margin: 12px 0; } .progress-bar-fill { height: 100%; background: linear-gradient(90deg, hsl(198 78% 37%), hsl(192 85% 55%)); border-radius: 12px; transition: width 0.5s ease; min-width: 2px; } .progress-percent { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); font-size: 0.85rem; font-weight: 700; color: var(--foreground); text-shadow: 0 0 2px rgba(255,255,255,0.5); } .progress-row { background: hsl(198 52% 95%); } .progress-row td { padding: 0; } /* Highlighted job row */ tr.job-highlighted { background: hsl(198 78% 95%); box-shadow: inset 0 0 0 2px hsl(198 78% 37%); } tr.job-highlighted td { animation: pulse-border 2s ease-in-out infinite; } @keyframes pulse-border { 0%, 100% { box-shadow: inset 0 0 0 1px hsl(198 78% 37% / 0.3); } 50% { box-shadow: inset 0 0 0 2px hsl(198 78% 37% / 0.6); } } /* Dark mode for highlighted job row */ .dark tr.job-highlighted { background: hsl(198 52% 20%); box-shadow: inset 0 0 0 2px hsl(198 78% 50%); } .dark tr.job-highlighted td { animation: pulse-border-dark 2s ease-in-out infinite; } @keyframes pulse-border-dark { 0%, 100% { box-shadow: inset 0 0 0 1px hsl(198 78% 50% / 0.3); } 50% { box-shadow: inset 0 0 0 2px hsl(198 78% 50% / 0.6); } } /* Monitoring styles */ .monitoring-cell { display: flex; flex-direction: column; gap: 4px; } .monitor-badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.75rem; font-weight: 700; text-transform: uppercase; } .monitor-auto { background: hsl(142 60% 45% / 0.2); color: hsl(142 60% 35%); border: 1px solid hsl(142 60% 45% / 0.5); } .monitor-manual { background: hsl(220 13% 80% / 0.2); color: hsl(220 13% 40%); border: 1px solid hsl(220 13% 80% / 0.5); } .scan-mode { font-size: 0.7rem; color: var(--text-muted); text-transform: capitalize; } .next-scan { font-size: 0.7rem; color: hsl(198 78% 37%); } .monitoring-form { display: flex; align-items: center; gap: 8px; margin-top: 4px; } .monitor-toggle { display: flex; align-items: center; gap: 4px; font-size: 0.8rem; cursor: pointer; } .monitor-toggle input[type="checkbox"] { cursor: pointer; } .monitoring-form select { font-size: 0.75rem; padding: 2px 4px; } /* Watcher toggle styles */ .watcher-toggle { background: hsl(45 93% 90% / 0.3); border: 1px solid hsl(45 93% 47% / 0.3); border-radius: 4px; padding: 2px 6px; } .watcher-toggle.active { background: hsl(45 93% 90% / 0.6); border-color: hsl(45 93% 47% / 0.6); } .toggle-hint { margin-left: 4px; cursor: help; } .monitor-options { display: flex; gap: 8px; flex-wrap: wrap; } /* Job Detail Page Styles */ .page-header { margin-bottom: 24px; } .back-link { display: inline-block; margin-bottom: 12px; color: hsl(198 78% 37%); text-decoration: none; } .back-link:hover { text-decoration: underline; } .job-detail-grid { display: grid; grid-template-columns: 1fr; gap: 20px; } @media (min-width: 768px) { .job-detail-grid { grid-template-columns: repeat(2, 1fr); } .job-progress-detail, .job-statistics, .job-errors, .job-error-message { grid-column: 1 / -1; } } .job-meta { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; } .meta-item { display: flex; flex-direction: column; gap: 4px; } .meta-label { font-size: 0.75rem; color: var(--text-muted); text-transform: uppercase; } .meta-value { font-weight: 600; } .job-type { text-transform: uppercase; font-size: 0.8rem; } .job-type.full_rebuild { color: hsl(280 60% 45%); } .job-type.rebuild { color: hsl(198 78% 37%); } /* Timeline */ .timeline { position: relative; padding-left: 24px; } .timeline::before { content: ''; position: absolute; left: 7px; top: 8px; bottom: 8px; width: 2px; background: var(--line); } .timeline-item { position: relative; padding-bottom: 16px; display: flex; align-items: flex-start; gap: 12px; } .timeline-item:last-child { padding-bottom: 0; } .timeline-dot { position: absolute; left: -20px; width: 12px; height: 12px; border-radius: 50%; background: var(--line); border: 2px solid var(--card); margin-top: 4px; } .timeline-item.completed .timeline-dot { background: hsl(142 60% 45%); } .timeline-item.active .timeline-dot { background: hsl(198 78% 37%); animation: pulse-dot 2s infinite; } .timeline-item.pending .timeline-dot { background: var(--line); } @keyframes pulse-dot { 0%, 100% { box-shadow: 0 0 0 0 hsl(198 78% 37% / 0.4); } 50% { box-shadow: 0 0 0 6px hsl(198 78% 37% / 0); } } .timeline-content { display: flex; flex-direction: column; gap: 2px; } .timeline-label { font-weight: 600; font-size: 0.9rem; } .timeline-time { font-size: 0.8rem; color: var(--text-muted); } .duration-badge { margin-top: 16px; padding: 8px 12px; background: hsl(198 52% 90%); border-radius: 6px; font-weight: 600; color: hsl(198 78% 37%); } /* Progress */ .progress-bar-large { position: relative; height: 32px; background: var(--line); border-radius: 16px; overflow: hidden; margin-bottom: 16px; } .progress-fill { height: 100%; background: linear-gradient(90deg, hsl(198 78% 37%), hsl(192 85% 55%)); border-radius: 16px; transition: width 0.3s ease; } .progress-text { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); font-weight: 700; font-size: 0.9rem; } .progress-stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 16px; } .stat-box { text-align: center; padding: 12px; background: hsl(198 52% 95%); border-radius: 8px; } .stat-box .stat-value { display: block; font-size: 1.5rem; font-weight: 700; color: hsl(198 78% 37%); } .stat-box .stat-label { font-size: 0.75rem; color: var(--text-muted); } .current-file-box { padding: 12px; background: hsl(45 93% 90% / 0.3); border: 1px solid hsl(45 93% 47% / 0.3); border-radius: 8px; } .current-file-box .label { display: block; font-size: 0.75rem; color: var(--text-muted); margin-bottom: 4px; } .current-file-box .file-path { font-size: 0.85rem; word-break: break-all; } /* Statistics */ .stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 16px; } .stat-item { text-align: center; } .stat-number { display: block; font-size: 2rem; font-weight: 700; color: var(--foreground); } .stat-number.success { color: hsl(142 60% 45%); } .stat-number.primary { color: hsl(198 78% 37%); } .stat-number.warning { color: hsl(45 93% 47%); } .stat-number.error { color: hsl(2 72% 48%); } .speed-stat { text-align: center; padding-top: 12px; border-top: 1px solid var(--line); } .speed-label { font-size: 0.85rem; color: var(--text-muted); } .speed-value { font-weight: 700; font-size: 1.1rem; margin-left: 8px; } /* Errors */ .errors-list { display: flex; flex-direction: column; gap: 12px; } .error-item { padding: 12px; background: hsl(2 72% 48% / 0.05); border: 1px solid hsl(2 72% 48% / 0.2); border-radius: 8px; } .error-file { display: block; font-size: 0.8rem; margin-bottom: 4px; word-break: break-all; } .error-message { display: block; font-size: 0.85rem; color: hsl(2 72% 48%); margin-bottom: 4px; } .error-time { font-size: 0.75rem; color: var(--text-muted); } .error-details { padding: 16px; background: hsl(2 72% 48% / 0.05); border: 1px solid hsl(2 72% 48% / 0.2); border-radius: 8px; overflow-x: auto; font-size: 0.85rem; } /* Job list enhancements */ .job-id-link { text-decoration: none; color: inherit; } .job-id-link:hover code { background: hsl(198 52% 90%); color: hsl(198 78% 37%); } .view-btn { padding: 4px 10px; font-size: 0.8rem; background: hsl(198 78% 37% / 0.1); border: 1px solid hsl(198 78% 37% / 0.3); border-radius: 4px; color: hsl(198 78% 37%); text-decoration: none; } .view-btn:hover { background: hsl(198 78% 37% / 0.2); } /* Libraries Grid - Modern Card Layout */ .libraries-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 20px; margin-top: 24px; } .library-card { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 20px; display: flex; flex-direction: column; gap: 16px; transition: box-shadow 0.2s ease, transform 0.2s ease; } .library-card:hover { box-shadow: var(--shadow-2); transform: translateY(-2px); } /* Library Header */ .library-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; } .library-name { margin: 0; font-size: 1.25rem; font-weight: 700; color: var(--foreground); line-height: 1.3; flex: 1; } .library-badges { display: flex; gap: 6px; flex-shrink: 0; } .badge-disabled { background: hsl(220 13% 80%); color: hsl(220 13% 40%); padding: 2px 8px; border-radius: 4px; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; } .badge-watcher { background: hsl(45 93% 90%); padding: 2px 6px; border-radius: 4px; font-size: 0.9rem; } /* Library Path */ .library-path { font-size: 0.8rem; color: var(--text-muted); background: hsl(220 13% 95%); padding: 6px 10px; border-radius: 6px; word-break: break-all; } .dark .library-path { background: hsl(220 13% 20%); } /* Library Stats */ .library-stats { display: flex; gap: 12px; } .stat-box { flex: 1; display: flex; flex-direction: column; align-items: center; padding: 12px; background: hsl(198 52% 95%); border-radius: 8px; text-decoration: none; color: inherit; transition: background 0.2s ease; } .stat-box:hover { background: hsl(198 52% 90%); } .stat-number { font-size: 1.5rem; font-weight: 700; color: hsl(198 78% 37%); } .stat-label { font-size: 0.75rem; color: var(--text-muted); text-transform: uppercase; margin-top: 2px; } .dark .stat-box { background: hsl(198 52% 20%); } .dark .stat-box:hover { background: hsl(198 52% 25%); } .dark .stat-number { color: hsl(198 78% 65%); } /* Library Monitoring */ .library-monitoring { background: hsl(220 13% 97%); border-radius: 8px; padding: 12px; } .dark .library-monitoring { background: hsl(220 13% 18%); } .monitor-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } .monitor-status { font-size: 0.85rem; font-weight: 600; } .monitor-status.active { color: hsl(142 60% 45%); } .monitor-status.inactive { color: var(--text-muted); } .next-scan-badge { font-size: 0.75rem; background: hsl(198 52% 90%); color: hsl(198 78% 37%); padding: 2px 8px; border-radius: 12px; font-weight: 600; } .dark .next-scan-badge { background: hsl(198 52% 25%); color: hsl(198 78% 65%); } /* Library Actions */ .library-actions { display: flex; gap: 8px; } .action-btn { flex: 1; padding: 8px 12px; border: none; border-radius: 6px; font-size: 0.85rem; font-weight: 600; cursor: pointer; transition: opacity 0.2s ease; } .action-btn:hover { opacity: 0.8; } .index-btn { background: hsl(142 60% 45% / 0.15); color: hsl(142 60% 35%); border: 1px solid hsl(142 60% 45% / 0.3); } .full-btn { background: hsl(280 60% 45% / 0.15); color: hsl(280 60% 45%); border: 1px solid hsl(280 60% 45% / 0.3); } .delete-btn { flex: 0 0 auto; background: hsl(2 72% 48% / 0.1); color: hsl(2 72% 48%); border: 1px solid hsl(2 72% 48% / 0.3); padding: 8px; } .delete-form { margin-left: auto; } /* Add Library Form */ .library-add-form { margin-bottom: 8px; } .library-add-form h2 { margin: 0 0 16px 0; font-size: 1.1rem; color: var(--foreground); } .form-row { display: flex; gap: 12px; align-items: stretch; } .library-name-input { flex: 1; min-width: 200px; } .library-folder-select { flex: 2; min-width: 250px; } .add-btn { padding: 10px 24px; background: hsl(198 78% 37%); color: white; border: none; border-radius: 8px; font-weight: 600; cursor: pointer; transition: background 0.2s ease; } .add-btn:hover { background: hsl(198 78% 32%); } /* Responsive */ @media (max-width: 768px) { .libraries-grid { grid-template-columns: 1fr; } .form-row { flex-direction: column; } .library-name-input, .library-folder-select { width: 100%; } } /* Compact Monitoring Form */ .monitoring-form-compact { margin-top: 8px; } .monitor-row { display: flex; gap: 8px; align-items: center; } .monitor-checkbox { display: flex; align-items: center; gap: 4px; padding: 4px 8px; background: hsl(220 13% 95%); border-radius: 6px; cursor: pointer; font-size: 0.8rem; transition: background 0.2s ease; } .monitor-checkbox:hover { background: hsl(220 13% 90%); } .monitor-checkbox input[type="checkbox"] { cursor: pointer; } .monitor-checkbox.watcher.active { background: hsl(45 93% 90%); } .dark .monitor-checkbox { background: hsl(220 13% 25%); } .dark .monitor-checkbox:hover { background: hsl(220 13% 30%); } .dark .monitor-checkbox.watcher.active { background: hsl(45 93% 25%); } .scan-mode-select { flex: 1; padding: 4px 8px; font-size: 0.8rem; border: 1px solid var(--line); border-radius: 6px; background: var(--card); } .save-btn { padding: 4px 10px; background: hsl(198 78% 37%); color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9rem; } .save-btn:hover:not(:disabled) { background: hsl(198 78% 32%); } .save-btn:disabled { opacity: 0.5; cursor: not-allowed; } /* ===== Jobs Indicator - Modern Version ===== */ .jobs-indicator-wrapper { position: relative; } /* Button */ .jobs-indicator-button { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--card); border: 1px solid var(--line); border-radius: 8px; cursor: pointer; transition: all 0.2s ease; color: var(--foreground); } .jobs-indicator-button:hover { background: hsl(198 52% 95%); border-color: hsl(198 78% 37% / 0.5); } .jobs-indicator-button.has-running { background: hsl(198 52% 95%); border-color: hsl(198 78% 37%); animation: jobs-button-pulse 2s infinite; } @keyframes jobs-button-pulse { 0%, 100% { box-shadow: 0 0 0 0 hsl(198 78% 37% / 0.4); } 50% { box-shadow: 0 0 0 4px hsl(198 78% 37% / 0); } } .jobs-indicator-button.open { background: hsl(198 52% 90%); } /* Spinner */ .jobs-spinner { width: 18px; height: 18px; animation: spin 1s linear infinite; color: hsl(198 78% 37%); } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* Icon */ .jobs-icon { color: var(--text-muted); } .has-running .jobs-icon { color: hsl(198 78% 37%); } /* Count Badge */ .jobs-count-badge { background: hsl(2 72% 48%); color: white; font-size: 0.75rem; font-weight: 700; min-width: 20px; height: 20px; border-radius: 10px; display: flex; align-items: center; justify-content: center; padding: 0 6px; } .has-running .jobs-count-badge { background: hsl(198 78% 37%); } /* Chevron */ .jobs-chevron { transition: transform 0.2s ease; color: var(--text-muted); } .jobs-chevron.open { transform: rotate(180deg); } /* Empty state (no jobs) */ .jobs-indicator-empty { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; color: var(--text-muted); border-radius: 8px; transition: all 0.2s ease; } .jobs-indicator-empty:hover { background: hsl(198 52% 95%); color: hsl(198 78% 37%); } /* ===== Popin/Dropdown ===== */ .jobs-popin { position: absolute; top: calc(100% + 8px); right: 0; width: 420px; max-width: calc(100vw - 32px); background: var(--card); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-2); z-index: 1000; overflow: hidden; } /* Header */ .jobs-popin-header { display: flex; justify-content: space-between; align-items: flex-start; padding: 16px; border-bottom: 1px solid var(--line); background: hsl(198 52% 97%); } .dark .jobs-popin-header { background: hsl(198 52% 15%); } .jobs-popin-title { display: flex; align-items: center; gap: 12px; } .jobs-icon-large { font-size: 1.5rem; } .jobs-popin-title h3 { margin: 0; font-size: 1rem; } .jobs-subtitle { margin: 2px 0 0 0; font-size: 0.8rem; color: var(--text-muted); } .jobs-view-all { padding: 6px 12px; background: hsl(198 78% 37%); color: white; border-radius: 6px; font-size: 0.8rem; font-weight: 600; text-decoration: none; transition: background 0.2s ease; } .jobs-view-all:hover { background: hsl(198 78% 32%); } /* Overall Progress */ .jobs-overall-progress { padding: 16px; border-bottom: 1px solid var(--line); background: hsl(198 52% 95%); } .dark .jobs-overall-progress { background: hsl(198 52% 12%); } .progress-header { display: flex; justify-content: space-between; margin-bottom: 8px; font-size: 0.85rem; font-weight: 600; } .progress-percent { color: hsl(198 78% 37%); } .progress-bar { height: 8px; background: var(--line); border-radius: 4px; overflow: hidden; } .progress-fill { height: 100%; background: linear-gradient(90deg, hsl(198 78% 37%), hsl(192 85% 55%)); border-radius: 4px; transition: width 0.3s ease; } /* List Container */ .jobs-list-container { max-height: 400px; overflow-y: auto; } /* Empty State */ .jobs-empty-state { display: flex; flex-direction: column; align-items: center; padding: 32px; color: var(--text-muted); } .empty-icon { font-size: 2rem; margin-bottom: 8px; } /* Detailed List */ .jobs-detailed-list { list-style: none; margin: 0; padding: 0; } .job-detailed-item { border-bottom: 1px solid var(--line); } .job-detailed-item:last-child { border-bottom: none; } .job-link { display: block; padding: 12px 16px; text-decoration: none; color: inherit; transition: background 0.2s ease; } .job-link:hover { background: hsl(198 52% 95%); } .dark .job-link:hover { background: hsl(198 52% 15%); } .job-info-row { display: flex; gap: 12px; align-items: flex-start; } .job-status-icon { font-size: 1.2rem; flex-shrink: 0; margin-top: 2px; } .spinning { display: inline-block; animation: spin 2s linear infinite; } .job-details { flex: 1; min-width: 0; } .job-main-info { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; } .job-id-short { font-size: 0.8rem; color: var(--text-muted); background: hsl(220 13% 90%); padding: 2px 6px; border-radius: 4px; } .dark .job-id-short { background: hsl(220 13% 25%); } .job-type-badge { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; padding: 2px 6px; border-radius: 4px; } .job-type-badge.full_rebuild { background: hsl(280 60% 45% / 0.15); color: hsl(280 60% 45%); } .job-type-badge.rebuild { background: hsl(198 78% 37% / 0.15); color: hsl(198 78% 37%); } /* Progress Row */ .job-progress-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; } .job-mini-progress-bar { flex: 1; height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; } .job-mini-progress-fill { height: 100%; background: hsl(198 78% 37%); border-radius: 2px; transition: width 0.3s ease; } .job-progress-text { font-size: 0.75rem; font-weight: 700; color: hsl(198 78% 37%); min-width: 35px; text-align: right; } /* Current File */ .job-current-file { margin: 4px 0; font-size: 0.8rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* Mini Stats */ .job-mini-stats { display: flex; gap: 12px; font-size: 0.75rem; color: hsl(142 60% 45%); } .error-stat { color: hsl(2 72% 48%); } /* Footer */ .jobs-popin-footer { padding: 8px 16px; border-top: 1px solid var(--line); background: hsl(220 13% 97%); } .dark .jobs-popin-footer { background: hsl(220 13% 15%); } .jobs-auto-refresh { margin: 0; font-size: 0.7rem; color: var(--text-muted); text-align: center; }