diff --git a/shaarli-pro/css/style.css b/shaarli-pro/css/style.css index e69a86d..9e54e52 100644 --- a/shaarli-pro/css/style.css +++ b/shaarli-pro/css/style.css @@ -426,13 +426,8 @@ input:checked+.theme-slider:before { font-family: inherit; } -.header-nav-link:hover { - background: rgba(255, 255, 255, 0.15); - color: white; -} - -.header-nav-link.active { - background: rgba(255, 255, 255, 0.15); +.header-nav-link-tag:hover { + background: var(--primary); color: white; } @@ -827,6 +822,44 @@ input:checked+.theme-slider:before { font-size: 0.9rem; } +.search-pill-btn:focus-visible { + outline: 2px solid var(--primary); + outline-offset: 2px; +} + +.search-pill-btn span { + white-space: nowrap; +} + +/* Notes pill */ +.search-pill-notes { + background: #E5E7EB; + color: #374151; +} + +.search-pill-notes:hover { + background: #D1D5DB; +} + +.search-pill-notes.active { + background: #3B82F6; + color: #ffffff; +} + +[data-theme="dark"] .search-pill-notes { + background: #374151; + color: #D1D5DB; +} + +[data-theme="dark"] .search-pill-notes:hover { + background: #4B5563; +} + +[data-theme="dark"] .search-pill-notes.active { + background: #3B82F6; + color: #ffffff; +} + /* Tags pill - Gray style */ .search-pill-tags { background: #E5E7EB; @@ -1075,2670 +1108,137 @@ input:checked+.theme-slider:before { white-space: nowrap; } -/* ===== Content Container ===== */ -.content-container { - flex: 1; - padding: 1rem 1.5rem; - max-width: 100%; - margin: 0; - width: 100%; -} - -.container { - max-width: 100%; - padding: 0; -} - -/* ===== Toolbar ===== */ -.content-toolbar { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 1.5rem; - gap: 1rem; - flex-wrap: wrap; -} - -.toolbar-left { - display: flex; - align-items: center; - gap: 1rem; -} - -.toolbar-right { - display: flex; - align-items: center; - gap: 0.5rem; -} - -/* View Toggle */ -.view-toggle { - display: flex; - background: var(--bg-card); - border: 1px solid var(--border); - border-radius: 0.5rem; - overflow: hidden; -} - -.view-toggle-btn { - display: flex; - align-items: center; - justify-content: center; - width: 36px; - height: 36px; - background: transparent; - border: none; - color: var(--text-muted); - cursor: pointer; - transition: all 0.15s ease; -} - -.view-toggle-btn:hover { - color: var(--text-main); - background: var(--border-light); -} - -.view-toggle-btn.active { - background: var(--primary); - color: white; -} - -/* ===== Pagination ===== */ -.paging { - display: flex; - align-items: center; - justify-content: space-between; - gap: 0.75rem; - flex-wrap: wrap; - width: 100%; - margin: 1.25rem 0 0; - padding: 0.75rem 0.9rem; - border: 1px solid var(--border); - border-radius: 0.75rem; - background: var(--bg-card); -} - -.content-toolbar .paging { - margin: 0; - padding: 0; - border: 0; - border-radius: 0; - background: transparent; -} - -.paging-links { - display: inline-flex; - align-items: center; - gap: 0.5rem; -} - -.paging-newer, -.paging-older { - display: inline-flex; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - border-radius: 0.5rem; - border: 1px solid var(--border); - color: var(--text-secondary); - background: var(--bg-body); - text-decoration: none; - transition: all 0.15s ease; -} - -.paging-newer:hover, -.paging-older:hover { - border-color: var(--primary); - color: var(--primary); - background: var(--primary-light); -} - -.paging-current { - font-size: 0.86rem; - color: var(--text-secondary); - text-transform: uppercase; - letter-spacing: 0.03em; -} - -.paging-current strong { - color: var(--text-main); -} - -.paging-stats { - font-size: 1.05rem; - font-weight: 600; - color: var(--text-main); -} - -.paging.single-page .paging-stats { - font-size: 0.95rem; -} - -.paging-plugin { - display: inline-flex; - align-items: center; -} - -.paging-plugin a { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 30px; - min-height: 30px; - padding: 0.2rem 0.45rem; - border-radius: 0.45rem; - border: 1px solid var(--border); - background: var(--bg-body); - color: var(--text-secondary); - text-decoration: none; -} - -body.view-notes .paging { - margin-top: 1rem; -} - -@media (max-width: 768px) { - .paging { - padding: 0.65rem 0.75rem; - } - - .paging-stats { - width: 100%; - order: -1; - } -} - -/* ===== Links Grid/List ===== */ -.links-list { - display: grid; - gap: 1rem; -} - -.links-list.view-grid { - grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); -} - -.links-list.view-list { - grid-template-columns: minmax(0, 1fr); -} - -.links-list.view-compact { - display: block; - background: var(--bg-card); - border: 1px solid var(--border); - border-radius: 0.8rem; - overflow: hidden; -} - -.compact-table-head { - display: none; -} - -/* ===== Link Card ===== */ -.link-outer { - background: var(--bg-card); - border: 1px solid var(--border); - border-radius: 0.75rem; - padding: 3.5rem 1.25rem 1.25rem; - transition: all 0.2s ease; - position: relative; - overflow: hidden; - content-visibility: auto; - contain-intrinsic-size: auto 300px; -} - -/* Link card hover states - same for both public and private */ -.link-outer:hover { - border-color: var(--primary); - box-shadow: var(--shadow-md); -} - -/* Selection state */ -.link-outer.selected { - background: var(--selection-bg); - border-color: var(--selection-border); -} - -.link-outer.selected::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - border: 2px solid var(--selection-border); - border-radius: 0.75rem; - pointer-events: none; -} - -/* Selection checkbox */ -.link-select-checkbox { - position: absolute; - top: 0.75rem; - left: auto; - right: 10.5rem; - transform: none; - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - background: rgba(255, 255, 255, 0.9); - border-radius: 0.5rem; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); - opacity: 0; - transition: opacity 0.15s ease; - z-index: 20; -} - -.view-grid .link-select-checkbox { - right: auto; - left: 0.75rem; -} - -[data-theme="dark"] .link-select-checkbox { - background: rgba(30, 41, 59, 0.9); - border: 1px solid var(--border); -} - -.link-outer:hover .link-select-checkbox, -.link-outer.selected .link-select-checkbox, -.selection-mode .link-select-checkbox { - opacity: 1; -} - -.link-select-checkbox input { - width: 18px; - height: 18px; - cursor: pointer; - accent-color: var(--primary); - margin: 0; -} - -/* Link thumbnail */ -.link-thumbnail { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 60%; - margin: 0; - background: transparent; - border-radius: 0; - border: none; - mask-image: linear-gradient(to bottom, black 50%, transparent 100%); - -webkit-mask-image: linear-gradient(to bottom, black 50%, transparent 100%); - z-index: 0; - pointer-events: none; - filter: brightness(0.6); -} - -.link-content { - position: relative; - z-index: 2; -} - -.link-thumbnail img { - width: 100%; - height: 100%; - object-fit: cover; -} - -.link-thumbnail-placeholder { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - color: var(--text-muted); - font-size: 2rem; -} - -/* Hover actions overlay */ -.link-hover-actions { - position: absolute; - top: 0.75rem; - right: 3.5rem; - display: flex; - gap: 0.25rem; - opacity: 0; - transition: opacity 0.15s ease; - z-index: 20; -} - -.link-outer:hover .link-hover-actions { - opacity: 1; -} - -.link-hover-btn { - display: flex; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - background: var(--bg-card); - border: 1px solid var(--border); - border-radius: 0.375rem; - color: var(--text-secondary); - cursor: pointer; - transition: all 0.15s ease; - text-decoration: none; -} - -.link-actions .readitlater-toggle-btn { - display: flex; - align-items: center; - justify-content: center; - width: 36px; - height: 36px; - background: transparent; - border: none; - color: var(--text-muted); - cursor: pointer; - transition: all 0.15s ease; - text-decoration: none; -} - -.link-actions .readitlater-toggle-btn i { - font-size: 1.15rem; - color: inherit; -} - -.link-actions .readitlater-toggle-btn.active { - color: #dc2626; - background: rgba(220, 38, 38, 0.08); -} - -.link-actions .readitlater-toggle-btn.is-loading { - opacity: 0.7; - pointer-events: none; -} - -.link-hover-btn:hover { - background: var(--primary); - border-color: var(--primary); - color: white; -} - -.link-header { - margin-bottom: 0.75rem; -} - -.link-title { - font-size: 1rem; - font-weight: 600; - color: var(--text-main); - display: block; - margin-bottom: 0.25rem; - line-height: 1.4; - padding-right: 2.5rem; -} - -.link-title:hover { - color: var(--primary); -} - -.link-url { - font-size: 0.8rem; - color: var(--text-muted); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - display: block; -} - -.link-meta { - display: flex; - align-items: center; - gap: 0.75rem; - margin-top: 0.25rem; -} - -/* Visibility Badge - Top Right Corner */ -.link-visibility-badge { - position: absolute; - top: 0.75rem; - right: 0.75rem; - display: flex; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - border-radius: 0.5rem; - background: rgba(0, 0, 0, 0.1); - z-index: 10; - transition: all 0.2s ease; -} - -.link-readlater-badge { - position: absolute; - top: 0.75rem; - right: 3.2rem; - display: inline-flex; - align-items: center; - justify-content: center; - height: 32px; - padding: 0 0.6rem; - border-radius: 0.5rem; - background: rgba(239, 68, 68, 0.92); - color: #fff; - font-size: 0.72rem; - font-weight: 700; - letter-spacing: 0.02em; - text-transform: uppercase; - z-index: 10; - box-shadow: 0 2px 8px rgba(239, 68, 68, 0.35); -} - -[data-theme="dark"] .link-readlater-badge { - background: rgba(248, 113, 113, 0.9); - color: #1b0b0b; -} - -.link-visibility-badge i { - font-size: 1.25rem; - line-height: 1; -} - -/* Private link - Yellow lock */ -.link-outer.private .link-visibility-badge { - background: rgba(245, 158, 11, 0.2); - border: 1px solid rgba(245, 158, 11, 0.3); -} - -.link-outer.private .link-visibility-badge i { - color: #f59e0b; - font-weight: 600; -} - -/* Public link - Green lock */ -.link-outer.public .link-visibility-badge { - background: rgba(16, 185, 129, 0.2); - border: 1px solid rgba(16, 185, 129, 0.3); -} - -.link-outer.public .link-visibility-badge i { - color: #10b981; - font-weight: 600; -} - -.link-date { - font-size: 0.8rem; - color: var(--text-muted); -} - -.link-description { - font-size: 0.9rem; - color: var(--text-secondary); - margin: 0.75rem 0; - line-height: 1.5; - display: -webkit-box; - -webkit-line-clamp: 3; - line-clamp: 3; - -webkit-box-orient: vertical; - overflow: hidden; -} - -.link-footer { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; - align-items: center; - justify-content: space-between; - margin-top: 1rem; - padding-top: 0.75rem; - border-top: 1px solid var(--border); -} - -.view-grid .link-footer { - flex-direction: column; - align-items: flex-end; - gap: 0.5rem; -} - -/* Tags */ -.link-tag-list { - display: flex; - flex-wrap: wrap; - gap: 0.375rem; - flex: 1 1 auto; +.search-result-main { min-width: 0; -} - -.link-tag { - display: inline-flex; - align-items: center; - gap: 0.25rem; - padding: 0.25rem 0.5rem; - background: var(--tag-bg); - color: var(--tag-text); - border-radius: 999px; - font-size: 0.75rem; - font-weight: 500; - transition: all 0.15s ease; - max-width: 100%; -} - -.link-tag.is-tech-tag { - display: none; -} - -.link-tag .link-tag-link { - color: inherit; - text-decoration: none; - display: inline-block; - line-height: 1.2; - max-width: 100%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.tag-remove-btn { - display: inline-flex; - align-items: center; - justify-content: center; - width: 1.1rem; - height: 1.1rem; - border: none; - border-radius: 999px; - background: rgba(0, 0, 0, 0.12); - color: inherit; - font-size: 0.8rem; - line-height: 1; - padding: 0; - cursor: pointer; - transition: background-color 0.15s ease, color 0.15s ease; -} - -[data-theme="dark"] .tag-remove-btn { - background: rgba(255, 255, 255, 0.18); -} - -.link-tag:hover { - background: var(--primary); - color: white; -} - -.link-tag:hover .tag-remove-btn { - background: rgba(255, 255, 255, 0.22); -} - -.view-grid .link-tag-list { - order: 2; - width: 100%; - justify-content: flex-end; -} - -.view-grid .link-actions { - order: 1; -} - -/* Actions */ -.link-actions { display: flex; - gap: 0.25rem; + align-items: center; + gap: 0.5rem; + width: 100%; +} + +.search-result-kind { flex-shrink: 0; - align-items: center; - flex-wrap: wrap; - justify-content: flex-end; - max-width: 100%; - margin-left: auto; - /* Force alignment to the right */ -} - -.link-actions a, -.link-actions button { - display: flex; - align-items: center; - justify-content: center; - width: 36px; - height: 36px; - background: transparent; - border: none; - border-radius: 0.375rem; - color: var(--text-muted); - cursor: pointer; - transition: all 0.15s ease; - text-decoration: none; -} - -.link-actions a i, -.link-actions button i { - font-size: 1.15rem; -} - -.link-actions a:hover, -.link-actions button:hover { - background: var(--primary-light); - color: var(--primary); -} - -/* ===== List View Specific ===== */ -.view-list .link-outer { - position: relative; - overflow: hidden; - display: flex; - align-items: flex-start; - gap: 1rem; - padding: 1.25rem 1.5rem 1.25rem 3.5rem; - background: var(--bg-card); - border: 1px solid var(--border); - border-radius: 0.75rem; - margin-bottom: 1rem; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - transition: all 0.2s ease; -} - -.view-list .link-outer:hover { - border-color: var(--primary); - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); -} - -/* List view - Visibility badge positioning */ -.view-list .link-visibility-badge { - top: 1.25rem; - right: 1.5rem; -} - -.view-list .link-readlater-badge { - top: 1.25rem; - right: 3.95rem; -} - -/* List view - selection */ -.view-list .link-select-checkbox { - left: 1rem; - top: 1.25rem; - transform: none; - background: var(--bg-card); - border: 1px solid var(--border); - z-index: 10; -} - -.view-list .link-thumbnail { - position: absolute; - top: 0; - left: 0; - bottom: 0; - width: 300px; - height: 100%; - margin: 0; - border-radius: 0; - border: none; - background: transparent; - mask-image: linear-gradient(to right, black 20%, transparent 100%); - -webkit-mask-image: linear-gradient(to right, black 20%, transparent 100%); - z-index: 0; - pointer-events: none; -} - -.view-list .link-content { - flex: 1; - min-width: 0; - position: relative; - z-index: 2; -} - -.view-list .link-header { - margin-bottom: 0.5rem; -} - -.view-list .link-description { - -webkit-line-clamp: 2; - line-clamp: 2; - margin: 0.5rem 0; -} - -.view-list .link-footer { - border-top: 1px solid var(--border-light); - padding-top: 0.75rem; - margin-top: 0.75rem; -} - -.view-list .link-hover-actions { - opacity: 1; - position: relative; - top: auto; - right: auto; - margin-left: auto; - flex-shrink: 0; -} - -/* ===== Bulk Actions Bar ===== */ -.bulk-actions-bar { - position: fixed; - bottom: 0; - left: var(--sidebar-width); - right: 0; - background: var(--bg-card); - border-top: 1px solid var(--border); - padding: 1rem 1.5rem; - display: none; - align-items: center; - justify-content: space-between; - box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.1); - z-index: 150; - animation: slideUp 0.2s ease; -} - -.bulk-actions-bar.show { - display: flex; -} - -.bulk-info { - display: flex; - align-items: center; - gap: 1rem; - font-size: 0.9rem; - color: var(--text-main); -} - -.bulk-select-all { - color: var(--primary); - cursor: pointer; - font-weight: 500; -} - -.bulk-select-all:hover { - text-decoration: underline; -} - -.bulk-buttons { - display: flex; - align-items: center; - gap: 0.5rem; -} - -.bulk-btn { - display: flex; - align-items: center; - gap: 0.375rem; - padding: 0.625rem 1rem; - border-radius: 0.5rem; - font-weight: 500; - font-size: 0.875rem; - cursor: pointer; - transition: all 0.15s ease; - border: none; -} - -.bulk-btn-cancel { - background: transparent; - color: var(--text-secondary); -} - -.bulk-btn-cancel:hover { - background: var(--border-light); - color: var(--text-main); -} - -.bulk-btn-delete { - background: var(--danger); - color: white; -} - -.bulk-btn-delete:hover { - background: #dc2626; -} - -.bulk-btn-public { - background: var(--success); - color: white; -} - -.bulk-btn-public:hover { - background: #059669; -} - -.bulk-btn-private { - background: var(--primary); - color: white; -} - -.bulk-btn-private:hover { - background: var(--primary-hover); -} - -/* ===== Footer ===== */ -.footer-main { - margin-top: 1.25rem; - padding: 1rem 0 1.25rem; - border-top: 1px solid var(--border); - color: var(--text-secondary); -} - -.footer-main p { - margin: 0; - font-size: 0.95rem; -} - -.footer-feeds { - margin-top: 0.55rem; - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 0.45rem; - font-size: 0.95rem; -} - -.footer-separator { - color: var(--text-muted); -} - -.plugin-footer-text { - margin-top: 0.5rem; - color: var(--text-secondary); -} - -/* ===== Media Player Bar ===== */ -.media-player-bar { - position: fixed; - left: var(--sidebar-width); - right: 0; - bottom: 0; - z-index: 155; - padding: 0.7rem 1.2rem; - border-top: 1px solid var(--border); - background: var(--bg-card); - box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.15); - display: none; -} - -.media-player-bar.show { - display: block; -} - -.media-player-inner { - display: grid; - grid-template-columns: auto minmax(180px, 1fr) auto auto auto; - gap: 0.75rem; - align-items: center; -} - -.media-player-btn { - width: 34px; - height: 34px; - border: 1px solid var(--border); - border-radius: 0.5rem; - background: var(--bg-body); - color: var(--text-main); - display: inline-flex; - align-items: center; - justify-content: center; - cursor: pointer; -} - -.media-player-btn:hover { - background: var(--primary-light); - color: var(--primary); -} - -.media-player-title { - font-size: 0.88rem; - color: var(--text-main); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.media-player-time { - font-variant-numeric: tabular-nums; - color: var(--text-secondary); - font-size: 0.8rem; - min-width: 82px; - text-align: right; -} - -.media-player-progress, -.media-player-volume { - width: 100%; -} - -.media-player-volume-wrap { - width: 130px; - display: flex; - align-items: center; - gap: 0.4rem; -} - -@media (max-width: 991px) { - .media-player-bar { - left: 0; - } -} - -@media (max-width: 768px) { - .media-player-inner { - grid-template-columns: auto minmax(120px, 1fr) auto; - } - - .media-player-volume-wrap { - display: none; - } -} - -/* ===== Sticky Links ===== */ -.link-outer.is-sticky { - border-left: 3px solid var(--primary); - background: var(--primary-light); -} - -/* ===== Empty State ===== */ -.empty-state { - text-align: center; - padding: 4rem 2rem; -} - -.empty-state-icon { - font-size: 4rem; - color: var(--text-muted); - margin-bottom: 1rem; -} - -.empty-state-title { - font-size: 1.5rem; - font-weight: 600; - color: var(--text-main); - margin-bottom: 0.5rem; -} - -.empty-state-text { - color: var(--text-secondary); -} - -/* ===== Generic Card ===== */ -.card { - background: var(--bg-card); - border: 1px solid var(--border); - border-radius: 0.75rem; - box-shadow: var(--shadow-sm); - overflow: hidden; - margin-bottom: 1.5rem; -} - -.card-header { - padding: 1.25rem 1.5rem; - background: var(--bg-card); - border-bottom: 1px solid var(--border); - font-weight: 600; - font-size: 1.1rem; - color: var(--text-main); - display: flex; - align-items: center; - justify-content: space-between; -} - -.card-body { - padding: 1.5rem; -} - -.card-footer { - padding: 1rem 1.5rem; - background: var(--bg-card-hover); - border-top: 1px solid var(--border); - display: flex; - align-items: center; - justify-content: flex-end; - gap: 0.75rem; -} - -.card-title { - font-size: 1.25rem; - font-weight: 600; - margin-bottom: 1rem; - color: var(--text-main); -} - -/* ===== Generic Forms ===== */ -.form-group, -.form-entry { - margin-bottom: 1.25rem; -} - -.form-label, -label { - display: block; - margin-bottom: 0.5rem; - font-weight: 500; - color: var(--text-main); - font-size: 0.9rem; -} - -.sublabel { - font-size: 0.8rem; - color: var(--text-secondary); - margin-top: 0.25rem; -} - -.form-control, -input[type="text"], -input[type="password"], -input[type="email"], -input[type="number"], -input[type="search"], -textarea, -select { - width: 100%; - padding: 0.625rem 0.875rem; - background: var(--bg-body); - border: 1px solid var(--border); - border-radius: 0.5rem; - color: var(--text-main); - font-size: 0.95rem; - transition: all 0.2s ease; - font-family: inherit; -} - -.form-control:focus, -input[type="text"]:focus, -input[type="password"]:focus, -input[type="email"]:focus, -input[type="number"]:focus, -input[type="search"]:focus, -textarea:focus, -select:focus { - outline: none; - border-color: var(--primary); - box-shadow: 0 0 0 3px var(--primary-light); -} - -/* Checkbox & Radio wrapper */ -.checkbox-wrapper { - display: flex; - align-items: center; - gap: 0.5rem; -} - -/* ===== Buttons Updates ===== */ -.btn { - display: inline-flex; - align-items: center; - justify-content: center; - gap: 0.5rem; - padding: 0.625rem 1.25rem; - border-radius: 0.5rem; - font-weight: 500; - font-size: 0.9rem; - cursor: pointer; - transition: all 0.2s ease; - border: 1px solid transparent; - text-decoration: none; - line-height: 1.2; -} - -.btn-primary, -.button-primary { - background: var(--primary); - color: white; - border-color: transparent; -} - -.btn-primary:hover, -.button-primary:hover { - background: var(--primary-hover); - color: white; -} - -.btn-secondary, -.button-secondary { - background: var(--bg-card); - border-color: var(--border); - color: var(--text-main); -} - -.btn-secondary:hover, -.button-secondary:hover { - background: var(--border-light); -} - -.btn-danger, -.button-alert { - background: var(--danger); - color: white; -} - -.btn-danger:hover, -.button-alert:hover { - background: #dc2626; - /* Darker red */ -} - -.btn-sm { - padding: 0.25rem 0.5rem; - font-size: 0.8rem; - gap: 0.25rem; + font-size: 0.6875rem; line-height: 1; -} - -/* ===== Forms ===== */ -.input-big { - width: 100%; - padding: 0.75rem 1rem; - border: 1px solid var(--border); - border-radius: 0.5rem; - background: var(--bg-card); - color: var(--text-main); - font-size: 1rem; - transition: all 0.15s ease; -} - -.input-big:focus { - outline: none; - border-color: var(--primary); - box-shadow: 0 0 0 3px var(--primary-light); -} - -/* ===== Alerts ===== */ -.alert { - padding: 1rem 1.25rem; - border-radius: 0.5rem; - margin-bottom: 1rem; - font-size: 0.9rem; -} - -.alert-success { - background: var(--tag-green-bg); - color: var(--tag-green-text); - border: 1px solid var(--tag-green-text); -} - -.alert-danger { - background: var(--tag-red-bg); - color: var(--tag-red-text); - border: 1px solid var(--tag-red-text); -} - -.alert-warning { - background: var(--tag-yellow-bg); - color: var(--tag-yellow-text); - border: 1px solid var(--tag-yellow-text); -} - -/* ===== Utilities ===== */ -.text-center { - text-align: center; -} - -.hidden { - display: none !important; -} - -.clearfix::after { - content: ''; - display: table; - clear: both; -} - -/* ===== List Groups (for Admin Pages) ===== */ -.list-group { - display: flex; - flex-direction: column; -} - -.list-group-item { - display: flex; - align-items: center; - padding: 1rem 1.25rem; - border-bottom: 1px solid var(--border); - transition: background-color 0.2s; - text-decoration: none; - color: var(--text-main); -} - -.list-group-item:last-child { - border-bottom: none; -} - -.list-group-item:hover { - background-color: var(--bg-card-hover); -} - -.list-group-item-content { - flex: 1; -} - -.list-group-item-label { - font-weight: 500; - font-size: 1rem; - color: var(--text-main); - margin-bottom: 0.125rem; -} - -.list-group-item-sublabel { - font-size: 0.85rem; - color: var(--text-secondary); -} - -.list-group-item-action { - margin-left: 1rem; - display: flex; - align-items: center; - gap: 0.5rem; -} - -.list-sortable-handle { - cursor: move; - color: var(--text-muted); - padding: 0.5rem; -} - -.list-sortable-handle:hover { - color: var(--text-main); -} - -/* Checkbox in list */ -.list-group-item .checkbox-wrapper { - margin-right: 1rem; -} - -/* Key-Value Lists (Server Info) */ -.key-value-list { - display: flex; - flex-direction: column; -} - -.key-value-item { - display: flex; - justify-content: space-between; - padding: 0.75rem 0; - border-bottom: 1px solid var(--border-light); - font-size: 0.95rem; -} - -.key-value-item:last-child { - border-bottom: none; -} - -.key-value-label { - color: var(--text-secondary); - font-weight: 500; -} - -.key-value-data { - color: var(--text-main); - font-weight: 500; - text-align: right; -} - -/* ===== Progress Bar ===== */ -.progress-bar { - width: 100%; - height: 1rem; - background-color: var(--border-light); - border-radius: 0.5rem; - overflow: hidden; - margin: 1rem 0; -} - -.progress-actual { - height: 100%; - background-color: var(--primary); - width: 0; - transition: width 0.3s ease; -} - -.progress-counter { - text-align: center; - font-weight: 600; - color: var(--text-secondary); -} - -/* ===== Picwall (Image Wall) ===== */ -.picwall-controls { - margin: 1.5rem 0 1.75rem; - display: flex; - justify-content: center; -} - -.picwall-controls-inner { - display: inline-flex; - align-items: center; - gap: 1rem; - padding: 0.85rem 1.25rem; + padding: 0.2rem 0.4rem; border-radius: 999px; - background: var(--bg-card); - border: 1px solid var(--border); - box-shadow: var(--shadow-sm); -} - -.picwall-controls-label { - display: inline-flex; - align-items: center; - gap: 0.45rem; - font-weight: 600; - color: var(--text-main); - font-size: 0.9rem; -} - -.picwall-size-controls { - display: inline-flex; - align-items: center; - gap: 0.5rem; -} - -.picwall-size-btn { - width: 32px; - height: 32px; - border-radius: 50%; - border: 1px solid var(--border); - background: var(--bg-body); - color: var(--text-main); - display: inline-flex; - align-items: center; - justify-content: center; - cursor: pointer; - transition: transform 0.2s ease, background-color 0.2s ease; -} - -.picwall-size-btn:hover { - background: var(--bg-card-hover); - transform: translateY(-1px); -} - -.picwall-size-slider { - width: 160px; - accent-color: var(--primary); -} - -.picwall-size-value { - font-weight: 600; - color: var(--text-secondary); - font-size: 0.85rem; - min-width: 60px; - text-align: right; -} - -.picwall-container { - --picwall-item-size: 220px; - column-width: var(--picwall-item-size); - column-gap: 18px; - width: 100%; - padding-bottom: 2rem; -} - -.picwall-pictureframe { - display: inline-block; - width: 100%; - margin: 0 0 18px; - position: relative; - border-radius: 18px; - overflow: hidden; - background: var(--bg-card); - box-shadow: var(--shadow-md); - break-inside: avoid; - isolation: isolate; -} - -.picwall-image-link img { - width: 100%; - height: auto; - display: block; - object-fit: cover; - transform: scale(1); - transition: transform 0.35s ease; -} - -.picwall-pictureframe:hover .picwall-image-link img, -.picwall-pictureframe:focus-within .picwall-image-link img { - transform: scale(1.04); -} - -.picwall-overlay { - position: absolute; - inset: 0; - background: linear-gradient(180deg, rgba(8, 15, 30, 0.05) 0%, rgba(8, 15, 30, 0.65) 60%, rgba(8, 15, 30, 0.85) 100%); - opacity: 0; - transition: opacity 0.3s ease; - display: flex; - align-items: flex-end; -} - -.picwall-pictureframe:hover .picwall-overlay, -.picwall-pictureframe:focus-within .picwall-overlay { - opacity: 1; -} - -.picwall-link { - display: flex; - flex-direction: column; - gap: 0.35rem; - padding: 1.1rem 1.2rem 1.25rem; - color: #ffffff; - width: 100%; -} - -.picwall-title { - font-size: 1.05rem; - font-weight: 600; - line-height: 1.3; - text-shadow: 0 8px 20px rgba(0, 0, 0, 0.45); -} - -.picwall-description { - font-size: 0.85rem; - line-height: 1.4; - color: rgba(255, 255, 255, 0.85); - display: -webkit-box; - line-clamp: 3; - -webkit-line-clamp: 3; - -webkit-box-orient: vertical; - overflow: hidden; -} - -[data-theme="dark"] .picwall-controls-inner { - background: #111827; - border-color: #1f2937; -} - -[data-theme="dark"] .picwall-size-btn { - background: #0f172a; - border-color: #1f2937; -} - -[data-theme="dark"] .picwall-pictureframe { - background: #0f172a; - box-shadow: 0 18px 26px rgba(4, 12, 26, 0.45); -} - -@media (max-width: 900px) { - .picwall-controls-inner { - flex-wrap: wrap; - justify-content: center; - } - - .picwall-size-slider { - width: 140px; - } -} - -@media (max-width: 600px) { - .picwall-controls { - margin: 1rem 0 1.25rem; - } - - .picwall-controls-inner { - width: 100%; - border-radius: 16px; - } - - .picwall-container { - column-gap: 14px; - } - - .picwall-pictureframe { - border-radius: 14px; - margin-bottom: 14px; - } -} - -/* ===== Daily / Weekly / Monthly ===== */ -.daily { - padding: 1.5rem 0 2.5rem; -} - -.daily-nav-unified { - display: flex; - align-items: center; - justify-content: space-between; - gap: 1.5rem; - padding: 1.1rem 1.4rem; - border-radius: 18px; - background: linear-gradient(135deg, rgba(15, 23, 42, 0.08), rgba(15, 23, 42, 0.03)); - border: 1px solid var(--border); - box-shadow: var(--shadow-sm); - margin-bottom: 1.6rem; - flex-wrap: wrap; -} - -.daily-nav-left { - display: inline-flex; - align-items: center; - gap: 0.65rem; - font-weight: 600; - color: var(--text-main); - white-space: nowrap; -} - -.daily-nav-center { - display: flex; - align-items: center; - gap: 0.75rem; - flex: 1; - justify-content: center; - flex-wrap: wrap; -} - -.daily-nav-tabs { - display: inline-flex; - gap: 0.4rem; - padding: 0.3rem; - border-radius: 999px; - background: var(--bg-body); - border: 1px solid var(--border-light); - white-space: nowrap; -} - -[data-theme="dark"] .daily-nav-tabs { - background: #0f172a; - border-color: #1f2937; -} - -.daily-tab { - padding: 0.45rem 1rem; - border-radius: 999px; - font-weight: 700; - font-size: 0.78rem; - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--text-secondary); - transition: all 0.2s ease; - border: 1px solid transparent; -} - -.daily-tab.is-active { - background: var(--primary); - color: #ffffff; - box-shadow: 0 12px 24px rgba(59, 130, 246, 0.3); -} - -.daily-tab.is-inactive:hover { - background: var(--bg-card-hover); - color: var(--text-main); - border-color: var(--border-light); -} - -.daily-date-pill { - border: 1px dashed var(--border); - background: var(--bg-card); - color: var(--text-main); - font-weight: 600; - padding: 0.4rem 1.1rem; - border-radius: 999px; - cursor: pointer; - font-size: 0.9rem; - transition: all 0.2s ease; -} - -.daily-date-pill:hover { - background: var(--bg-card-hover); -} - -.daily-calendar-btn { - display: inline-flex; - align-items: center; - gap: 0.5rem; - padding: 0.45rem 1.05rem; - border-radius: 999px; - border: 1px solid var(--border-light); - background: var(--bg-card); - color: var(--text-main); - font-weight: 600; - font-size: 0.85rem; - cursor: pointer; - transition: all 0.2s ease; -} - -[data-theme="dark"] .daily-calendar-btn { - background: #0f172a; - border-color: #1f2937; - color: #e2e8f0; -} - -[data-theme="dark"] .daily-calendar-btn:hover { - background: #111827; - border-color: #334155; -} - -.daily-calendar-btn:hover { - background: var(--bg-card-hover); - color: var(--text-main); - border-color: var(--border); -} - -.daily-calendar-wrap { - position: relative; -} - -.daily-calendar-panel { - position: absolute; - top: calc(100% + 12px); - right: 0; - z-index: 120; - display: none; -} - -.daily-calendar-panel.is-open { - display: block; -} - -.daily-calendar-shell { - display: flex; - width: min(640px, 92vw); - background: var(--bg-card); - border: 1px solid var(--border); - border-radius: 20px; - box-shadow: 0 25px 60px rgba(15, 23, 42, 0.35); - overflow: hidden; -} - -.daily-calendar-sidebar { - width: 190px; - padding: 1.1rem; - background: var(--bg-body); - border-right: 1px solid var(--border-light); - display: flex; - flex-direction: column; - gap: 0.6rem; -} - -.daily-calendar-title { - font-size: 0.7rem; - font-weight: 700; - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--text-muted); - margin-bottom: 0.5rem; -} - -.daily-calendar-shortcut { - text-align: left; - padding: 0.5rem 0.7rem; - border-radius: 10px; - border: 1px solid transparent; - background: transparent; - color: var(--text-secondary); - font-size: 0.85rem; - cursor: pointer; - transition: all 0.2s ease; -} - -.daily-calendar-shortcut:hover { - background: var(--bg-card-hover); - color: var(--text-main); - border-color: var(--border); -} - -.daily-calendar-summary { - margin-top: auto; - padding-top: 1rem; - border-top: 1px solid var(--border-light); - font-size: 0.75rem; - color: var(--text-muted); - display: grid; - gap: 0.4rem; -} - -.daily-calendar-summary strong { - display: block; - color: var(--text-main); - font-size: 0.85rem; - margin-top: 0.2rem; -} - -.daily-calendar-main { - flex: 1; - padding: 1.5rem; - display: flex; - flex-direction: column; -} - -.daily-calendar-header { - display: flex; - align-items: center; - justify-content: space-between; - gap: 1rem; - margin-bottom: 1rem; -} - -.daily-calendar-nav { - width: 36px; - height: 36px; - border-radius: 12px; - border: 1px solid var(--border); - background: var(--bg-body); - color: var(--text-secondary); - cursor: pointer; - display: inline-flex; - align-items: center; - justify-content: center; - transition: all 0.2s ease; -} - -.daily-calendar-nav:hover { - color: var(--text-main); - background: var(--bg-card-hover); -} - -.daily-calendar-month { - font-weight: 700; - color: var(--text-main); - font-size: 1rem; - text-transform: capitalize; -} - -.daily-calendar-weekdays, -.daily-calendar-grid { - display: grid; - grid-template-columns: repeat(7, minmax(0, 1fr)); - gap: 0.35rem; - text-align: center; -} - -.daily-calendar-weekdays { - margin-bottom: 0.5rem; - font-size: 0.7rem; - text-transform: uppercase; - color: var(--text-muted); - letter-spacing: 0.05em; -} - -/* --- Styles Calendrier React-like --- */ -.daily-calendar-day { - width: 40px; - height: 40px; - border-radius: 999px; - border: none; - background: transparent; - color: var(--text-secondary); - font-weight: 600; - font-size: 0.9rem; - cursor: pointer; - transition: all 0.15s ease; - display: inline-flex; - align-items: center; - justify-content: center; -} - -/* Hover: cercle visible comme dans React */ -.daily-calendar-day:hover { - background: rgba(59, 130, 246, 0.18); - color: var(--text-main); - border-radius: 999px; - box-shadow: 0 0 0 1px rgba(59, 130, 246, 0.25); -} - -[data-theme="dark"] .daily-calendar-day:hover { - background: rgba(99, 102, 241, 0.25); - color: #ffffff; - box-shadow: 0 0 0 1px rgba(99, 102, 241, 0.35); -} - -/* In range: fond bleu semi-transparent, pas d'arrondi */ -.daily-calendar-day.is-in-range { - background: rgba(59, 130, 246, 0.16); - color: var(--primary); - border-radius: 0; -} - -[data-theme="dark"] .daily-calendar-day.is-in-range { - background: rgba(59, 130, 246, 0.25); - color: #60a5fa; -} - -/* Start/End: fond bleu plein avec glow */ -.daily-calendar-day.is-range-start, -.daily-calendar-day.is-range-end { - background: var(--primary); - color: #ffffff; - box-shadow: 0 0 15px rgba(59, 130, 246, 0.5); -} - -[data-theme="dark"] .daily-calendar-day.is-range-start, -[data-theme="dark"] .daily-calendar-day.is-range-end { - background: #2563eb; - box-shadow: 0 0 15px rgba(37, 99, 235, 0.5); -} - -/* Single date selection: cercle complet */ -.daily-calendar-day.is-range-single { - border-radius: 999px; -} - -/* Range start: arrondi gauche seulement */ -.daily-calendar-day.is-range-start:not(.is-range-end) { - border-radius: 999px 0 0 999px; -} - -/* Range end: arrondi droite seulement */ -.daily-calendar-day.is-range-end:not(.is-range-start) { - border-radius: 0 999px 999px 0; -} - -/* Hover sur in-range/start/end: pas de shadow supplémentaire */ -.daily-calendar-day.is-in-range:hover, -.daily-calendar-day.is-range-start:hover, -.daily-calendar-day.is-range-end:hover { - box-shadow: none; -} - -.daily-calendar-footer { - margin-top: auto; - padding-top: 1rem; - border-top: 1px solid var(--border-light); - display: flex; - justify-content: flex-end; - gap: 0.6rem; -} - -.daily-calendar-cancel, -.daily-calendar-apply { - padding: 0.45rem 1rem; - border-radius: 10px; - border: 1px solid var(--border); - background: var(--bg-body); - color: var(--text-secondary); - font-weight: 600; - cursor: pointer; - transition: all 0.2s ease; -} - -.daily-calendar-cancel:hover { - background: var(--bg-card-hover); - color: var(--text-main); -} - -.daily-calendar-apply { - background: var(--primary); - border-color: transparent; - color: #ffffff; - box-shadow: 0 12px 24px rgba(59, 130, 246, 0.25); -} - -.daily-calendar-apply:disabled { - opacity: 0.6; - cursor: not-allowed; - box-shadow: none; -} - -.daily-calendar-wrap.is-open .daily-calendar-btn { - background: rgba(59, 130, 246, 0.16); - color: var(--primary); - border-color: rgba(59, 130, 246, 0.35); -} - -.daily-grid { - column-count: 4; - column-gap: 18px; - width: 100%; -} - -.daily-item { - display: inline-block; - width: 100%; - margin-bottom: 18px; - break-inside: avoid; -} - -.daily-card { - background: var(--bg-card); - border: 1px solid var(--border); - border-radius: 18px; - overflow: hidden; - box-shadow: var(--shadow-md); - transition: transform 0.25s ease, box-shadow 0.25s ease; -} - -.daily-card:hover { - transform: translateY(-4px); - box-shadow: var(--shadow-lg); -} - -.daily-item-header { - display: block; - padding: 1rem 1.1rem 0.75rem; - font-weight: 600; - color: var(--text-main); - font-size: 1rem; - line-height: 1.35; -} - -.daily-item-image { - width: 100%; - height: 160px; - background-size: cover; - background-position: center; -} - -.daily-item-body { - padding: 0.85rem 1.1rem 0.5rem; - color: var(--text-secondary); - font-size: 0.9rem; - line-height: 1.55; -} - -.daily-item-footer { - padding: 0.75rem 1.1rem 1rem; - display: flex; - align-items: center; - justify-content: space-between; - gap: 0.75rem; - flex-wrap: wrap; - border-top: 1px solid var(--border-light); - font-size: 0.8rem; - color: var(--text-muted); -} - -.daily-item-footer-subtitle { - color: var(--text-secondary); - font-weight: 600; -} - -.daily-item-tags { - color: var(--text-muted); - font-size: 0.78rem; - font-weight: 500; -} - -[data-theme="dark"] .daily-nav-unified { - background: linear-gradient(135deg, rgba(15, 23, 42, 0.8), rgba(15, 23, 42, 0.55)); - border-color: #1f2937; -} - -@media (max-width: 1200px) { - .daily-grid { - column-count: 3; - } -} - -@media (max-width: 900px) { - .daily-grid { - column-count: 2; - } - - .daily-nav-unified { - justify-content: center; - } -} - -@media (max-width: 600px) { - .daily-grid { - column-count: 1; - } - - .daily-nav-unified { - padding: 1rem; - } -} - -/* ===== Bulk Bookmark Creation ===== */ -.page-add .col-md-6.col-md-offset-3 { - width: 100%; - max-width: 920px; - margin: 0 auto; - float: none; -} - -.page-add .card, -.page-edit-link-batch .batch-add-card { - border: 1px solid var(--border); - border-radius: 16px; - background: var(--bg-card); - box-shadow: var(--shadow-md); - overflow: hidden; -} - -.page-add .card .card-header, -.page-add .batch-add-card .card-header { - border-bottom: 1px solid var(--border); - color: var(--text-main); -} - -.page-add .page-add-actions { - margin: 1.25rem 0 1rem; - line-height: 1.2; - color: var(--bookmark-text-main); - letter-spacing: 0.01em; -} - -.page-add .page-add-bulk-toggle { - min-height: 42px; - border-radius: 10px; -} - -.page-add .batch-private-wrap { - display: inline-flex; - align-items: center; - gap: 0.45rem; -} - -.page-add .batch-private-checkbox { - width: 18px; - height: 18px; - accent-color: var(--primary); -} - -.page-add .batch-private-label { - margin: 0; - color: var(--text-main); - font-weight: 500; -} - -.bookmark-editor-meta { - margin: 0.35rem 0 0; - font-size: 0.8rem; - color: var(--bookmark-text-muted); + background: #E5E7EB; + color: #4B5563; text-transform: uppercase; letter-spacing: 0.04em; } -.page-edit .bookmark-editor-card .card-body { - padding: 1.5rem; - background: transparent; +[data-theme="dark"] .search-result-kind { + background: #334155; + color: #cbd5e1; } -.page-edit .bookmark-field-group { - margin-bottom: 1.15rem; -} - -.page-edit .bookmark-field-group .form-label { - margin-bottom: 0.45rem; - color: var(--bookmark-text-main); - font-weight: 600; - font-size: 0.86rem; - letter-spacing: 0.02em; -} - -.page-edit .bookmark-editor-card .form-control, -.page-edit .bookmark-editor-card input[type="text"], -.page-edit .bookmark-editor-card textarea { - border-radius: 10px; - border: 1px solid var(--bookmark-input-border); - background: var(--bookmark-input-bg); - color: var(--bookmark-text-main); - min-height: 44px; -} - -.page-edit .bookmark-editor-card .form-control::placeholder, -.page-edit .bookmark-tags-text-input::placeholder { - color: var(--bookmark-text-muted); -} - -.page-edit .bookmark-editor-card .form-control:focus, -.page-edit .bookmark-editor-card input[type="text"]:focus, -.page-edit .bookmark-editor-card textarea:focus, -.page-edit .bookmark-tags-text-input:focus { - border-color: var(--bookmark-input-focus); - box-shadow: 0 0 0 3px var(--bookmark-input-focus-ring); -} - -.page-edit .bookmark-editor-form.is-enhanced .bookmark-editor-source { - display: none; -} - -.page-edit .bookmark-markdown-editor { - border: 1px solid var(--bookmark-input-border); - border-radius: 12px; +.search-result-sub { + margin: 0.25rem 0 0; + padding-left: 1.9rem; + font-size: 0.78rem; + color: #6B7280; + line-height: 1.35; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; overflow: hidden; - background: var(--bookmark-input-bg); } -.page-edit .bookmark-editor-sublabel { - margin-top: 0.5rem; - color: var(--bookmark-text-muted); +[data-theme="dark"] .search-result-sub { + color: #94a3b8; } -.page-edit .bookmark-editor-sublabel a { - color: #8fb8ff; -} - -.page-edit .toastui-editor-defaultUI, -.page-edit .toastui-editor-md-container, -.page-edit .toastui-editor-ww-container, -.page-edit .toastui-editor-toolbar, -.page-edit .toastui-editor-mode-switch { - background: var(--bookmark-input-bg); -} -.page-edit .toastui-editor-defaultUI { - border: 0; -} - -.page-edit .toastui-editor-toolbar { - border-bottom: 1px solid var(--bookmark-input-border); -} - -.page-edit .toastui-editor-toolbar button { - border: 0; - background-color: transparent; - box-shadow: none; -} - -.page-edit .toastui-editor-toolbar button:hover, -.page-edit .toastui-editor-toolbar button.active, -.page-edit .toastui-editor-toolbar button:focus-visible { - background-color: rgba(126, 168, 255, 0.16); -} - -.page-edit .toastui-editor-toolbar-icons { - opacity: 0.96; -} - -.page-edit .toastui-editor-toolbar-divider { - background-color: var(--bookmark-input-border); -} - -.page-edit .toastui-editor-mode-switch .tab-item { - color: var(--bookmark-text-main); -} - -.page-edit .toastui-editor-md-tab-container, -.page-edit .toastui-editor-mode-switch { - border-top: 1px solid var(--bookmark-input-border); -} - -.page-edit .bookmark-tags-input { - min-height: 48px; - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 0.5rem; - padding: 0.5rem; - border-radius: 12px; - border: 1px solid var(--bookmark-input-border); - background: var(--bookmark-input-bg); - transition: border-color 0.2s ease, box-shadow 0.2s ease; -} - -.page-edit .bookmark-tags-input:focus-within { - border-color: var(--bookmark-input-focus); - box-shadow: 0 0 0 3px var(--bookmark-input-focus-ring); -} - -.page-edit .bookmark-tags-list { +.search-result-tags { + margin-top: 0.35rem; + padding-left: 1.9rem; display: flex; flex-wrap: wrap; - gap: 0.45rem; + gap: 0.3rem; } -.page-edit .bookmark-tag-pill { +.search-result-tag { display: inline-flex; align-items: center; - gap: 0.4rem; - height: 34px; - padding: 0 0.4rem 0 0.8rem; + border: 1px solid #dbeafe; + background: #eff6ff; + color: #1e40af; border-radius: 999px; - border: 1px solid rgba(191, 203, 255, 0.12); - background: var(--bookmark-tag-bg); - color: var(--bookmark-tag-text); - font-size: 0.95rem; - font-weight: 600; - letter-spacing: 0.01em; - transition: transform 0.2s ease, background-color 0.2s ease; -} - -.page-edit .bookmark-tag-pill:hover { - transform: translateY(-1px); - background: var(--bookmark-tag-bg-hover); -} - -.page-edit .bookmark-tag-remove { - border: 0; - width: 24px; - height: 24px; - border-radius: 999px; - background: var(--bookmark-tag-remove-bg); - color: var(--bookmark-tag-text); - display: inline-flex; - align-items: center; - justify-content: center; - cursor: pointer; + font-size: 0.72rem; line-height: 1; - padding: 0; - transition: background-color 0.2s ease, transform 0.2s ease; + padding: 0.2rem 0.45rem; } -.page-edit .bookmark-tag-remove:hover, -.page-edit .bookmark-tag-remove:focus-visible { - background: var(--bookmark-tag-remove-bg-hover); - transform: scale(1.04); +[data-theme="dark"] .search-result-tag { + border-color: #334155; + background: #0f172a; + color: #93c5fd; } -.page-edit .bookmark-tag-remove:focus-visible { - outline: none; - box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.2); -} - -.page-edit .bookmark-tags-text-input { - border: 0; - background: transparent; - color: var(--bookmark-text-main); - min-width: 190px; - flex: 1; - font-size: 0.92rem; - padding: 0.45rem 0.4rem; -} - -.page-edit .bookmark-tags-text-input:focus { - outline: none; - box-shadow: none; -} - -.page-edit .bookmark-toggle-grid { - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 0.75rem; - margin-top: 0.45rem; -} - -.page-edit .bookmark-toggle-item { - display: inline-flex; - align-items: center; - gap: 0.55rem; - color: var(--bookmark-text-main); - font-size: 0.92rem; - font-weight: 500; - cursor: pointer; -} - -.page-edit .bookmark-toggle-item input[type="checkbox"] { - width: 18px; - height: 18px; - accent-color: #7ea8ff; -} - -.page-edit .bookmark-editor-footer { - background: var(--bookmark-panel-soft); - border-top: 1px solid var(--bookmark-panel-border); - padding: 1rem 1.5rem; -} - -.page-edit .bookmark-editor-footer .btn { - min-height: 42px; - border-radius: 10px; - padding-inline: 1rem; - font-weight: 600; -} - -.page-edit .bookmark-editor-footer .btn-primary { - background: var(--bookmark-save-bg); - border-color: transparent; - box-shadow: 0 10px 22px rgba(77, 130, 240, 0.35); -} - -.page-edit .bookmark-editor-footer .btn-primary:hover { - filter: brightness(1.06); -} - -.page-edit .bookmark-editor-footer .btn-danger { - background: #c84e4e; - border-color: transparent; -} - -.page-edit .bookmark-editor-footer .btn-danger:hover { - background: #dd5a5a; -} - -@media (max-width: 991px) { - .page-edit .editlinkform-col { - max-width: 100%; - padding-inline: 0; - } - - .page-edit .bookmark-editor-header, - .page-edit .bookmark-editor-card .card-body, - .page-edit .bookmark-editor-footer { - padding: 1rem; - } - - .page-edit .bookmark-toggle-grid { - grid-template-columns: 1fr; - } - - .page-edit .bookmark-tags-input { - gap: 0.4rem; - } - - .page-edit .bookmark-tag-pill { - height: 32px; - font-size: 0.9rem; - } - - .page-edit .bookmark-editor-footer { - flex-wrap: wrap; - justify-content: stretch; - } - - .page-edit .bookmark-editor-footer .btn, - .page-edit .bookmark-editor-footer a.btn { - flex: 1 1 calc(50% - 0.4rem); - } -} - -@media (max-width: 640px) { - .page-edit .bookmark-tags-text-input { - min-width: 120px; - } - - .page-edit .bookmark-editor-footer .btn, - .page-edit .bookmark-editor-footer a.btn { - flex: 1 1 100%; - } -} - -/* ===== Bulk Creation + Edit (final overrides) ===== */ -.page-add .page-add-actions { - margin: 1.25rem 0 1rem; - color: var(--text-secondary); -} - -.page-add .page-add-bulk-toggle { - min-height: 42px; - border-radius: 10px; -} - -.page-add .batch-private-wrap { - display: inline-flex; - align-items: center; - gap: 0.45rem; -} - -.page-add .batch-private-checkbox { - width: 18px; - height: 18px; - accent-color: var(--primary); -} - -.page-add .batch-private-label { - margin: 0; - color: var(--text-main); -} - -.page-edit { - --bookmark-panel-bg: var(--bg-card); - --bookmark-panel-border: var(--border); - --bookmark-panel-soft: var(--bg-card-hover); - --bookmark-input-bg: var(--bg-body); - --bookmark-input-border: var(--border); - --bookmark-input-focus: var(--primary); - --bookmark-input-focus-ring: rgba(59, 130, 246, 0.2); - --bookmark-text-main: var(--text-main); - --bookmark-text-muted: var(--text-secondary); - --bookmark-tag-bg: var(--tag-bg); - --bookmark-tag-bg-hover: var(--primary-light); - --bookmark-tag-text: var(--tag-text); - --bookmark-tag-remove-bg: rgba(17, 24, 39, 0.1); - --bookmark-tag-remove-bg-hover: rgba(17, 24, 39, 0.2); - --bookmark-save-bg: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%); -} - -[data-theme="dark"] .page-edit { - --bookmark-panel-bg: #121c30; - --bookmark-panel-border: #25324a; - --bookmark-panel-soft: #1a2640; - --bookmark-input-bg: #0c1528; - --bookmark-input-border: #334769; - --bookmark-input-focus: #70a0ff; - --bookmark-input-focus-ring: rgba(112, 160, 255, 0.25); - --bookmark-text-main: #eaf1ff; - --bookmark-text-muted: #9fb1d4; - --bookmark-tag-bg: #2f2f90; - --bookmark-tag-bg-hover: #3939a6; - --bookmark-tag-text: #cfdaff; - --bookmark-tag-remove-bg: rgba(255, 255, 255, 0.16); - --bookmark-tag-remove-bg-hover: rgba(255, 255, 255, 0.26); - --bookmark-save-bg: linear-gradient(135deg, #6fa8ff 0%, #4d82f0 100%); -} - -.page-edit .bookmark-editor-card { - border-radius: 16px; - border: 1px solid var(--bookmark-panel-border); - background: var(--bookmark-panel-bg); - box-shadow: var(--shadow-lg); -} - -.page-edit .bookmark-editor-header { - background: linear-gradient(180deg, rgba(148, 163, 184, 0.12) 0%, rgba(148, 163, 184, 0) 100%); -} - -.bookmark-editor-title { - margin: 0; - font-size: 1.35rem; - line-height: 1.2; - color: var(--bookmark-text-main); -} - -.page-edit .bookmark-editor-form[data-batch-mode="1"] .bookmark-markdown-editor { - display: none; -} - -.page-edit-link-batch .batch-save-all-wrap { - margin: 1.5rem 0; -} - -.page-edit-link-batch .batch-save-all-btn { - min-width: 150px; - min-height: 42px; - border-radius: 10px; -} - -.page-edit-link-batch .fullscreen { - position: fixed; - inset: 0; - z-index: 1600; - background: var(--overlay-bg); -} - -.page-edit-link-batch .content-fullscreen { - min-height: 100vh; +.search-results-header { display: flex; align-items: center; + flex-wrap: wrap; + gap: 0.45rem; + margin-bottom: 1rem; +} + +.search-tag-chip { + display: inline-flex; + align-items: center; + gap: 0.3rem; + border: 1px solid #f59e0b; + background: #fef3c7; + color: #78350f; + border-radius: 999px; + font-size: 0.78rem; + font-weight: 600; + padding: 0.26rem 0.6rem; +} + +.search-tag-close { + color: inherit; + display: inline-flex; + align-items: center; justify-content: center; - padding: 1.25rem; } -.page-edit-link-batch .batch-progress-card { - border: 1px solid var(--border); - border-radius: 14px; - background: var(--bg-card); - color: var(--text-main); - box-shadow: var(--shadow-xl); - padding: 1.25rem 1.5rem; -} - -.page-edit-link-batch .batch-progress-title { - margin: 0 0 0.6rem; - font-size: 1.1rem; - text-align: center; -} - -[data-theme="dark"] .page-edit-link-batch .batch-progress-card { - border-color: #314564; - background: #122039; - color: #eaf2ff; -} - -/* ===== Global Responsive Overhaul ===== */ -.sidebar-overlay { - position: fixed; - inset: 0; - background: rgba(15, 23, 42, 0.55); - opacity: 0; - visibility: hidden; - transition: opacity 0.2s ease, visibility 0.2s ease; - z-index: 180; -} - -.sidebar-overlay.show { - opacity: 1; - visibility: visible; -} - -@media (max-width: 1100px) { - .header-nav { - display: none; - } - - .mobile-menu-btn { - display: inline-flex; - align-items: center; - justify-content: center; - width: 38px; - height: 38px; - border-radius: 10px; - background: rgba(255, 255, 255, 0.14); - } - - .mobile-menu-btn:hover { - background: rgba(255, 255, 255, 0.22); - } - - .sidebar { - transform: translateX(-100%); - width: min(86vw, 320px); - max-width: 320px; - border-right: 0; - box-shadow: 0 24px 50px rgba(2, 6, 23, 0.45); - z-index: 220; - } - - .sidebar.show { - transform: translateX(0); - } - - .main-content, - .media-player-bar, - .bulk-actions-bar { - margin-left: 0; - left: 0; - } - - .header-main { - padding: 0 0.9rem; - } - - .content-container { - padding: 0.85rem 0.9rem; - } - - .content-toolbar { - flex-direction: column; - align-items: stretch; - gap: 0.8rem; - } - - .toolbar-left, - .toolbar-right { - width: 100%; - justify-content: space-between; - flex-wrap: wrap; - } - - .links-list.view-grid { - grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); - } - - .paging { - gap: 0.6rem; - } - - .paging-current { - order: 2; - } - - .paging-links, - .paging-plugin { - order: 3; - } - - .bulk-actions-bar { - flex-direction: column; - align-items: stretch; - gap: 0.8rem; - padding: 0.8rem 0.9rem; - } - - .bulk-info, - .bulk-buttons { - width: 100%; - justify-content: space-between; - } - - .bulk-buttons { - flex-wrap: wrap; - } - - .bulk-btn { - flex: 1 1 calc(50% - 0.35rem); - } - - .daily-nav-left { - width: 100%; - justify-content: center; - } - - .daily-nav-tabs { - width: 100%; - overflow-x: auto; - justify-content: flex-start; - } +[data-theme="dark"] .search-tag-chip { + border-color: #fbbf24; + background: rgba(251, 191, 36, 0.2); + color: #fde68a; } +/* Mobile styles */ @media (max-width: 768px) { - body { - -webkit-text-size-adjust: 100%; - } - - .header-main { - height: 52px; - } - - .header-inner { - gap: 0.6rem; - } - - .header-actions { - gap: 0.35rem; - } - - .header-action-btn, - .header-nav-link { - width: 34px; - height: 34px; - border-radius: 0.45rem; - font-size: 1rem; - } - - .filter-panel { - position: fixed; - top: auto; - right: 0.5rem; - left: 0.5rem; - bottom: 0.6rem; - width: auto; - max-height: 78vh; - overflow: auto; - border-radius: 14px; - animation: none; - } - - .search-overlay { - padding: 1rem 0.6rem; - align-items: flex-start; - } - - .search-modal { - width: 100%; - max-width: none; - border-radius: 12px; - } - .search-modal-header { flex-wrap: wrap; } .search-modal-actions { width: 100%; + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); } .search-pill-btn { - flex: 1; + width: 100%; justify-content: center; + padding: 0.55rem 0.45rem; } - .links-list, - .links-list.view-grid { - grid-template-columns: minmax(0, 1fr); - gap: 0.8rem; + .search-footer-hint { + flex-wrap: wrap; + justify-content: center; + row-gap: 0.35rem; + column-gap: 0.5rem; + } + + .search-result-sub, + .search-result-tags { + padding-left: 0; + margin-left: 1.9rem; } .link-outer { @@ -4289,6 +1789,22 @@ table { display: inline-flex; } +.link-tag.is-search-match { + background: #fef3c7; + border: 1px solid #f59e0b; + color: #78350f; +} + +.link-tag.is-search-match .tag-remove-btn { + background: rgba(120, 53, 15, 0.14); +} + +[data-theme="dark"] .link-tag.is-search-match { + background: rgba(251, 191, 36, 0.18); + border-color: #fbbf24; + color: #fde68a; +} + .view-compact .link-actions { grid-column: 4; grid-row: 1 / span 2; diff --git a/shaarli-pro/js/script.js b/shaarli-pro/js/script.js index e6e6036..63ab00d 100644 --- a/shaarli-pro/js/script.js +++ b/shaarli-pro/js/script.js @@ -91,9 +91,10 @@ document.addEventListener('DOMContentLoaded', () => { const searchResults = document.getElementById('search-results'); const searchTagsBtn = document.getElementById('search-tags-btn'); const searchAllBtn = document.getElementById('search-all-btn'); + const searchNotesBtn = document.getElementById('search-notes-btn'); const searchForm = document.getElementById('search-form'); - let searchMode = 'search'; // 'search' or 'tags' + let searchMode = 'search'; // 'search' | 'tags' | 'notes' let selectedIndex = -1; let searchTimeout = null; let cachedBookmarks = null; @@ -167,9 +168,10 @@ document.addEventListener('DOMContentLoaded', () => { if (linkElements.length > 0) { cachedBookmarks = Array.from(linkElements).map(el => ({ id: el.dataset.id, + isNote: (el.querySelector('.link-title')?.getAttribute('title') || '').toLowerCase().includes('note'), title: el.querySelector('.link-title a')?.textContent || el.querySelector('.link-title')?.textContent || '', url: el.querySelector('.link-url a')?.href || el.querySelector('.link-title a')?.href || '', - tags: Array.from(el.querySelectorAll('.link-tag')).map(t => t.textContent.trim()), + tags: Array.from(el.querySelectorAll('.link-tag[data-tag]')).map(t => (t.getAttribute('data-tag') || '').trim()).filter(Boolean), description: el.querySelector('.link-description')?.textContent || '' })); return cachedBookmarks; @@ -181,21 +183,32 @@ document.addEventListener('DOMContentLoaded', () => { return []; } - // Render search results (tags or bookmarks) - function renderResults(results, query, isTagMode = false) { + function getSearchHint(mode) { + if (mode === 'tags') { + return 'Type to search in tags...'; + } + if (mode === 'notes') { + return 'Type to search in notes...'; + } + return 'Type to search in bookmarks and notes...'; + } + + // Render search results (tags, global bookmarks, or notes) + function renderResults(results, query, mode = 'search') { if (!searchResults) return; if (results.length === 0) { if (query && query.length > 0) { + const scopeLabel = mode === 'tags' ? 'tags' : (mode === 'notes' ? 'notes' : 'bookmarks/notes'); searchResults.innerHTML = `
- No results found for "${escapeHtml(query)}" + No ${scopeLabel} found for "${escapeHtml(query)}"
`; } else { searchResults.innerHTML = `
- Start typing to see tag suggestions... + ${getSearchHint(mode)}
`; } @@ -203,7 +216,7 @@ document.addEventListener('DOMContentLoaded', () => { } let html; - if (isTagMode) { + if (mode === 'tags') { // Render tags html = results.slice(0, 15).map((tag, index) => { const highlightedTag = highlightMatch(escapeHtml(tag), query); @@ -219,18 +232,32 @@ document.addEventListener('DOMContentLoaded', () => { `; }).join(''); } else { - // Render bookmarks - html = results.slice(0, 10).map((item, index) => { + // Render bookmarks or notes + html = results.slice(0, 12).map((item, index) => { const highlightedTitle = highlightMatch(escapeHtml(item.title), query); + const highlightedDescription = item.description ? highlightMatch(escapeHtml(item.description), query) : ''; + const typeLabel = item.isNote ? 'note' : 'bookmark'; + const typeIcon = item.isNote ? 'mdi-note-text-outline' : 'mdi-bookmark-outline'; + + const highlightedTags = (item.tags || []).slice(0, 4).map((tag) => { + const tagValue = escapeHtml(tag); + return `${highlightMatch(tagValue, query)}`; + }).join(''); + return `
- - ${highlightedTitle} + +
+ ${highlightedTitle} + ${typeLabel} +
+ ${highlightedDescription ? `
${highlightedDescription}
` : ''} + ${highlightedTags ? `
${highlightedTags}
` : ''}
`; }).join(''); @@ -241,7 +268,7 @@ document.addEventListener('DOMContentLoaded', () => { // Add click handlers to results searchResults.querySelectorAll('.search-result-item').forEach(item => { item.addEventListener('click', () => { - if (isTagMode) { + if (mode === 'tags') { const tag = item.dataset.tag; if (tag) { // Navigate to tag search @@ -257,26 +284,42 @@ document.addEventListener('DOMContentLoaded', () => { }); } - // Escape HTML to prevent XSS - function escapeHtml(text) { - const div = document.createElement('div'); - div.textContent = text; - return div.innerHTML; - } - // Perform live search async function performSearch(query) { - const tags = fetchTags(); + const normalizedQuery = (query || '').trim(); - if (!query || query.length === 0) { - // Show all tags when empty - renderResults(tags.slice(0, 15), '', true); + if (searchMode === 'tags') { + const tags = fetchTags(); + if (!normalizedQuery) { + renderResults(tags.slice(0, 15), '', 'tags'); + return; + } + + const tagResults = tags.filter(tag => fuzzyMatch(tag, normalizedQuery)); + renderResults(tagResults, normalizedQuery, 'tags'); return; } - // Filter tags with fuzzy matching - const results = tags.filter(tag => fuzzyMatch(tag, query)); - renderResults(results, query, true); + const bookmarks = await fetchBookmarks(); + const searchPool = searchMode === 'notes' ? bookmarks.filter(item => item.isNote) : bookmarks; + + if (!normalizedQuery) { + renderResults(searchPool.slice(0, 12), '', searchMode); + return; + } + + const results = searchPool.filter((item) => { + const haystack = [ + item.title, + item.url, + item.description, + (item.tags || []).join(' ') + ].join(' ').toLowerCase(); + + return haystack.includes(normalizedQuery.toLowerCase()); + }); + + renderResults(results, normalizedQuery, searchMode); } // Update selected result @@ -318,15 +361,12 @@ document.addEventListener('DOMContentLoaded', () => { return false; } - function openSearch() { + function openSearch(mode = 'search') { searchOverlay?.classList.add('show'); selectedIndex = -1; setTimeout(() => { + setSearchMode(mode); searchModalInput?.focus(); - // Trigger initial search if there's existing text - if (searchModalInput?.value) { - performSearch(searchModalInput.value); - } }, 100); } @@ -337,20 +377,30 @@ document.addEventListener('DOMContentLoaded', () => { // Toggle search mode (tags vs search) function setSearchMode(mode) { + if (!['search', 'tags', 'notes'].includes(mode)) { + mode = 'search'; + } + searchMode = mode; - searchTagsBtn?.classList.toggle('active', mode === 'tags'); searchAllBtn?.classList.toggle('active', mode === 'search'); + searchTagsBtn?.classList.toggle('active', mode === 'tags'); + searchNotesBtn?.classList.toggle('active', mode === 'notes'); + + searchAllBtn?.setAttribute('aria-pressed', String(mode === 'search')); + searchTagsBtn?.setAttribute('aria-pressed', String(mode === 'tags')); + searchNotesBtn?.setAttribute('aria-pressed', String(mode === 'notes')); if (searchModalInput) { searchModalInput.name = mode === 'tags' ? 'searchtags' : 'searchterm'; + searchModalInput.placeholder = getSearchHint(mode); // Re-run search with new mode performSearch(searchModalInput.value); } } searchToggleBtns.forEach((btn) => { - btn.addEventListener('click', openSearch); + btn.addEventListener('click', () => openSearch('search')); }); // Close search on overlay click @@ -367,7 +417,25 @@ document.addEventListener('DOMContentLoaded', () => { }); searchAllBtn?.addEventListener('click', (e) => { - // Only prevent default if not submitting + e.preventDefault(); + setSearchMode('search'); + }); + + searchNotesBtn?.addEventListener('click', (e) => { + e.preventDefault(); + setSearchMode('notes'); + }); + + searchForm?.addEventListener('submit', (e) => { + if (searchMode === 'notes') { + e.preventDefault(); + if (selectedIndex < 0) { + updateSelection(0); + } + navigateToSelected(); + return; + } + if (selectedIndex >= 0) { e.preventDefault(); navigateToSelected(); @@ -425,6 +493,10 @@ document.addEventListener('DOMContentLoaded', () => { // If an item is selected, navigate to it if (selectedIndex >= 0 && navigateToSelected()) { e.preventDefault(); + } else if (searchMode === 'notes') { + e.preventDefault(); + updateSelection(0); + navigateToSelected(); } // Otherwise, submit the form normally break; @@ -435,14 +507,19 @@ document.addEventListener('DOMContentLoaded', () => { // S to open search (when not typing) if (!isTyping && !e.ctrlKey && !e.metaKey && !e.altKey && (e.key === 's' || e.key === 'S')) { e.preventDefault(); - openSearch(); + openSearch('search'); } // T to open search directly in tags mode (when not typing) if (!isTyping && !e.ctrlKey && !e.metaKey && !e.altKey && (e.key === 't' || e.key === 'T')) { e.preventDefault(); - openSearch(); - setSearchMode('tags'); + openSearch('tags'); + } + + // N to open search directly in notes mode (when not typing) + if (!isTyping && !e.ctrlKey && !e.metaKey && !e.altKey && (e.key === 'n' || e.key === 'N')) { + e.preventDefault(); + openSearch('notes'); } }); diff --git a/shaarli-pro/linklist.html b/shaarli-pro/linklist.html index bc796a0..33dfb31 100644 --- a/shaarli-pro/linklist.html +++ b/shaarli-pro/linklist.html @@ -12,6 +12,10 @@ {loop="$plugin_start_zone"} {$value} {/loop} + {$active_search_tags=[]} + {if="!empty($search_tags)"} + {$active_search_tags=tags_str2array($search_tags, $tags_separator)} + {/if}
{include="linklist.paging"}
@@ -32,8 +36,7 @@ {if="!empty($search_tags)"}
{$result_count} résultat(s) tagué(s) - {$exploded_tags=tags_str2array($search_tags, $tags_separator)} - {loop="$exploded_tags"} + {loop="$active_search_tags"} {$value} {$value.description}
{/if}