@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&family=Lora:ital,wght@0,400;0,600;1,400&display=swap"); /* ===== RESET ===== */ *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } /* ── Editor save dot state colors ── */ :root { --ok: #34d399; --warn: #fbbf24; --ai: #8b5cf6; --err: #f87171; } /* ===== THEME — DARK (fallback default, no data-theme) ===== */ :root { --bg-primary: #0f1117; --bg-secondary: #161b22; --bg-sidebar: #13161d; --bg-hover: #1f2430; --border: #21262d; --text-primary: #e6edf3; --text-secondary: #8b949e; --text-muted: #484f58; --accent: #58a6ff; --accent-green: #3fb950; --tag-bg: #1f2a3a; --tag-text: #79c0ff; --code-bg: #161b22; --search-bg: #21262d; --scrollbar: #30363d; --resize-handle: #30363d; --overlay-bg: rgba(0, 0, 0, 0.5); --danger: #ff7b72; --danger-bg: #3d1a18; --success: #3fb950; --success-bg: #1a3d1f; --accent-card: #58a6ff; --accent-bg: #1f2a3a; --accent-text: #79c0ff; --green: #3fb950; --green-bg: #1a3d1f; --purple: #a371f7; --purple-bg: #2d1b4e; --surface: #161b22; --surface2: #0f1117; --surface3: #0d0f14; --border-md: #30363d; --text: #e6edf3; --text-2: #8b949e; --text-3: #484f58; --mono: "JetBrains Mono", monospace; --radius: 6px; --radius-lg: 10px; } /* ===== THEME — DARK (explicit) ===== */ :root[data-theme="dark"] { --bg-primary: #0f1117; --bg-secondary: #161b22; --bg-sidebar: #13161d; --bg-hover: #1f2430; --border: #21262d; --text-primary: #e6edf3; --text-secondary: #8b949e; --text-muted: #484f58; --accent: #58a6ff; --accent-green: #3fb950; --tag-bg: #1f2a3a; --tag-text: #79c0ff; --code-bg: #161b22; --search-bg: #21262d; --scrollbar: #30363d; --resize-handle: #30363d; --overlay-bg: rgba(0, 0, 0, 0.5); --danger: #ff7b72; --danger-bg: #3d1a18; --success: #3fb950; --success-bg: #1a3d1f; /* Accent Card variables */ --accent-card: #58a6ff; --accent-bg: #1f2a3a; --accent-text: #79c0ff; --green: #3fb950; --green-bg: #1a3d1f; --purple: #a371f7; --purple-bg: #2d1b4e; --surface: #161b22; --surface2: #0f1117; --surface3: #0d0f14; --border-md: #30363d; --text: #e6edf3; --text-2: #8b949e; --text-3: #484f58; --mono: "JetBrains Mono", monospace; --radius: 6px; --radius-lg: 10px; } /* ===== THEME — LIGHT ===== */ :root[data-theme="light"] { --bg-primary: #ffffff; --bg-secondary: #f6f8fa; --bg-sidebar: #f0f2f5; --bg-hover: #e8ecf0; --border: #d0d7de; --text-primary: #1f2328; --text-secondary: #57606a; --text-muted: #9198a1; --accent: #0969da; --accent-green: #1a7f37; --tag-bg: #ddf4ff; --tag-text: #0969da; --code-bg: #f6f8fa; --search-bg: #ffffff; --scrollbar: #d0d7de; --resize-handle: #d0d7de; --overlay-bg: rgba(0, 0, 0, 0.3); --danger: #cf222e; --danger-bg: #ffebe9; --success: #1a7f37; --success-bg: #dafbe1; /* Accent Card variables */ --accent-card: #4f6ef7; --accent-bg: #eef1fe; --accent-text: #2540c9; --green: #1a7f50; --green-bg: #eaf5ee; --purple: #6b40c4; --purple-bg: #f1ecfd; --surface: #ffffff; --surface2: #f2f1ef; --surface3: #ebe9e6; --border-md: rgba(0, 0, 0, 0.13); --text: #1a1917; --text-2: #6b6a67; --text-3: #a09e9b; --mono: "JetBrains Mono", monospace; --radius: 6px; --radius-lg: 10px; } /* ===== BASE ===== */ html { font-size: 16px; scroll-behavior: smooth; } body { font-family: "Lora", Georgia, serif; background: var(--bg-primary); color: var(--text-primary); line-height: 1.7; transition: background 200ms ease, color 200ms ease; overflow: hidden; height: 100vh; } a { color: var(--accent); text-decoration: none; } a:hover { text-decoration: underline; } /* ===== LAYOUT ===== */ .app-container { display: flex; flex-direction: column; height: 100vh; } /* --- Header --- */ .header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 20px; background: var(--bg-secondary); border-bottom: 1px solid var(--border); flex-shrink: 0; z-index: 100; transition: background 200ms ease; } .header-left { display: flex; align-items: center; gap: 12px; flex: 0 1 auto; } .header-center { display: flex; justify-content: center; flex: 1 1 auto; max-width: 600px; } .header-right { display: flex; align-items: center; justify-content: flex-end; gap: 12px; flex: 0 1 auto; } .vault-context-indicator { display: flex; align-items: center; gap: 6px; padding: 6px 12px; border: 1px solid var(--border); border-radius: 8px; font-family: "JetBrains Mono", monospace; font-size: 0.75rem; font-weight: 600; cursor: default; transition: all 200ms ease; /* Default: neutral (overridden by classes below) */ background: var(--bg-tertiary); color: var(--text-muted); } .vault-context-indicator:hover { filter: brightness(1.15); } .vault-context-indicator i { opacity: 0.8; } /* ── Offline Indicator ── */ .offline-indicator { position: relative; display: flex; align-items: center; justify-content: center; margin-right: 8px; cursor: default; } .offline-indicator.offline i { color: var(--warning, #f59e0b); opacity: 1; } .offline-pending { position: absolute; top: -4px; right: -8px; background: var(--danger, #ef4444); color: #fff; font-size: 0.6rem; font-weight: 700; min-width: 14px; height: 14px; line-height: 14px; text-align: center; border-radius: 7px; padding: 0 3px; } /* ── Offline Search Result Badge ── */ .search-result-offline-badge { display: inline-block; background: var(--warning, #f59e0b); color: #000; font-size: 0.55rem; font-weight: 700; padding: 1px 5px; border-radius: 3px; margin-left: 6px; vertical-align: middle; text-transform: uppercase; } /* ── Conflict Resolution Modal ── */ .conflict-modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.6); z-index: 9999; display: flex; align-items: center; justify-content: center; } .conflict-modal { background: var(--bg-card, #1e1e2e); border: 1px solid var(--border, #333); border-radius: 8px; padding: 24px; max-width: 600px; width: 90%; max-height: 80vh; overflow-y: auto; } .conflict-modal h3 { margin: 0 0 8px; font-size: 1.1rem; } .conflict-modal p { color: var(--text-muted, #888); font-size: 0.85rem; margin: 0 0 16px; } .conflict-modal-actions { display: flex; gap: 8px; justify-content: flex-end; } .conflict-modal-actions button { padding: 8px 16px; border-radius: 6px; border: 1px solid var(--border, #333); background: var(--bg-input, #2a2a3c); color: var(--text, #ddd); cursor: pointer; font-size: 0.85rem; } .conflict-modal-actions .btn-primary { background: var(--accent, #3b82f6); border-color: var(--accent); color: #fff; } /* All vaults — blue */ .vault-ctx-all { background: color-mix(in srgb, #3b82f6 14%, transparent) !important; border-color: color-mix(in srgb, #3b82f6 30%, var(--border)) !important; color: #60a5fa !important; } .vault-ctx-all i { color: #60a5fa !important; } /* Specific vault — mauve/violet */ .vault-ctx-vault { background: color-mix(in srgb, #a855f7 14%, transparent) !important; border-color: color-mix(in srgb, #a855f7 30%, var(--border)) !important; color: #c084fc !important; } .vault-ctx-vault i { color: #c084fc !important; } /* Directory — amber/yellow */ .vault-ctx-dir { background: color-mix(in srgb, #f59e0b 14%, transparent) !important; border-color: color-mix(in srgb, #f59e0b 30%, var(--border)) !important; color: #fbbf24 !important; } .vault-ctx-dir i { color: #fbbf24 !important; } .hamburger-btn { display: none; background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 4px; align-items: center; justify-content: center; flex-shrink: 0; } .hamburger-btn:hover { color: var(--accent); } .sidebar-toggle-btn { display: flex; background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 4px; align-items: center; justify-content: center; flex-shrink: 0; transition: color 200ms ease; } .sidebar-toggle-btn:hover { color: var(--accent); } .sidebar-toggle-btn.active { color: var(--accent); } .header-logo { font-family: "JetBrains Mono", monospace; font-weight: 700; font-size: 1.15rem; color: var(--accent); white-space: nowrap; display: flex; align-items: center; gap: 8px; cursor: pointer; transition: opacity 200ms ease; text-decoration: none; } .header-logo:hover { opacity: 0.8; text-decoration: none; } .search-wrapper { width: 100%; max-width: 620px; position: relative; display: flex; flex-direction: column; gap: 4px; } .search-wrapper .search-icon { position: absolute; left: 10px; top: 14px; color: var(--text-secondary); pointer-events: none; z-index: 1; } .search-input-wrapper { position: relative; flex: 1; display: flex; align-items: center; } .search-input-wrapper input { flex: 1; min-width: 0; padding: 8px 14px 8px 38px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-secondary); color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.9rem; outline: none; transition: border-color 200ms ease, background 200ms ease; } .search-input-wrapper input:focus { border-color: var(--accent); } .search-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; padding-left: 4px; } .search-btn { display: flex; align-items: center; justify-content: center; min-width: 26px; height: 26px; padding: 0 4px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; font-family: "JetBrains Mono", monospace; font-size: 0.7rem; font-weight: 600; transition: all 150ms ease; flex-shrink: 0; } .search-btn:hover { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--bg-secondary)); } .search-btn.active { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 20%, var(--bg-secondary)); color: var(--accent); } .header-menu { position: relative; } .header-menu-btn { background: transparent; border: 1px solid color-mix(in srgb, var(--accent) 22%, var(--border)); border-radius: 12px; padding: 10px 12px; cursor: pointer; color: var(--text-secondary); display: flex; align-items: center; justify-content: center; transition: color 200ms ease, border-color 200ms ease, background 200ms ease, transform 180ms ease; } .header-menu-btn:hover { color: var(--accent); border-color: var(--accent); transform: translateY(-1px); } .header-menu-btn.active { color: var(--accent); border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); } /* Version badge in header — always visible */ .version-badge { display: inline-block; font-size: 11px; color: var(--text-secondary); font-weight: 500; padding: 3px 10px; border-radius: 10px; background: color-mix(in srgb, var(--text-secondary) 10%, transparent); border: 1px solid color-mix(in srgb, var(--text-secondary) 20%, transparent); font-family: var(--font-mono, monospace); white-space: nowrap; cursor: default; user-select: none; } .header-menu-dropdown { display: none; position: absolute; top: calc(100% + 8px); right: 0; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 16px; box-shadow: 0 16px 36px rgba(0, 0, 0, 0.28); min-width: 260px; z-index: 100; padding: 8px; } .header-menu-dropdown.active { display: block; } .menu-list { display: flex; flex-direction: column; } .menu-list-row { width: 100%; display: grid; grid-template-columns: 28px minmax(0, 1fr); align-items: center; gap: 8px; padding: 4px 8px; border-radius: 6px; text-align: left; } .menu-list-button { border: none; background: transparent; cursor: pointer; transition: background 160ms ease, color 160ms ease; } .menu-list-button:hover, .menu-list-select-row:hover { background: var(--bg-hover); } .menu-list-button + .menu-list-button, .menu-list-select-row + .menu-list-button { margin-top: 2px; } .menu-list-icon { width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--accent); } .menu-list-content { display: flex; flex-direction: column; gap: 1px; min-width: 0; } .menu-list-title { font-family: "JetBrains Mono", monospace; font-size: 0.8rem; font-weight: 600; color: var(--text-primary); } .menu-list-subtitle { font-size: 0.7rem; color: var(--text-muted); } .menu-select { width: 100%; padding: 4px 22px 4px 0; border: none; border-radius: 0; background: inherit; color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.78rem; font-weight: 500; outline: none; cursor: pointer; transition: color 160ms ease; color-scheme: dark; background-color: transparent; -webkit-appearance: none; -moz-appearance: none; appearance: none; } .menu-select option { background-color: var(--bg-secondary); color: var(--text-primary); } [data-theme="dark"] .menu-select, [data-theme="dark"] .menu-select option { background-color: #1e1e1e; color: #e0e0e0; } .menu-select:hover, .menu-select:focus { color: var(--accent); } .menu-list-select { margin-top: 1px; } /* Force dark mode on all select elements */ select { color-scheme: dark; } [data-theme="dark"] select, [data-theme="dark"] select option { background-color: #161b22 !important; color: #e6edf3 !important; } [data-theme="light"] select, [data-theme="light"] select option { background-color: #f6f8fa !important; color: #1f2328 !important; } /* Custom Dropdown Styles */ .custom-dropdown { position: relative; width: 100%; } .custom-dropdown-trigger { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 8px; color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.8rem; cursor: pointer; transition: border-color 200ms ease, background 200ms ease; } .custom-dropdown-trigger:hover { border-color: var(--accent); background: var(--bg-hover); } .custom-dropdown-trigger[aria-expanded="true"] { border-color: var(--accent); } .custom-dropdown-selected { flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .custom-dropdown-menu { display: none; position: absolute; top: calc(100% + 4px); left: 0; right: 0; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 6px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); max-height: 240px; overflow-y: auto; z-index: 1000; list-style: none; padding: 3px; margin: 0; } .custom-dropdown.open .custom-dropdown-menu { display: block; } .custom-dropdown-option { padding: 6px 10px; border-radius: 4px; cursor: pointer; font-family: "JetBrains Mono", monospace; font-size: 0.8rem; color: var(--text-primary); transition: background 150ms ease, color 150ms ease; } .custom-dropdown-option:hover, .custom-dropdown-option:focus { background: var(--bg-hover); color: var(--accent); } .custom-dropdown-option.selected { background: color-mix(in srgb, var(--accent) 15%, transparent); color: var(--accent); } /* Sidebar dropdown specific */ .sidebar-dropdown { padding: 0 16px 12px; position: relative; } .sidebar-dropdown .custom-dropdown-menu { position: fixed; z-index: 10000; left: auto; right: auto; width: auto; min-width: 200px; } .sidebar-dropdown .custom-dropdown-trigger { background: var(--bg-sidebar); } /* Menu list dropdown specific */ .menu-list-select-row .custom-dropdown { margin-top: 4px; } .menu-list-select-row .custom-dropdown-trigger { padding: 6px 10px; font-size: 0.78rem; background: var(--bg-primary); } .main-body { display: flex; flex: 1; overflow: hidden; position: relative; } /* --- Mobile overlay --- */ .sidebar-overlay { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: var(--overlay-bg); z-index: 199; } .sidebar-overlay.active { display: block; } /* --- Sidebar --- */ .sidebar { width: 280px; min-width: 200px; max-width: 500px; background: var(--bg-sidebar); border-right: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; transition: background 200ms ease, transform 300ms ease; flex-shrink: 0; } .sidebar.hidden { transform: translateX(-100%); width: 0; min-width: 0; border-right: none; } /* --- Sidebar filter --- */ .sidebar-filter { padding: 10px 12px; border-bottom: 1px solid var(--border); position: relative; flex-shrink: 0; display: flex; align-items: center; } .sidebar-filter-input-wrapper { position: relative; flex: 1; display: flex; align-items: center; } .sidebar-filter-input-wrapper input { width: 100%; padding: 6px 10px 6px 32px; border: 1px solid var(--border); border-radius: 6px; background: var(--search-bg); color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.78rem; outline: none; transition: border-color 200ms ease; } .sidebar-filter-input-wrapper input:focus { border-color: var(--accent); } .sidebar-filter-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--text-muted); pointer-events: none; z-index: 1; } .sidebar-filter-actions { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); display: flex; align-items: center; gap: 4px; } .sidebar-filter-btn { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; font-family: "JetBrains Mono", monospace; font-size: 0.65rem; font-weight: 600; transition: all 150ms ease; padding: 0; flex-shrink: 0; } .sidebar-filter-btn:hover { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--bg-secondary)); } .sidebar-filter-btn.active { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 20%, var(--bg-secondary)); color: var(--accent); } /* --- Sidebar tabs --- */ .sidebar-tabs { display: flex; flex-shrink: 0; border-bottom: 1px solid var(--border); padding: 0 8px; gap: 2px; background: var(--bg-sidebar); } .sidebar-tab { flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 4px 6px; border: none; border-bottom: 2px solid transparent; background: transparent; color: var(--text-muted); cursor: pointer; transition: color 150ms ease, border-color 150ms ease; margin-bottom: -1px; } .sidebar-tab:hover { color: var(--text-primary); } .sidebar-tab.active { color: var(--accent); border-bottom-color: var(--accent); } .sidebar-tab .icon { flex-shrink: 0; color: inherit; } /* --- Sidebar tab panels --- */ .sidebar-tab-panel { display: none; flex: 1 1 auto; min-height: 0; overflow-y: auto; scroll-behavior: smooth; flex-direction: column; } .sidebar-tab-panel.active { display: flex; flex-direction: column; } .sidebar-tab-panel::-webkit-scrollbar { width: 6px; } .sidebar-tab-panel::-webkit-scrollbar-thumb { background: var(--scrollbar); border-radius: 3px; } #sidebar-panel-vaults .sidebar-dropdown { padding: 10px 12px 6px; } .tree-item { display: flex; align-items: center; gap: 6px; padding: 5px 16px; font-family: "JetBrains Mono", monospace; font-size: 0.82rem; color: var(--text-secondary); cursor: pointer; border-radius: 0; transition: background 120ms ease, color 120ms ease; white-space: nowrap; min-width: 0; /* Allow flex item to shrink */ } .tree-item > .tree-item-text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; } .tree-item:hover { background: var(--bg-hover); color: var(--text-primary); } .tree-item > .badge-small { margin-left: 4px; } .tree-item.active { background: var(--bg-hover); color: var(--accent); } .tree-item.focused { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--text-primary); box-shadow: inset 2px 0 0 var(--accent); } .tree-item.path-selected { background: color-mix(in srgb, var(--accent) 20%, transparent); color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent), inset 2px 0 0 var(--accent); border-radius: 6px; animation: pathPulse 1.5s ease-out; } @keyframes pathPulse { 0% { background: color-mix(in srgb, var(--accent) 40%, transparent); } 100% { background: color-mix(in srgb, var(--accent) 20%, transparent); } } .tree-item.filtered-out { display: none; } .tree-item .icon { width: 16px; height: 16px; flex-shrink: 0; color: var(--accent); } .tree-item.active .icon { color: var(--accent); } .tree-item.vault-item .icon { color: var(--accent); } .tree-item-action-btn { margin-left: auto; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-secondary); color: var(--accent); cursor: pointer; opacity: 1; pointer-events: auto; transition: opacity 140ms ease, color 140ms ease, background 140ms ease, border-color 140ms ease; flex-shrink: 0; z-index: 1; } .tree-item-action-btn:hover, .tree-item-action-btn:focus-visible { background: color-mix(in srgb, var(--accent) 10%, transparent); border-color: color-mix(in srgb, var(--accent) 25%, var(--border)); color: var(--accent); outline: none; } /* --------------------------------------------------------------------------- Drag & Drop — tree items --------------------------------------------------------------------------- */ /* Source item being dragged */ .tree-item.drag-source { opacity: 0.35; outline: 1px dashed var(--border); } /* Valid drop targets during drag — subtle pulse indicator */ .tree-item.drag-valid-target { outline: 1px dashed color-mix(in srgb, var(--accent) 30%, transparent); outline-offset: -1px; } /* Active drop target (hovering over) */ .tree-item.drag-over { background: color-mix(in srgb, var(--accent) 18%, transparent) !important; outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 4px; } /* Vault item as drop target */ .tree-item.vault-item.drag-over { background: color-mix(in srgb, var(--accent) 15%, transparent) !important; outline: 2px solid var(--accent); outline-offset: -2px; } /* Global Drag & Drop Overlay (#89) */ .obsigate-drop-overlay { position: fixed; inset: 0; z-index: 99999; display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: opacity 0.2s cubic-bezier(0.16, 1, 0.3, 1); } .obsigate-drop-overlay.active { opacity: 1; pointer-events: auto; } .obsigate-drop-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.65); backdrop-filter: blur(4px); } .obsigate-drop-modal { position: relative; z-index: 1; background: var(--bg-primary, #1e1e2e); border: 1px solid var(--border-color, #313244); border-radius: 12px; padding: 24px; width: min(600px, 90vw); box-shadow: 0 16px 32px rgba(0, 0, 0, 0.4); text-align: center; } .obsigate-drop-title { margin: 0 0 20px 0; font-size: 1.25rem; font-weight: 600; color: var(--text-normal, #cdd6f4); } .obsigate-drop-zones { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } .obsigate-drop-zone { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 28px 16px; border: 2px dashed var(--border-color, #45475a); border-radius: 8px; background: var(--bg-secondary, #181825); cursor: pointer; transition: all 0.15s ease; } .obsigate-drop-zone.hover { border-color: var(--accent, #89b4fa); background: color-mix(in srgb, var(--accent, #89b4fa) 15%, var(--bg-secondary, #181825)); transform: scale(1.02); } .obsigate-drop-zone-icon { font-size: 2.5rem; margin-bottom: 12px; } .obsigate-drop-zone-title { font-size: 1rem; font-weight: 600; color: var(--text-normal, #cdd6f4); margin-bottom: 6px; } .bookslm-composer.bookslm-drop-over { outline: 2px dashed var(--accent, #89b4fa); outline-offset: 2px; background: color-mix(in srgb, var(--accent, #89b4fa) 10%, var(--bg-secondary, #181825)); } .tree-children { padding-left: 16px; overflow: hidden; } .tree-children.collapsed { display: none; } .tree-children.filtered-out { display: none; } .filter-results-header { margin-top: 8px; } .filter-results-group { display: flex; flex-direction: column; gap: 4px; padding: 4px 0 10px 12px; } .filter-result-item { align-items: flex-start; white-space: normal; overflow: visible; border-radius: 6px; } .filter-result-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; white-space: normal; } .filter-result-primary { color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .filter-result-secondary { color: var(--text-muted); font-size: 0.75rem; word-break: break-all; opacity: 0.8; } .sidebar-filter-empty { padding: 12px 16px; color: var(--text-muted); font-size: 0.85rem; } .filter-highlight { background: color-mix(in srgb, var(--accent) 22%, transparent); color: var(--accent); padding: 0 2px; border-radius: 4px; } /* --- Tag Cloud --- */ .tag-cloud { display: flex; flex-wrap: wrap; gap: 6px; padding: 14px 16px 16px; align-content: flex-start; } .tag-item { display: inline-block; padding: 2px 8px; background: var(--tag-bg); color: var(--tag-text); border-radius: 4px; font-family: "JetBrains Mono", monospace; cursor: pointer; transition: opacity 150ms ease; line-height: 1.4; } .tag-item:hover { opacity: 0.8; } .tag-item.filtered-out { display: none; } /* --- Sidebar resize handle (horizontal) --- */ .sidebar-resize-handle { width: 5px; cursor: ew-resize; background: transparent; flex-shrink: 0; transition: background 150ms ease, opacity 300ms ease; z-index: 10; } .sidebar-resize-handle:hover, .sidebar-resize-handle.active { background: var(--accent); opacity: 0.5; } .sidebar-resize-handle.hidden { width: 0; opacity: 0; pointer-events: none; } /* --- Content Wrapper (tabs + content) --- */ .content-wrapper { flex: 1; display: flex; flex-direction: column; min-width: 0; overflow: hidden; position: relative; } /* --- Multi-Pane Grid (Split View #75) --- */ .pane-grid { flex: 1; display: grid; overflow: hidden; min-width: 0; min-height: 0; } .pane-container { display: flex; flex-direction: column; overflow: hidden; min-width: 0; min-height: 0; border: 2px solid transparent; transition: border-color 150ms ease; position: relative; } .pane-container.pane-active { border-color: var(--accent); } .pane-container .tab-bar.pane-tab-bar { flex-shrink: 0; } .pane-container .content-area.pane-content { flex: 1; overflow-y: auto; overflow-x: hidden; padding: clamp(12px, 2vw, 24px) clamp(12px, 3vw, 24px) 40px; } .pane-resize-handle { width: 4px; background: var(--border); transition: background 150ms ease; position: relative; z-index: 2; flex-shrink: 0; } .pane-resize-handle:hover { background: var(--accent); } .pane-resize-handle::after { content: ''; position: absolute; top: 10%; bottom: 10%; left: 50%; transform: translateX(-50%); width: 2px; background: var(--accent); opacity: 0; transition: opacity 150ms ease; } .pane-resize-handle:hover::after { opacity: 1; } /* Pane active state */ .pane-container.pane-active { outline: none; border: 2px solid var(--accent); } /* --- Drop zone indicators for drag-to-split --- */ .pane-drop-zone-indicator { position: absolute; z-index: 10; background: var(--accent); opacity: 0.4; pointer-events: none; transition: opacity 100ms ease; } .pane-drop-zone-indicator.pane-drop-zone-right { top: 0; right: 0; width: 25%; height: 100%; } .pane-drop-zone-indicator.pane-drop-zone-bottom { bottom: 0; left: 0; width: 100%; height: 25%; } /* Tab bar drop target highlight */ .tab-bar.drop-target { background: var(--accent); opacity: 0.15; outline: 2px dashed var(--accent); outline-offset: -2px; } /* Responsive: disable split view below 768px */ @media (max-width: 768px) { .pane-grid { display: flex !important; flex-direction: column !important; } .pane-grid .pane-container:not(:first-child) { display: none; } .pane-grid .pane-resize-handle { display: none; } .pane-container.pane-active { border-color: transparent; } } /* --- Content Area --- */ .content-area { flex: 1; overflow-y: auto; overflow-x: hidden; padding: clamp(16px, 3vw, 40px) clamp(16px, 4vw, 40px) 60px; transition: background 200ms ease, margin 300ms ease; min-width: 0; } /* Center content when sidebar is hidden */ .sidebar.hidden ~ .content-wrapper .content-area { margin: 0 auto; max-width: 1200px; } /* Full-bleed viewers (PDF, images, Excalidraw) must use the whole width when the navigation sidebar is hidden instead of the centered reading column. */ .sidebar.hidden ~ .content-wrapper .content-area:has(.pdf-viewer-container), .sidebar.hidden ~ .content-wrapper .content-area:has(.image-viewer-container), .sidebar.hidden ~ .content-wrapper .content-area:has(iframe[src*="excalidraw-editor.html"]) { margin: 0; max-width: none; } .content-area::-webkit-scrollbar { width: 8px; } .content-area::-webkit-scrollbar-thumb { background: var(--scrollbar); border-radius: 4px; } /* --- Right Sidebar Resize Handle --- */ .right-sidebar-resize-handle { width: 5px; cursor: ew-resize; background: transparent; flex-shrink: 0; transition: background 150ms ease, opacity 300ms ease; z-index: 10; } .right-sidebar-resize-handle:hover, .right-sidebar-resize-handle.active { background: var(--accent); opacity: 0.5; } .right-sidebar-resize-handle.hidden { width: 0; opacity: 0; pointer-events: none; } /* --- Right Sidebar (Outline/TOC) --- */ .right-sidebar { width: 280px; min-width: 200px; max-width: 400px; background: var(--bg-sidebar); border-left: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; transition: background 200ms ease, transform 300ms ease, width 300ms ease; flex-shrink: 0; } .right-sidebar.hidden { transform: translateX(100%); width: 0; min-width: 0; border-left: none; } /* Right sidebar header */ .right-sidebar-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--bg-sidebar); flex-shrink: 0; } .right-sidebar-title { font-family: "JetBrains Mono", monospace; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); margin: 0; } .right-sidebar-toggle-btn { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; background: transparent; border: 1px solid var(--border); border-radius: 4px; color: var(--text-secondary); cursor: pointer; transition: all 150ms ease; } .right-sidebar-toggle-btn:hover { background: var(--bg-hover); border-color: var(--accent); color: var(--accent); } .right-sidebar-toggle-btn i { transition: transform 200ms ease; } .right-sidebar.hidden .right-sidebar-toggle-btn i { transform: rotate(180deg); } /* Outline panel */ .outline-panel { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 8px 0; min-height: 0; } .outline-panel::-webkit-scrollbar { width: 6px; } .outline-panel::-webkit-scrollbar-thumb { background: var(--scrollbar); border-radius: 3px; } .outline-list { display: flex; flex-direction: column; gap: 2px; padding: 0 8px; } .outline-item { display: flex; align-items: center; padding: 8px 12px; border-radius: 6px; font-family: "JetBrains Mono", monospace; font-size: 0.82rem; color: var(--text-secondary); cursor: pointer; transition: all 150ms ease; position: relative; text-decoration: none; line-height: 1.4; word-break: break-word; } .outline-item:hover { background: var(--bg-hover); color: var(--text-primary); } .outline-item.active { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); font-weight: 500; } .outline-item.active::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--accent); border-radius: 0 2px 2px 0; } /* Heading levels */ .outline-item.level-2 { font-weight: 600; font-size: 0.85rem; padding-left: 12px; } .outline-item.level-3 { font-weight: 400; font-size: 0.8rem; padding-left: 28px; color: var(--text-muted); } .outline-item.level-3:hover { color: var(--text-secondary); } .outline-item.level-3.active { color: var(--accent); } /* Empty state */ .outline-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px 20px; gap: 12px; color: var(--text-muted); font-size: 0.85rem; text-align: center; } /* Reading progress */ .reading-progress { padding: 12px 16px; border-top: 1px solid var(--border); background: var(--bg-sidebar); flex-shrink: 0; } .reading-progress-bar { width: 100%; height: 6px; background: color-mix(in srgb, var(--border) 50%, transparent); border-radius: 3px; overflow: hidden; margin-bottom: 8px; } .reading-progress-fill { height: 100%; background: var(--accent); border-radius: 3px; transition: width 150ms ease; width: 0%; } .reading-progress-text { font-family: "JetBrains Mono", monospace; font-size: 0.75rem; font-weight: 600; color: var(--text-muted); text-align: center; } /* Welcome */ .welcome { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; color: var(--text-muted); text-align: center; gap: 12px; } .welcome h2 { font-family: "JetBrains Mono", monospace; font-size: 1.6rem; color: var(--text-secondary); } .welcome p { font-size: 0.95rem; max-width: 400px; } /* Breadcrumb */ .breadcrumb { font-family: "JetBrains Mono", monospace; font-size: 0.78rem; color: var(--text-muted); margin-bottom: 12px; display: flex; align-items: center; flex-wrap: wrap; gap: 4px; } .breadcrumb span { cursor: pointer; color: var(--text-secondary); transition: color 120ms ease; } .breadcrumb span:hover { color: var(--accent); } .breadcrumb .sep { cursor: default; color: var(--text-muted); } .breadcrumb .sep:hover { color: var(--text-muted); } /* File header */ .file-header { margin-bottom: 8px; } /* #115 — sticky document action bar: stays visible while long content scrolls. A direct child of `.content-area` (the scroll container), opaque so the text scrolling underneath never bleeds through. */ .file-toolbar { position: sticky; top: 0; z-index: 30; margin: 0 0 16px; padding: 8px 0; background: var(--bg-primary); border-bottom: 1px solid var(--border); } .file-toolbar .file-actions { margin-top: 0; } .file-title { font-family: "JetBrains Mono", monospace; font-size: 1.6rem; font-weight: 700; margin-bottom: 8px; } .file-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; } .file-tag { display: inline-block; padding: 2px 8px; background: var(--tag-bg); color: var(--tag-text); border-radius: 4px; font-family: "JetBrains Mono", monospace; font-size: 0.75rem; margin-right: 6px; margin-bottom: 4px; cursor: pointer; transition: opacity 150ms ease, transform 100ms ease; } .file-tag:hover { opacity: 0.8; transform: translateY(-1px); } .file-actions { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; } /* Separateur vertical entre groupes d'actions (#90) */ .file-actions .action-sep { align-self: stretch; width: 1px; min-height: 20px; margin: 2px 4px; background: var(--border-md, var(--border)); flex-shrink: 0; } .btn-action { font-family: "JetBrains Mono", monospace; font-size: 0.75rem; padding: 4px 10px; border: 1px solid var(--border); border-radius: 6px; background: transparent; color: var(--text-secondary); cursor: pointer; transition: color 150ms ease, border-color 150ms ease; display: inline-flex; align-items: center; gap: 4px; } .btn-action:hover { color: var(--accent); border-color: var(--accent); } .btn-action.active { color: var(--accent); border-color: var(--accent); background: var(--tag-bg); } /* ===== FRONTMATTER — ACCENT CARD ===== */ /* Frontmatter section wrapper */ .fm-section { margin-bottom: 20px; } /* Header toggle */ .fm-header { font-family: "JetBrains Mono", monospace; font-size: 0.78rem; color: var(--text-muted); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; margin-bottom: 12px; user-select: none; transition: color 150ms ease; } .fm-header:hover { color: var(--text-secondary); } /* Chevron icon */ .fm-chevron { transition: transform 0.2s; display: inline-flex; align-items: center; justify-content: center; } .fm-chevron.open { transform: rotate(0deg); } .fm-chevron.closed { transform: rotate(-90deg); } /* Accent Card main container */ .ac-card { border: 1px solid var(--border-md); border-left: 3px solid var(--accent-card); border-radius: 0 var(--radius-lg) var(--radius-lg) 0; background: var(--surface); overflow: hidden; } /* ZONE 1 — Top strip */ .ac-top { padding: 12px 16px 10px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } .ac-title { font-size: 14px; font-weight: 600; color: var(--text); font-family: var(--mono); letter-spacing: -0.01em; flex-shrink: 0; } .ac-badge { padding: 2px 9px; border-radius: 99px; font-size: 11px; font-weight: 500; display: inline-flex; align-items: center; gap: 4px; } .ac-badge.green { background: var(--green-bg); color: var(--green); } .ac-badge.blue { background: var(--accent-bg); color: var(--accent-text); } .ac-badge.purple { background: var(--purple-bg); color: var(--purple); } .ac-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.7; } /* ZONE 2 — Body 2 columns */ .ac-body { display: grid; grid-template-columns: 1fr 1fr; gap: 0; } .ac-col { padding: 12px 16px; } .ac-col + .ac-col { border-left: 1px solid var(--border); } .ac-row { display: flex; align-items: baseline; gap: 6px; padding: 4px 0; font-size: 12.5px; } .ac-row + .ac-row { border-top: 1px solid var(--border); } .ac-k { color: var(--text-3); font-size: 11px; font-family: var(--mono); min-width: 110px; flex-shrink: 0; } .ac-v { color: var(--text); font-weight: 500; font-size: 12.5px; } .ac-v.mono { font-family: var(--mono); font-weight: 400; color: var(--text-2); font-size: 11px; } .ac-v.muted { color: var(--text-3); font-weight: 400; } /* ZONE 3 — Tags row */ .ac-tags-row { padding: 10px 16px; border-top: 1px solid var(--border); display: flex; align-items: center; gap: 10px; } .ac-tags-k { font-size: 11px; font-family: var(--mono); color: var(--text-3); flex-shrink: 0; } .ac-tags-wrap { display: flex; flex-wrap: wrap; gap: 4px; } .ac-tag { padding: 2px 9px; border-radius: 99px; font-size: 11px; font-weight: 500; background: var(--accent-bg); color: var(--accent-text); border: 1px solid rgba(79, 110, 247, 0.18); } /* ZONE 4 — Flags row */ .ac-flags-row { padding: 9px 16px; border-top: 1px solid var(--border); background: var(--surface2); display: flex; flex-wrap: wrap; gap: 6px; align-items: center; } .ac-flags-k { font-size: 11px; font-family: var(--mono); color: var(--text-3); margin-right: 2px; } .flag-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: var(--radius); font-size: 11px; font-weight: 500; border: 1px solid var(--border-md); } .flag-chip.on { background: var(--green-bg); color: var(--green); border-color: rgba(26, 127, 80, 0.2); } .flag-chip.off { background: var(--surface3); color: var(--text-3); } .flag-dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: 0.7; } /* --- Raw source view --- */ .raw-source-view { background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px; padding: 16px; margin-top: 12px; font-family: "JetBrains Mono", monospace; font-size: 0.82rem; color: var(--text-secondary); white-space: pre-wrap; word-break: break-word; overflow-x: auto; line-height: 1.55; max-height: 70vh; overflow-y: auto; } /* --- Pretty print (mode lecture fichiers texte non-markdown) --- */ .pretty-view { position: relative; display: grid; grid-template-columns: auto 1fr; align-items: stretch; background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px; overflow: auto; max-height: 78vh; } .pretty-view .pp-gutter { position: sticky; /* figee au scroll horizontal, suit le scroll vertical */ left: 0; z-index: 2; display: flex; flex-direction: column; padding: 16px 10px 16px 14px; text-align: right; font-family: "JetBrains Mono", monospace; font-size: 0.85rem; line-height: 1.55; color: var(--text-muted); opacity: 0.65; user-select: none; background: var(--bg-secondary); border-right: 1px solid var(--border); box-sizing: border-box; } .pretty-view .pp-pre { margin: 0 !important; border: none !important; border-radius: 0 !important; background: transparent !important; padding: 16px !important; overflow: visible; } .pretty-view .pp-pre code { font-family: "JetBrains Mono", monospace; font-size: 0.85rem; line-height: 1.55; white-space: pre; display: block; } /* Niveaux de log colorises par le fallback pretty-print (pas d'equivalent hljs) */ .pretty-view .pp-level { font-weight: 700; } .pretty-view .pp-err { color: #f87171; } .pretty-view .pp-warn { color: #fbbf24; } .pretty-view .pp-info { color: #38bdf8; } .pretty-view .pp-debug { color: var(--text-muted); } [data-theme="light"] .pretty-view .pp-err { color: #dc2626; } [data-theme="light"] .pretty-view .pp-warn { color: #b45309; } [data-theme="light"] .pretty-view .pp-info { color: #0369a1; } /* --- Markdown Rendered Content --- */ .md-content h1, .md-content h2, .md-content h3, .md-content h4, .md-content h5, .md-content h6 { font-family: "JetBrains Mono", monospace; font-weight: 700; margin: 1.4em 0 0.5em; color: var(--text-primary); } .md-content h1 { font-size: 1.5rem; border-bottom: 1px solid var(--border); padding-bottom: 6px; } .md-content h2 { font-size: 1.25rem; } .md-content h3 { font-size: 1.1rem; } .md-content p { margin: 0.6em 0; } .md-content ul, .md-content ol { padding-left: 1.6em; margin: 0.5em 0; } .md-content li { margin: 0.25em 0; } .md-content blockquote { border-left: 3px solid var(--accent); padding: 4px 16px; margin: 0.8em 0; color: var(--text-secondary); background: var(--bg-secondary); border-radius: 0 6px 6px 0; } .md-content code { font-family: "JetBrains Mono", monospace; background: var(--code-bg); padding: 2px 6px; border-radius: 4px; font-size: 0.88em; border: 1px solid var(--border); } .md-content pre { background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px; padding: 16px; overflow-x: auto; margin: 0.8em 0; } .md-content pre code { background: none; border: none; padding: 0; font-size: 0.85rem; line-height: 1.55; } .md-content table { width: 100%; border-collapse: collapse; margin: 0.8em 0; font-size: 0.92rem; } .md-content th, .md-content td { border: 1px solid var(--border); padding: 8px 12px; text-align: left; } .md-content th { background: var(--bg-secondary); font-family: "JetBrains Mono", monospace; font-weight: 600; font-size: 0.85rem; } .md-content img { max-width: 100%; border-radius: 8px; margin: 0.6em 0; } .md-content hr { border: none; border-top: 1px solid var(--border); margin: 1.5em 0; } .md-content .task-list-item { list-style: none; margin-left: -1.2em; } .md-content .task-list-item input[type="checkbox"] { margin-right: 6px; } /* Wikilinks */ .wikilink, .wikilink-anchor { color: var(--accent); border-bottom: 1px dashed var(--accent); cursor: pointer; } .wikilink:hover, .wikilink-anchor:hover { opacity: 0.8; } .wikilink-anchor { text-decoration: none; } .wikilink-missing { color: var(--text-muted); border-bottom: 1px dashed var(--text-muted); cursor: default; } /* Image placeholders */ .image-not-found { display: inline-block; padding: 8px 12px; background: var(--danger-bg); color: var(--danger); border: 1px dashed var(--danger); border-radius: 4px; font-family: "JetBrains Mono", monospace; font-size: 0.85rem; cursor: help; } /* Markdown images */ .file-content img { max-width: 100%; height: auto; display: block; margin: 16px 0; border-radius: 6px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } .file-content a img { cursor: pointer; transition: opacity 0.2s ease; } .file-content a img:hover { opacity: 0.85; } /* --- Search Results --- */ .search-results { padding: 0; } .search-results-header { font-family: "JetBrains Mono", monospace; font-size: 0.85rem; color: var(--text-muted); margin-bottom: 16px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; } .search-results-summary-text { display: inline; } .search-results-active-tags { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; } .search-results-active-tag { display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; background: var(--tag-bg); color: var(--tag-text); border-radius: 999px; font-family: "JetBrains Mono", monospace; font-size: 0.75rem; line-height: 1.2; } .search-results-active-tag-remove { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border: none; background: transparent; color: inherit; cursor: pointer; padding: 0; } .search-result-item { padding: 14px 16px; border: 1px solid var(--border); border-radius: 8px; margin-bottom: 10px; cursor: pointer; transition: background 120ms ease, border-color 120ms ease; position: relative; } .search-result-item:hover { background: var(--bg-hover); border-color: var(--accent); } .search-result-ext { position: absolute; top: 8px; right: 10px; font-size: 0.65rem; font-weight: 700; text-transform: uppercase; color: var(--accent); background: var(--accent-bg, rgba(99, 102, 241, 0.12)); padding: 2px 8px; border-radius: 4px; letter-spacing: 0.5px; border: 1px solid rgba(99, 102, 241, 0.2); } .search-filters-row { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 4px; } .search-filter-badge { font-size: 0.65rem; font-family: "JetBrains Mono", monospace; padding: 1px 6px; border-radius: 3px; background: rgba(99, 102, 241, 0.1); color: var(--accent); font-weight: 600; } .search-filter-badge.path { background: rgba(5, 150, 105, 0.1); color: #059669; } /* Save search button */ .search-save-btn { padding: 4px 10px; font-size: 0.75rem; border: 1px solid var(--border); border-radius: 4px; background: var(--bg-secondary); color: var(--text-primary); cursor: pointer; display: flex; align-items: center; gap: 4px; } .search-save-btn:hover { background: var(--bg-hover); } /* Saved searches sidebar */ .saved-search-item { position: relative; padding: 10px 12px; cursor: pointer; border-radius: 6px; transition: background 0.15s; border: 1px solid transparent; margin-bottom: 4px; } .saved-search-item:hover { background: var(--bg-hover); border-color: var(--border); } .saved-search-query { font-size: 0.82rem; font-family: "JetBrains Mono", monospace; line-height: 1.4; word-break: break-word; overflow-wrap: anywhere; margin-bottom: 6px; } .saved-search-meta { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; margin-bottom: 2px; } .saved-search-badges { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; flex: 1; min-width: 0; } .saved-search-type-icon { margin-left: auto; flex-shrink: 0; opacity: 0.6; } /* Saved filter bar */ .saved-filter-bar { display: flex; gap: 6px; padding: 8px 10px 10px; } .saved-filter-pill { padding: 3px 10px; font-size: 0.7rem; font-weight: 500; border: 1px solid var(--border); border-radius: 12px; background: transparent; color: var(--text-secondary); cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s; } .saved-filter-pill:hover { background: var(--bg-hover); color: var(--text-primary); } .saved-filter-pill.active { background: var(--accent-bg, rgba(99,102,241,0.12)); color: var(--accent); border-color: var(--accent); } /* Offline indicator */ .offline-indicator { display: flex; align-items: center; gap: 6px; padding: 2px 8px; border-radius: 4px; font-size: 0.7rem; cursor: default; } .offline-indicator.offline { background: var(--warn-bg, rgba(251,191,36,0.12)); color: var(--warn); border: 1px solid var(--warn); } .offline-pending { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--warn); color: #000; font-size: 0.6rem; font-weight: 700; } /* Theme picker grid */ .theme-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; margin-top: 12px; } .theme-card { background: var(--bg-secondary); border: 2px solid var(--border); border-radius: 8px; padding: 10px; cursor: pointer; transition: border-color 0.2s, transform 0.15s; } .theme-card:hover { border-color: var(--accent); transform: translateY(-1px); } .theme-card.active { border-color: var(--accent-green); } .theme-card-preview { height: 40px; border-radius: 4px; margin-bottom: 8px; overflow: hidden; display: flex; flex-direction: column; } .theme-card-preview-bar { height: 14px; } .theme-card-preview-body { flex: 1; display: flex; align-items: center; padding: 0 6px; } .theme-card-preview-btn { width: 50%; height: 10px; border-radius: 3px; } .theme-card-name { font-size: 0.75rem; font-weight: 600; color: var(--text-primary); margin-bottom: 2px; } .theme-card-desc { font-size: 0.65rem; color: var(--text-muted); } .theme-mode-toggle { display: flex; gap: 0; margin-top: 16px; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; width: fit-content; } .theme-mode-btn { padding: 4px 14px; font-size: 0.7rem; border: none; background: transparent; color: var(--text-secondary); cursor: pointer; } .theme-mode-btn.active { background: var(--accent); color: #fff; } /* Theme import/export actions */ .theme-actions { display: flex; gap: 8px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); } .theme-action-btn { padding: 5px 14px; font-size: 0.7rem; font-weight: 600; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text-secondary); border-radius: 6px; cursor: pointer; transition: background 0.15s, color 0.15s; } .theme-action-btn:hover { background: var(--bg-hover); color: var(--text-primary); } .theme-custom-badge { font-size: 0.6rem; color: var(--accent); margin-left: 2px; } /* Profile section */ .profile-form { max-width: 420px; } .profile-field { margin-bottom: 14px; } .profile-field label { display: block; font-size: 0.75rem; font-weight: 600; color: var(--text-primary); margin-bottom: 4px; } .profile-field .config-input, .profile-field .config-select { width: 100%; padding: 6px 10px; font-size: 0.8rem; background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px; font-family: inherit; } .profile-hint { display: block; font-size: 0.65rem; color: var(--text-muted); margin-top: 4px; } .profile-saved { font-size: 0.7rem; color: var(--accent-green); margin-left: 10px; } /* Profile picture picker (#113) */ .profile-avatar-field { margin-bottom: 18px; } .profile-avatar-label { display: block; font-size: 0.75rem; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; } .profile-avatar-row { display: flex; align-items: center; gap: 16px; } .profile-avatar-preview { position: relative; width: 88px; height: 88px; border-radius: 50%; flex-shrink: 0; overflow: hidden; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, var(--accent), color-mix(in srgb, var(--accent) 55%, #7c3aed)); border: 2px solid var(--border); cursor: pointer; transition: border-color 0.15s ease, box-shadow 0.15s ease; } .profile-avatar-preview:hover, .profile-avatar-preview:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); } .profile-avatar-preview img { width: 100%; height: 100%; object-fit: cover; display: block; } .profile-avatar-initials { font-size: 1.5rem; font-weight: 700; letter-spacing: 0.02em; color: #fff; user-select: none; } .profile-avatar-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; border: 0; padding: 0; margin: 0; background: rgba(0, 0, 0, 0.45); color: #fff; cursor: pointer; opacity: 0; transition: opacity 0.15s ease; } .profile-avatar-preview:hover .profile-avatar-overlay, .profile-avatar-overlay:focus-visible { opacity: 1; } .profile-avatar-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0; } .profile-avatar-actions .config-btn-secondary { font-size: 0.75rem; padding: 6px 14px; } .profile-avatar-remove-btn { background: var(--danger-bg) !important; color: var(--danger) !important; border-color: var(--danger) !important; } .profile-avatar-error { font-size: 0.7rem; color: var(--danger); margin-top: 8px; } .profile-avatar-error.hidden { display: none; } /* #117 — preset avatar gallery */ .profile-avatar-presets { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; margin-top: 10px; max-width: 420px; } .profile-avatar-preset { padding: 0; margin: 0; border: 2px solid var(--border); border-radius: 50%; overflow: hidden; cursor: pointer; background: var(--bg-secondary); aspect-ratio: 1; transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease; } .profile-avatar-preset img { width: 100%; height: 100%; object-fit: cover; display: block; } .profile-avatar-preset:hover { border-color: var(--accent); transform: translateY(-1px); } .profile-avatar-preset.active { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); } .profile-avatar-preset:disabled { opacity: 0.6; cursor: progress; } .config-save-btn { padding: 6px 18px; font-size: 0.75rem; font-weight: 600; background: var(--accent); color: #fff; border: 1px solid var(--accent); border-radius: 6px; cursor: pointer; transition: opacity 0.15s; } .config-save-btn:hover { opacity: 0.85; } .saved-search-vault { font-size: 0.65rem; color: var(--text-muted); padding: 1px 5px; background: var(--bg-secondary); border-radius: 3px; } .saved-search-filters { font-size: 0.65rem; color: var(--accent); display: flex; gap: 4px; flex-wrap: wrap; } .saved-search-path { font-size: 0.6rem; color: #059669; background: rgba(5,150,105,0.08); padding: 1px 5px; border-radius: 3px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .saved-search-delete { position: absolute; top: 6px; right: 8px; background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 0.9rem; padding: 2px 6px; opacity: 0; transition: opacity 0.15s; } .saved-search-item:hover .saved-search-delete { opacity: 1; } .saved-search-delete:hover { color: var(--text-error); } .search-result-title { font-family: "JetBrains Mono", monospace; font-size: 0.92rem; font-weight: 600; color: var(--text-primary); margin-bottom: 4px; } .search-result-vault { font-family: "JetBrains Mono", monospace; font-size: 0.72rem; color: var(--accent-green); margin-bottom: 4px; } .search-result-snippet { font-size: 0.85rem; color: var(--text-secondary); line-height: 1.5; } .search-result-snippet .search-highlight { background: color-mix(in srgb, var(--accent) 25%, transparent); color: var(--accent); font-weight: 600; padding: 1px 3px; border-radius: 3px; } .search-result-title .search-highlight { background: color-mix(in srgb, var(--accent) 25%, transparent); color: var(--accent); font-weight: 700; padding: 1px 3px; border-radius: 3px; } .search-result-tags { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 4px; } .search-result-tags .file-tag { font-size: 0.7rem; padding: 1px 6px; } /* --- Loading indicator --- */ .loading-indicator { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px 20px; color: var(--text-muted); gap: 12px; } .loading-spinner { width: 32px; height: 32px; border: 3px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* --- Search progress bar --- */ .search-progress-bar { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 9999; background: transparent; pointer-events: none; opacity: 0; transition: opacity 0.15s; } .search-progress-bar.active { opacity: 1; } .search-progress-bar .search-progress-bar__fill { height: 100%; background: var(--accent); width: 0%; animation: progress-indeterminate 1.5s ease-in-out infinite; } @keyframes progress-indeterminate { 0% { width: 0%; margin-left: 0%; } 50% { width: 40%; margin-left: 30%; } 100% { width: 0%; margin-left: 100%; } } .search-time-badge { font-size: 0.7rem; color: var(--text-muted); margin-left: 8px; } /* --- Editor Modal --- */ .editor-modal { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 1000; background: var(--overlay-bg); align-items: center; justify-content: center; padding: 20px; } .editor-modal.active { display: flex; } .help-container { max-width: 1320px; } .editor-container { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 12px; width: 100%; max-width: 1200px; max-height: 90vh; display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); } /* Native fullscreen (#101) — the editor fills the viewport regardless of the inline/modal constraints above. */ .editor-container:fullscreen { width: 100vw; height: 100vh; max-width: none; max-height: none; border: none; border-radius: 0; box-shadow: none; } .editor-container:fullscreen .editor-body, .editor-container:fullscreen .editor-body-cm { flex: 1; min-height: 0; } /* --- Inline edition (#93) -------------------------------------------------- When a document is being edited, `#editor-container` is moved into the document content area: the editor *replaces* the read view instead of covering it with the overlay, so the AI assistant sidebar stays usable. The overlay itself is neutralised but kept mounted (and `active`) because the mobile editing ribbon (`#me-toolbar`, `.me-ribbon`) is anchored to it. */ .editor-modal.editor-inline-mode { display: block; background: transparent; padding: 0; pointer-events: none; } .editor-modal.editor-inline-mode .me-ribbon { pointer-events: auto; } .content-area.editor-inline-host, .pane-content.editor-inline-host { display: flex; flex-direction: column; padding: 0; overflow: hidden; } .content-area.editor-inline-host .editor-container.editor-inline, .pane-content.editor-inline-host .editor-container.editor-inline { flex: 1; height: auto; width: 100%; min-height: 0; max-width: none; max-height: none; border: none; border-radius: 0; box-shadow: none; background: var(--bg-primary); } .editor-container.editor-inline .editor-body, .editor-container.editor-inline .editor-body-cm { flex: 1; min-height: 0; } .editor-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--bg-primary); flex-shrink: 0; position: sticky; top: 0; z-index: 10; } /* AI processing indicator — shown inside editor header during AI calls */ .ai-processing-indicator { display: none; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 12px; font-size: 0.72rem; font-weight: 500; color: #ffffff; background: rgba(59, 130, 246, 0.3); border: 1px solid rgba(96, 165, 250, 0.4); animation: ai-indicator-pulse 1s ease-in-out infinite; margin-left: 12px; } .ai-spinner { width: 10px; height: 10px; border: 2px solid rgba(255,255,255,0.3); border-top-color: #ffffff; border-radius: 50%; animation: ai-spinner-spin 0.6s linear infinite; } @keyframes ai-spinner-spin { to { transform: rotate(360deg); } } @keyframes ai-indicator-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } /* AI custom-rewrite modal — replaces the browser prompt() for a consistent, theme-aware and keyboard-accessible experience. */ .ai-modal-overlay { position: fixed; inset: 0; z-index: 10050; display: flex; align-items: center; justify-content: center; padding: 20px; background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(2px); } .ai-modal { width: 100%; max-width: 460px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 10px; padding: 18px 18px 14px; box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45); } .ai-modal-title { margin: 0 0 4px; font-size: 0.95rem; color: var(--text-primary); } .ai-modal-hint { margin: 0 0 10px; font-size: 0.78rem; color: var(--text-muted); } .ai-modal-input { width: 100%; resize: vertical; min-height: 72px; padding: 8px 10px; font-family: inherit; font-size: 0.85rem; color: var(--text-primary); background: var(--bg-primary); border: 1px solid var(--border); border-radius: 6px; } .ai-modal-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.25); } .ai-modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; } .ai-modal-btn { padding: 6px 14px; font-size: 0.8rem; border-radius: 6px; cursor: pointer; border: 1px solid var(--border); background: transparent; color: var(--text-primary); } .ai-modal-btn:hover { background: var(--bg-hover); } .ai-modal-btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; } .ai-modal-btn.primary:hover { filter: brightness(1.08); } .editor-title { font-family: "JetBrains Mono", monospace; font-size: 0.9rem; color: var(--text-primary); font-weight: 600; } .editor-brand { font-weight: 700; font-size: 12px; color: var(--accent); letter-spacing: 0.5px; white-space: nowrap; margin-right: 8px; } .editor-title-input { flex: 1; min-width: 80px; background: transparent; border: 1px solid transparent; color: var(--text-primary); font-size: 13px; padding: 3px 6px; border-radius: 6px; outline: none; font-family: var(--font-sans); } .editor-title-input:hover { border-color: var(--border); } .editor-title-input:focus { border-color: var(--accent); background: var(--bg-input); } .editor-sep { color: var(--text-muted); font-size: 13px; padding: 0 2px; user-select: none; } .editor-filename-input { width: 140px; background: transparent; border: 1px solid transparent; color: var(--text-primary); font-size: 12px; padding: 3px 6px; border-radius: 6px; outline: none; font-family: var(--font-mono); } .editor-filename-input:hover { border-color: var(--border); } .editor-filename-input:focus { border-color: var(--ok); background: var(--bg-input); } .editor-spacer { flex: 1; } /* Collaboration temps réel (#62) — indicateur de présence */ .collab-presence { display: flex; align-items: center; gap: 6px; margin-right: 10px; } .collab-status { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; } .collab-status-connected { background: var(--ok); } .collab-status-connecting { background: var(--warn); animation: editor-pulse 1s infinite; } .collab-status-disconnected { background: var(--err); animation: editor-pulse 0.8s infinite; } .collab-avatars { display: flex; align-items: center; } .collab-avatar { width: 20px; height: 20px; border-radius: 50%; color: #fff; font-size: 11px; font-weight: 600; display: flex; align-items: center; justify-content: center; margin-left: -6px; border: 2px solid var(--bg-secondary); } .collab-avatar:first-child { margin-left: 0; } .collab-avatar-self { box-shadow: 0 0 0 2px var(--bg-primary); } .collab-count { font-size: 11px; color: var(--text-muted); min-width: 10px; } /* Collaboration temps réel (#62) — curseurs distants CodeMirror */ .cm-remote-cursor { display: inline-block; width: 0; border-left: 2px solid; height: 1.2em; vertical-align: text-bottom; position: relative; margin-left: -1px; } .cm-remote-cursor-label { position: absolute; top: -1.35em; left: -1px; padding: 1px 4px; border-radius: 3px 3px 3px 0; color: #fff; font-size: 10px; font-weight: 600; white-space: nowrap; pointer-events: none; z-index: 5; } .editor-save-dot { display: flex; align-items: center; gap: 4px; font-size: 11px; padding: 0 4px; margin-right: 8px; } .editor-btn + .editor-btn { margin-left: 6px; } .editor-save-dot .dot { width: 6px; height: 6px; border-radius: 50%; } .editor-save-dot.ok { color: var(--ok); } .editor-save-dot.ok .dot { background: var(--ok); } .editor-save-dot.dirty { color: var(--warn); } .editor-save-dot.dirty .dot { background: var(--warn); } .editor-save-dot.saving { color: var(--ai); } .editor-save-dot.saving .dot { background: var(--ai); } @keyframes editor-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } } .editor-save-dot.saving { animation: editor-pulse 0.8s infinite; } .editor-save-dot.err { color: var(--err); } .editor-save-dot.err .dot { background: var(--err); } /* BUG-045: only the CodeMirror scroller scrolls. #editor-body used to keep overflow:auto AND host a 100%-tall .cm-editor below the AI toolbar row, so the body (toolbar + editor) and the scroller both overflowed → two stacked scrollbars. Flex column: toolbar fixed, editor fills, scroller scrolls. Combined selector on purpose: `.editor-body` (defined later with equal specificity) must not re-introduce overflow-y:auto. */ .editor-body.editor-body-cm { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; } .editor-body.editor-body-cm #ai-toolbar-container { flex: 0 0 auto; } .editor-body.editor-body-cm .cm-editor { flex: 1 1 auto; height: auto; min-height: 0; overflow: hidden; } .editor-body.editor-body-cm .fallback-editor { flex: 1 1 auto; height: auto; min-height: 0; resize: none; overflow: auto; } .editor-body-cm .cm-editor .cm-scroller { font-family: var(--font-mono); font-size: 13.5px; line-height: 1.75; } .editor-footer { height: 26px; min-height: 26px; display: flex; align-items: center; justify-content: space-between; padding: 0 12px; background: var(--bg-secondary); border-top: 1px solid var(--border); font-size: 11px; color: var(--text-muted); flex-shrink: 0; } .editor-stat-file { color: var(--text-secondary); max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .editor-actions { display: flex; gap: 6px; } .editor-btn { width: 36px; height: 36px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: transparent; color: var(--text-secondary); cursor: pointer; transition: all 150ms ease; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; } .editor-btn:hover { color: var(--accent); border-color: var(--accent); } .editor-btn.primary { background: var(--accent); color: #ffffff; border-color: var(--accent); } .editor-btn.primary:hover { opacity: 0.9; } .editor-btn.danger:hover { color: var(--danger); border-color: var(--danger); } .editor-body { flex: 1; min-height: 0; position: relative; overflow-y: auto; overflow-x: hidden; } .help-body { padding: 0; background: radial-gradient(circle at top right, color-mix(in srgb, var(--accent) 10%, transparent), transparent 30%), var(--bg-primary); display: flex; gap: 0; overflow-y: auto; overflow-x: hidden; scroll-behavior: smooth; } /* Help Navigation Menu */ .help-hamburger { display: none; width: 36px; height: 36px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: transparent; color: var(--text-secondary); cursor: pointer; align-items: center; justify-content: center; flex-shrink: 0; margin-right: 8px; } .help-hamburger:hover { color: var(--accent); border-color: var(--accent); } /* #114: close button for the mobile TOC drawer (hidden on desktop where the nav is always visible). Scoped to #config-modal so the help modal — which has no such button — is unaffected. */ .help-toc-close { display: none; width: 44px; height: 44px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: transparent; color: var(--text-secondary); cursor: pointer; align-items: center; justify-content: center; flex-shrink: 0; } .help-nav { width: 260px; min-width: 260px; background: color-mix(in srgb, var(--bg-secondary) 94%, var(--bg-primary)); border-right: 1px solid color-mix(in srgb, var(--border) 85%, transparent); display: flex; flex-direction: column; position: sticky; top: 0; align-self: flex-start; height: 100%; max-height: calc(90vh - 57px); flex-shrink: 0; backdrop-filter: blur(12px); overflow: hidden; } .help-nav-header { display: flex; align-items: center; justify-content: space-between; padding: 20px 16px 10px; flex-shrink: 0; } .help-nav-title { font-family: "JetBrains Mono", monospace; font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); } .help-nav-search-wrap { padding: 0 12px 8px; flex-shrink: 0; display: flex; align-items: center; gap: 0; } .help-nav-search { flex: 1; padding: 7px 10px; border: 1px solid var(--border); border-right: none; border-radius: 8px 0 0 8px; background: var(--bg-primary); color: var(--text-primary); font-size: 0.78rem; outline: none; transition: border-color 0.2s; min-width: 0; } .help-nav-search:focus { border-color: var(--accent); } .help-nav-search:focus + .help-search-clear { border-color: var(--accent); border-left-color: var(--accent); } .help-nav-search::placeholder { color: var(--text-muted); } .help-search-clear { padding: 7px 10px; border: 1px solid var(--border); border-left: none; border-radius: 0 8px 8px 0; background: var(--bg-primary); color: var(--text-muted); cursor: pointer; font-size: 14px; line-height: 1; display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: color 0.15s, background 0.15s; } .help-search-clear:hover { color: var(--text-primary); background: rgba(255,255,255,0.06); } .help-nav-list { list-style: none; margin: 0; padding: 0 12px 20px; flex: 1; overflow-y: auto; overflow-x: hidden; scrollbar-width: thin; scrollbar-color: var(--border) transparent; } .help-nav-list li { margin: 0 0 3px; } .help-nav-link { display: block; padding: 8px 12px; font-size: 0.85rem; color: var(--text-secondary); text-decoration: none; transition: all 150ms ease; border: 1px solid transparent; border-radius: 8px; outline: none; } .help-nav-link:hover { color: var(--accent); background: color-mix(in srgb, var(--bg-hover) 80%, transparent); border-color: color-mix(in srgb, var(--accent) 16%, transparent); text-decoration: none; transform: translateX(2px); } .help-nav-link:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 8px; } .help-nav-link.active { color: var(--accent); background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 16%, transparent), color-mix(in srgb, var(--accent) 7%, transparent)); border-color: color-mix(in srgb, var(--accent) 22%, transparent); font-weight: 600; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 10%, transparent); } .help-nav-link.hidden { display: none; } .help-section.help-hidden { display: none; } .help-search-highlight { background: rgba(250, 204, 21, 0.35); color: inherit; border-radius: 2px; padding: 0 1px; } .help-content { flex: 1; max-width: 980px; margin: 0 auto; padding: 32px 40px 56px; overflow: visible; min-width: 0; } .help-lead { font-size: 1.08rem; line-height: 1.75; color: var(--text-primary); margin-bottom: 18px; } .help-footer { margin-top: 48px; padding-top: 24px; border-top: 1px solid var(--border); text-align: center; color: var(--text-muted); font-size: 0.85rem; } .help-footer a { color: var(--accent); text-decoration: none; } .help-footer a:hover { text-decoration: underline; } .help-content h1, .help-content h2, .help-content h3 { font-family: "JetBrains Mono", monospace; color: var(--text-primary); } .help-content h1 { font-size: 2rem; margin-bottom: 16px; letter-spacing: -0.02em; } .help-content h2 { font-size: 1.18rem; margin: 0 0 14px; } .help-content h3 { font-size: 0.95rem; margin: 20px 0 8px; color: var(--text-secondary); } .help-content p { margin: 0 0 14px; color: var(--text-secondary); line-height: 1.7; } .help-content pre, .help-content table { max-width: 100%; overflow-x: auto; } .help-content pre code { white-space: pre; } .help-content ul, .help-content ol { margin: 10px 0 18px; padding-left: 24px; color: var(--text-secondary); } .help-content ul li, .help-content ol li { margin: 6px 0; line-height: 1.6; } .help-content code { font-family: "JetBrains Mono", monospace; background: var(--code-bg); border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px; color: var(--text-primary); font-size: 0.88em; } .help-content strong { color: var(--text-primary); font-weight: 600; } .help-section { position: relative; margin-bottom: 22px; padding: 24px 26px; border: 1px solid color-mix(in srgb, var(--border) 82%, transparent); border-radius: 18px; background: linear-gradient(180deg, color-mix(in srgb, var(--bg-secondary) 94%, var(--bg-primary)), color-mix(in srgb, var(--bg-secondary) 86%, var(--bg-primary))); box-shadow: 0 14px 34px rgba(0, 0, 0, 0.18); } .help-section::before { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 8%, transparent), transparent 35%); } .help-hero { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(260px, 1fr); gap: 22px; align-items: stretch; padding: 22px; border: 1px solid color-mix(in srgb, var(--accent) 16%, var(--border)); border-radius: 18px; background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 12%, transparent), transparent 45%), color-mix(in srgb, var(--bg-secondary) 92%, var(--bg-primary)); margin-bottom: 26px; } .help-kicker { display: inline-flex; align-items: center; padding: 5px 10px; border-radius: 999px; background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); font-family: "JetBrains Mono", monospace; font-size: 0.72rem; margin-bottom: 12px; } .help-badges { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; } .help-badge { display: inline-flex; align-items: center; padding: 6px 10px; border-radius: 999px; background: color-mix(in srgb, var(--bg-primary) 72%, transparent); border: 1px solid var(--border); color: var(--text-primary); font-size: 0.8rem; } .help-hero-visual { display: flex; align-items: center; justify-content: center; } .help-mini-window { width: 100%; max-width: 320px; border-radius: 18px; overflow: hidden; border: 1px solid color-mix(in srgb, var(--accent) 18%, var(--border)); background: color-mix(in srgb, var(--bg-primary) 88%, black 12%); box-shadow: 0 18px 44px rgba(0, 0, 0, 0.28); } .help-mini-window-bar { display: flex; gap: 7px; padding: 12px 14px; border-bottom: 1px solid var(--border); } .help-mini-window-bar span { width: 9px; height: 9px; border-radius: 50%; background: color-mix(in srgb, var(--accent) 45%, var(--text-muted)); } .help-mini-window-body { display: flex; min-height: 190px; } .help-mini-sidebar { width: 72px; background: color-mix(in srgb, var(--bg-secondary) 92%, black 8%); border-right: 1px solid var(--border); } .help-mini-content { flex: 1; padding: 16px; } .help-mini-line { height: 10px; border-radius: 999px; background: color-mix(in srgb, var(--text-muted) 28%, transparent); margin-bottom: 10px; } .help-mini-line.short { width: 62%; } .help-mini-tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0; } .help-mini-tags span { padding: 3px 8px; border-radius: 999px; background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--text-primary); font-size: 0.72rem; } .help-mini-card { height: 64px; border-radius: 12px; border: 1px solid var(--border); background: linear-gradient(180deg, color-mix(in srgb, var(--bg-secondary) 94%, white 6%), var(--bg-primary)); } .help-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin-bottom: 26px; } .help-card { padding: 18px; border-radius: 16px; border: 1px solid var(--border); background: color-mix(in srgb, var(--bg-secondary) 92%, var(--bg-primary)); } .help-card-icon { width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center; border-radius: 12px; background: color-mix(in srgb, var(--accent) 14%, transparent); font-size: 1.2rem; margin-bottom: 10px; } .help-section { margin-top: 26px; } .help-feature-list, .help-steps, .help-checklist, .help-tip-grid { display: grid; gap: 14px; } .help-feature-item, .help-step, .help-check-item, .help-tip-card { border: 1px solid var(--border); border-radius: 16px; background: color-mix(in srgb, var(--bg-secondary) 92%, var(--bg-primary)); } .help-feature-item { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 14px; padding: 16px; } .help-feature-emoji { width: 52px; height: 52px; display: flex; align-items: center; justify-content: center; border-radius: 14px; background: color-mix(in srgb, var(--accent) 12%, transparent); font-size: 1.4rem; } .help-steps { counter-reset: step; } .help-step { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 14px; padding: 16px; } .help-step-number { width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); font-family: "JetBrains Mono", monospace; font-weight: 700; } .help-check-item { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 12px; padding: 14px 16px; align-items: start; } .help-check-item span { font-size: 1rem; line-height: 1.4; } .help-check-item p { margin-bottom: 0; } .help-tip-panel { margin-top: 28px; } .help-tip-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } .help-tip-card { padding: 16px; } /* BUG-045: inside the editor, the CodeMirror scroller is the ONLY scroll surface. `#editor-body` stays `overflow:hidden` (BUG-020 rule below) and the scroller fills it — otherwise the body and the scroller scroll together and render two stacked scrollbars. */ .cm-editor { font-size: 0.9rem; } .cm-scroller { font-family: "JetBrains Mono", monospace; overflow-x: auto !important; max-width: 100%; } /* BUG-058: CodeMirror paints its line-number gutter with hardcoded light defaults (#f5f5f5 background, #ddd border), so the bar stayed pale in dark themes while the editor body followed the theme. Deriving the tint from `--text-primary` keeps the gutter subtle and makes it adapt to every theme and mode (dark, light, high-contrast, sepia). */ .cm-editor .cm-gutters { background: color-mix(in srgb, var(--text-primary) 5%, transparent) !important; color: var(--text-secondary) !important; border-right: 1px solid var(--border) !important; } .cm-editor .cm-gutters .cm-activeLineGutter { background: color-mix(in srgb, var(--text-primary) 10%, transparent) !important; color: var(--text-primary) !important; } .fallback-editor { width: 100%; min-height: 100%; height: auto; border: none; outline: none; resize: none; padding: 16px; background: var(--code-bg); color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.9rem; line-height: 1.55; box-sizing: border-box; overflow-y: auto; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word; } /* Mobile right sidebar - hide by default */ @media (max-width: 768px) { .right-sidebar { display: none; } .right-sidebar-resize-handle { display: none; } } /* Mobile help navigation */ @media (max-width: 768px) { .help-nav { display: none; } .help-content { padding: 20px 16px 32px; } .vault-context-indicator { /* Keep visible on mobile — same look as desktop */ padding: 4px 8px; font-size: 0.7rem; } } /* Mobile editor */ @media (max-width: 768px) { .editor-modal { padding: 0; align-items: stretch; } .editor-container { max-width: 100%; max-height: 100vh; border-radius: 0; height: 100vh; overflow: hidden; } .editor-header { padding: 10px 12px; position: sticky; top: 0; z-index: 20; background: var(--bg-primary); } .editor-title { font-size: 0.85rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .editor-actions { gap: 4px; } .editor-btn { width: 36px; height: 36px; min-width: 36px; } /* BUG-018: keep the Save / Cancel / Delete buttons reachable on small screens by shrinking the inputs and hiding secondary header items. */ .editor-brand, .editor-sep, .editor-spacer, .collab-presence { display: none !important; } .editor-title-input { flex: 1 1 60px; min-width: 0; font-size: 13px; } .editor-filename-input { width: auto; flex: 0 1 84px; min-width: 0; font-size: 11px; } .editor-save-dot { margin-right: 2px; padding: 0; } #editor-save-label { display: none; } .editor-header .editor-btn { flex: 0 0 auto; } .editor-body { flex: 1; min-height: 0; /* BUG-020: only the CodeMirror scroller scrolls — no double scrollbar. */ overflow: hidden; display: flex; flex-direction: column; } #ai-toolbar-container { flex: 0 0 auto; } .cm-editor { flex: 1 1 auto; height: auto; min-height: 0; } .cm-scroller { overflow-y: auto !important; overflow-x: hidden !important; /* BUG-019: keep the caret clear of the fixed ribbon. */ padding-bottom: 72px; } .fallback-editor { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-bottom: 72px; } .search-results-header { align-items: flex-start; } } /* --- No-select during resize --- */ body.resizing { user-select: none; -webkit-user-select: none; cursor: ew-resize; } body.resizing-v { user-select: none; -webkit-user-select: none; cursor: ns-resize; } /* --- Responsive — Tablet --- */ @media (max-width: 1024px) { .sidebar { width: 240px; min-width: 200px; } } /* --- Responsive — Mobile --- */ @media (max-width: 768px) { .hamburger-btn { display: flex; } .sidebar-toggle-btn { display: none; } .header { flex-wrap: wrap; gap: 8px 10px; padding: 10px 12px; } .header-left { flex: 1; gap: 12px; } .header-center { flex: 0 0 100%; order: 3; max-width: none; padding: 4px 0; } .header-right { flex: 0 0 auto; gap: 8px; } .header-logo { font-size: 1.05rem; gap: 8px; } .header-right .user-display-name { display: none; /* Masquer le nom d'utilisateur dans le header sur mobile */ } .search-wrapper { max-width: none; width: 100%; } .search-input-wrapper input { padding: 10px 40px 10px 40px; font-size: 1rem; border-radius: 12px; } .search-wrapper .search-icon { left: 14px; top: 14px; width: 18px !important; height: 18px !important; } /* Mobile: keep only filter + clear visible in header search */ .search-actions .tog, .search-actions .search-sep, .search-actions .search-count { display: none; } .search-actions { gap: 4px; } .search-actions .search-btn#search-clear-btn { display: flex; } .search-dropdown { position: fixed; top: 100px; left: 8px; right: 8px; width: calc(100vw - 16px); max-height: calc(100vh - 120px); border-radius: 12px; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4); } .search-dropdown__item { padding: 14px 16px; font-size: 0.95rem; } .search-dropdown__icon { width: 18px; height: 18px; margin-right: 8px; } .header-menu-btn { padding: 10px; border-radius: 10px; } .header-menu-dropdown { position: fixed; top: 60px; right: 10px; left: 10px; width: auto; min-width: 0; border-radius: 16px; } .sidebar-quick-select { padding: 0 16px 12px; } .sidebar-quick-select select { color-scheme: dark; background-color: var(--bg-secondary); color: var(--text-primary); } [data-theme="dark"] .sidebar-quick-select select { background-color: #1e1e1e; color: #e0e0e0; } .sidebar-panel-toggle { padding: 8px 12px 10px; } .tag-cloud { padding: 0 12px 12px; } .sidebar { position: fixed; top: 0; left: 0; bottom: 0; z-index: 200; width: 280px !important; min-width: 280px !important; max-width: 85vw !important; transform: translateX(-100%); transition: transform 250ms ease, background 200ms ease; box-shadow: none; } .sidebar.mobile-open { transform: translateX(0); box-shadow: 4px 0 20px rgba(0, 0, 0, 0.3); } /* Mobile sidebar overlay */ .sidebar-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 199; } .sidebar-overlay.active { display: block; } /* Right Sidebar handling on mobile */ .right-sidebar { position: fixed; top: 0; right: 0; bottom: 0; z-index: 200; width: 280px !important; min-width: 280px !important; max-width: 85vw !important; transform: translateX(100%); transition: transform 250ms ease, background 200ms ease; box-shadow: none; border-left: 1px solid var(--border); } .right-sidebar.hidden { transform: translateX(100%) !important; width: 280px !important; min-width: 280px !important; display: flex; } .right-sidebar:not(.hidden) { transform: translateX(0) !important; box-shadow: -4px 0 20px rgba(0, 0, 0, 0.3) !important; display: flex !important; visibility: visible !important; } .right-sidebar-resize-handle { display: none; } .sidebar-resize-handle { display: none; } .tag-resize-handle { display: none; } .tag-cloud-section { height: auto; max-height: 200px; min-height: 80px; } #vault-panel-content { max-height: none; } #tag-panel-content { max-height: none; } .help-content { padding: 20px 16px 28px; } .help-hero { grid-template-columns: 1fr; padding: 18px; } .help-grid, .help-tip-grid { grid-template-columns: 1fr; } .content-area { padding: 12px 8px 24px; width: 100%; } .file-title { font-size: 1.15rem; } .file-actions { flex-wrap: wrap; gap: 4px; } .file-actions .btn-action { padding: 6px 8px; font-size: 0.75rem; } /* Full-width search results */ .search-result-item { padding: 12px 14px; border-radius: 8px; margin-bottom: 8px; } .search-result-title { font-size: 0.9rem; padding-right: 40px; } .search-result-ext { top: 6px; right: 8px; font-size: 0.6rem; } .search-results-header { flex-wrap: wrap; gap: 6px; } /* Full-width dashboard */ .dashboard-stats-grid { grid-template-columns: repeat(2, 1fr); gap: 8px; } .stat-card { padding: 12px 8px; } .dashboard-tab { padding: 6px 5px !important; font-size: 0 !important; gap: 0 !important; overflow: hidden; min-width: 32px; } .dashboard-tab > *:not(i):not(svg) { display: none; } .dashboard-tab i, .dashboard-tab svg { width: 18px !important; height: 18px !important; flex-shrink: 0; } .breadcrumb { font-size: 0.75rem; flex-wrap: wrap; } /* Mobile tab bar */ .tab-bar { padding: 0 4px; } .tab-item { padding: 6px 10px; font-size: 0.7rem; } .tab-item .tab-name { max-width: 80px; } .tab-item .tab-close { opacity: 0.6; width: 14px; height: 14px; } .md-content { padding: 0 4px; } .md-content h1 { font-size: 1.4rem; } .md-content h2 { font-size: 1.15rem; } .md-content h3 { font-size: 1rem; } .md-content pre { margin: 8px -4px; border-radius: 6px; padding: 10px 12px; font-size: 0.8rem; } /* Full-width content wrapper */ .content-wrapper { margin-left: 0 !important; } } /* --- Configuration Modal --- */ .config-content { max-width: 720px; margin: 0 auto; padding: 28px 24px 40px; } .config-section { margin-bottom: 28px; } .config-section h2 { font-family: "JetBrains Mono", monospace; font-size: 1.05rem; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; } .config-description { font-size: 0.85rem; color: var(--text-secondary); margin-bottom: 16px; line-height: 1.5; } .config-filters-list { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; min-height: 32px; } .config-filter-badge { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; background: var(--tag-bg); color: var(--tag-text); border-radius: 6px; font-family: "JetBrains Mono", monospace; font-size: 0.8rem; border: 1px solid color-mix(in srgb, var(--tag-text) 30%, transparent); } .config-filter-badge.disabled { opacity: 0.5; } .config-filter-remove { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border: none; background: transparent; color: inherit; cursor: pointer; padding: 0; font-size: 1.1rem; line-height: 1; } .config-filter-remove:hover { opacity: 0.7; } .config-filter-toggle { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border: none; background: transparent; color: inherit; cursor: pointer; padding: 0; font-size: 0.9rem; } .config-add-pattern { display: flex; gap: 8px; margin-bottom: 12px; } .config-input { flex: 1; padding: 8px 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-secondary); color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.8rem; outline: none; transition: border-color 200ms ease; } .config-input:focus { border-color: var(--accent); } .config-select { padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--r); background: var(--bg-input); color: var(--text-primary); font-size: 0.86rem; font-family: var(--mono); cursor: pointer; } .config-select option { background: var(--bg-input, #1a1a2e); color: var(--text-primary, #e0e0e0); padding: 4px 8px; } .config-btn-add { padding: 8px 16px; border: 1px solid var(--accent); border-radius: 6px; background: var(--accent); color: #ffffff; font-family: "JetBrains Mono", monospace; font-size: 0.8rem; font-weight: 600; cursor: pointer; transition: opacity 150ms ease; } .config-btn-add:hover { opacity: 0.9; } .config-regex-preview { padding: 8px 12px; background: var(--code-bg); border: 1px solid var(--border); border-radius: 6px; font-size: 0.75rem; color: var(--text-secondary); } .config-regex-preview code { font-family: "JetBrains Mono", monospace; color: var(--accent); background: transparent; border: none; padding: 0; } /* --- Config rows & controls --- */ .config-row { display: grid; grid-template-columns: 200px 120px 1fr; align-items: center; gap: 12px; margin-bottom: 10px; } .config-label { font-size: 0.82rem; color: var(--text-primary); font-weight: 500; } .config-input--num { flex: none; width: 120px; text-align: right; } .config-hint { font-size: 0.72rem; color: var(--text-muted); } .config-badge-restart { display: inline-block; font-size: 0.65rem; font-weight: 500; padding: 2px 8px; border-radius: 4px; background: var(--danger-bg, #3d1a18); color: var(--danger, #ff7b72); vertical-align: middle; margin-left: 6px; } .config-actions-row { display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap; } .config-btn-save { padding: 8px 20px; border: 1px solid var(--accent); border-radius: 6px; background: var(--accent); color: #fff; font-family: "JetBrains Mono", monospace; font-size: 0.8rem; font-weight: 600; cursor: pointer; transition: opacity 150ms; } .config-btn-save:hover { opacity: 0.9; } .config-btn-save.config-btn-highlight { background: var(--accent-green); border-color: var(--accent-green); animation: pulse 2s ease-in-out infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.8; } } .config-btn-secondary { padding: 8px 16px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-secondary); color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.8rem; cursor: pointer; transition: background 150ms; } .config-btn-secondary:hover { background: var(--bg-hover); } /* BUG-068: .config-btn-primary / .config-btn-danger were used by the account security section (frontend/js/auth.js) but never defined — the buttons fell back to the browser default and ignored the theme. Defined here with the same conventions as .config-btn-save / .config-btn-secondary. */ .config-btn-primary { padding: 8px 16px; border: 1px solid var(--accent); border-radius: 6px; background: var(--accent); color: #fff; font-family: "JetBrains Mono", monospace; font-size: 0.8rem; font-weight: 600; cursor: pointer; transition: opacity 150ms; } .config-btn-primary:hover { opacity: 0.9; } .config-btn-primary:disabled { opacity: 0.55; cursor: not-allowed; } .config-btn-danger { padding: 8px 16px; border: 1px solid var(--danger, #e74c3c); border-radius: 6px; background: var(--danger-bg, #3d1a18); color: var(--danger, #ff7b72); font-family: "JetBrains Mono", monospace; font-size: 0.8rem; font-weight: 600; cursor: pointer; transition: opacity 150ms; } .config-btn-danger:hover { opacity: 0.9; } .config-btn-danger:disabled { opacity: 0.55; cursor: not-allowed; } /* BUG-068: local QR code (backend SVG data: URI) + password section share the security-tab card conventions. */ .mfa-qr-code-img { max-width: 200px; border-radius: 8px; background: #fff; padding: 8px; } .password-settings { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border, #333); } .password-settings .form-group { margin: 8px 0; } .password-settings .form-group label { display: block; font-size: 0.78rem; color: var(--text-secondary, #aaa); margin-bottom: 4px; } .password-settings .config-input { width: 100%; max-width: 320px; } /* --- AI keys section: accordion redesign (#104) --- */ .ai-keys-header { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; justify-content: space-between; margin-bottom: 18px; } .ai-keys-header-text { flex: 1 1 320px; min-width: 0; } .ai-keys-header-text h2 { margin-bottom: 4px; } .ai-keys-search { position: relative; flex: 0 1 260px; min-width: 200px; } .ai-keys-search .icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; color: var(--text-muted); pointer-events: none; } .ai-keys-search input { width: 100%; padding: 8px 12px 8px 32px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); color: var(--text-primary); font-size: 0.8rem; outline: none; transition: border-color 150ms ease; } .ai-keys-search input:focus { border-color: var(--accent); } .ai-card-title { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.6px; text-transform: uppercase; color: var(--text-secondary); } .ai-default-card { background: var(--surface, #1e1e24); border: 1px solid var(--border); border-radius: 10px; padding: 16px 18px; margin-bottom: 22px; } .ai-default-card > .ai-card-title { margin-bottom: 12px; } .ai-default-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px; } .ai-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; } .ai-field-label { font-size: 0.75rem; font-weight: 500; color: var(--text-secondary); letter-spacing: 0.2px; } .ai-field .config-select, .ai-field .config-input { width: 100%; } .ai-caps-badges { display: flex; flex-wrap: wrap; gap: 6px; min-height: 22px; } .ai-cap-badge { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 999px; font-size: 0.7rem; font-weight: 600; background: var(--accent-bg); color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); } .ai-providers-header { margin: 0 0 10px; } .ai-providers-list { display: flex; flex-direction: column; gap: 8px; } .ai-provider-card { background: var(--surface, #1e1e24); border: 1px solid var(--border); border-radius: 10px; transition: border-color 150ms ease; } .ai-provider-card:hover { border-color: var(--border-md); } .ai-provider-card.open { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); } .ai-provider-head { display: flex; align-items: center; gap: 12px; padding: 12px 14px; cursor: pointer; user-select: none; border-radius: 10px; } .ai-provider-head:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; } .ai-provider-logo { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 8px; background: var(--accent-bg); color: var(--accent); font-weight: 700; font-size: 0.85rem; flex: none; } .ai-provider-name { flex: 1; font-size: 0.88rem; font-weight: 600; color: var(--text-primary); min-width: 0; } .ai-provider-badge { font-size: 0.68rem; padding: 2px 9px; border-radius: 999px; white-space: nowrap; background: var(--muted-bg, rgba(255, 255, 255, 0.06)); color: var(--text-muted); border: 1px solid var(--border); } .ai-provider-badge.configured { background: var(--success-bg); color: var(--success); border-color: color-mix(in srgb, var(--success) 40%, transparent); } .ai-provider-delete { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: none; border-radius: 6px; background: transparent; color: var(--text-muted); cursor: pointer; flex: none; transition: color 150ms ease, background 150ms ease; } .ai-provider-delete:hover { color: var(--danger); background: var(--danger-bg); } .ai-provider-chevron { flex: none; color: var(--text-muted); transition: transform 200ms ease; } .ai-provider-card.open .ai-provider-chevron { transform: rotate(180deg); } .ai-provider-body { padding: 0 14px 14px; } .ai-provider-body.hidden { display: none; } .ai-provider-fields { display: grid; grid-template-columns: 3fr 2fr; gap: 12px; padding-top: 12px; border-top: 1px solid var(--border); } .ai-providers-empty { padding: 14px; text-align: center; color: var(--text-muted); font-size: 0.8rem; border: 1px dashed var(--border); border-radius: 10px; } .ai-keys-footer { position: sticky; bottom: 0; z-index: 5; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 20px; padding: 12px 16px; background: var(--surface, #1e1e24); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.25); } .ai-keys-status { flex: 1; font-size: 0.75rem; color: var(--text-muted); min-width: 0; } @media (max-width: 600px) { .ai-default-grid, .ai-provider-fields { grid-template-columns: 1fr; } .ai-keys-search { flex: 1 1 100%; } } /* --- Config diagnostics panel --- */ .config-diagnostics { background: var(--code-bg); border: 1px solid var(--border); border-radius: 6px; padding: 14px 16px; font-family: "JetBrains Mono", monospace; font-size: 0.78rem; line-height: 1.7; color: var(--text-secondary); } .config-diag-loading { color: var(--text-muted); } .config-diag-row { display: flex; justify-content: space-between; } .config-diag-row .diag-label { color: var(--text-secondary); } .config-diag-row .diag-value { color: var(--text-primary); font-weight: 500; } .config-diag-section { margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid var(--border); } .config-diag-section:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; } .config-diag-section-title { font-weight: 600; color: var(--accent); margin-bottom: 4px; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; } @media (max-width: 768px) { .config-row { grid-template-columns: 1fr; gap: 4px; } .config-input--num { width: 100%; } } /* --- #114: Configurations modal — mobile UX refonte (viewport ≤ 768px). Builds on BUG-071 (which stacked grids/wrapped rows): the TOC becomes a left slide-over drawer with a backdrop, the modal goes full-screen with 100dvh, every interactive control gets a ≥44px touch target, inputs are ≥16px to stop iOS auto-zoom, and the backend Save row sticks to the bottom of its scroll container. The drawer is opened by JS toggling .config-toc-open on #config-modal (backdrop + nav visibility) plus an inline display on #config-nav (kept for the display-reset contract). */ @media (max-width: 768px) { /* Full-screen modal with dynamic viewport height (mobile browser chrome). */ #config-modal { padding: 0; align-items: stretch; } #config-modal .editor-container { max-width: 100%; width: 100%; height: 100vh; height: 100dvh; max-height: 100vh; max-height: 100dvh; border-radius: 0; border: none; overflow: hidden; } /* Hamburger: 44px touch target (shared .help-hamburger rule in the help modal media query also sets 44px; this scopes it to the config modal in case rule order changes). */ #config-modal .help-hamburger { display: inline-flex; width: 44px; height: 44px; min-width: 44px; } /* Close button in the TOC drawer header. */ #config-modal .help-toc-close { display: inline-flex; align-items: center; justify-content: center; } #config-modal .help-nav-header { padding: 12px 12px 8px; gap: 8px; } /* Close (X) in the modal header. */ #config-modal .editor-btn { width: 44px; height: 44px; min-width: 44px; } /* Anti-zoom: ≥16px font on text fields inside the config modal. Never target input[type=text] globally — it would clobber .mfa-code-input. */ #config-modal .config-input, #config-modal .config-select, #config-modal .help-nav-search, #config-modal .profile-field .config-input, #config-modal .profile-field .config-select { min-height: 44px; font-size: 16px; } #config-modal .config-input--num { width: 100%; text-align: left; } #config-modal .help-nav-search-wrap { padding: 0 12px 10px; } #config-modal .help-search-clear { min-width: 44px; min-height: 44px; } #config-modal .help-nav-link { min-height: 44px; display: flex; align-items: center; box-sizing: border-box; } /* Sticky Save row inside #cfg-backend-settings (its scroll container is #config-scroll.help-content, which is the overflow ancestor). */ #config-modal .config-actions-row { position: sticky; bottom: 0; z-index: 5; display: flex; flex-direction: column; gap: 8px; margin-top: 16px; margin-bottom: 0; padding: 10px 0 calc(10px + env(safe-area-inset-bottom, 0)); background: var(--bg-primary); border-top: 1px solid var(--border); } #config-modal .config-actions-row .config-btn-save, #config-modal .config-actions-row .config-btn-secondary, #config-modal .config-actions-row .config-btn-primary, #config-modal .config-actions-row .config-btn-danger { flex: 1 1 auto; width: 100%; min-height: 44px; box-sizing: border-box; } #config-modal .config-btn-save, #config-modal .config-btn-secondary, #config-modal .config-btn-primary, #config-modal .config-btn-danger, #config-modal .config-btn-add, #config-modal .config-btn-sm, #config-modal .mfa-link-btn, #config-modal .theme-action-btn, #config-modal .profile-avatar-actions .config-btn-secondary, #config-modal .editor-btn { min-height: 44px; box-sizing: border-box; } #config-modal .config-btn-sm, #config-modal .mfa-link-btn, #config-modal .theme-action-btn { min-width: 44px; padding-left: 12px; padding-right: 12px; } /* Profile avatar row: wrap instead of overflowing a 360px viewport. */ #config-modal .profile-avatar-row { flex-wrap: wrap; gap: 12px; } /* Preset avatars: 4 per row on narrow screens (44px touch targets). */ #config-modal .profile-avatar-presets { grid-template-columns: repeat(4, minmax(0, 1fr)); max-width: 100%; } #config-modal .profile-form { max-width: 100%; } /* MFA: one-column recovery list, wrapping action rows, full-width code input with a readable letter-spacing (12px overflows 360px). */ #config-modal .mfa-recovery-list { grid-template-columns: 1fr; gap: 6px; } #config-modal .mfa-verify-section, #config-modal .mfa-recovery-actions, #config-modal .mfa-disable-actions { flex-wrap: wrap; } #config-modal .mfa-verify-section .config-input, #config-modal .mfa-verify-section .config-btn-primary { flex: 1 1 100%; width: 100%; min-width: 0; box-sizing: border-box; } #config-modal .mfa-recovery-actions .config-btn-secondary, #config-modal .mfa-disable-actions .config-btn-danger { flex: 1 1 auto; min-height: 44px; box-sizing: border-box; } #config-modal .mfa-code-input { width: 100%; max-width: 320px; min-height: 52px; font-size: 24px; letter-spacing: 6px; } #config-modal .mfa-secret-code { display: block; word-break: break-all; overflow-wrap: anywhere; } #config-modal .mfa-code-input-group { flex-wrap: wrap; justify-content: flex-start; } /* WebAuthn key rows: wrap instead of clipping the remove button. */ #config-modal .webauthn-key-item { flex-wrap: wrap; gap: 8px; } #config-modal .webauthn-key-label { flex: 1 1 100%; min-width: 0; } #config-modal .webauthn-key-item .config-btn-sm { min-height: 44px; min-width: 44px; } #config-modal .hidden-files-add-row { flex-wrap: wrap; } #config-modal .hidden-files-add-row .config-input { flex: 1 1 100%; max-width: none; min-width: 0; } #config-modal .config-diag-row { flex-wrap: wrap; gap: 4px 8px; } /* AI keys sticky footer: clear the mobile toolbar + home indicator. */ #config-modal .ai-keys-footer { padding-bottom: calc(12px + env(safe-area-inset-bottom, 0)); bottom: 0; } /* Two-column grids → single column. */ #config-modal .ai-default-grid, #config-modal .ai-provider-fields { grid-template-columns: 1fr; } /* Add-rows (tokens, webhooks, tag filters) wrap instead of overflowing. */ #config-modal .config-add-row, #config-modal .config-add-pattern { flex-wrap: wrap; } #config-modal .config-add-row .config-input, #config-modal .config-add-pattern .config-input, #config-modal .config-add-row .config-select { flex: 1 1 140px; width: auto !important; /* override fixed inline widths (180/140/100px) */ min-width: 0; } #config-modal .config-add-row .config-btn-add, #config-modal .config-add-pattern .config-btn-add { flex: 1 1 auto; min-height: 44px; } /* Webhook / token / share rows wrap; long URLs and meta take their own line instead of squeezing the delete control off-screen. */ #config-modal .webhook-item, #config-modal .token-item, #config-modal .share-item { flex-wrap: wrap; } #config-modal .webhook-url, #config-modal .token-meta, #config-modal .share-url { flex: 1 1 100%; min-width: 0; white-space: normal; overflow-wrap: anywhere; } #config-modal .webhook-delete, #config-modal .token-delete, #config-modal .share-revoke { min-width: 44px; min-height: 44px; } /* Sticky AI-keys footer: full-width touch-friendly buttons. */ #config-modal .ai-keys-footer .config-btn-save, #config-modal .ai-keys-footer .config-btn-secondary { flex: 1 1 100%; min-height: 44px; } /* Long inline code in tips (ex. MCP usage snippet) must wrap. */ #config-modal .qh-tip { flex-wrap: wrap; } #config-modal .qh-tip span { min-width: 0; overflow-wrap: anywhere; } /* Drawer: left slide-over above a dimming backdrop. Higher specificity than the generic .help-nav rules (body .help-nav / .help-nav) that hide the nav on mobile. JS toggles .config-toc-open on #config-modal. */ #config-modal #config-nav { position: fixed; top: 0; left: 0; bottom: 0; width: min(320px, 88vw); min-width: 0; max-width: 88vw; max-height: 100dvh; height: 100%; box-sizing: border-box; z-index: 40; background: var(--bg-secondary); border-right: 1px solid var(--border); border-bottom: none; box-shadow: none; backdrop-filter: none; display: none; overflow: hidden; animation: config-toc-slide-in 200ms ease-out; } #config-modal.config-toc-open #config-nav { display: flex; max-height: 100dvh; } #config-modal .help-nav-list { padding-bottom: calc(20px + env(safe-area-inset-bottom, 0)); } /* Backdrop: covers the full modal, sits above the content (z-index auto) and below the drawer (z-index 40). Clicks on the pseudo-element are attributed to #config-modal, so the existing e.target === modal handler closes the drawer first; it also blocks taps reaching the content. */ #config-modal.config-toc-open::before { content: ""; position: absolute; inset: 0; z-index: 35; background: rgba(0, 0, 0, 0.45); } @keyframes config-toc-slide-in { from { transform: translateX(-100%); } to { transform: translateX(0); } } /* Content area gets a bottom pad so the sticky Save row never covers the last controls while the virtual keyboard is open. */ #config-modal #config-scroll .config-content { padding-bottom: 80px; } } /* --- Toast notifications --- */ .toast-container { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 10000; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; } .toast { padding: 10px 20px; border-radius: 8px; font-family: "JetBrains Mono", monospace; font-size: 0.82rem; color: var(--text-primary); background: var(--bg-secondary); border: 1px solid var(--border); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3); opacity: 0; transform: translateY(12px); transition: opacity 250ms ease, transform 250ms ease; pointer-events: auto; max-width: 420px; text-align: center; } .toast.show { opacity: 1; transform: translateY(0); } .toast-error { border-color: var(--danger); background: var(--danger-bg); color: var(--danger); } .toast-success { border-color: var(--success); background: var(--success-bg); color: var(--success); } /* --- Tree loading indicator --- */ .tree-loading { display: flex; align-items: center; justify-content: center; padding: 8px 16px; } /* --------------------------------------------------------------------------- Advanced Search — Autocomplete Dropdown --------------------------------------------------------------------------- */ .search-dropdown { position: absolute; top: 100%; left: 0; right: 0; margin-top: 4px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25); z-index: 200; } .search-dropdown[hidden] { display: none; } .search-dropdown__section { border-bottom: 1px solid var(--border); } .search-dropdown__section:last-child { border-bottom: none; } .search-dropdown__section[hidden] { display: none; } .search-dropdown__section-header { display: flex; align-items: center; justify-content: space-between; padding: 6px 12px; font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); background: var(--bg-primary); position: sticky; top: 0; z-index: 1; } .search-dropdown__clear-btn { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 2px 4px; border-radius: 4px; display: flex; align-items: center; } .search-dropdown__clear-btn:hover { color: var(--danger); background: var(--danger-bg, rgba(255, 0, 0, 0.08)); } .search-dropdown__list { list-style: none; margin: 0; padding: 0; } .search-dropdown__item { display: flex; align-items: center; gap: 8px; padding: 7px 12px; cursor: pointer; font-size: 0.82rem; color: var(--text-primary); transition: background 120ms ease; } .search-dropdown__item:hover, .search-dropdown__item.active { background: var(--bg-hover); } .search-dropdown__item--history { color: var(--text-secondary); } .search-dropdown__item--history .search-dropdown__icon { color: var(--text-muted); } .search-dropdown__item--title .search-dropdown__meta { font-size: 0.72rem; color: var(--text-muted); margin-left: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 180px; } .search-dropdown__item--tag .search-dropdown__badge { margin-left: auto; font-size: 0.7rem; color: var(--text-muted); background: var(--bg-primary); padding: 1px 6px; border-radius: 10px; } .search-dropdown__icon { flex-shrink: 0; width: 14px; height: 14px; color: var(--text-muted); } .search-dropdown__text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .search-dropdown__text mark { background: var(--accent); color: var(--bg-primary); border-radius: 2px; padding: 0 1px; } .search-dropdown__empty { padding: 16px 12px; text-align: center; font-size: 0.82rem; color: var(--text-muted); } .search-dropdown__empty[hidden] { display: none; } /* --------------------------------------------------------------------------- Advanced Search — Filter Chips --------------------------------------------------------------------------- */ .search-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 6px 0 0; } .search-chips[hidden] { display: none; } .search-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; font-size: 0.75rem; font-family: "JetBrains Mono", monospace; border-radius: 12px; background: var(--accent); color: var(--bg-primary); cursor: default; max-width: 200px; white-space: nowrap; } .search-chip__label { overflow: hidden; text-overflow: ellipsis; } .search-chip__remove { display: flex; align-items: center; justify-content: center; background: none; border: none; color: inherit; cursor: pointer; padding: 0; opacity: 0.7; transition: opacity 120ms; } .search-chip__remove:hover { opacity: 1; } .search-chip--tag { background: var(--accent); color: var(--bg-primary); } .search-chip--vault { background: var(--success, #22c55e); color: #fff; } .search-chip--title { background: var(--warning, #f59e0b); color: #1a1a1a; } .search-chip--path { background: var(--text-muted); color: var(--bg-primary); } /* --------------------------------------------------------------------------- Advanced Search — Snippet Highlights --------------------------------------------------------------------------- */ .search-result__snippet mark { background: var(--accent); color: var(--bg-primary); border-radius: 2px; padding: 0 2px; font-weight: 600; } /* --------------------------------------------------------------------------- Advanced Search — Facets Panel --------------------------------------------------------------------------- */ .search-facets { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 12px; padding: 10px 12px; background: var(--bg-primary); border: 1px solid var(--border); border-radius: 8px; } .search-facets[hidden] { display: none; } .search-facets__group { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; } .search-facets__label { font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); margin-right: 4px; } .search-facets__item { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; font-size: 0.75rem; border: 1px solid var(--border); border-radius: 12px; color: var(--text-secondary); background: var(--bg-secondary); cursor: pointer; transition: border-color 120ms, background 120ms; } .search-facets__item:hover { border-color: var(--accent); background: var(--bg-hover); } .search-facets__item .facet-count { font-size: 0.68rem; color: var(--text-muted); } /* --------------------------------------------------------------------------- Advanced Search — Pagination --------------------------------------------------------------------------- */ .search-pagination { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px 0; } .search-pagination__btn { padding: 6px 14px; font-size: 0.82rem; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-secondary); color: var(--text-primary); cursor: pointer; transition: border-color 120ms, background 120ms; } .search-pagination__btn:hover:not(:disabled) { border-color: var(--accent); background: var(--bg-hover); } .search-pagination__btn:disabled { opacity: 0.4; cursor: not-allowed; } .search-pagination__info { font-size: 0.78rem; color: var(--text-muted); } /* --------------------------------------------------------------------------- Advanced Search — Sort Controls --------------------------------------------------------------------------- */ .search-sort { display: flex; align-items: center; gap: 6px; margin-left: auto; } .search-sort__btn { padding: 3px 10px; font-size: 0.75rem; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; transition: all 120ms; } .search-sort__btn.active { border-color: var(--accent); color: var(--accent); background: var(--bg-hover); } /* --------------------------------------------------------------------------- Advanced Search — Responsive --------------------------------------------------------------------------- */ @media (max-width: 768px) { .search-dropdown { max-height: 280px; } .search-facets { flex-direction: column; gap: 8px; } .search-chip { max-width: 150px; } } /* --------------------------------------------------------------------------- Sync Badge — real-time connection status indicator --------------------------------------------------------------------------- */ .sync-badge { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-left: 8px; cursor: pointer; transition: background 300ms, box-shadow 300ms; flex-shrink: 0; vertical-align: middle; } .sync-badge--disconnected { background: #ef4444; box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.25); } .sync-badge--connecting { background: #f59e0b; box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.25); animation: sync-pulse 1.5s ease-in-out infinite; } .sync-badge--connected { background: #22c55e; box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.2); } .sync-badge--syncing { background: #3b82f6; box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3); animation: sync-pulse 0.8s ease-in-out infinite; } @keyframes sync-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } /* AI processing — white flash on the sync badge */ .sync-badge--ai-processing { background: #ffffff !important; box-shadow: 0 0 6px 3px rgba(255, 255, 255, 0.6) !important; animation: ai-flash 0.6s ease-in-out infinite; } @keyframes ai-flash { 0%, 100% { opacity: 1; box-shadow: 0 0 6px 3px rgba(255,255,255,0.6); } 50% { opacity: 0.3; box-shadow: 0 0 12px 6px rgba(255,255,255,0.9); } } /* ── AI Status section inside sync panel ── */ .sync-panel__ai-section { border-top: 1px solid var(--border); padding: 10px 14px; } .sync-panel__ai-title { font-size: 0.78rem; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; } .sync-panel__ai-row { display: flex; align-items: center; justify-content: space-between; margin-top: 5px; } .sync-panel__ai-label { font-size: 0.72rem; color: var(--text-muted); } .sync-panel__ai-state { font-size: 0.75rem; display: flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 4px; } .sync-panel__ai-state i { flex-shrink: 0; } .sync-panel__ai--active { color: #22c55e; background: rgba(34, 197, 94, 0.1); } .sync-panel__ai--inactive { color: #f59e0b; background: rgba(245, 158, 11, 0.1); } .sync-panel__ai--processing { color: #ffffff; background: rgba(59, 130, 246, 0.2); animation: ai-status-pulse 1s ease-in-out infinite; } .sync-panel__ai--unknown { color: var(--text-muted); background: var(--bg-tertiary); } @keyframes ai-status-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } /* --------------------------------------------------------------------------- Vault Home Page --------------------------------------------------------------------------- */ .vault-home { padding: 16px 24px; max-width: 900px; margin: 0 auto; } .vault-home-breadcrumb { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; font-size: 0.85rem; margin-bottom: 16px; padding: 8px 12px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 8px; } .vault-home-breadcrumb-item { display: inline-flex; align-items: center; gap: 4px; padding: 2px 6px; border-radius: 4px; color: var(--text-secondary); transition: background 0.15s, color 0.15s; user-select: none; } .vault-home-breadcrumb-item:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); color: var(--text-primary); } .vault-home-breadcrumb-root { font-weight: 600; color: var(--accent); } .vault-home-breadcrumb-sep { color: var(--text-muted); user-select: none; font-size: 0.8rem; } .vault-home-header { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--border); } .vault-home-count { font-size: 0.8rem; font-weight: 600; color: var(--text-primary); background: var(--bg-secondary); padding: 3px 10px; border-radius: 4px; } .vault-home-recursive-badge { font-size: 0.7rem; font-weight: 600; color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); padding: 2px 8px; border-radius: 4px; text-transform: uppercase; letter-spacing: 0.05em; } .vault-home-dir-info { font-size: 0.75rem; color: var(--text-muted); font-family: var(--font-mono); } .vault-home-results { min-height: 200px; } .vault-home-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 3rem; color: var(--text-muted); gap: 8px; } .vault-home-empty p { font-size: 0.85rem; margin: 0; } .vault-home-error { padding: 2rem; text-align: center; color: var(--danger, #ef4444); font-size: 0.85rem; } /* ── Recent files section on vault home ── */ .vault-home-recent { margin-bottom: 20px; padding: 12px 16px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 8px; } .vault-home-recent-header { display: flex; align-items: center; gap: 6px; font-size: 0.75rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px solid var(--border); } .vault-home-recent-list { display: flex; flex-direction: column; gap: 2px; } .vault-home-recent-item { display: flex; align-items: center; gap: 8px; padding: 5px 6px; border-radius: 4px; cursor: pointer; transition: background 0.12s; font-size: 0.82rem; } .vault-home-recent-item:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); } .vault-home-recent-title { color: var(--text-primary); font-weight: 500; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .vault-home-recent-dir { color: var(--text-muted); font-size: 0.72rem; font-family: var(--font-mono); max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .vault-home-recent-time { color: var(--text-muted); font-size: 0.7rem; white-space: nowrap; flex-shrink: 0; } .vault-home-item { cursor: pointer; } .vault-home-item:hover { background: var(--bg-secondary); } /* --------------------------------------------------------------------------- Sync Panel — event log overlay --------------------------------------------------------------------------- */ .sync-panel { position: fixed; top: 52px; left: 16px; width: 340px; max-height: 400px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); z-index: 9999; overflow: hidden; font-size: 0.82rem; } .sync-panel__header { display: flex; justify-content: space-between; align-items: center; padding: 12px 14px; border-bottom: 1px solid var(--border); } .sync-panel__title { font-weight: 600; color: var(--text-primary); } .sync-panel__state { font-size: 0.72rem; padding: 2px 8px; border-radius: 8px; font-weight: 500; } .sync-panel__state--connected { background: rgba(34, 197, 94, 0.15); color: #22c55e; } .sync-panel__state--disconnected { background: rgba(239, 68, 68, 0.15); color: #ef4444; } .sync-panel__state--connecting { background: rgba(245, 158, 11, 0.15); color: #f59e0b; } .sync-panel__state--syncing { background: rgba(59, 130, 246, 0.15); color: #3b82f6; } .sync-panel__empty { padding: 20px 14px; text-align: center; color: var(--text-muted); } .sync-panel__events { max-height: 320px; overflow-y: auto; padding: 4px 0; } .sync-panel__event { display: flex; align-items: center; gap: 8px; padding: 7px 14px; border-bottom: 1px solid var(--border); } .sync-panel__event:last-child { border-bottom: none; } .sync-panel__event-type { font-weight: 500; color: var(--text-primary); white-space: nowrap; } .sync-panel__event-detail { color: var(--text-secondary); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .sync-panel__event-time { font-size: 0.7rem; color: var(--text-muted); white-space: nowrap; } /* --------------------------------------------------------------------------- Toast — info variant (blue) --------------------------------------------------------------------------- */ .toast.toast-info { background: #1e3a5f; border-left: 4px solid #3b82f6; color: #bfdbfe; } [data-theme="light"] .toast.toast-info { background: #eff6ff; border-left: 4px solid #3b82f6; color: #1e40af; } /* --------------------------------------------------------------------------- Config Toggle Switch --------------------------------------------------------------------------- */ .config-toggle { position: relative; display: inline-block; width: 40px; height: 22px; flex-shrink: 0; } .config-toggle input { opacity: 0; width: 0; height: 0; } .config-toggle-slider { position: absolute; cursor: pointer; inset: 0; background: var(--bg-hover); border: 1px solid var(--border); border-radius: 22px; transition: background 200ms, border-color 200ms; } .config-toggle-slider::before { content: ""; position: absolute; height: 16px; width: 16px; left: 2px; bottom: 2px; background: var(--text-muted); border-radius: 50%; transition: transform 200ms, background 200ms; } .config-toggle input:checked + .config-toggle-slider { background: rgba(34, 197, 94, 0.2); border-color: #22c55e; } .config-toggle input:checked + .config-toggle-slider::before { transform: translateX(18px); background: #22c55e; } /* --------------------------------------------------------------------------- Hidden Files Configuration --------------------------------------------------------------------------- */ .hidden-files-vault-card { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 6px; padding: 12px; margin-bottom: 12px; transition: border-color 200ms ease; } .hidden-files-vault-card:hover { border-color: var(--accent); } .hidden-files-vault-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--border); } .hidden-files-vault-header h3 { font-size: 0.95rem; font-weight: 600; color: var(--text-primary); margin: 0; } .hidden-files-vault-type { font-size: 0.7rem; padding: 2px 6px; background: var(--tag-bg); color: var(--tag-text); border-radius: 3px; font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.5px; } .hidden-files-whitelist { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); } .hidden-files-whitelist-items { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; min-height: 28px; padding: 4px; background: var(--bg-primary); border-radius: 4px; border: 1px dashed var(--border); } .hidden-files-whitelist-items:empty::before { content: "Aucun dossier dans la liste blanche"; color: var(--text-muted); font-size: 0.85rem; font-style: italic; } .hidden-files-whitelist-item { display: inline-flex; align-items: center; gap: 4px; padding: 3px 6px 3px 8px; background: var(--tag-bg); color: var(--tag-text); border-radius: 4px; font-size: 0.85rem; font-family: var(--mono); border: 1px solid color-mix(in srgb, var(--tag-text) 30%, transparent); transition: all 150ms ease; } .hidden-files-whitelist-item:hover { background: color-mix(in srgb, var(--tag-bg) 80%, var(--accent) 20%); border-color: var(--accent); } .whitelist-item-text { user-select: none; } .whitelist-item-remove { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 1.1rem; line-height: 1; padding: 0 2px; transition: all 150ms ease; border-radius: 2px; } .whitelist-item-remove:hover { color: var(--danger); background: color-mix(in srgb, var(--danger) 15%, transparent); } .hidden-files-add-row { display: flex; gap: 8px; align-items: center; margin-top: 4px; } .hidden-files-add-row .config-input { flex: 1; max-width: 250px; font-family: var(--mono); font-size: 0.9rem; } /* --------------------------------------------------------------------------- Utility — hidden class --------------------------------------------------------------------------- */ .hidden { display: none !important; } /* --------------------------------------------------------------------------- Login Screen --------------------------------------------------------------------------- */ .login-screen { position: fixed; inset: 0; z-index: 10001; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #090e17 0%, #101827 50%, #1b2838 100%); } .login-card { width: 380px; max-width: 90vw; background: rgba(30, 30, 46, 0.85); backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 16px; padding: 40px 36px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); animation: loginFadeIn 0.4s ease-out; } @keyframes loginFadeIn { from { opacity: 0; transform: translateY(20px) scale(0.97); } to { opacity: 1; transform: translateY(0) scale(1); } } .login-header { text-align: center; margin-bottom: 32px; } .login-logo { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 8px; } .login-logo-icon { font-size: 2rem; } .login-logo-text { font-size: 1.8rem; font-weight: 700; background: linear-gradient(135deg, #7dd3fc, #38bdf8, #0ea5e9); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; letter-spacing: -0.02em; } .login-subtitle { font-size: 0.88rem; color: rgba(255, 255, 255, 0.45); margin: 0; } .login-form .form-group { margin-bottom: 20px; } .login-form .form-group label { display: block; font-size: 0.82rem; font-weight: 500; color: rgba(255, 255, 255, 0.6); margin-bottom: 6px; } .login-form input[type="text"], .login-form input[type="password"] { width: 100%; padding: 12px 14px; border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 10px; background: rgba(255, 255, 255, 0.06); color: #e2e8f0; font-size: 0.92rem; font-family: inherit; outline: none; transition: border-color 200ms, box-shadow 200ms; box-sizing: border-box; } .login-form input:focus { border-color: #818cf8; box-shadow: 0 0 0 3px rgba(129, 140, 248, 0.2); } .login-form input::placeholder { color: rgba(255, 255, 255, 0.25); } .password-input-wrapper { position: relative; } .password-toggle { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer; font-size: 1rem; opacity: 0.5; transition: opacity 150ms; padding: 4px; } .password-toggle:hover { opacity: 0.9; } .form-group--inline { display: flex; align-items: center; } .checkbox-label { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.82rem; color: rgba(255, 255, 255, 0.5); } .checkbox-label input[type="checkbox"] { accent-color: #818cf8; width: 15px; height: 15px; } .login-error { padding: 10px 14px; border-radius: 8px; background: rgba(239, 68, 68, 0.12); border: 1px solid rgba(239, 68, 68, 0.3); color: #fca5a5; font-size: 0.82rem; margin-bottom: 16px; } .btn-login { width: 100%; padding: 13px 24px; border: none; border-radius: 10px; background: linear-gradient(135deg, #3b82f6, #2563eb); color: #fff; font-size: 0.95rem; font-weight: 600; cursor: pointer; transition: opacity 200ms, transform 100ms; display: flex; align-items: center; justify-content: center; gap: 8px; font-family: inherit; } .btn-login:hover:not(:disabled) { opacity: 0.92; } .btn-login:active:not(:disabled) { transform: scale(0.98); } .btn-login:disabled { opacity: 0.6; cursor: not-allowed; } .btn-spinner { font-size: 1rem; } /* Light theme login */ [data-theme="light"] .login-screen { background: linear-gradient(135deg, #dbeafe, #eff6ff, #bfdbfe); } [data-theme="light"] .login-card { background: rgba(255, 255, 255, 0.9); border: 1px solid rgba(0, 0, 0, 0.08); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.12); } [data-theme="light"] .login-subtitle { color: rgba(0, 0, 0, 0.45); } [data-theme="light"] .login-form .form-group label { color: rgba(0, 0, 0, 0.6); } [data-theme="light"] .login-form input[type="text"], [data-theme="light"] .login-form input[type="password"] { background: rgba(0, 0, 0, 0.04); border-color: rgba(0, 0, 0, 0.12); color: #1e293b; } [data-theme="light"] .login-form input::placeholder { color: rgba(0, 0, 0, 0.3); } [data-theme="light"] .checkbox-label { color: rgba(0, 0, 0, 0.5); } [data-theme="light"] .login-error { background: rgba(239, 68, 68, 0.08); color: #dc2626; } /* --------------------------------------------------------------------------- User Menu (header) --------------------------------------------------------------------------- */ .user-menu { display: flex; align-items: center; gap: 8px; } .user-display-name { font-size: 0.8rem; color: var(--text-secondary); font-weight: 500; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .user-menu-link, .btn-logout { display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 4px; border-radius: 4px; transition: color 150ms, background 150ms; } .user-menu-link:hover, .btn-logout:hover { color: var(--text-primary); background: var(--bg-hover); } .btn-logout:hover { color: var(--danger); } /* --------------------------------------------------------------------------- Sidebar account section (#112) — identity + logout pinned at the bottom --------------------------------------------------------------------------- */ .sidebar-user { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--border); background: var(--bg-sidebar); flex-shrink: 0; } .sidebar-user[hidden] { display: none; } .sidebar-user-profile { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; padding: 6px 8px; border: 1px solid transparent; border-radius: 8px; background: transparent; cursor: pointer; text-align: left; transition: background 150ms ease, border-color 150ms ease; } .sidebar-user-profile:hover { background: var(--bg-hover); border-color: var(--border); } .sidebar-user-avatar { width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.02em; color: #fff; background: linear-gradient(135deg, var(--accent), color-mix(in srgb, var(--accent) 55%, #7c3aed)); } /* #113 — custom avatar image fills the circle; initials stay the fallback */ .sidebar-user-avatar-img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block; } .sidebar-user-meta { display: flex; flex-direction: column; gap: 1px; min-width: 0; } .sidebar-user-name { font-size: 0.82rem; font-weight: 600; color: var(--text-primary); max-width: none; } .sidebar-user-role { font-size: 0.7rem; color: var(--text-muted); } .sidebar-user-logout { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; flex-shrink: 0; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--text-muted); cursor: pointer; transition: color 150ms ease, background 150ms ease, border-color 150ms ease; } .sidebar-user-logout:hover { color: var(--danger); background: var(--bg-hover); border-color: var(--border); } /* Version row inside the header options menu (#112) */ .menu-list-version { cursor: default; border-top: 1px solid var(--border); margin-top: 4px; padding-top: 8px; } .menu-list-version .version-badge { margin-left: 4px; } /* --------------------------------------------------------------------------- Admin Panel --------------------------------------------------------------------------- */ .admin-toolbar { padding: 16px; display: flex; justify-content: flex-end; } .admin-users-list { padding: 0 16px 16px; } .admin-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; } .admin-table th, .admin-table td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--border); } .admin-table th { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); font-weight: 600; background: var(--bg-primary); position: sticky; top: 0; } .admin-table td { color: var(--text-primary); } .admin-role-badge { display: inline-block; padding: 2px 10px; border-radius: 10px; font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; } .admin-role-admin { background: rgba(59, 130, 246, 0.15); color: #3b82f6; } .admin-role-user { background: rgba(34, 197, 94, 0.12); color: #22c55e; } .admin-vaults-text { font-size: 0.78rem; color: var(--text-secondary); } .admin-actions { white-space: nowrap; } .admin-action-btn { background: none; border: none; cursor: pointer; padding: 4px 6px; border-radius: 4px; font-size: 0.9rem; transition: background 150ms; } .admin-action-btn:hover { background: var(--bg-hover); } .admin-action-btn.danger:hover { background: rgba(239, 68, 68, 0.12); } /* Admin form overlay */ .admin-form-overlay { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.6); display: flex; align-items: center; justify-content: center; z-index: 10; backdrop-filter: blur(4px); } .admin-form-card { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 12px; padding: 28px 24px; width: 440px; max-width: 90vw; max-height: 80vh; overflow-y: auto; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3); } .admin-form-card h3 { margin: 0 0 20px; font-size: 1.05rem; color: var(--text-primary); } .admin-form-card .form-group { margin-bottom: 16px; } .admin-form-card .form-group label { display: block; font-size: 0.82rem; font-weight: 500; color: var(--text-secondary); margin-bottom: 6px; } .admin-form-card input[type="text"], .admin-form-card input[type="password"], .admin-form-card select { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-primary); font-size: 0.88rem; font-family: inherit; outline: none; transition: border-color 200ms; box-sizing: border-box; } .admin-form-card input:focus, .admin-form-card select:focus { border-color: var(--accent); } .admin-vault-list { display: flex; flex-direction: column; gap: 6px; max-height: 160px; overflow-y: auto; padding: 8px; background: var(--bg-primary); border: 1px solid var(--border); border-radius: 8px; } .admin-vault-list .checkbox-label { color: var(--text-primary); font-size: 0.82rem; } .admin-form-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px; } /* --------------------------------------------------------------------------- Popup Mode (Nouvelle fenêtre) --------------------------------------------------------------------------- */ body.popup-mode .top-nav, body.popup-mode .sidebar, body.popup-mode .resizer, body.popup-mode .content-header { display: none !important; } body.popup-mode .main-layout { height: 100vh; } body.popup-mode .content-area { margin: 15px auto; padding: 30px; border: 1px solid var(--border); border-radius: 12px; height: calc(100vh - 30px); max-width: 1000px; overflow-y: auto; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15); box-sizing: border-box; } /* --------------------------------------------------------------------------- Recent Tab Styles --------------------------------------------------------------------------- */ /* Liste récente */ .recent-list { display: flex; flex-direction: column; gap: 2px; padding: 4px 0; } /* Item */ .recent-item { padding: 10px 12px; border-radius: 6px; cursor: pointer; border-left: 3px solid transparent; transition: background 0.15s, border-color 0.15s; } .recent-item:hover { background: var(--bg-secondary); border-left-color: var(--accent); } .recent-item.active { border-left-color: var(--accent); background: var(--bg-secondary); } /* Header: temps + badge vault */ .recent-item-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 3px; } .recent-time { font-size: 11px; color: var(--text-muted); display: flex; align-items: center; gap: 4px; } .recent-vault-badge { font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 10px; background: var(--accent); color: #fff; opacity: 0.85; } /* Titre */ .recent-item-title { font-size: 13px; font-weight: 600; color: var(--text-primary); margin-bottom: 2px; } /* Breadcrumb path */ .recent-item-path { font-size: 11px; color: var(--text-muted); margin-bottom: 4px; font-family: monospace; } /* Preview */ .recent-item-preview { font-size: 12px; color: var(--text-muted); display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; line-height: 1.4; margin-bottom: 5px; } /* Tags */ .recent-item-tags { display: flex; flex-wrap: wrap; gap: 4px; } .recent-item-tags .tag-pill { font-size: 10px; padding: 1px 6px; border-radius: 10px; background: var(--bg-secondary); color: var(--accent); border: 1px solid var(--border); } /* Filtre vault */ .recent-filter-bar { padding: 8px 12px 4px; } .recent-filter-bar select { width: 100%; padding: 4px 8px; font-size: 12px; background: var(--bg-secondary); color: var(--text-primary); border: 1px solid var(--border); border-radius: 4px; cursor: pointer; } /* État vide */ .recent-empty { display: flex; flex-direction: column; align-items: center; padding: 32px 16px; color: var(--text-muted); gap: 8px; font-size: 13px; } /* --------------------------------------------------------------------------- Find in Page --------------------------------------------------------------------------- */ /* Animation d'entrée */ @keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } /* Barre principale */ .find-in-page-bar { position: fixed; bottom: 20px; right: 20px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 12px; padding: 12px 16px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); z-index: 1000; animation: slideUp 200ms ease; max-width: calc(100vw - 40px); } .find-in-page-bar[hidden] { display: none; } /* Contenu de la barre */ .find-in-page-content { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } /* Icône de recherche */ .find-icon { color: var(--text-secondary); flex-shrink: 0; } /* Input de recherche */ #find-input { flex: 1; min-width: 200px; padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-primary); color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.85rem; outline: none; transition: border-color 200ms ease; } #find-input:focus { border-color: var(--accent); } /* Compteur d'occurrences */ .find-counter { font-family: "JetBrains Mono", monospace; font-size: 0.75rem; color: var(--text-secondary); white-space: nowrap; min-width: 90px; text-align: center; } /* Boutons de navigation */ .find-nav-buttons { display: flex; gap: 4px; } /* Boutons génériques */ .find-btn { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-primary); color: var(--text-secondary); cursor: pointer; transition: all 150ms ease; padding: 0; flex-shrink: 0; } .find-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--bg-primary)); } .find-btn:disabled { opacity: 0.4; cursor: not-allowed; } /* Options */ .find-options { display: flex; gap: 4px; border-left: 1px solid var(--border); padding-left: 10px; } .find-option-btn { font-family: "JetBrains Mono", monospace; font-size: 0.7rem; font-weight: 600; } .find-option-btn[aria-pressed="true"] { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 20%, var(--bg-primary)); color: var(--accent); } .find-option-text { pointer-events: none; } /* Bouton fermer */ .find-close { border-left: 1px solid var(--border); margin-left: 6px; } .find-close:hover { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); } /* Message d'erreur */ .find-error { margin-top: 8px; padding: 6px 10px; background: var(--danger-bg); border: 1px solid var(--danger); border-radius: 6px; color: var(--danger); font-size: 0.75rem; font-family: "JetBrains Mono", monospace; } .find-error[hidden] { display: none; } /* Highlights dans le contenu */ .find-highlight { background: rgba(255, 235, 59, 0.4); padding: 0 2px; border-radius: 2px; transition: background 150ms ease; } [data-theme="dark"] .find-highlight { background: rgba(255, 193, 7, 0.35); } .find-highlight-active { background: rgba(255, 193, 7, 0.7); box-shadow: 0 0 0 2px rgba(255, 193, 7, 0.3); } [data-theme="dark"] .find-highlight-active { background: rgba(255, 193, 7, 0.6); box-shadow: 0 0 0 2px rgba(255, 193, 7, 0.4); } /* Responsive mobile */ @media (max-width: 768px) { .find-in-page-bar { bottom: 10px; left: 10px; right: 10px; max-width: none; padding: 10px 12px; } .find-in-page-content { gap: 6px; } #find-input { min-width: 120px; font-size: 0.8rem; } .find-counter { font-size: 0.7rem; min-width: 80px; } .find-btn { width: 32px; height: 32px; } .find-options { padding-left: 6px; } } /* ===== PWA STYLES ===== */ /* PWA Update Notification */ .pwa-update-notification { position: fixed; bottom: 20px; right: 20px; z-index: 10000; animation: slideInUp 0.3s ease-out; } .pwa-update-content { background: var(--accent); color: white; padding: 16px 20px; border-radius: var(--radius); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); display: flex; align-items: center; gap: 12px; max-width: 400px; } .pwa-update-content span { flex: 1; font-size: 0.9rem; font-weight: 500; } .pwa-update-btn { background: white; color: var(--accent); border: none; padding: 8px 16px; border-radius: var(--radius); font-size: 0.85rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; white-space: nowrap; } .pwa-update-btn:hover { transform: translateY(-1px); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); } .pwa-update-dismiss { background: transparent; border: none; color: white; font-size: 1.5rem; line-height: 1; cursor: pointer; padding: 0; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; opacity: 0.8; transition: opacity 0.2s ease; } .pwa-update-dismiss:hover { opacity: 1; } /* PWA Install Button (optional - can be added to header) */ #pwa-install-btn { display: none; background: var(--accent); color: white; border: none; padding: 8px 16px; border-radius: var(--radius); font-size: 0.85rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; } #pwa-install-btn:hover { background: var(--accent-green); transform: translateY(-1px); } /* Animations */ @keyframes slideInUp { from { transform: translateY(100%); opacity: 0; } to { transform: translateY(0); opacity: 1; } } /* Mobile responsive */ @media (max-width: 768px) { .pwa-update-notification { bottom: 10px; right: 10px; left: 10px; } .pwa-update-content { padding: 12px 16px; font-size: 0.85rem; } .pwa-update-btn { padding: 6px 12px; font-size: 0.8rem; } } /* --------------------------------------------------------------------------- Dashboard Home - Recent Files Widget --------------------------------------------------------------------------- */ .dashboard-home { padding: 0; width: 100%; display: flex; flex-direction: column; gap: 32px; } .dashboard-section { display: flex; flex-direction: column; } .dashboard-header { margin-bottom: 20px; } .dashboard-title-row { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; } .dashboard-icon { width: 28px; height: 28px; color: var(--accent); } .dashboard-title-row h2 { font-family: "JetBrains Mono", monospace; font-size: 1.4rem; font-weight: 600; color: var(--text-primary); margin: 0; } .dashboard-filter-row { display: flex; align-items: center; gap: 12px; } .dashboard-select { padding: 6px 12px; font-size: 13px; background: var(--bg-secondary); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px; cursor: pointer; min-width: 160px; } .dashboard-select:focus { outline: none; border-color: var(--accent); } .dashboard-count { font-size: 12px; color: var(--text-muted); padding: 4px 10px; background: var(--bg-secondary); border-radius: 12px; } /* Grid */ .dashboard-recent-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; flex: 1; width: 100%; } @media (max-width: 1200px) { .dashboard-recent-grid { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 768px) { .dashboard-home { padding: 16px; } .dashboard-recent-grid { grid-template-columns: 1fr; } .dashboard-title-row h2 { font-size: 1.2rem; } } /* Card */ .dashboard-card { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 12px; padding: 12px; cursor: pointer; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); position: relative; display: flex; flex-direction: column; gap: 4px; animation: fadeSlideIn 0.3s ease forwards; opacity: 0; /* BUG-017: allow the card to shrink inside the grid instead of overflowing the viewport because of long nowrap titles/paths. */ min-width: 0; overflow: hidden; } .dashboard-card:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3); border-color: var(--accent); } .dashboard-card:active { transform: translateY(0); } @keyframes fadeSlideIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } /* Staggered animation for cards */ .dashboard-card:nth-child(1) { animation-delay: 0ms; } .dashboard-card:nth-child(2) { animation-delay: 50ms; } .dashboard-card:nth-child(3) { animation-delay: 100ms; } .dashboard-card:nth-child(4) { animation-delay: 150ms; } .dashboard-card:nth-child(5) { animation-delay: 200ms; } .dashboard-card:nth-child(6) { animation-delay: 250ms; } .dashboard-card:nth-child(7) { animation-delay: 300ms; } .dashboard-card:nth-child(8) { animation-delay: 350ms; } .dashboard-card:nth-child(9) { animation-delay: 400ms; } /* Card header */ .dashboard-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; min-width: 0; } .dashboard-card-icon { width: 40px; height: 40px; padding: 4px; background: transparent; border: 2px solid var(--accent); border-radius: 8px; color: var(--accent); flex-shrink: 0; display: flex; align-items: center; justify-content: center; } .dashboard-card-icon svg { width: 24px; height: 24px; } .dashboard-vault-badge { font-size: 10px; font-weight: 600; padding: 3px 8px; border-radius: 10px; background: var(--bg-primary); color: var(--text-secondary); border: 1px solid var(--border); margin-right: auto; } .dashboard-card-bookmark-btn { background: transparent; border: none; color: var(--text-muted); cursor: pointer; padding: 4px; border-radius: 4px; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; } .dashboard-card-bookmark-btn:hover { background: var(--bg-primary); color: var(--accent); } .dashboard-card-bookmark-btn.active { color: var(--accent-green); } /* Card title */ .dashboard-card-title { font-size: 14px; font-weight: 600; color: var(--text-primary); margin: 0; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; } /* Card path */ .dashboard-card-path { font-size: 11px; color: var(--text-muted); font-family: "JetBrains Mono", monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Card preview */ .dashboard-card-preview { display: none; } /* Card footer */ .dashboard-card-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; padding-top: 6px; border-top: 1px solid color-mix(in srgb, var(--border) 50%, transparent); min-width: 0; } .dashboard-card-time { font-size: 11px; color: var(--text-muted); display: flex; align-items: center; gap: 4px; } .dashboard-card-time svg { width: 12px; height: 12px; } /* Card tags */ .dashboard-card-tags { display: flex; flex-wrap: wrap; gap: 4px; } .dashboard-card-tags .tag-pill { font-size: 10px; padding: 2px 6px; border-radius: 8px; background: var(--bg-tertiary); color: var(--accent); border: 1px solid var(--border); } /* Empty state */ .dashboard-recent-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 24px; color: var(--text-muted); gap: 12px; text-align: center; flex: 1; } .dashboard-recent-empty svg { width: 48px; height: 48px; opacity: 0.4; } .dashboard-recent-empty span { font-size: 16px; font-weight: 500; } .dashboard-recent-empty p { font-size: 13px; margin: 0; opacity: 0.7; } /* Loading skeletons */ .dashboard-loading { display: none; grid-template-columns: repeat(3, 1fr); gap: 16px; } .dashboard-loading.active { display: grid; } @media (max-width: 1200px) { .dashboard-loading { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 768px) { .dashboard-loading { grid-template-columns: 1fr; } } .skeleton-card { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 12px; padding: 16px; height: 160px; position: relative; overflow: hidden; } .skeleton-card::after { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.05), transparent); animation: shimmer 1.5s infinite; } @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } /* ===== CONTEXT MENU ===== */ .context-menu { position: fixed; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); min-width: 200px; z-index: 10000; padding: 4px; display: none; } .context-menu.active { display: block; } .context-menu-item { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-radius: 6px; cursor: pointer; font-family: "JetBrains Mono", monospace; font-size: 0.82rem; color: var(--text-primary); transition: all 150ms ease; } .context-menu-item:hover:not(.disabled) { background: var(--bg-hover); color: var(--accent); } .context-menu-item.disabled { opacity: 0.4; cursor: not-allowed; } .context-menu-item .icon { width: 16px; height: 16px; flex-shrink: 0; } .context-menu-separator { height: 1px; background: var(--border); margin: 4px 0; } /* ===== INLINE RENAME ===== */ .sidebar-item-input { width: 100%; padding: 4px 8px; background: var(--bg-primary); border: 1px solid var(--accent); border-radius: 4px; color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.82rem; outline: none; } /* ===== VAULT READONLY BADGE ===== */ .vault-readonly-badge { display: inline-flex; align-items: center; gap: 4px; padding: 2px 6px; background: var(--danger-bg); color: var(--danger); border-radius: 4px; font-size: 0.7rem; font-weight: 600; margin-left: 6px; } /* ===== OBSIGATE MODALS ===== */ .obsigate-modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: var(--overlay-bg); z-index: 9999; display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: opacity 200ms ease; } .obsigate-modal-overlay.active { opacity: 1; pointer-events: all; } .obsigate-modal { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5); min-width: 400px; max-width: 600px; transform: scale(0.9); transition: transform 200ms ease; } .obsigate-modal-overlay.active .obsigate-modal { transform: scale(1); } .obsigate-modal-header { padding: 16px 20px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; } .obsigate-modal-title { font-family: "JetBrains Mono", monospace; font-size: 1.1rem; font-weight: 700; color: var(--text-primary); } .obsigate-modal-body { padding: 20px; } .obsigate-modal-footer { padding: 16px 20px; border-top: 1px solid var(--border); display: flex; gap: 10px; justify-content: flex-end; } .modal-input { width: 100%; padding: 10px 12px; background: var(--bg-primary); border: 1px solid var(--border); border-radius: 6px; color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.9rem; outline: none; transition: border-color 200ms ease; } .modal-input:focus { border-color: var(--accent); } .modal-input.error { border-color: var(--danger); } .modal-label { display: block; font-family: "JetBrains Mono", monospace; font-size: 0.85rem; font-weight: 600; color: var(--text-secondary); margin-bottom: 8px; } .modal-hint { font-size: 0.75rem; color: var(--text-muted); margin-top: 6px; } .modal-error { font-size: 0.8rem; color: var(--danger); margin-top: 6px; } .modal-select { width: 100%; padding: 10px 12px; background: var(--bg-primary); border: 1px solid var(--border); border-radius: 6px; color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.9rem; outline: none; cursor: pointer; transition: border-color 200ms ease; } .modal-select:focus { border-color: var(--accent); } .modal-btn { padding: 8px 16px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-primary); color: var(--text-primary); font-family: "JetBrains Mono", monospace; font-size: 0.85rem; cursor: pointer; transition: all 150ms ease; } .modal-btn:hover { border-color: var(--accent); color: var(--accent); } .modal-btn.primary { background: var(--accent); color: white; border-color: var(--accent); } .modal-btn.primary:hover { opacity: 0.9; } .modal-btn.danger { background: var(--danger); color: white; border-color: var(--danger); } .modal-btn.danger:hover { opacity: 0.9; } .modal-btn:disabled { opacity: 0.5; cursor: not-allowed; } .modal-form-group { margin-bottom: 16px; } .modal-form-group:last-child { margin-bottom: 0; } .modal-warning { padding: 12px; background: var(--danger-bg); border: 1px solid var(--danger); border-radius: 6px; color: var(--danger); font-size: 0.85rem; margin-bottom: 16px; display: flex; align-items: flex-start; gap: 10px; } .modal-warning .icon { flex-shrink: 0; margin-top: 2px; } /* ===== TAB BAR ===== */ .tab-bar { display: flex; align-items: stretch; background: var(--bg-secondary); border-bottom: 1px solid var(--border); overflow: hidden; flex-shrink: 0; min-height: 36px; } .tab-bar[hidden] { display: none; } .tab-list { display: flex; align-items: stretch; overflow-x: auto; overflow-y: hidden; flex: 1; scrollbar-width: thin; } /* Split buttons in tab bar */ .tab-split-buttons { display: flex; align-items: center; gap: 2px; padding: 0 4px; flex-shrink: 0; opacity: 0.3; transition: opacity 150ms ease; } .tab-bar:hover .tab-split-buttons, .tab-split-buttons:hover { opacity: 1; } .tab-split-btn { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: none; border-radius: 4px; background: transparent; color: var(--text-muted); cursor: pointer; transition: background 100ms ease, color 100ms ease; } .tab-split-btn:hover { background: var(--bg-hover); color: var(--accent); } .tab-list::-webkit-scrollbar { height: 3px; } .tab-item { display: flex; align-items: center; gap: 6px; padding: 6px 12px; font-size: 0.8rem; color: var(--text-muted); cursor: pointer; white-space: nowrap; border-right: 1px solid var(--border); background: transparent; transition: background 0.15s, color 0.15s; user-select: none; position: relative; min-width: 0; flex-shrink: 0; } .tab-item:hover { background: var(--bg-hover); color: var(--text-secondary); } .tab-item.active { background: var(--bg-primary); color: var(--text-primary); border-bottom: 2px solid var(--accent); margin-bottom: -1px; } .tab-item .tab-icon { width: 14px; height: 14px; flex-shrink: 0; opacity: 0.7; } .tab-item .tab-name { overflow: hidden; text-overflow: ellipsis; max-width: 150px; } /* Preview tab (single-click) — italic title, slightly muted */ .tab-item.preview .tab-name { font-style: italic; opacity: 0.75; } .tab-item.preview { background: var(--bg-hover); } .tab-item .tab-close { width: 16px; height: 16px; display: flex; align-items: center; justify-content: center; border-radius: 3px; flex-shrink: 0; opacity: 0; transition: opacity 0.15s, background 0.15s; } .tab-item:hover .tab-close, .tab-item.active .tab-close { opacity: 0.6; } .tab-item .tab-close:hover { opacity: 1; background: var(--bg-hover); } .tab-item.dragging { opacity: 0.5; background: var(--bg-hover); } .tab-drop-indicator { width: 2px; background: var(--accent); flex-shrink: 0; } /* ── Backlinks panel ── */ .backlinks-panel { margin-top: 24px; padding: 12px 16px; background: var(--bg-card, var(--bg-secondary)); border-radius: 8px; border: 1px solid var(--border); } .backlinks-header { font-size: 0.8rem; font-weight: 600; color: var(--text-muted); display: flex; align-items: center; gap: 6px; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; } .backlinks-list { display: flex; flex-direction: column; gap: 4px; } .backlink-item { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 4px; cursor: pointer; transition: background 0.15s; } .backlink-item:hover { background: var(--bg-hover); } .backlink-vault { font-size: 0.7rem; color: var(--accent); background: var(--accent-bg, rgba(99, 102, 241, 0.1)); padding: 1px 6px; border-radius: 3px; } .backlink-title { font-size: 0.85rem; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* ── Unsupported file notice ── */ .unsupported-file { padding: 40px; text-align: center; color: var(--text-muted); } .unsupported-file i { display: block; margin: 0 auto 12px; opacity: 0.4; } .unsupported-file .filename { font-weight: 600; color: var(--text-primary); margin-bottom: 8px; word-break: break-all; } .unsupported-file .btn-action { margin-top: 12px; display: inline-flex; } /* ── Dashboard Stats Grid ── */ .dashboard-stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; } .stat-card { display: flex; flex-direction: column; align-items: center; padding: 16px 12px; background: var(--bg-card, var(--bg-secondary)); border-radius: 8px; border: 1px solid var(--border); } .stat-icon { width: 24px; height: 24px; opacity: 0.6; margin-bottom: 8px; color: var(--accent); } .stat-value { font-size: 1.4rem; font-weight: 700; color: var(--text-primary); } .stat-label { font-size: 0.75rem; color: var(--text-muted); margin-top: 2px; } .dashboard-stats-loading { padding: 16px; text-align: center; color: var(--text-muted); } /* ── Dashboard Conflicts ── */ .dashboard-conflicts-grid { display: flex; flex-direction: column; gap: 8px; } .conflict-card { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; background: var(--bg-card, var(--bg-secondary)); border-radius: 6px; border: 1px solid var(--border); gap: 12px; } .conflict-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; } .conflict-vault { font-size: 0.7rem; color: var(--accent); background: var(--accent-bg, rgba(99,102,241,0.1)); padding: 1px 6px; border-radius: 3px; align-self: flex-start; } .conflict-name { font-size: 0.85rem; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .conflict-date { font-size: 0.7rem; color: var(--text-muted); } .conflict-actions { display: flex; gap: 8px; flex-shrink: 0; } .conflict-btn { padding: 4px 10px; font-size: 0.75rem; border: 1px solid var(--border); border-radius: 4px; cursor: pointer; background: var(--bg-primary); color: var(--text-primary); white-space: nowrap; } .conflict-btn:hover { background: var(--bg-hover); } /* ── Quick Help (Dashboard) ── */ .quick-help { margin-top: 16px; background: var(--bg-card, var(--bg-secondary)); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; } .qh-header { display: flex; align-items: center; gap: 8px; padding: 10px 14px; font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); border-bottom: 1px solid var(--border); user-select: none; } .qh-header i { color: var(--accent); opacity: 0.7; } .qh-toggle { margin-left: auto; background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 1rem; line-height: 1; padding: 2px 6px; border-radius: 4px; } .qh-toggle:hover { color: var(--text-secondary); background: var(--bg-hover); } .qh-body { padding: 10px 14px 14px; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 6px 20px; } .qh-body.collapsed { display: none; } .qh-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; } .qh-kbd { display: inline-flex; align-items: center; padding: 2px 8px; font-family: var(--mono); font-size: 0.7rem; font-weight: 500; color: var(--accent-text, #79c0ff); background: var(--accent-bg, #1f2a3a); border: 1px solid var(--border-md, #30363d); border-radius: 4px; white-space: nowrap; min-width: 0; letter-spacing: 0.3px; } .qh-desc { font-size: 0.78rem; color: var(--text-secondary); } .qh-divider { grid-column: 1 / -1; height: 1px; background: var(--border); margin: 6px 0 8px; } .qh-tip { grid-column: 1 / -1; display: flex; align-items: flex-start; gap: 8px; font-size: 0.75rem; color: var(--text-muted); line-height: 1.5; } .qh-tip i { color: var(--warn); flex-shrink: 0; margin-top: 1px; } .qh-tip strong { color: var(--text-secondary); } /* ── Webhooks UI ── */ .webhook-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; background: var(--bg-card, var(--bg-secondary)); border-radius: 6px; margin-bottom: 6px; font-size: 0.8rem; } .webhook-name { font-weight: 500; min-width: 80px; } .webhook-url { color: var(--accent); overflow: hidden; text-overflow: ellipsis; flex: 1; } .webhook-events { color: var(--text-muted); font-size: 0.7rem; } .webhook-delete { background: none; border: none; color: var(--text-error); cursor: pointer; font-size: 1rem; padding: 2px 6px; } .config-add-row { display: flex; gap: 8px; margin-top: 8px; } /* ── API/MCP tokens UI (#107) ── */ .token-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; background: var(--bg-card, var(--bg-secondary)); border-radius: 6px; margin-bottom: 6px; font-size: 0.8rem; } .token-name { font-weight: 500; min-width: 90px; } .token-badge { font-size: 0.65rem; padding: 2px 8px; border-radius: 10px; white-space: nowrap; } .token-badge-active { background: color-mix(in srgb, var(--success, #2e7d32) 18%, transparent); color: var(--success, #2e7d32); } .token-badge-expired { background: color-mix(in srgb, var(--text-error, #c62828) 15%, transparent); color: var(--text-error, #c62828); } .token-meta { color: var(--text-muted); font-size: 0.7rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; } .token-delete { background: none; border: none; color: var(--text-error); cursor: pointer; font-size: 1rem; padding: 2px 6px; } .token-secret-area { margin-top: 10px; padding: 10px; border: 1px dashed var(--accent); border-radius: 8px; } .token-secret-area.hidden { display: none; } .token-secret-text { width: 100%; font-family: monospace; font-size: 0.7rem; word-break: break-all; resize: none; } /* ── Shares UI ── */ .share-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; background: var(--bg-card, var(--bg-secondary)); border-radius: 6px; margin-bottom: 6px; font-size: 0.8rem; } .share-path { font-weight: 500; min-width: 0; overflow: hidden; text-overflow: ellipsis; } .share-url a { color: var(--accent); font-size: 0.75rem; } .share-meta { color: var(--text-muted); font-size: 0.7rem; } .share-revoke { background: none; border: 1px solid var(--text-error); color: var(--text-error); cursor: pointer; padding: 2px 8px; border-radius: 4px; font-size: 0.7rem; } /* ── Share Dialog ── */ .share-dialog-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 10000; } .share-dialog { background: var(--bg-primary); border-radius: 12px; padding: 24px; max-width: 480px; width: 90%; box-shadow: 0 8px 32px rgba(0,0,0,0.2); } .share-dialog h3 { margin: 0 0 4px; } .share-url-input { width: 100%; padding: 8px 12px; border: 1px solid var(--border); border-radius: 6px; font-size: 0.8rem; background: var(--bg-secondary); color: var(--text-primary); box-sizing: border-box; } .share-dialog-actions { display: flex; gap: 8px; margin-top: 12px; justify-content: flex-end; } .share-copy-btn { padding: 6px 16px; background: var(--accent); color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 0.85rem; } .share-close-btn { padding: 6px 16px; background: var(--bg-secondary); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px; cursor: pointer; font-size: 0.85rem; } .share-create-btn { padding: 6px 16px; background: var(--accent); color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 0.85rem; } .share-revoke-btn { padding: 6px 16px; background: none; color: var(--text-error); border: 1px solid var(--text-error); border-radius: 6px; cursor: pointer; font-size: 0.85rem; } /* ── Enhanced Search Bar Toggles ── */ .search-actions .tog { font-family: var(--font-mono, monospace); font-size: 10px; font-weight: 600; padding: 2px 5px; border-radius: 3px; min-width: auto; line-height: 1.4; } .search-actions .tog.active { color: var(--accent); border-color: var(--accent); background: rgba(99, 102, 241, 0.12); } .search-actions .icon-only { padding: 2px 4px; min-width: auto; } .search-sep { width: 1px; height: 16px; background: var(--border); margin: 0 2px; align-self: center; } .search-count { font-size: 10px; color: var(--text-muted); font-family: var(--font-mono, monospace); white-space: nowrap; min-width: 28px; text-align: center; } .search-filter-row, .search-replace-row { display: flex; gap: 6px; align-items: center; padding: 4px 0 0 0; } .search-filter-input { flex: 1; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 4px; color: var(--text-primary); font-family: var(--font-mono, monospace); font-size: 11px; padding: 4px 8px; outline: none; } .search-filter-input:focus { border-color: var(--accent); } .search-filter-input::placeholder { color: var(--text-muted); } /* ── Floating Results Bar ── */ .results-bar { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 2px; margin: 0 auto; padding: 6px 10px; background: var(--bg-secondary); border: 1px solid var(--border-md, var(--border)); border-radius: 10px; box-shadow: 0 2px 16px rgba(0,0,0,0.35); width: fit-content; max-width: 95%; z-index: 50; backdrop-filter: blur(8px); } .results-bar-count { font-size: 10px; color: var(--text-muted); font-family: var(--mono); white-space: nowrap; min-width: 28px; text-align: center; padding: 0 4px; } .results-bar-btn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: 1px solid transparent; border-radius: 4px; background: transparent; color: var(--text-secondary); cursor: pointer; font-size: 12px; transition: background 0.15s, color 0.15s, border-color 0.15s; } .results-bar-btn:hover { background: var(--bg-hover); color: var(--text-primary); } .results-bar-btn.tog { font-family: var(--mono); font-size: 10px; font-weight: 600; width: auto; padding: 2px 5px; } .results-bar-btn.tog.active { color: var(--accent); border-color: var(--accent); background: rgba(99,102,241,0.12); } .results-bar-sep { width: 1px; height: 16px; background: var(--border); margin: 0 6px; align-self: center; } .search-replace-btn { padding: 4px 10px; font-size: 11px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg-secondary); color: var(--text-primary); cursor: pointer; white-space: nowrap; } .search-replace-btn:hover { background: var(--bg-hover); } .search-replace-btn.destructive { border-color: var(--text-error); color: var(--text-error); } /* ── Active search result highlight ── */ .btn-bookmark.active { color: #059669; border-color: #059669; background: rgba(5, 150, 105, 0.08); } .btn-bookmark.active:hover { background: rgba(5, 150, 105, 0.15); } .btn-share.shared { color: #059669; border-color: #059669; background: rgba(5, 150, 105, 0.08); } .btn-share.shared:hover { background: rgba(5, 150, 105, 0.15); } /* ── Shared Cards ── */ .shared-card { padding: 10px 14px; background: var(--bg-card, var(--bg-secondary)); border-radius: 6px; border: 1px solid var(--border); cursor: pointer; transition: background 0.15s; display: flex; flex-direction: column; gap: 6px; } .shared-card:hover { background: var(--bg-hover); } .shared-card-header { display: flex; align-items: center; gap: 8px; } .shared-card-title { font-weight: 500; font-size: 0.85rem; } .shared-card-vault { font-size: 0.65rem; color: var(--accent); background: var(--accent-bg, rgba(99,102,241,0.1)); padding: 1px 6px; border-radius: 3px; margin-left: auto; } .shared-card-meta { font-size: 0.7rem; color: var(--text-muted); display: flex; gap: 12px; } .shared-card-actions { display: flex; gap: 6px; } .shared-card-actions button { font-size: 0.7rem; padding: 2px 8px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg-primary); color: var(--text-primary); cursor: pointer; } .shared-card-actions button:hover { background: var(--bg-hover); } /* ── Dashboard Tab Navigation ── */ .dashboard-tabs { display: flex; gap: 2px; margin-bottom: 16px; border-bottom: 2px solid var(--border); } .dashboard-tab { padding: 8px 16px; border: none; background: none; color: var(--text-muted); cursor: pointer; font-size: 0.85rem; font-weight: 500; display: flex; align-items: center; gap: 6px; border-bottom: 2px solid transparent; margin-bottom: -2px; transition: color 0.15s, border-color 0.15s; } .dashboard-tab:hover { color: var(--text-primary); } .dashboard-tab.active { color: var(--accent); border-bottom-color: var(--accent); } .dashboard-panel { display: none; } .dashboard-panel.active { display: block; } /* ═══════════════════════════════════════════════════════════════════ Command Palette (Ctrl+P) ═══════════════════════════════════════════════════════════════════ */ .command-palette-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: 0 0; z-index: 10000; display: flex; justify-content: center; padding-top: 12vh; pointer-events: none; opacity: 0; transition: opacity 0.1s ease, background 0.1s ease; } .command-palette-overlay.active { opacity: 1; background: var(--overlay-bg); pointer-events: auto; } .command-palette { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 40px rgba(0,0,0,0.45), 0 0 0 1px rgba(255,255,255,0.03); width: 580px; max-width: calc(100vw - 40px); max-height: 60vh; display: flex; flex-direction: column; overflow: hidden; animation: cp-slide-in 0.12s ease-out; } @keyframes cp-slide-in { from { transform: translateY(-12px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .cp-header { display: flex; align-items: center; border-bottom: 1px solid var(--border); padding: 0 14px; } .cp-input { flex: 1; border: none; background: none; padding: 14px 0; font-size: 16px; color: var(--text-primary); outline: none; font-family: inherit; } .cp-input::placeholder { color: var(--text-muted); } .cp-hint { font-size: 11px; color: var(--text-muted); background: var(--bg-hover); padding: 3px 8px; border-radius: 4px; font-family: "JetBrains Mono", monospace; opacity: 0.7; } .cp-results { flex: 1; overflow-y: auto; padding: 6px 0; max-height: 40vh; } .cp-empty { padding: 24px 16px; text-align: center; color: var(--text-muted); font-size: 13px; } .cp-error { color: var(--accent-orange, #d29922); } .cp-item { display: flex; justify-content: space-between; align-items: center; padding: 8px 14px; cursor: pointer; border-left: 3px solid transparent; } .cp-item:hover { background: var(--bg-hover); border-left-color: var(--accent); } .cp-item.cp-selected { background: var(--accent-bg); border-left-color: var(--accent); } .cp-item-label { font-size: 14px; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .cp-item-sublabel { font-size: 11px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 45%; text-align: right; margin-left: 12px; } .cp-footer { display: flex; gap: 14px; padding: 8px 14px; border-top: 1px solid var(--border); font-size: 11px; color: var(--text-muted); } .cp-footer span { display: flex; align-items: center; gap: 4px; } .cp-footer span::before { content: ''; display: inline-block; width: 3px; height: 3px; background: var(--text-muted); border-radius: 50%; margin-right: 4px; } .cp-footer span:first-child::before { display: none; } /* ── Breadcrumb ── */ .cp-breadcrumb { display: none; align-items: center; gap: 2px; padding: 8px 14px; font-size: 12px; color: var(--text-secondary); background: var(--bg-primary); border-bottom: 1px solid var(--border); overflow-x: auto; white-space: nowrap; scrollbar-width: none; } .cp-breadcrumb::-webkit-scrollbar { display: none; } .cp-bc-root { font-weight: 600; color: var(--accent); } .cp-bc-sep { color: var(--text-muted); padding: 0 2px; } .cp-bc-item { cursor: pointer; padding: 1px 4px; border-radius: 3px; } .cp-bc-item:hover { background: var(--bg-hover); } /* ── Name input ── */ .cp-name-input { display: flex; flex-direction: column; padding: 8px 14px; border-bottom: 1px solid var(--border); background: var(--bg-primary); } .cp-name-field { width: 100%; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text-primary); padding: 10px 12px; border-radius: 6px; font-size: 14px; font-family: inherit; outline: none; transition: border-color 0.15s; } .cp-name-field:focus { border-color: var(--accent); } .cp-name-hint { font-size: 11px; color: var(--text-muted); margin-top: 6px; } /* Browse filter in command palette */ .cp-browse-filter { width: calc(100% - 24px); margin: 8px 12px 4px; padding: 7px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-primary); color: var(--text-primary); font-size: 0.8rem; font-family: inherit; outline: none; transition: border-color 0.15s; } .cp-browse-filter:focus { border-color: var(--accent); } .cp-browse-filter::placeholder { color: var(--text-muted); } /* ── Help Modal: desktop = wider reading (#105) ── The Tauri shell (body.desktop-mode) and wide web viewports get the full reading layout instead of the 1320px modal cap. */ body.desktop-mode .help-container { max-width: 1760px; width: 96vw; } body.desktop-mode .help-content { max-width: 1440px; padding: 36px 56px 64px; } body.desktop-mode .editor-container { max-height: 94vh; } @media (min-width: 1400px) { .help-container { max-width: min(1640px, calc(100vw - 48px)); } .help-content { max-width: 1280px; } } /* ── Help Modal: Mobile responsive ── */ @media (max-width: 768px) { .help-container, .editor-container.help-container { max-width: 100vw; width: 100vw; height: 100vh; max-height: 100vh; border-radius: 0; box-sizing: border-box; } .help-hamburger { display: inline-flex; width: 44px; height: 44px; min-width: 44px; } /* TOC drawer: collapsible block for the help modal; the config modal (#114) overrides this with a fixed left drawer + backdrop. */ .help-nav { position: static; width: 100%; min-width: 0; max-width: 100%; max-height: none; height: auto; z-index: auto; transform: none; transition: none; border-right: none; border-bottom: 1px solid var(--border); box-shadow: none; flex-shrink: 0; display: none; box-sizing: border-box; } .help-nav-header { padding: 10px 16px 6px; } /* Content full-width */ .help-body { flex-direction: column; overflow-y: auto; overflow-x: hidden; padding: 0; width: 100%; box-sizing: border-box; } .help-content { padding: 14px 14px 40px; flex: 1; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; word-break: break-word; width: 100%; max-width: 100%; box-sizing: border-box; } .help-content pre, .help-content code, .help-content table { max-width: 100%; overflow-x: auto; } .help-content:focus { outline: none; } .help-hero { flex-direction: column; gap: 16px; min-width: 0; width: 100%; box-sizing: border-box; padding: 20px 16px; } .help-hero-copy { min-width: 0; width: 100%; } .help-badges { flex-wrap: wrap; gap: 6px; } .help-badge { white-space: normal; } .help-hero-visual { display: none; } .help-section { padding: 20px 0 16px; min-width: 0; width: 100%; box-sizing: border-box; } .help-nav-link { padding: 10px 12px; font-size: 0.88rem; } } /* ══════════════════════════════════════════ Mobile Bottom Toolbar (Obsidian-style) ══════════════════════════════════════════ */ .mobile-toolbar { display: none; } .vault-context-bar { display: none; } @media (max-width: 768px) { .mobile-toolbar { display: flex; position: fixed; bottom: 0; left: 0; right: 0; height: 64px; background: var(--bg-secondary); border-top: 1px solid var(--border); z-index: 900; align-items: center; justify-content: space-around; padding: 4px 4px; padding-bottom: calc(4px + env(safe-area-inset-bottom, 0)); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); } /* Push content up to avoid toolbar overlap */ .main-body { padding-bottom: 64px; padding-bottom: calc(64px + env(safe-area-inset-bottom, 0)); } /* Enable pull-to-refresh on mobile — unblock the overscroll chain */ html { overscroll-behavior-y: auto; } body { overflow-y: auto; overscroll-behavior-y: auto; height: 100vh; height: 100dvh; } .app-container { overflow-y: visible; } .main-layout { overflow-y: visible; } .content-wrapper { overflow: visible; } .content-area { overscroll-behavior-y: auto; } /* Hide desktop tab bar on mobile (bottom toolbar has its own tab button) */ .tab-bar { display: none !important; } /* Vault context indicator — hidden (now in header) */ .vault-context-bar { display: none !important; } .vault-context-pill { display: none; } .mt-btn { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; flex: 1; height: auto; min-height: 48px; padding: 4px 4px; border: none; border-radius: 8px; background: transparent; color: var(--text-muted); cursor: pointer; transition: color 0.15s, background 0.15s; position: relative; -webkit-tap-highlight-color: transparent; } .mt-btn:active { background: rgba(255,255,255,0.06); } .mt-btn svg { flex-shrink: 0; } .mt-label { font-size: 10px; font-weight: 500; line-height: 1; } .mt-btn-primary { color: var(--accent); } .mt-btn-primary .mt-label { color: var(--accent); } /* Explorer, Search and Tabs share the Commands button accent color */ #mt-explorer, #mt-search, #mt-tabs { color: var(--accent); } /* Hide the floating AI pastille on mobile — the assistant lives in the centre of the bottom toolbar instead (below). */ .ai-fab { display: none !important; } /* AI assistant — raised central button, stands out from the 4 other items */ .mt-btn-ai { flex: 0 0 auto; width: 56px; height: 56px; min-height: 56px; margin: -18px 2px 0; border-radius: 50%; background: var(--accent); color: #fff; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35), 0 0 0 4px var(--bg-secondary); z-index: 2; } .mt-btn-ai:active { background: var(--accent); transform: scale(0.94); } .mt-btn-ai svg { width: 26px; height: 26px; } .mt-btn-ai .mt-label { display: none; } /* Tab count badge */ .mt-badge { position: absolute; top: 2px; right: 50%; transform: translateX(18px); background: var(--accent); color: #fff; font-size: 9px; font-weight: 700; min-width: 16px; height: 16px; border-radius: 8px; display: flex; align-items: center; justify-content: center; padding: 0 4px; line-height: 1; } /* ── Tab Switcher Bottom Sheet ── */ .mt-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 950; opacity: 0; transition: opacity 0.25s; } .mt-overlay.visible { display: block; opacity: 1; } .mt-tab-switcher { position: fixed; bottom: 0; left: 0; right: 0; max-height: 60vh; background: var(--bg-secondary); border-radius: 16px 16px 0 0; z-index: 960; transform: translateY(100%); transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1); display: flex; flex-direction: column; box-shadow: 0 -4px 24px rgba(0,0,0,0.4); padding-bottom: env(safe-area-inset-bottom, 0); } .mt-tab-switcher.open { transform: translateY(0); } .mt-sheet-handle { width: 36px; height: 4px; background: var(--border); border-radius: 2px; margin: 10px auto 6px; flex-shrink: 0; } .mt-sheet-header { display: flex; align-items: center; justify-content: space-between; padding: 8px 16px 12px; flex-shrink: 0; } .mt-sheet-title { font-family: "JetBrains Mono", monospace; font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); } .mt-sheet-close { width: 28px; height: 28px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: transparent; color: var(--text-secondary); cursor: pointer; font-size: 12px; display: flex; align-items: center; justify-content: center; } .mt-sheet-close:hover { color: var(--accent); border-color: var(--accent); } .mt-sheet-actions { display: flex; align-items: center; gap: 8px; } .mt-sheet-close-all { padding: 5px 10px; border: 1px solid var(--danger, #ef4444); border-radius: 6px; background: transparent; color: var(--danger, #ef4444); cursor: pointer; font-size: 0.7rem; font-weight: 600; transition: background 0.15s; } .mt-sheet-close-all:hover { background: rgba(239,68,68,0.1); } .mt-sheet-list { flex: 1; overflow-y: auto; padding: 0 12px 12px; -webkit-overflow-scrolling: touch; } .mt-tab-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 8px; cursor: pointer; color: var(--text-primary); font-size: 0.85rem; transition: background 0.1s; margin-bottom: 2px; } .mt-tab-item:active { background: rgba(255,255,255,0.06); } .mt-tab-item.active { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); font-weight: 600; } .mt-tab-item-icon { flex-shrink: 0; opacity: 0.6; } .mt-tab-item-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .mt-tab-item-close { width: 24px; height: 24px; padding: 0; border: none; border-radius: 4px; background: transparent; color: var(--text-muted); cursor: pointer; font-size: 14px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .mt-tab-item-close:hover { color: var(--danger, #ef4444); background: rgba(239,68,68,0.1); } } /* ========================================================================== Backup / Diff Viewer Modal ========================================================================== */ .backup-viewer-panel { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: min(90vw, 960px); height: min(85vh, 700px); background: var(--bg-primary, #1e1e2e); border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 25px 60px rgba(0,0,0,0.5); display: flex; flex-direction: column; overflow: hidden; z-index: 1001; } .backup-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--border); background: var(--bg-secondary); flex-shrink: 0; } .backup-header-left { display: flex; align-items: baseline; gap: 10px; min-width: 0; } .backup-header h3 { margin: 0; font-size: 1rem; font-weight: 600; color: var(--text-primary); } .backup-file-path { font-size: 0.78rem; color: var(--text-muted); font-family: var(--font-mono, 'SF Mono', 'Fira Code', monospace); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .backup-header-right { display: flex; align-items: center; gap: 12px; flex-shrink: 0; } .backup-count { font-size: 0.75rem; color: var(--text-muted); background: var(--bg-tertiary); padding: 3px 8px; border-radius: 4px; } .backup-close-btn { width: 36px; height: 36px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-primary); color: var(--text-secondary); cursor: pointer; transition: all 150ms ease; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; box-shadow: 0 2px 8px rgba(0,0,0,0.15); } .backup-close-btn:hover { color: var(--accent); border-color: var(--accent); } .backup-toolbar { display: flex; align-items: center; gap: 10px; padding: 10px 18px; border-bottom: 1px solid var(--border); background: var(--bg-primary); flex-shrink: 0; } .backup-selector-group { display: flex; align-items: center; gap: 6px; } .backup-selector-group label { font-size: 0.78rem; color: var(--text-muted); white-space: nowrap; } .backup-select { padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-secondary); color: var(--text-primary); font-size: 0.8rem; font-family: var(--font-mono); max-width: 240px; cursor: pointer; } .backup-select:focus { outline: none; border-color: var(--accent); } .backup-vs-label { font-size: 0.75rem; color: var(--text-muted); font-weight: 600; user-select: none; } .backup-restore-btn { margin-left: auto; padding: 6px 14px; border: 1px solid var(--accent); border-radius: 6px; background: color-mix(in srgb, var(--accent) 10%, transparent); color: var(--accent); font-size: 0.8rem; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 5px; transition: background 0.15s, opacity 0.15s; white-space: nowrap; } .backup-restore-btn:hover { background: color-mix(in srgb, var(--accent) 20%, transparent); } .backup-restore-btn:disabled { opacity: 0.5; cursor: not-allowed; } .backup-restore-btn .icon-sm { width: 14px; height: 14px; } .backup-diff-container { flex: 1; overflow-y: auto; background: var(--bg-primary); } .backup-diff-loading, .backup-diff-error, .backup-diff-empty { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--text-muted); font-size: 0.85rem; } .backup-diff-error { color: var(--danger, #ef4444); } .backup-diff-output { padding: 0; } .backup-diff-table { width: 100%; border-collapse: collapse; font-family: var(--font-mono, 'SF Mono', 'Fira Code', 'Cascadia Code', monospace); font-size: 0.8rem; line-height: 1.55; table-layout: fixed; } .backup-diff-table td { padding: 0; } .backup-diff-table td.diff-prefix { width: 22px; text-align: center; user-select: none; font-weight: 600; padding: 1px 0; vertical-align: top; } .backup-diff-table td.diff-content { padding: 1px 8px; vertical-align: top; } .backup-diff-table td.diff-content pre { margin: 0; white-space: pre-wrap; word-break: break-all; font-family: inherit; font-size: inherit; line-height: inherit; } .backup-diff-table tr.diff-add td { background: rgba(34, 197, 94, 0.12); } .backup-diff-table tr.diff-add td.diff-prefix { color: #22c55e; } .backup-diff-table tr.diff-del td { background: rgba(239, 68, 68, 0.12); } .backup-diff-table tr.diff-del td.diff-prefix { color: #ef4444; } .backup-diff-table tr.diff-hunk td { background: color-mix(in srgb, var(--accent) 8%, transparent); color: var(--accent); font-weight: 600; } .backup-diff-table tr.diff-header-line td { background: var(--bg-secondary); color: var(--text-muted); font-weight: 600; } .backup-diff-table tr.diff-context td { color: var(--text-secondary); } .backup-body { flex: 1; display: flex; flex-direction: column; overflow: auto; } .backup-footer { padding: 6px 18px; border-top: 1px solid var(--border); background: var(--bg-secondary); flex-shrink: 0; } .backup-footer-hint { font-size: 0.7rem; color: var(--text-muted); } /* ── Side-by-side diff view ── */ .backup-diff-sidebyside .sidebyside { table-layout: fixed; } .backup-diff-sidebyside td.sidebyside-left { border-right: 1px solid var(--border); } .backup-diff-sidebyside td.sidebyside-right { border-left: 1px solid var(--border); } .backup-diff-sidebyside td.diff-empty-cell { background: var(--bg-tertiary); } .backup-diff-mode-btn { padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: transparent; color: var(--text-secondary); cursor: pointer; display: inline-flex; align-items: center; gap: 4px; font-size: 0.8rem; transition: all 150ms ease; } .backup-diff-mode-btn:hover { color: var(--accent); border-color: var(--accent); } .backup-diff-mode-btn .icon-sm { width: 14px; height: 14px; } /* ── Backup Manager ── */ .backup-manager { padding: 16px 24px; max-width: 1000px; margin: 0 auto; } .backup-manager-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; gap: 12px; } .backup-manager-header h2 { margin: 0; font-size: 1.1rem; display: flex; align-items: center; gap: 8px; } .backup-manager-actions { display: flex; gap: 6px; } .backup-manager-filter { padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-primary); color: var(--text-primary); font-size: 0.8rem; min-width: 200px; } .backup-manager-btn { width: 32px; height: 32px; border: 1px solid var(--border); border-radius: 6px; background: transparent; color: var(--text-secondary); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; } .backup-manager-btn:hover { color: var(--accent); border-color: var(--accent); } .backup-manager-stats { display: flex; gap: 16px; margin-bottom: 14px; } .bm-stat { font-size: 0.8rem; color: var(--text-muted); } .bm-vault-group { margin-bottom: 16px; } .bm-vault-name { font-size: 0.85rem; font-weight: 600; margin: 0 0 6px 0; display: flex; align-items: center; gap: 6px; } .bm-file-group { border: 1px solid var(--border); border-radius: 6px; margin-bottom: 8px; overflow: hidden; } .bm-file-header { display: flex; align-items: center; gap: 12px; padding: 8px 12px; background: var(--bg-secondary); border-bottom: 1px solid var(--border); } .bm-file-name { font-size: 0.8rem; font-weight: 500; display: flex; align-items: center; gap: 4px; } .bm-file-meta { font-size: 0.7rem; color: var(--text-muted); flex: 1; } .bm-file-purge { width: 28px; height: 28px; border: 1px solid var(--border); border-radius: 4px; background: transparent; color: var(--text-muted); cursor: pointer; display: flex; align-items: center; justify-content: center; } .bm-file-purge:hover { color: var(--danger); border-color: var(--danger); } .bm-backup-list { padding: 2px 0; } .bm-backup-item { display: flex; align-items: center; gap: 12px; padding: 4px 12px; font-size: 0.75rem; } .bm-backup-item:hover { background: var(--bg-secondary); } .bm-backup-date { color: var(--text-secondary); min-width: 130px; font-family: var(--font-mono); } .bm-backup-size { color: var(--text-muted); flex: 1; } .bm-backup-delete { width: 22px; height: 22px; border: none; border-radius: 4px; background: transparent; color: var(--text-muted); cursor: pointer; display: flex; align-items: center; justify-content: center; opacity: 0; } .bm-backup-item:hover .bm-backup-delete { opacity: 1; } .bm-backup-delete:hover { color: var(--danger); background: rgba(239,68,68,0.1); } .backup-footer-manage-btn { background: none; border: 1px solid var(--border); border-radius: 4px; color: var(--accent); font-size: 0.7rem; cursor: pointer; padding: 3px 10px; transition: all 150ms ease; } .backup-footer-manage-btn:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); } .backup-manager-empty, .backup-manager-error { text-align: center; padding: 2rem; color: var(--text-muted); font-size: 0.85rem; } .backup-manager-error { color: var(--danger); } /* ========================================================================== Mermaid.js Diagrams ========================================================================== */ .mermaid-container { margin: 12px 0; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--bg-secondary); } /* ── Header bar ── */ .mermaid-header { display: flex; align-items: center; justify-content: space-between; padding: 6px 10px; background: var(--bg-hover); border-bottom: 1px solid var(--border); min-height: 34px; } .mermaid-diagram-type { font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace; font-size: 0.75rem; font-weight: 600; color: var(--text-secondary); } .mermaid-header-actions { display: flex; align-items: center; gap: 2px; } /* ── Buttons ── */ .mermaid-btn { width: 28px; height: 28px; border: 1px solid transparent; border-radius: 4px; background: transparent; color: var(--text-secondary); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.12s, color 0.12s; } .mermaid-btn:hover { background: var(--bg-primary); color: var(--accent); border-color: var(--border); } /* ── Code / Preview toggle ── */ .mermaid-toggle { display: flex; margin-left: 8px; border: 1px solid var(--border); border-radius: 5px; overflow: hidden; } .mermaid-toggle-btn { padding: 2px 10px; font-size: 0.7rem; font-weight: 500; border: none; background: transparent; color: var(--text-muted, #999); cursor: pointer; transition: background 0.12s, color 0.12s; } .mermaid-toggle-btn.active { background: var(--bg-primary); color: var(--text-primary); box-shadow: 0 0 0 1px var(--border); } .mermaid-toggle-btn:first-child { border-right: 1px solid var(--border); } /* ── Body ── */ .mermaid-body { position: relative; } .mermaid-rendered { padding: 16px; overflow: hidden; min-height: 80px; display: flex; justify-content: center; } .mermaid-rendered svg { max-width: 100%; height: auto; } .mermaid-source { padding: 16px; overflow: auto; } .mermaid-source pre { margin: 0; padding: 12px; background: var(--code-bg); border-radius: 4px; font-size: 0.78rem; line-height: 1.5; color: var(--text-primary); } /* ── Error ── */ .mermaid-error { margin: 12px 0; padding: 12px 16px; border: 1px solid rgba(239,68,68,0.3); border-radius: 6px; background: rgba(239,68,68,0.08); color: var(--danger); font-size: 0.8rem; line-height: 1.5; } .mermaid-error strong { display: block; margin-bottom: 4px; } /* ── Fullscreen ── */ .mermaid-fullscreen-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10000; display: flex; flex-direction: column; } /* Light theme — clean white like the example */ [data-theme="light"] .mermaid-fullscreen-overlay { background: rgba(255,255,255,0.97); } [data-theme="light"] .mermaid-fullscreen-header { background: rgba(0,0,0,0.03); border-bottom: 1px solid rgba(0,0,0,0.08); } [data-theme="light"] .mermaid-fullscreen-header .mermaid-diagram-type { color: rgba(0,0,0,0.5); } [data-theme="light"] .mermaid-fullscreen-header .mermaid-btn { color: rgba(0,0,0,0.4); } [data-theme="light"] .mermaid-fullscreen-header .mermaid-btn:hover { background: rgba(0,0,0,0.05); color: rgba(0,0,0,0.8); } /* Dark theme */ [data-theme="dark"] .mermaid-fullscreen-overlay { background: rgba(18,18,24,0.97); } [data-theme="dark"] .mermaid-fullscreen-header { background: rgba(255,255,255,0.06); border-bottom: 1px solid rgba(255,255,255,0.08); } [data-theme="dark"] .mermaid-fullscreen-header .mermaid-diagram-type { color: rgba(255,255,255,0.7); } [data-theme="dark"] .mermaid-fullscreen-header .mermaid-btn { color: rgba(255,255,255,0.6); } [data-theme="dark"] .mermaid-fullscreen-header .mermaid-btn:hover { background: rgba(255,255,255,0.1); color: #fff; } .mermaid-fullscreen-header { display: flex; align-items: center; justify-content: space-between; padding: 10px 16px; min-height: 46px; flex-shrink: 0; } .mermaid-fullscreen-content { flex: 1; display: flex; align-items: center; justify-content: center; padding: 16px; overflow: hidden; } .mermaid-fullscreen-content svg { width: 100%; height: 100%; max-width: 100%; max-height: 100%; } /* ── Dark mode overrides for beta diagrams that ignore themeVariables ── */ /* packet-beta */ [data-theme="dark"] .mermaid-rendered svg .row rect, [data-theme="dark"] .mermaid-rendered svg g[id*="packet"] rect { fill: #1e3a5f !important; stroke: #4a7ab5 !important; } [data-theme="dark"] .mermaid-rendered svg .row text, [data-theme="dark"] .mermaid-rendered svg g[id*="packet"] text { fill: #c8daf0 !important; } [data-theme="dark"] .mermaid-fullscreen-content svg .row rect, [data-theme="dark"] .mermaid-fullscreen-content svg g[id*="packet"] rect { fill: #1e3a5f !important; stroke: #4a7ab5 !important; } [data-theme="dark"] .mermaid-fullscreen-content svg .row text, [data-theme="dark"] .mermaid-fullscreen-content svg g[id*="packet"] text { fill: #c8daf0 !important; } /* xychart-beta — bar fills and line color */ [data-theme="dark"] .mermaid-rendered svg rect[class*="plot"], [data-theme="dark"] .mermaid-rendered svg rect[id*="bar"] { fill: #1e3a5f !important; stroke: #4a7ab5 !important; } [data-theme="dark"] .mermaid-rendered svg path[class*="plot"], [data-theme="dark"] .mermaid-rendered svg path[id*="line"] { stroke: #6a9ad0 !important; } [data-theme="dark"] .mermaid-fullscreen-content svg rect[class*="plot"], [data-theme="dark"] .mermaid-fullscreen-content svg rect[id*="bar"] { fill: #1e3a5f !important; stroke: #4a7ab5 !important; } [data-theme="dark"] .mermaid-fullscreen-content svg path[class*="plot"], [data-theme="dark"] .mermaid-fullscreen-content svg path[id*="line"] { stroke: #6a9ad0 !important; } .mermaid-focus-panel { position: fixed; top: 0; right: 0; bottom: 0; width: 480px; z-index: 9998; background: var(--bg-secondary); border-left: 1px solid var(--border); box-shadow: -4px 0 24px rgba(0,0,0,0.3); display: flex; flex-direction: column; } .mermaid-focus-header { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--border); font-size: 0.85rem; font-weight: 600; } .mermaid-focus-close { width: 28px; height: 28px; border: 1px solid var(--border); border-radius: 4px; background: transparent; color: var(--text-muted); cursor: pointer; display: flex; align-items: center; justify-content: center; } .mermaid-focus-close:hover { color: var(--accent); } .mermaid-focus-content { flex: 1; overflow: auto; padding: 16px; } /* Mermaid editor live preview panel */ .mermaid-live-preview { border-top: 1px solid var(--border); background: var(--bg-secondary); min-height: 100px; max-height: 300px; overflow: auto; padding: 12px; } .mermaid-live-preview .mermaid-error { margin: 0; } /* Manager body: list + preview side panel */ .backup-manager-body { display: flex; gap: 0; min-height: 400px; } .backup-manager-list { flex: 1; min-width: 0; } .backup-manager-preview { width: 400px; flex-shrink: 0; border-left: 1px solid var(--border); background: var(--bg-primary); display: flex; flex-direction: column; } .bm-preview-header { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--border); } .bm-preview-header h3 { margin: 0; font-size: 0.85rem; } .bm-preview-content { flex: 1; overflow: auto; padding: 12px 14px; font-family: var(--font-mono); font-size: 0.75rem; line-height: 1.55; white-space: pre-wrap; word-break: break-all; color: var(--text-secondary); margin: 0; } /* Vault header with purge button */ .bm-vault-header { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); margin-bottom: 8px; } .bm-vault-meta { font-size: 0.7rem; color: var(--text-muted); flex: 1; } .bm-vault-purge { padding: 3px 10px; border: 1px solid var(--border); border-radius: 4px; background: transparent; color: var(--danger); cursor: pointer; font-size: 0.7rem; display: flex; align-items: center; gap: 4px; transition: all 150ms ease; } .bm-vault-purge:hover { background: rgba(239,68,68,0.08); border-color: var(--danger); } /* Backup item actions */ .bm-backup-actions { display: flex; gap: 2px; opacity: 0; transition: opacity 0.12s; } .bm-backup-item:hover .bm-backup-actions { opacity: 1; } .bm-backup-preview, .bm-backup-restore { width: 22px; height: 22px; border: none; border-radius: 4px; background: transparent; color: var(--text-muted); cursor: pointer; display: flex; align-items: center; justify-content: center; } .bm-backup-preview:hover { color: var(--accent); background: rgba(59,130,246,0.1); } .bm-backup-restore:hover { color: #22c55e; background: rgba(34,197,94,0.1); } .bm-backup-item.active { background: color-mix(in srgb, var(--accent) 10%, transparent); border-radius: 4px; } /* ── About Modal ── */ .about-overlay { position: fixed; inset: 0; z-index: 1000; background: rgba(0,0,0,0.7); backdrop-filter: blur(6px); display: none; align-items: center; justify-content: center; } .about-overlay.active { display: flex; } .about-modal { background: var(--bg-secondary); border: 1px solid var(--border-md); border-radius: 16px; width: 540px; max-width: 94vw; max-height: 90vh; overflow-y: auto; position: relative; box-shadow: 0 20px 60px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.05); animation: about-in 0.35s ease; } @keyframes about-in { from { opacity: 0; transform: translateY(20px) scale(0.97); } to { opacity: 1; transform: translateY(0) scale(1); } } .about-close { position: absolute; top: 12px; right: 14px; background: var(--bg-hover); border: none; color: var(--text-secondary); width: 30px; height: 30px; border-radius: 8px; font-size: 18px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.15s, color 0.15s; z-index: 1; } .about-close:hover { background: var(--danger-bg); color: var(--danger); } .about-hero { text-align: center; padding: 22px 24px 16px; background: linear-gradient(160deg, var(--accent-bg) 0%, transparent 60%); border-bottom: 1px solid var(--border); } .about-logo { margin-bottom: 8px; display: inline-block; } .about-title { font-size: 1.4rem; font-weight: 700; color: var(--text-primary); letter-spacing: -0.5px; margin-bottom: 4px; } .about-tagline { font-size: 0.8rem; color: var(--text-secondary); line-height: 1.4; margin-bottom: 8px; } .about-version { display: inline-block; padding: 3px 12px; background: var(--accent); color: #fff; font-size: 0.7rem; font-weight: 600; font-family: var(--mono); border-radius: 20px; letter-spacing: 0.5px; } .about-body { padding: 12px 28px 16px; } .about-stats { display: flex; gap: 0; justify-content: center; margin-bottom: 10px; } .about-stat { flex: 1; text-align: center; padding: 8px 8px; border-right: 1px solid var(--border); } .about-stat:last-child { border-right: none; } .about-stat-value { display: block; font-size: 1.3rem; font-weight: 700; color: var(--accent); font-family: var(--mono); } .about-stat-label { font-size: 0.6rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.6px; margin-top: 1px; } .about-stack { margin-bottom: 10px; } .about-stack h3 { font-size: 0.65rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.8px; margin-bottom: 6px; } .about-stack-grid { display: flex; flex-wrap: wrap; gap: 5px; } .about-stack-badge { padding: 2px 8px; font-size: 0.65rem; background: var(--bg-hover); color: var(--text-secondary); border: 1px solid var(--border); border-radius: 6px; font-family: var(--mono); } .about-footer { border-top: 1px solid var(--border); padding-top: 10px; } .about-meta { display: flex; gap: 16px; font-size: 0.65rem; color: var(--text-muted); margin-bottom: 6px; flex-wrap: wrap; } .about-meta strong { color: var(--text-secondary); font-family: var(--mono); font-size: 0.65rem; } .about-joke { font-size: 0.68rem; color: var(--text-muted); font-style: italic; margin-bottom: 6px; opacity: 0.7; } .about-copy { font-size: 0.62rem; color: var(--text-muted); opacity: 0.5; } .about-copy code { font-family: var(--mono); font-size: 0.58rem; } /* ── PDF Viewer ── */ .pdf-viewer-container { display: flex; flex-direction: column; height: 100%; } .pdf-toolbar { display: flex; align-items: center; gap: 8px; padding: 8px 16px; background: var(--surface); border-bottom: 1px solid var(--border); font-size: 0.85rem; flex-shrink: 0; } .pdf-info { flex: 1; color: var(--text-secondary); } .pdf-iframe { flex: 1; width: 100%; border: none; min-height: 70vh; } .pdf-body { display: flex; flex: 1; min-height: 0; } .pdf-toc { width: 240px; flex-shrink: 0; overflow-y: auto; padding: 12px; border-right: 1px solid var(--border); background: var(--surface2); font-size: 0.85rem; } .pdf-toc h3 { margin: 0 0 8px 0; font-size: 0.9rem; color: var(--text-secondary); } .pdf-toc ul { list-style: none; padding: 0; margin: 0; } .pdf-toc li { padding: 2px 0; } .pdf-toc a { color: var(--text); text-decoration: none; } .pdf-toc a:hover { color: var(--accent); text-decoration: underline; } .toc-page { color: var(--text-secondary); font-size: 0.75rem; margin-left: 4px; } /* ── Image Viewer ── */ .image-viewer-body { display: flex; align-items: center; justify-content: center; min-height: 200px; background: var(--surface); padding: 20px; } .image-viewer-body img { border-radius: 4px; box-shadow: 0 2px 12px rgba(0,0,0,0.15); } /* #108-D — dedicated image viewer: zoom, pan, filmstrip, metadata, lightbox */ /* #111 — the viewer owns the whole content box (no page scrolling): the image is always resized to the available frame and the toolbar/filmstrip stay put. */ .content-area:has(> .image-viewer-container) { padding: 0; overflow: hidden; } .image-viewer-container { display: flex; flex-direction: column; height: 100%; min-height: 0; outline: none; } .image-toolbar { display: flex; align-items: center; gap: 6px; padding: 6px 12px; background: var(--surface); border-bottom: 1px solid var(--border); flex-shrink: 0; } .image-toolbar .image-title { color: var(--text); font-size: 0.85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40%; } .image-toolbar-spacer { flex: 1; } .image-zoom-badge { font-variant-numeric: tabular-nums; font-size: 0.75rem; color: var(--text-secondary); min-width: 46px; text-align: center; } .image-counter { font-variant-numeric: tabular-nums; font-size: 0.75rem; color: var(--text-secondary); padding: 0 6px; white-space: nowrap; } .image-counter[hidden] { display: none; } .image-viewer-body { flex: 1; display: flex; /* #111 — stretch (not center) so .image-stage is capped to the body height and the image can actually resolve max-height:100% against a definite frame. */ align-items: stretch; padding: 0; min-height: 0; overflow: hidden; } .image-stage { flex: 1; position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center; min-width: 0; min-height: 0; padding: 16px; box-sizing: border-box; background: var(--surface2); cursor: grab; touch-action: none; } .image-stage.panning { cursor: grabbing; } .image-main { width: auto; height: auto; max-width: 100%; max-height: 100%; object-fit: contain; transform-origin: center center; user-select: none; -webkit-user-drag: none; will-change: transform; } .image-error { color: var(--text-secondary); font-size: 0.9rem; } /* #111 — translucent overlay arrows along the frame edges (revealed on hover) */ .image-nav-arrow { position: absolute; top: 0; bottom: 0; width: clamp(44px, 6vw, 84px); display: flex; align-items: center; justify-content: center; padding: 0; border: none; background: transparent; color: #fff; opacity: 0; cursor: pointer; z-index: 6; transition: opacity 160ms ease, background 160ms ease; } .image-nav-arrow[hidden] { display: none; } .image-nav-arrow-prev { left: 0; } .image-nav-arrow-next { right: 0; } .image-nav-arrow-prev:hover, .image-nav-arrow-prev:focus-visible { background: linear-gradient(to right, rgba(0, 0, 0, 0.42), transparent); } .image-nav-arrow-next:hover, .image-nav-arrow-next:focus-visible { background: linear-gradient(to left, rgba(0, 0, 0, 0.42), transparent); } .image-stage:hover .image-nav-arrow { opacity: 0.4; } .image-stage .image-nav-arrow:hover, .image-stage .image-nav-arrow:focus-visible { opacity: 1; outline: none; } .image-nav-arrow .icon { filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.85)); } @media (hover: none) { .image-nav-arrow { opacity: 0.55; } } /* #112 — filmstrip wrapper so the scroll arrows stay fixed over the film */ .image-nav { position: relative; flex-shrink: 0; background: var(--surface); border-top: 1px solid var(--border); } .image-nav[hidden] { display: none; } .image-nav-strip { display: flex; gap: 6px; padding: 8px 40px; overflow-x: auto; scroll-behavior: smooth; scrollbar-width: thin; flex-shrink: 0; } .image-nav-strip[hidden] { display: none; } /* Translucent arrows that scroll the film left/right (revealed on hover). */ .image-strip-arrow { position: absolute; top: 0; bottom: 0; width: 34px; display: flex; align-items: center; justify-content: center; padding: 0; border: none; color: var(--text-primary); opacity: 0; cursor: pointer; z-index: 2; transition: opacity 160ms ease; } .image-strip-arrow-prev { left: 0; background: linear-gradient(to right, var(--surface) 55%, transparent); } .image-strip-arrow-next { right: 0; background: linear-gradient(to left, var(--surface) 55%, transparent); } .image-nav:hover .image-strip-arrow { opacity: 0.6; } .image-strip-arrow:hover, .image-strip-arrow:focus-visible { opacity: 1; outline: none; } @media (hover: none) { .image-strip-arrow { opacity: 0.55; } } .image-thumb { width: 72px; height: 72px; object-fit: cover; border-radius: 4px; border: 2px solid transparent; cursor: pointer; opacity: 0.65; flex-shrink: 0; } .image-thumb:hover { opacity: 1; } .image-thumb.active { border-color: var(--accent); opacity: 1; } .image-meta-panel { width: 280px; max-width: 40%; overflow-y: auto; padding: 10px 16px; background: var(--surface); border-left: 1px solid var(--border); font-size: 0.8rem; color: var(--text-secondary); flex-shrink: 0; } .image-meta-panel[hidden] { display: none; } .image-meta-panel dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 0; } .image-meta-panel dt { color: var(--text-secondary); } .image-meta-panel dd { margin: 0; color: var(--text); overflow-wrap: anywhere; } .image-viewer-container.lightbox { position: fixed; inset: 0; z-index: 2000; background: rgba(0, 0, 0, 0.9); } .image-viewer-container.lightbox .image-nav, .image-viewer-container.lightbox .image-nav-strip { display: none; } /* ── Audio / Video viewers (roadmap #109) ── */ .audio-viewer-container, .video-viewer-container { display: flex; flex-direction: column; height: 100%; } .media-toolbar { display: flex; align-items: center; gap: 6px; padding: 6px 12px; background: var(--surface); border-bottom: 1px solid var(--border); flex-shrink: 0; } .media-toolbar .media-title { color: var(--text); font-size: 0.85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40%; } .media-toolbar-spacer { flex: 1; } .media-duration-badge { font-variant-numeric: tabular-nums; font-size: 0.75rem; color: var(--text-secondary); min-width: 46px; text-align: center; } .media-meta { font-size: 0.75rem; color: var(--text-secondary); } .audio-stage { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px; padding: 32px 24px; min-height: 50vh; background: var(--surface2); } .audio-artwork { display: flex; align-items: center; justify-content: center; width: 140px; height: 140px; border-radius: 12px; background: var(--surface); border: 1px solid var(--border); color: var(--accent); } .audio-player { width: min(560px, 100%); } .video-stage { flex: 1; display: flex; align-items: center; justify-content: center; background: #000; overflow: hidden; min-height: 60vh; } .video-player { max-width: 100%; max-height: calc(100vh - 180px); object-fit: contain; } .media-fallback-actions { display: flex; gap: 8px; margin-top: 12px; } /* ── Now Playing — persistent media dock (roadmap #110) ── */ .np-inline-slot { display: flex; align-items: center; justify-content: center; width: 100%; } .np-inline-slot .np-media--audio { width: min(560px, 100%); } .np-media--video { max-width: 100%; max-height: calc(100vh - 180px); } .np-host { position: fixed; inset: 0; z-index: 950; pointer-events: none; } .np-dock { pointer-events: auto; } .np-ctrl { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; padding: 0; border: none; border-radius: 50%; background: transparent; color: var(--text); cursor: pointer; transition: background 0.15s ease, color 0.15s ease; } .np-ctrl:hover { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); } .np-ctrl:disabled { opacity: 0.35; cursor: default; } .np-ctrl:disabled:hover { background: transparent; color: var(--text); } .np-dock--audio { position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); display: flex; align-items: center; gap: 10px; width: min(720px, calc(100vw - 32px)); padding: 8px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45); backdrop-filter: blur(12px); overflow: hidden; } .np-dock--audio .np-media { display: none; } .np-dock-art { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface2); color: var(--accent); cursor: pointer; } .np-dock-info { flex: 1 1 120px; min-width: 0; display: flex; flex-direction: column; gap: 2px; cursor: pointer; } .np-dock-title { color: var(--text); font-size: 0.85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .np-dock-sub { color: var(--text-secondary); font-size: 0.72rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .np-dock-controls { flex: 0 0 auto; display: flex; align-items: center; gap: 2px; } .np-dock-progress { flex: 1 1 160px; min-width: 0; display: flex; align-items: center; gap: 8px; } .np-time { color: var(--text-secondary); font-size: 0.7rem; font-variant-numeric: tabular-nums; min-width: 34px; text-align: center; } .np-seek { flex: 1; -webkit-appearance: none; appearance: none; height: 4px; border-radius: 2px; background: var(--border); cursor: pointer; } .np-seek::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 12px; height: 12px; border-radius: 50%; background: var(--accent); } .np-seek::-moz-range-thumb { width: 12px; height: 12px; border: none; border-radius: 50%; background: var(--accent); } .np-dock-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 2px; } .np-volume { display: flex; align-items: center; gap: 4px; color: var(--text-secondary); padding: 0 4px; } .np-volume-range { width: 70px; -webkit-appearance: none; appearance: none; height: 4px; border-radius: 2px; background: var(--border); cursor: pointer; } .np-volume-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 11px; height: 11px; border-radius: 50%; background: var(--accent); } .np-volume-range::-moz-range-thumb { width: 11px; height: 11px; border: none; border-radius: 50%; background: var(--accent); } /* Video dock — floating, draggable, resizable mini-window */ .np-dock--video { position: fixed; background: #000; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5); } .np-dock-video-frame { position: absolute; inset: 0; display: flex; flex-direction: column; } .np-dock-video-slot { flex: 1; display: flex; min-height: 0; background: #000; overflow: hidden; } .np-dock-video-slot .np-media--video { width: 100%; height: 100%; object-fit: contain; max-height: none; } .np-dock-video-bar { display: flex; align-items: center; gap: 4px; padding: 4px 6px; background: rgba(0, 0, 0, 0.62); } .np-dock-video-bar .np-ctrl, .np-dock-video-bar .np-time { color: #f5f5f5; } .np-dock-video-bar .np-seek { background: rgba(255, 255, 255, 0.28); } .np-dock-video-bar .np-ctrl:hover { background: rgba(255, 255, 255, 0.16); color: #fff; } .np-video-grip { display: inline-flex; align-items: center; color: rgba(255, 255, 255, 0.7); cursor: grab; touch-action: none; } .np-video-grip:active { cursor: grabbing; } .np-video-resize { position: absolute; right: 0; bottom: 0; width: 18px; height: 18px; cursor: nwse-resize; touch-action: none; } .np-video-resize::after { content: ""; position: absolute; right: 3px; bottom: 3px; width: 9px; height: 9px; border-right: 2px solid rgba(255, 255, 255, 0.55); border-bottom: 2px solid rgba(255, 255, 255, 0.55); } .np-dock--error .np-dock-error-msg { color: #fff; font-size: 0.8rem; padding: 24px 16px; text-align: center; } /* Expanded audio panel (bottom sheet on mobile) */ .np-expanded { position: fixed; inset: 0; z-index: 960; pointer-events: auto; } .np-expanded[hidden] { display: none; } .np-expanded-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.35); } .np-exp-card { position: absolute; left: 50%; bottom: 96px; transform: translateX(-50%); width: min(460px, calc(100vw - 32px)); display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 22px 20px; background: var(--surface); border: 1px solid var(--border); border-radius: 18px; box-shadow: 0 18px 48px rgba(0, 0, 0, 0.5); } .np-exp-art { display: flex; align-items: center; justify-content: center; width: 120px; height: 120px; border-radius: 14px; background: var(--surface2); border: 1px solid var(--border); color: var(--accent); } .np-exp-title { color: var(--text); font-size: 1rem; text-align: center; overflow-wrap: anywhere; } .np-exp-sub { color: var(--text-secondary); font-size: 0.78rem; } .np-exp-seek { width: 100%; } .np-exp-times { width: 100%; display: flex; justify-content: space-between; } .np-exp-controls { display: flex; align-items: center; gap: 14px; } .np-exp-controls .np-ctrl { width: 44px; height: 44px; } .np-exp-play { background: var(--accent); color: #fff; } .np-exp-play:hover { background: var(--accent); color: #fff; filter: brightness(1.08); } .np-exp-extra { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center; } .np-rate { background: var(--surface2); color: var(--text); border: 1px solid var(--border); border-radius: 8px; padding: 4px 6px; font-size: 0.75rem; } /* Mid-size screens: drop the volume slider before the row gets cramped. */ @media (max-width: 1100px) { .np-dock--audio .np-volume { display: none; } } @media (max-width: 768px) { .np-dock--audio { left: 8px; right: 8px; bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 8px); transform: none; width: auto; display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; grid-template-areas: "progress progress progress progress" "art info controls actions"; align-items: center; gap: 6px 8px; padding: 8px 10px; border-radius: 12px; } .np-dock--audio .np-dock-art { grid-area: art; width: 38px; height: 38px; } .np-dock--audio .np-dock-info { grid-area: info; } .np-dock--audio .np-dock-controls { grid-area: controls; } .np-dock--audio .np-dock-progress { grid-area: progress; width: 100%; min-width: 0; } .np-dock--audio .np-dock-actions { grid-area: actions; } /* Compact mobile: keep play / return / close; expand via the artwork. */ .np-dock--audio [data-np="prev"], .np-dock--audio [data-np="next"], .np-dock--audio [data-np="expand"] { display: none; } .np-dock--video { left: 8px !important; right: 8px; top: auto !important; bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 8px) !important; width: auto !important; height: 200px !important; border-radius: 12px; } .np-video-resize { display: none; } .np-exp-card { bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 12px); } body.np-active .content-area { /* Toolbar clearance is carried by .main-body (BUG-073): only the dock zone (76px above the toolbar) remains here — same total as before. */ padding-bottom: 76px; } } @media (prefers-reduced-motion: reduce) { .np-ctrl, .np-dock, .np-exp-card { transition: none; } } /* ── Text / CSV Viewer ── */ .text-viewer-container { display: flex; flex-direction: column; height: 100%; } .file-toolbar { display: flex; align-items: center; gap: 8px; padding: 8px 16px; background: var(--surface); border-bottom: 1px solid var(--border); font-size: 0.85rem; flex-shrink: 0; } .file-info { flex: 1; color: var(--text-secondary); } .text-viewer-body { flex: 1; overflow: auto; padding: 16px; background: var(--surface2); } .text-viewer-body pre { margin: 0; font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; font-size: 0.85rem; line-height: 1.5; white-space: pre-wrap; } .text-viewer-body code { color: var(--text); } /* ── CSV Table ── */ .csv-table-wrapper { overflow: auto; max-height: 70vh; } .csv-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; } .csv-table th { background: var(--surface); color: var(--text-secondary); font-weight: 600; padding: 8px 12px; text-align: left; border-bottom: 2px solid var(--border); position: sticky; top: 0; } .csv-table td { padding: 6px 12px; border-bottom: 1px solid var(--border-light, var(--border)); } .csv-table tr:hover td { background: var(--surface); } /* ── XLSX Viewer ── */ .xlsx-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; } .xlsx-toolbar-actions { margin-left: auto; display: flex; gap: 8px; } .xlsx-tabs { display: flex; gap: 4px; flex-wrap: wrap; } .xlsx-tab { border: 1px solid var(--border); background: var(--surface); color: var(--text-secondary); border-radius: 4px; padding: 4px 10px; font-size: 0.8rem; cursor: pointer; } .xlsx-tab.active { background: var(--accent, #4a90d9); border-color: var(--accent, #4a90d9); color: #fff; } .xlsx-table th.xlsx-corner, .xlsx-table th.xlsx-rownum { background: var(--surface); color: var(--text-secondary); font-weight: 400; text-align: right; padding: 6px 8px; border-bottom: 2px solid var(--border); border-right: 1px solid var(--border-light, var(--border)); position: sticky; left: 0; z-index: 1; } .xlsx-table th.xlsx-corner { left: 0; top: 0; z-index: 2; } .xlsx-table td[contenteditable] { cursor: text; min-width: 40px; white-space: pre-wrap; } .xlsx-table td[contenteditable]:focus { outline: 2px solid var(--accent, #4a90d9); outline-offset: -2px; } .xlsx-table td.xlsx-dirty { background: rgba(255, 196, 0, 0.18); } /* #153 A12 — last result Excel computed, shown under a formula cell. Discreet by design: the formula is what the user edits, the cached value is context (stale until Excel recalculates). */ .xlsx-cached { display: block; margin-top: 2px; padding-left: 6px; border-left: 2px solid var(--border, #d0d7de); color: var(--text-muted); font-size: 0.85em; font-variant-numeric: tabular-nums; white-space: nowrap; } /* #153 A1/A4 — lossy-save warning + formula toggle */ .xlsx-warning { display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px; margin-bottom: 8px; border: 1px solid var(--warning, #e0a800); border-left-width: 3px; border-radius: 4px; background: var(--surface); color: var(--text-secondary); font-size: 0.82rem; line-height: 1.45; } .xlsx-warning-icon { width: 16px; height: 16px; flex: 0 0 auto; margin-top: 1px; color: var(--warning, #e0a800); } .xlsx-warning-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; } .xlsx-warning-body strong { color: var(--text-primary); font-weight: 600; } .xlsx-warning-list { display: flex; flex-wrap: wrap; gap: 4px; } .xlsx-warning-tag { padding: 1px 6px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-secondary); color: var(--text-secondary); font-size: 0.75rem; white-space: nowrap; } .xlsx-warning-hint { color: var(--text-secondary); opacity: 0.85; } .xlsx-formula-toggle { font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; font-weight: 600; } .xlsx-formula-toggle.active { background: var(--accent, #4a90d9); border-color: var(--accent, #4a90d9); color: #fff; } /* ── JSON Viewer ── */ .json-viewer { font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; font-size: 0.85rem; line-height: 1.5; padding: 16px; background: var(--surface2); border-radius: 6px; overflow: auto; max-height: 70vh; } /* ── PaneManager — Split View ── */ .pane-grid { display: grid; height: 100%; overflow: hidden; } .pane-container { display: flex; flex-direction: column; overflow: hidden; position: relative; } .pane-container.pane-active { outline: 2px solid var(--accent); outline-offset: -2px; z-index: 1; } .pane-tab-bar { flex-shrink: 0; } .pane-content { flex: 1; overflow-y: auto; } .pane-resize-handle { background: var(--border); transition: background 150ms; min-width: 4px; min-height: 4px; z-index: 2; } .pane-resize-handle:hover { background: var(--accent); } .code-block-wrapper:hover .copy-code-btn { opacity: 1; } .copy-code-btn { position: absolute; top: 8px; right: 8px; display: flex; align-items: center; gap: 4px; padding: 4px 10px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text-secondary); font-size: 11px; font-family: var(--mono); cursor: pointer; opacity: 0; transition: opacity 150ms ease, background 150ms ease, color 150ms ease; z-index: 5; } .copy-code-btn:hover { background: var(--accent); color: #fff; border-color: var(--accent); } .copy-code-btn.copied { background: var(--accent-green); color: #fff; border-color: var(--accent-green); } /* Mobile : toujours visible (pas de hover sur tactile) */ @media (max-width: 768px) { .copy-code-btn { opacity: 1; padding: 2px 8px; font-size: 10px; top: 4px; right: 4px; } } /* ── MFA (Multi-Factor Authentication) ────────────────────────────────── */ .mfa-challenge { margin-top: 20px; padding: 24px; border-radius: 12px; background: var(--surface, #1a1a2e); border: 1px solid var(--border, #333); text-align: center; } .mfa-challenge .mfa-icon { font-size: 48px; margin-bottom: 12px; } .mfa-challenge h3 { margin: 0 0 8px; color: var(--text, #fff); } .mfa-challenge p { color: var(--muted, #999); margin: 0 0 16px; } .mfa-code-input { width: 180px; font-size: 28px; text-align: center; letter-spacing: 12px; padding: 12px; border: 2px solid var(--border, #444); border-radius: 8px; background: var(--bg, #0d0d1a); color: var(--text, #fff); font-family: monospace; outline: none; } .mfa-code-input:focus { border-color: var(--accent, #7C3AED); } .mfa-code-input-group { display: flex; gap: 8px; justify-content: center; align-items: center; margin-bottom: 12px; } .mfa-code-input-group span { color: var(--muted, #999); font-size: 24px; } .mfa-link-btn { background: none; border: none; color: var(--accent, #7C3AED); cursor: pointer; font-size: 13px; text-decoration: underline; } .mfa-link-btn:hover { opacity: 0.8; } .mfa-error { color: #e74c3c; font-size: 13px; margin-top: 8px; } /* MFA Settings (Security tab) */ .mfa-status-section { padding: 16px 0; } .mfa-status-row { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; } .mfa-badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 12px; border-radius: 20px; font-size: 13px; font-weight: 600; } .mfa-badge-on { background: #1a3a2a; color: #4ade80; } .mfa-badge-off { background: #3a2a1a; color: #f59e0b; } .mfa-status-label { color: var(--text, #fff); font-weight: 500; } /* MFA Setup card */ .mfa-setup-card { padding: 20px; border-radius: 10px; background: var(--surface2, #1e1e3a); border: 1px solid var(--border, #333); } .mfa-setup-card h4 { margin: 0 0 12px; color: var(--text, #fff); } .mfa-qr-container { text-align: center; margin: 16px 0; } .mfa-qr-code img, .mfa-qr-code canvas { max-width: 200px; border-radius: 8px; } .mfa-secret-details { margin-top: 12px; } .mfa-secret-code { font-family: monospace; font-size: 14px; padding: 8px 12px; background: var(--bg, #0d0d1a); border-radius: 6px; color: var(--accent, #7C3AED); cursor: pointer; user-select: all; display: inline-block; } .mfa-info-text { color: var(--muted, #999); font-size: 13px; margin: 8px 0; } .mfa-subtitle { color: var(--muted, #999); font-size: 13px; margin: 0 0 16px; } .mfa-verify-section { display: flex; gap: 8px; align-items: center; margin-top: 12px; } .mfa-actions { margin-top: 16px; } /* MFA Recovery codes display */ .mfa-recovery-card { padding: 20px; border-radius: 10px; background: var(--surface2, #1e1e3a); border: 1px solid var(--border, #333); margin-top: 16px; } .mfa-recovery-card h4 { margin: 0 0 8px; color: var(--text, #fff); } .mfa-recovery-list { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 24px; margin: 12px 0; list-style: none; padding: 0; } .mfa-recovery-code { font-family: monospace; font-size: 14px; padding: 4px 8px; background: var(--bg, #0d0d1a); border-radius: 4px; color: var(--text, #fff); letter-spacing: 1px; } .mfa-recovery-actions { display: flex; gap: 8px; margin-top: 12px; } /* WebAuthn security keys (ROADMAP #64) */ .webauthn-settings { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border, #333); } .webauthn-title { margin: 0 0 6px; color: var(--text, #fff); font-size: 0.95rem; } .webauthn-key-list { list-style: none; margin: 10px 0; padding: 0; display: flex; flex-direction: column; gap: 6px; } .webauthn-key-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; background: var(--surface2, #1a1a2e); border-radius: 6px; } .webauthn-key-label { flex: 1; font-size: 0.9rem; color: var(--text, #fff); } .webauthn-key-meta { font-size: 0.75rem; color: var(--text-muted, #888); } .config-btn-sm { padding: 4px 10px; font-size: 0.78rem; } /* MFA Disable card */ .mfa-disable-card { padding: 16px; border-radius: 10px; background: var(--surface2, #1e1e3a); border: 1px solid #e74c3c33; margin-top: 16px; } .mfa-disable-card h4 { margin: 0 0 8px; color: #e74c3c; } .mfa-disable-actions { display: flex; gap: 8px; margin-top: 12px; } .mfa-warning { color: #f59e0b; font-size: 13px; padding: 8px 12px; background: #3a2a1a; border-radius: 6px; margin-top: 8px; } /* ── BooksLM Panel ──────────────────────────────────── */ .bookslm-panel { position: fixed; right: 0; top: 0; bottom: 0; width: 450px; background: var(--bg-primary); border-left: 1px solid var(--border); z-index: 100; display: flex; flex-direction: column; transform: translateX(100%); transition: transform 300ms ease-out; box-shadow: -4px 0 20px rgba(0,0,0,0.3); color: var(--text-primary); } .bookslm-panel.open { transform: translateX(0); } /* The `.hidden` class is applied by the header toggle button to collapse the panel while keeping it mounted (so the toggle icon stays usable). When hidden, the panel is slid fully off-screen and the open animation no longer overrides the translateX. */ .bookslm-panel.open.hidden { transform: translateX(100%); } .bookslm-btn-toggle { display: flex; align-items: center; justify-content: center; background: none; border: none; cursor: pointer; color: var(--text-secondary); padding: 4px; border-radius: 4px; flex-shrink: 0; transition: color 200ms ease, background 200ms ease; } .bookslm-btn-toggle:hover { color: var(--accent); background: var(--surface2); } .bookslm-header { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--border); } .bookslm-header .bookslm-context-icon { display: flex; color: var(--accent); flex-shrink: 0; } .bookslm-header-titles { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; } .bookslm-header-titles .bookslm-title { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .bookslm-header-titles .bookslm-subtitle { font-size: 11px; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .bookslm-header-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; } .bookslm-header button { background: none; border: none; cursor: pointer; color: var(--text-secondary); padding: 5px; border-radius: 6px; display: flex; align-items: center; } .bookslm-header button:hover { background: var(--surface2); color: var(--text-primary); } /* Provider/model picker on its own row so the header actions never get hidden. */ .bookslm-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; padding: 8px 12px; border-bottom: 1px solid var(--border); background: var(--bg-secondary); } .bookslm-toolbar-label { font-size: 11px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: .04em; flex-shrink: 0; } .bookslm-toolbar .ai-picker { margin-left: 0; padding-left: 0; border-left: none; flex-wrap: wrap; row-gap: 4px; } .bookslm-toolbar .ai-picker select { max-width: 220px; } /* `!important` is required: the panel width is also written inline by the resize handle / persisted width, and an inline style would otherwise win. */ .bookslm-panel.fullscreen { width: 100vw !important; } .bookslm-status { padding: 6px 16px; font-size: 12px; color: var(--text-secondary); border-bottom: 1px solid var(--border); display: flex; gap: 12px; align-items: center; } .bookslm-status .bookslm-status-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .bookslm-status .bookslm-status-error { color: #f87171; } .bookslm-status .bookslm-context-bar { flex: 1; height: 4px; border-radius: 2px; background: var(--surface2); overflow: hidden; } .bookslm-status .bookslm-context-fill { height: 100%; border-radius: 2px; background: var(--accent); transition: width 0.3s; } /* Assistant activity — no loading bar above the composer anymore: in agent mode the animated dots sit in the steps header (« ●●● 3 étapes ▶ »), in plain chat they sit in the pending answer. Pure CSS, reduced-motion aware. */ .bookslm-dots { display: inline-flex; align-items: center; gap: 2px; } .bookslm-dots i { width: 4px; height: 4px; border-radius: 50%; background: currentColor; opacity: 0.25; animation: bookslm-dot 1.2s ease-in-out infinite; } .bookslm-dots i:nth-child(2) { animation-delay: 0.15s; } .bookslm-dots i:nth-child(3) { animation-delay: 0.3s; } @keyframes bookslm-dot { 0%, 60%, 100% { opacity: 0.25; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-2px); } } .bookslm-pending { display: flex; align-items: center; height: 20px; color: var(--text-secondary); } /* Notion-style AI thread: only this zone scrolls; entries stack vertically with generous spacing. The latest user post is anchored to the top of the visible area on send: the post is anchored flush at the top (block:start, and the bottom padding is grown so a short answer can still roll the post all the way up). */ .bookslm-messages { flex: 1; overflow-y: auto; padding: 20px 16px; display: flex; flex-direction: column; gap: 24px; overflow-anchor: none; } .bookslm-msg { display: flex; flex-direction: column; gap: 4px; } /* The user bubble is capped against the *thread* width, not against a shrink-to-fit wrapper: capping both would compound (80% × 85% ≈ 68%) and produced very short lines. Wrapper stretches, bubble carries the cap. */ .bookslm-msg.user { align-items: flex-end; } .bookslm-msg.assistant { align-items: stretch; width: 100%; } .bookslm-msg-meta { font-size: 11px; color: var(--text-secondary); opacity: 0.75; padding: 0 2px; align-self: flex-start; user-select: none; } /* Hover-revealed action bar (Copier / Ajouter). */ .bookslm-msg-actions { display: flex; gap: 6px; margin-top: 4px; opacity: 0; transition: opacity 0.15s; } .bookslm-msg.user .bookslm-msg-actions { justify-content: flex-end; } .bookslm-msg:hover .bookslm-msg-actions, .bookslm-msg-actions:focus-within { opacity: 1; } .bookslm-msg-action { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; padding: 3px 9px; border-radius: 6px; border: 1px solid transparent; background: transparent; color: var(--text-secondary); cursor: pointer; } .bookslm-msg-action:hover { background: var(--surface2); color: var(--text-primary); border-color: var(--border); } .bookslm-bubble { max-width: 85%; padding: 10px 14px; border-radius: 18px; font-size: 14px; line-height: 1.5; word-wrap: break-word; } .bookslm-bubble.user { align-self: flex-end; max-width: 90%; min-width: 0; background: var(--surface2); color: var(--text-primary); border-bottom-right-radius: 6px; } .bookslm-bubble.assistant { align-self: flex-start; background: transparent; padding: 0; width: 100%; max-width: 100%; color: var(--text-primary); } .bookslm-bubble.assistant code { background: rgba(0,0,0,0.2); padding: 1px 4px; border-radius: 3px; font-size: 0.9em; } .bookslm-bubble.assistant pre { background: rgba(0,0,0,0.3); padding: 10px; border-radius: 6px; overflow-x: auto; margin: 8px 0; } /* #102 — per-code-block “Ajouter”: a discreet button in the block's corner, revealed on hover/focus, that inserts only this section. */ .bookslm-code-block { position: relative; } .bookslm-code-block .bookslm-code-insert { position: absolute; top: 6px; right: 6px; z-index: 1; background: var(--surface2); border-color: var(--border); opacity: 0; transition: opacity 0.15s; } .bookslm-code-block:hover .bookslm-code-insert, .bookslm-code-block:focus-within .bookslm-code-insert { opacity: 1; } .bookslm-sources { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; } .bookslm-source-badge { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; font-size: 11px; color: var(--accent); cursor: pointer; } .bookslm-source-badge:hover { background: var(--surface2); } .bookslm-input-area { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--border); align-items: flex-end; } .bookslm-input-area textarea { flex: 1; resize: none; min-height: 36px; max-height: 120px; padding: 8px 12px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg-primary); color: var(--text-primary); font-size: 14px; font-family: inherit; } .bookslm-input-area textarea:focus { border-color: var(--accent); outline: none; } .bookslm-input-area button { padding: 8px 16px; border-radius: 8px; border: none; background: var(--accent); color: #fff; cursor: pointer; font-size: 14px; } .bookslm-input-area button.bookslm-btn-send { width: 40px; height: 40px; padding: 0; border-radius: 50%; font-size: 16px; line-height: 1; display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .bookslm-input-area button:hover { opacity: 0.9; } .bookslm-input-area button:disabled { opacity: 0.5; cursor: not-allowed; } /* BUG-077 — the send button doubles as a Stop control while streaming. */ .bookslm-input-area button.bookslm-btn-send.is-stopping { background: var(--danger); } .bookslm-input-area button.bookslm-btn-send.is-stopping:hover { opacity: 1; filter: brightness(1.08); } .bookslm-input-hint { padding: 0 16px 10px; font-size: 10px; color: var(--text-secondary); text-align: right; border-top: none; } /* Action cards proposed by the General assistant (file/dir creation). */ .bookslm-actions { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; } .bookslm-action { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); } .bookslm-action.done { opacity: 0.65; } .bookslm-action-meta { flex: 1; display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-primary); word-break: break-word; } .bookslm-action-icon { flex-shrink: 0; } .bookslm-action-apply { padding: 5px 12px; border-radius: 6px; border: none; background: var(--accent); color: #fff; cursor: pointer; font-size: 12px; flex-shrink: 0; } .bookslm-action-apply:disabled { opacity: 0.6; cursor: default; } .bookslm-action-apply:not(:disabled):hover { filter: brightness(1.08); } /* Agent-mode toggle in the header. */ .bookslm-header button.bookslm-btn-agent.active { color: var(--accent); background: var(--surface2); } /* Tool-call trace shown above an assistant answer (agent mode). The header is the live indicator (« ●●● 3 étapes ▶ »); expanding it reveals the chronological steps, thinking notes as « Réflexion » sub-sections and web sources as clickable links. */ .bookslm-tool-trace { margin: 0 0 8px; } .bookslm-tool-trace > summary { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-secondary); cursor: pointer; user-select: none; list-style: none; padding: 2px 0; } .bookslm-tool-trace > summary::-webkit-details-marker { display: none; } .bookslm-tool-trace > summary:hover { color: var(--text-primary); } .bookslm-tool-trace[open] > summary { margin-bottom: 4px; } .bookslm-steps-dots { color: var(--accent); } /* BUG-074 — preview of the first action next to the step counter. */ .bookslm-steps-title { color: var(--text-secondary); max-width: 45vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .bookslm-steps-body { display: flex; flex-direction: column; gap: 3px; } .bookslm-chevron { font-size: 8px; line-height: 1; opacity: 0.7; } .bookslm-chevron::before { content: '▶'; } details[open] > summary .bookslm-chevron::before { content: '▼'; } .bookslm-thought { margin-left: 12px; } .bookslm-thought > summary { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text-secondary); cursor: pointer; user-select: none; list-style: none; } .bookslm-thought > summary::-webkit-details-marker { display: none; } .bookslm-thought > summary:hover { color: var(--text-primary); } .bookslm-thought-text { margin: 4px 0 6px 6px; padding-left: 9px; border-left: 2px solid var(--border); font-size: 11.5px; line-height: 1.5; color: var(--text-secondary); font-style: italic; white-space: pre-wrap; word-break: break-word; } .bookslm-web-sources { margin-left: 12px; } .bookslm-web-sources > summary { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text-secondary); cursor: pointer; user-select: none; list-style: none; } .bookslm-web-sources > summary::-webkit-details-marker { display: none; } .bookslm-web-sources > summary:hover { color: var(--text-primary); } .bookslm-web-sources-list { list-style: none; margin: 4px 0 6px 6px; padding: 0; display: flex; flex-direction: column; gap: 3px; border-left: 2px solid var(--border); padding-left: 9px; } .bookslm-web-sources-list a { font-size: 11px; color: var(--accent); text-decoration: none; word-break: break-word; } .bookslm-web-sources-list a::before { content: '↗ '; opacity: 0.7; } .bookslm-web-sources-list a:hover { text-decoration: underline; } .bookslm-tool-line { font-size: 11px; color: var(--text-secondary); padding-left: 12px; } .bookslm-tool-line.failed { color: #f87171; } @media (prefers-reduced-motion: reduce) { .bookslm-dots i { animation: none; opacity: 0.6; } } /* Mutation confirmation card (two-step propose/apply). */ .bookslm-confirm { flex-wrap: wrap; } .bookslm-confirm-diff { flex-basis: 100%; width: 100%; margin-top: 4px; } /* BUG-075 — one row per action when the run batches several mutations. */ .bookslm-confirm-actions { flex-basis: 100%; width: 100%; display: flex; flex-direction: column; gap: 4px; margin-top: 4px; } .bookslm-confirm-action > summary { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-secondary); cursor: pointer; list-style: none; word-break: break-word; } .bookslm-confirm-action > summary::-webkit-details-marker { display: none; } .bookslm-confirm-action > summary:hover { color: var(--text-primary); } .bookslm-confirm-action[open] > summary { color: var(--text-primary); } .bookslm-diff-title { font-size: 11px; color: var(--text-secondary); margin-bottom: 4px; } .bookslm-diff { background: rgba(0,0,0,0.25); border-radius: 6px; padding: 8px; overflow-x: auto; font-size: 12px; line-height: 1.4; max-height: 240px; margin: 0; } .bookslm-diff-add { color: #4ade80; display: block; } .bookslm-diff-del { color: #f87171; display: block; } .bookslm-diff-ctx { color: var(--text-secondary); display: block; } /* #106 — Actions instantanées contextuelles de l'assistant. */ .bookslm-suggestions { display: flex; flex-direction: column; gap: 6px; padding: 8px 16px 0; } .bookslm-suggestions.hidden { display: none; } .bookslm-qa-badge { flex-shrink: 0; font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600; color: var(--accent-text, var(--accent)); background: var(--accent-bg); border: 1px solid var(--border); border-radius: 999px; padding: 2px 8px; } .bookslm-qa-badge.hidden { display: none; } .bookslm-qa-hint { margin: 0 0 2px; font-size: 12px; color: var(--text-secondary); line-height: 1.45; } .bookslm-qa-head { display: flex; align-items: center; justify-content: space-between; padding: 0 2px; } .bookslm-qa-label { font-size: 10px; font-weight: 700; letter-spacing: 0.8px; text-transform: uppercase; color: var(--text-muted, var(--text-secondary)); opacity: 0.85; } .bookslm-qa-more { display: inline-flex; align-items: center; gap: 5px; background: none; border: none; color: var(--accent); font-size: 12px; cursor: pointer; padding: 2px 4px; border-radius: 6px; } .bookslm-qa-more:hover { background: var(--bg-hover); } .bookslm-qa-list { display: flex; flex-direction: column; gap: 6px; } .bookslm-qa-btn { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 9px 12px; border-radius: 10px; cursor: pointer; background: var(--surface); border: 1px solid var(--border); color: var(--text-secondary); font-size: 13px; transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease; } .bookslm-qa-btn:hover { background: var(--surface2); border-color: var(--accent); color: var(--text-primary); } .bookslm-qa-btn .bookslm-qa-icon { color: var(--text-muted, var(--text-secondary)); flex-shrink: 0; } .bookslm-qa-btn:hover .bookslm-qa-icon { color: var(--accent); } .bookslm-qa-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; } .bookslm-qa-go { opacity: 0; transform: translateX(-3px); transition: opacity 0.15s ease, transform 0.15s ease; color: var(--accent); flex-shrink: 0; } .bookslm-qa-btn:hover .bookslm-qa-go { opacity: 1; transform: translateX(0); } /* Tiroir catalogue ("Toutes les actions") : bottom-sheet dans le panneau. */ .bookslm-qa-drawer { position: absolute; inset: 0; z-index: 60; background: rgba(0, 0, 0, 0.45); display: flex; align-items: flex-end; opacity: 0; transition: opacity 0.2s ease; } .bookslm-qa-drawer.hidden { display: none; } .bookslm-qa-drawer.open { opacity: 1; } .bookslm-qa-sheet { width: 100%; max-height: 82%; display: flex; flex-direction: column; background: var(--bg-primary); border-top: 1px solid var(--border); border-radius: 14px 14px 0 0; padding: 12px 14px 10px; box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.35); transform: translateY(100%); transition: transform 0.22s ease; } .bookslm-qa-drawer.open .bookslm-qa-sheet { transform: translateY(0); } .bookslm-qa-sheet-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; } .bookslm-qa-sheet-title { display: inline-flex; align-items: center; gap: 7px; font-size: 14px; font-weight: 600; color: var(--text-primary); } .bookslm-qa-sheet-title i { color: var(--accent); } .bookslm-qa-sheet-close { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 50%; border: none; cursor: pointer; background: var(--surface); color: var(--text-secondary); } .bookslm-qa-sheet-close:hover { background: var(--surface2); color: var(--text-primary); } .bookslm-qa-search { position: relative; margin-bottom: 10px; } .bookslm-qa-search i { position: absolute; left: 9px; top: 50%; transform: translateY(-50%); color: var(--text-secondary); pointer-events: none; } .bookslm-qa-search input { width: 100%; box-sizing: border-box; padding: 7px 10px 7px 30px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface); color: var(--text-primary); font-size: 13px; outline: none; } .bookslm-qa-search input:focus { border-color: var(--accent); } .bookslm-qa-sheet-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; padding-bottom: 8px; } .bookslm-qa-cat { margin: 8px 2px 2px; display: flex; align-items: center; gap: 6px; font-size: 10px; font-weight: 700; letter-spacing: 0.8px; text-transform: uppercase; color: var(--text-secondary); position: sticky; top: 0; background: var(--bg-primary); padding: 4px 0; z-index: 1; } .bookslm-qa-btn.compact { padding: 7px 10px; border-radius: 8px; font-size: 12.5px; } .bookslm-qa-empty { padding: 18px 8px; text-align: center; font-size: 12px; color: var(--text-secondary); } @media (prefers-reduced-motion: reduce) { .bookslm-qa-drawer, .bookslm-qa-sheet, .bookslm-qa-btn, .bookslm-qa-go { transition: none; } } /* Formatted markdown inside assistant answers. */ .bookslm-bubble.assistant > *:first-child { margin-top: 0; } .bookslm-bubble.assistant > *:last-child { margin-bottom: 0; } .bookslm-bubble.assistant p { margin: 6px 0; } .bookslm-bubble.assistant h1, .bookslm-bubble.assistant h2, .bookslm-bubble.assistant h3, .bookslm-bubble.assistant h4, .bookslm-bubble.assistant h5, .bookslm-bubble.assistant h6 { margin: 10px 0 6px; line-height: 1.3; font-weight: 600; } .bookslm-bubble.assistant h1 { font-size: 1.35em; } .bookslm-bubble.assistant h2 { font-size: 1.2em; } .bookslm-bubble.assistant h3 { font-size: 1.1em; } .bookslm-bubble.assistant h4, .bookslm-bubble.assistant h5, .bookslm-bubble.assistant h6 { font-size: 1em; } .bookslm-bubble.assistant ul, .bookslm-bubble.assistant ol { margin: 6px 0; padding-left: 20px; } .bookslm-bubble.assistant li { margin: 2px 0; } .bookslm-bubble.assistant blockquote { margin: 8px 0; padding: 4px 10px; border-left: 3px solid var(--accent); background: rgba(0,0,0,0.12); border-radius: 0 4px 4px 0; color: var(--text-secondary); } .bookslm-bubble.assistant hr { border: none; border-top: 1px solid var(--border); margin: 10px 0; } .bookslm-bubble.assistant table { border-collapse: collapse; margin: 8px 0; width: 100%; display: block; overflow-x: auto; } .bookslm-bubble.assistant th, .bookslm-bubble.assistant td { border: 1px solid var(--border); padding: 4px 8px; font-size: 0.92em; text-align: left; } .bookslm-bubble.assistant th { background: rgba(0,0,0,0.15); } .bookslm-bubble.assistant pre { max-width: 100%; } .bookslm-bubble.assistant a { color: var(--accent); } .bookslm-path-link { color: var(--accent); cursor: pointer; text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 2px; } .bookslm-path-link:hover { text-decoration-style: solid; } /* Session history dropdown. */ .bookslm-history-menu { position: absolute; top: 48px; right: 10px; z-index: 20; width: min(320px, calc(100% - 20px)); max-height: 60vh; overflow-y: auto; background: var(--bg-primary); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,0.35); padding: 6px; } .bookslm-history-menu.hidden { display: none; } .bookslm-history-item { display: flex; align-items: stretch; gap: 4px; border-radius: 8px; } .bookslm-history-item:hover { background: var(--surface2); } .bookslm-history-item.active { background: var(--surface2); outline: 1px solid var(--accent); } .bookslm-history-open { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; background: none; border: none; cursor: pointer; text-align: left; padding: 7px 8px; color: var(--text-primary); border-radius: 8px; } .bookslm-history-title { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .bookslm-history-date { font-size: 10px; color: var(--text-secondary); } .bookslm-history-meta { font-size: 10px; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .bookslm-history-delete { background: none; border: none; cursor: pointer; color: var(--text-secondary); padding: 0 8px; border-radius: 6px; display: flex; align-items: center; } .bookslm-history-delete:hover { color: #f87171; background: rgba(248,113,113,0.12); } .bookslm-history-empty { padding: 10px; font-size: 12px; color: var(--text-secondary); text-align: center; } /* Resizable left edge. */ .bookslm-resize-handle { position: absolute; left: 0; top: 0; bottom: 0; width: 6px; cursor: ew-resize; z-index: 30; background: transparent; } .bookslm-resize-handle:hover { background: var(--accent); opacity: 0.4; } .bookslm-panel.fullscreen .bookslm-resize-handle { display: none; } body.bookslm-resizing { cursor: ew-resize; user-select: none; } /* Attachment chips (ad-hoc context, skill, images). */ .bookslm-attachments { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 12px 0; } .bookslm-attachments.empty { display: none; } .bookslm-chip { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; padding: 3px 6px 3px 8px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface2); font-size: 11px; color: var(--text-primary); } .bookslm-chip-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 220px; } .bookslm-chip-remove { background: none; border: none; cursor: pointer; color: var(--text-secondary); font-size: 14px; line-height: 1; padding: 0 2px; border-radius: 50%; } .bookslm-chip-remove:hover { color: #f87171; } .bookslm-chip-thumb { width: 18px; height: 18px; object-fit: cover; border-radius: 4px; } .bookslm-chip-skill { border-color: var(--accent); } .bookslm-chip-deep-research { border-color: var(--accent); } /* Composer menus (`/` commands and `@` mentions). */ .bookslm-menu-layer { position: relative; } .bookslm-command-menu, .bookslm-mention-menu { position: absolute; left: 12px; right: 12px; bottom: 4px; max-height: 260px; overflow-y: auto; background: var(--bg-primary); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,0.35); padding: 4px; z-index: 40; } .bookslm-command-menu.hidden, .bookslm-mention-menu.hidden { display: none; } .bookslm-menu-item { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; background: none; border: none; cursor: pointer; padding: 7px 9px; border-radius: 7px; color: var(--text-primary); font-size: 13px; } .bookslm-menu-item:hover { background: var(--bg-hover); } /* The active (keyboard) item needs a clearly visible highlight: --surface2 is identical to --bg-primary in the default dark theme, so it was invisible. */ .bookslm-menu-item.active { background: var(--bg-hover); color: var(--text-primary); box-shadow: inset 3px 0 0 var(--accent); } .bookslm-menu-icon { flex-shrink: 0; } .bookslm-menu-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .bookslm-menu-desc, .bookslm-menu-usage { margin-left: auto; font-size: 11px; color: var(--text-secondary); white-space: nowrap; } .bookslm-menu-empty { padding: 10px; font-size: 12px; color: var(--text-secondary); text-align: center; } /* Image attach button. */ .bookslm-input-area button.bookslm-btn-plus { display: flex; align-items: center; justify-content: center; flex-shrink: 0; background: none; border: 1px solid var(--border); color: var(--text-secondary); cursor: pointer; border-radius: 50%; width: 32px; height: 32px; padding: 0; } .bookslm-input-area button.bookslm-btn-plus:hover { color: var(--accent); border-color: var(--accent); } .bookslm-file-input { display: none; } .bookslm-files-input { display: none; } /* Extensible "+" panel (#97). */ .bookslm-ext-menu { position: absolute; left: 12px; right: 12px; bottom: 72px; z-index: 45; max-height: 55vh; overflow-y: auto; background: var(--bg-primary); border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 8px 24px rgba(0,0,0,0.35); padding: 6px; } .bookslm-ext-menu.hidden { display: none; } .bookslm-ext-item { display: grid; grid-template-columns: 20px 1fr auto; align-items: center; gap: 8px; width: 100%; text-align: left; background: none; border: none; cursor: pointer; padding: 8px 9px; border-radius: 8px; color: var(--text-primary); font-size: 13px; } .bookslm-ext-item:hover { background: var(--bg-hover); } .bookslm-ext-item .bookslm-ext-hint { grid-column: 2 / 4; font-size: 11px; color: var(--text-secondary); margin-top: -4px; } .bookslm-ext-item.disabled { opacity: 0.55; cursor: not-allowed; } .bookslm-ext-item.disabled:hover { background: none; } .bookslm-ext-soon { font-size: 9px; text-transform: uppercase; letter-spacing: 0.4px; color: var(--accent); border: 1px solid var(--accent); border-radius: 10px; padding: 1px 6px; } .bookslm-ext-footer { padding: 7px 9px 4px; font-size: 10px; color: var(--text-secondary); text-align: center; border-top: 1px dashed var(--border); margin-top: 4px; } /* Create-skill modal. */ .bookslm-modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.55); z-index: 2000; display: flex; align-items: center; justify-content: center; padding: 16px; } .bookslm-modal { background: var(--bg-primary); border: 1px solid var(--border); border-radius: 12px; padding: 18px; width: min(520px, 100%); box-shadow: 0 12px 40px rgba(0,0,0,0.45); } .bookslm-modal-title { margin: 0 0 12px; font-size: 15px; } .bookslm-modal-field { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-secondary); margin-bottom: 10px; } .bookslm-modal-field input, .bookslm-modal-field textarea { padding: 8px 10px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text-primary); font-size: 13px; font-family: inherit; } .bookslm-modal-error { color: #f87171; font-size: 12px; min-height: 14px; margin-bottom: 6px; } .bookslm-modal-actions { display: flex; justify-content: flex-end; gap: 8px; } .bookslm-modal-actions button { padding: 7px 14px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface); color: var(--text-primary); cursor: pointer; font-size: 13px; } .bookslm-modal-actions button.primary { background: var(--accent); color: #fff; border-color: var(--accent); } /* ── Provider/model picker (shared by assistant + editor) ── */ .ai-picker { display: inline-flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--text-secondary); flex-shrink: 0; position: relative; } .ai-picker-label { white-space: nowrap; } .ai-picker select { font-size: 0.8rem; background: var(--surface); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px; cursor: pointer; min-height: 34px; } .ai-picker select:hover { border-color: var(--accent); } .ai-picker select:focus { border-color: var(--accent); outline: none; } /* Searchable model combobox. */ .ai-picker-model-combo { position: relative; display: inline-flex; } .ai-picker-model-trigger { display: inline-flex; align-items: center; justify-content: space-between; gap: 6px; max-width: 240px; min-width: 120px; min-height: 34px; font-size: 0.8rem; background: var(--surface); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px; cursor: pointer; } .ai-picker-model-trigger:hover, .ai-picker-model-trigger:focus { border-color: var(--accent); outline: none; } .ai-picker-model-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .ai-picker-model-chevron { opacity: 0.6; font-size: 0.7rem; flex-shrink: 0; } .ai-picker-model-pop { position: absolute; top: calc(100% + 4px); right: 0; z-index: 60; min-width: 220px; width: 340px; max-width: calc(100vw - 24px); background: var(--bg-primary); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.35); padding: 6px; } .ai-picker-model-pop.hidden { display: none; } .ai-picker-model-search { width: 100%; box-sizing: border-box; font-size: 0.8rem; background: var(--bg-secondary); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px; padding: 7px 10px; margin-bottom: 4px; } .ai-picker-model-search:focus { border-color: var(--accent); outline: none; } .ai-picker-model-list { max-height: 260px; overflow-y: auto; display: flex; flex-direction: column; } .ai-picker-model-option { display: block; width: 100%; text-align: left; font-size: 0.8rem; line-height: 1.35; padding: 7px 10px; border-radius: 5px; background: none; border: none; color: var(--text-primary); cursor: pointer; white-space: normal; overflow-wrap: anywhere; } .ai-picker-model-option:hover { background: var(--bg-hover); } .ai-picker-model-option.active { background: var(--bg-hover); box-shadow: inset 3px 0 0 var(--accent); } .ai-picker-model-empty { font-size: 0.78rem; color: var(--text-secondary); padding: 8px 10px; text-align: center; } .ai-picker-model-more { font-size: 0.78rem; color: var(--text-secondary); padding: 8px 10px; text-align: center; } /* Capability info button (ⓘ) + informational bubble. */ .ai-picker-caps-host { position: relative; display: inline-flex; } .ai-picker-info { background: none; border: none; cursor: pointer; color: var(--text-secondary); font-size: 1rem; line-height: 1; padding: 5px 7px; border-radius: 6px; } .ai-picker-info:hover, .ai-picker-info:focus { color: var(--accent); } .ai-picker-info.hidden { display: none; } .ai-picker-caps-pop { position: absolute; top: calc(100% + 4px); left: 0; z-index: 60; min-width: 220px; max-width: 300px; background: var(--bg-primary); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.35); padding: 8px 10px; } .ai-picker-caps-pop.hidden { display: none; } .ai-picker-caps-title { font-size: 0.7rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 4px; } .ai-picker-caps { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 4px; font-size: 10px; color: var(--text-secondary); } .ai-cap-item { white-space: nowrap; opacity: 0.65; } .ai-cap-item.on { opacity: 1; color: var(--accent); } @media (max-width: 768px) { .bookslm-resize-handle { display: none; } .bookslm-panel { width: 100%; /* Clear the fixed bottom toolbar so the input box and the send button are not hidden behind it. The panel background still fills the area behind the bar. */ padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); } } /* ── AI Floating Action Button ───────────────────────── */ .ai-fab { position: fixed; bottom: 24px; right: 24px; width: 52px; height: 52px; border-radius: 50%; background: var(--accent); color: #fff; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; z-index: 99; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); transition: transform 200ms ease, opacity 200ms ease; padding: 0; } .ai-fab:hover { transform: scale(1.08); } .ai-fab:active { transform: scale(0.96); } .ai-fab[hidden] { display: none; } /* ══════════════════════════════════════════ Mobile editor UX (ROADMAP #69) Floating Markdown toolbar, paste helper, pinch-zoom, adjustable height, swipe shortcuts and distraction-free reading mode. ══════════════════════════════════════════ */ /* ── Obsidian-style editing ribbon (ROADMAP #83) ── */ .me-toolbar { display: none; } .me-ribbon { --kb-offset: 0px; } .me-ribbon-scroll { display: flex; align-items: center; gap: 4px; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding: 2px 2px; min-width: 0; flex: 1; } .me-ribbon-scroll::-webkit-scrollbar { display: none; } .me-ribbon-btn { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; min-width: 42px; height: 42px; padding: 0 8px; border: 1px solid transparent; border-radius: 10px; background: transparent; color: var(--text-primary); font-size: 14px; font-weight: 600; font-family: var(--font-mono); cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background 120ms ease, transform 120ms ease; } .me-ribbon-btn:active { transform: scale(0.92); background: rgba(128, 128, 128, 0.22); } .me-ribbon-gear { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; border: none; border-left: 1px solid var(--border); border-radius: 0; background: transparent; color: var(--text-muted); font-size: 18px; cursor: pointer; -webkit-tap-highlight-color: transparent; } .me-ribbon-gear:active { color: var(--accent); } /* Ribbon customiser rows */ .me-ribbon-customizer-list { max-height: 50vh; overflow-y: auto; } .me-ribbon-cmd-row { display: flex; align-items: center; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--border); } .me-ribbon-cmd-row.disabled { opacity: 0.75; } .me-ribbon-cmd-label { flex: 1; font-size: 0.85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .me-ribbon-cmd-move, .me-ribbon-cmd-remove, .me-ribbon-cmd-add { flex: 0 0 auto; width: 34px; height: 34px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-primary); font-size: 14px; cursor: pointer; } .me-ribbon-cmd-move:disabled { opacity: 0.35; } .me-ribbon-cmd-remove { color: var(--danger); } .me-ribbon-cmd-divider { padding: 10px; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); } .me-ribbon-customizer-actions { display: flex; justify-content: flex-end; gap: 8px; padding: 10px; border-top: 1px solid var(--border); } /* BUG-018: the in-editor AI toolbar was too dense on small screens. */ @media (max-width: 768px) { .ai-toolbar { gap: 4px !important; padding: 6px 8px !important; } .ai-toolbar-btn { min-height: 34px; padding: 6px 10px !important; font-size: 0.78rem !important; } } @media (max-width: 768px) { .editor-modal.active .me-ribbon { display: flex; position: fixed; left: 8px; right: 8px; /* BUG-019: sit just above the on-screen keyboard. */ bottom: calc(var(--kb-offset, 0px) + 8px + env(safe-area-inset-bottom, 0)); z-index: 30; align-items: center; gap: 4px; padding: 4px; background: #1c1c1e; border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 14px; box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45); } .me-ribbon-btn { color: #e8e8ea; } .me-ribbon-gear { color: #b8b8bd; } [data-theme="light"] .me-ribbon { background: #f1f1f4; border-color: rgba(0, 0, 0, 0.08); } [data-theme="light"] .me-ribbon-btn { color: #1c1c1e; } [data-theme="light"] .me-ribbon-gear { color: #5a5a60; } } /* ── Adjustable editor height handle ── */ .me-resize-handle { display: none; } @media (max-width: 768px) { .me-resize-handle { display: block; height: 14px; margin: 0; background: var(--bg-secondary); border-top: 1px solid var(--border); cursor: ns-resize; touch-action: none; position: relative; flex-shrink: 0; } .me-resize-handle::after { content: ''; position: absolute; top: 50%; left: 50%; width: 40px; height: 4px; border-radius: 2px; background: var(--border); transform: translate(-50%, -50%); } } /* ── Reading mode enter / exit buttons ── */ .me-reading-btn, .me-reading-exit { display: none; } /* Author `display: flex` would otherwise win over the `[hidden]` attribute. */ .me-reading-btn[hidden] { display: none; } @media (max-width: 768px) { .me-reading-btn { display: flex; position: fixed; right: 16px; bottom: calc(80px + env(safe-area-inset-bottom, 0)); z-index: 890; width: 48px; height: 48px; align-items: center; justify-content: center; border: none; border-radius: 50%; background: var(--accent); color: #fff; font-size: 20px; cursor: pointer; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35); } body.reading-mode .me-reading-btn { display: none; } body.reading-mode .me-reading-exit { display: flex; position: fixed; top: calc(12px + env(safe-area-inset-top, 0)); right: 12px; z-index: 1100; width: 40px; height: 40px; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 50%; background: var(--bg-secondary); color: var(--text-primary); font-size: 16px; cursor: pointer; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); } } /* ── Distraction-free reading mode ── */ body.reading-mode .header, body.reading-mode .sidebar, body.reading-mode .sidebar-overlay, body.reading-mode .right-sidebar, body.reading-mode .right-sidebar-resize-handle, body.reading-mode .mobile-toolbar, body.reading-mode .vault-context-bar, body.reading-mode .tab-bar { display: none !important; } body.reading-mode .content-area { max-width: 820px; margin: 0 auto; padding: clamp(20px, 6vw, 48px) clamp(18px, 6vw, 40px) 96px; } /* The bottom toolbar is hidden in reading mode: no clearance needed. */ body.reading-mode .main-body { padding-bottom: 0; } body.reading-mode .breadcrumb, body.reading-mode .file-toolbar, body.reading-mode .file-actions { display: none; } /* ── Bottom sheet (backlinks / table of contents) ── */ .me-sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 1200; max-height: 70vh; display: flex; flex-direction: column; background: var(--bg-secondary); border-top-left-radius: 16px; border-top-right-radius: 16px; box-shadow: 0 -6px 28px rgba(0, 0, 0, 0.4); transform: translateY(110%); transition: transform 220ms ease; } .me-sheet.open { transform: translateY(0); } .me-sheet-overlay { position: fixed; inset: 0; z-index: 1190; background: var(--overlay-bg, rgba(0, 0, 0, 0.5)); opacity: 0; pointer-events: none; transition: opacity 220ms ease; } .me-sheet-overlay.visible { opacity: 1; pointer-events: auto; } .me-sheet-handle { width: 40px; height: 4px; border-radius: 2px; background: var(--border); margin: 8px auto 4px; flex-shrink: 0; } .me-sheet-header { display: flex; align-items: center; justify-content: space-between; padding: 6px 16px 10px; border-bottom: 1px solid var(--border); flex-shrink: 0; } .me-sheet-title { font-size: 0.9rem; font-weight: 600; color: var(--text-primary); } .me-sheet-close { width: 32px; height: 32px; border: none; border-radius: 8px; background: transparent; color: var(--text-muted); font-size: 16px; cursor: pointer; } .me-sheet-list { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 6px 8px calc(12px + env(safe-area-inset-bottom, 0)); } .me-sheet-item { display: block; width: 100%; padding: 12px 12px; border: none; border-radius: 8px; background: transparent; color: var(--text-primary); font-size: 0.9rem; text-align: left; cursor: pointer; } .me-sheet-item:active { background: var(--bg-hover, rgba(128, 128, 128, 0.18)); } .me-sheet-empty { padding: 24px 16px; text-align: center; color: var(--text-muted); font-size: 0.85rem; }