Settings overhaul + UI polish pass

Two months of iteration on the Settings panel, integration forms, and
small visual nudges across the app. Highlights:

Settings restructure
- Add Models: split into separate Local + API cards (no more in-card
  tabs); each fuses Type/Provider with the URL input.
- Added Models: new dedicated sidebar tab, with Probe + Clear-offline
  pulled into its header; Local/API sub-section icons accent-tinted.
- Search: Web Search and a new Deep Research card (Model + tuning),
  with a cross-link to AI Defaults. Provider hints use real clickable
  anchors; Web Search Test button shows a whirlpool spinner.
- AI Defaults: Image Generation card returns; Research Model card
  carries only Endpoint+Model with a cross-link to Search; Vision /
  Default / Utility fallbacks unified under one numbered-row design
  matching Search's chain.
- API Permissions (was 'API Tokens'): per-row rename, inline
  Permissions toggle that expands the scope-edit panel, in-field
  copy icons (icon→check on success). Empty state accent-tinted.
- Integrations: + Add Integration drops a type-picker menu directly
  under the button (drop-up on tight viewports); each integration
  form (API, CalDAV, CardDAV, Email, Codex/Claude, Vault, MCP) uses
  the same accent-outlined Save/Test/Cancel buttons right-aligned.
- Danger Zone: Wipe→Delete with trash icons; new 'Delete everything'
  row at the bottom that loops every category.

AI Synthesis (Reminders)
- Persona dropdown sourced from PROMPT_TEMPLATES + custom preset.
- src/reminder_personas.py mirrors the five built-ins for the
  server-side synthesis path.
- dispatch_reminder() reads reminder_llm_persona and uses the
  persona's system prompt; empty/unknown falls back to warm-neutral.

Esc handling
- Kebab menus and the provider picker intercept Esc in capture phase
  so dismissing a popup no longer closes the whole Settings modal.

Accent tinting
- Scoped CSS rule across data-settings-panel=ai/services/added-models/
  search/integrations/reminders for card h2 icons + the Added Models
  sub-section icons.

Codex/Claude integration form
- No more auto-creation on form open — explicit Create token button.
- New tokens start with every scope granted; existing tokens move out
  of the integration form into the API Permissions card.
- Setup reveal: copy buttons inline inside the token + setup code
  blocks; shorter subtitle wording.

Misc visual polish
- Save/Test/Cancel uniformly accent-outlined and right-aligned on
  every integration form.
- Provider logos render inline next to the search fallback selects
  and the Deep Research Search dropdown.
- Trash icons in fallback rows bumped to 20x20 so they fill the 32px
  button.
- Image generation default flipped to off.
This commit is contained in:
pewdiepie-archdaemon
2026-06-10 15:15:13 +09:00
parent 7690860ab1
commit 4f7061fd61
18 changed files with 1512 additions and 552 deletions
+41 -22
View File
@@ -1239,23 +1239,27 @@ body.bg-pattern-sparkles {
.section-header-btn.active { opacity: 0.9; color: var(--accent); }
.section-header-btn svg { width: 12px; height: 12px; }
/* Chats library — grid icon, hover-reveal so the header only toggles collapse */
/* Chats library grid icon, hover-reveal so the header only toggles
collapse. Uses !important to win over .list-item-plus-btn's
opacity:1!important (the email-style plus button forces always-on,
which we don't want here the manage button should fade until the
user actually hovers the section). */
#sessions-section .chats-manage-btn {
opacity: 0;
opacity: 0 !important;
transition: opacity 0.12s, background 0.08s;
}
#sessions-section .section-header-flex:hover .chats-manage-btn,
#sessions-section .chats-manage-btn:hover,
#sessions-section .chats-manage-btn:focus-visible {
opacity: 0.45;
opacity: 0.45 !important;
}
#sessions-section .chats-manage-btn:hover,
#sessions-section .chats-manage-btn:focus-visible {
opacity: 1;
opacity: 1 !important;
}
@media (hover: none) {
#sessions-section .chats-manage-btn { opacity: 0.35; }
#sessions-section .chats-manage-btn:active { opacity: 1; }
#sessions-section .chats-manage-btn { opacity: 0.35 !important; }
#sessions-section .chats-manage-btn:active { opacity: 1 !important; }
}
/* Collapse chevron */
@@ -14011,7 +14015,7 @@ body:has(.doc-version-panel:not(.hidden)) .hamburger-btn {
background: color-mix(in srgb, var(--fg) 12%, transparent);
border-radius: 50%;
}
.adm-provider-caret { flex-shrink: 0; opacity: 0.5; transition: transform 0.15s; }
.adm-provider-caret { flex-shrink: 0; transition: transform 0.15s; }
.adm-provider-picker:has(.adm-provider-menu:not(.hidden)) .adm-provider-caret {
transform: rotate(180deg);
}
@@ -14273,6 +14277,25 @@ body:has(.doc-version-panel:not(.hidden)) .hamburger-btn {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-top: -4px;
}
/* Settings panel tint each card's h2 title icon with the user's accent
colour. Direct-child selector (`> h2 > svg`) so SVGs nested inside
header buttons (Test, kebab, etc.) are untouched. Each title icon uses
stroke="currentColor", so setting color propagates; existing inline
opacity:0.6 stays so the tint reads soft. */
/* Selected integration card — class beats inline borderColor reset */
.intg-card.intg-card-active { border-color: var(--accent, var(--red)) !important; }
[data-settings-panel="ai"] .admin-card > h2 > svg,
[data-settings-panel="services"] .admin-card > h2 > svg,
[data-settings-panel="added-models"] .admin-card > h2 > svg,
[data-settings-panel="search"] .admin-card > h2 > svg,
[data-settings-panel="integrations"] .admin-card > h2 > svg,
[data-settings-panel="reminders"] .admin-card > h2 > svg,
[data-settings-panel="added-models"] .adm-ep-section-head > svg {
color: var(--accent, var(--red));
}
.admin-ep-actions {
display: flex;
@@ -21463,7 +21486,7 @@ body.gallery-selecting .gallery-dl-btn,
padding: 8px 10px;
border: none;
background: none;
color: var(--color-muted);
color: color-mix(in srgb, var(--fg) 60%, transparent);
font-family: inherit;
font-size: 12px;
font-weight: 500;
@@ -21565,9 +21588,11 @@ body.gallery-selecting .gallery-dl-btn,
background: transparent; color: var(--fg); cursor: pointer; font-size: 13px;
display: flex; align-items: center; justify-content: center; transition: all 0.15s;
}
.shortcut-action-btn:hover { border-color: var(--accent, #cc6a3a); background: color-mix(in srgb, var(--accent, #cc6a3a) 10%, var(--bg)); }
.shortcut-action-btn.is-reset { opacity: 0.5; }
.shortcut-action-btn.is-reset:hover { opacity: 1; }
.shortcut-action-btn:not(.is-reset):hover { border-color: var(--accent, #cc6a3a); background: color-mix(in srgb, var(--accent, #cc6a3a) 10%, var(--bg)); }
.shortcut-action-btn.is-reset { opacity: 0.55; border-color: transparent; background: transparent; }
.shortcut-action-btn.is-reset:hover,
.shortcut-action-btn.is-reset:focus,
.shortcut-action-btn.is-reset:active { opacity: 0.55; background: transparent; border-color: transparent; }
@keyframes shortcut-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
@@ -22659,23 +22684,17 @@ details.hwfit-serve-advanced > .hwfit-serve-checks:last-of-type {
.settings-fallback-remove {
flex-shrink: 0;
margin-right: 4px;
width: 22px;
height: 22px;
line-height: 1;
font-size: 15px;
/* Nudge the × glyph 5px left within the button (button size unchanged). */
text-indent: -5px;
width: 32px;
height: 32px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid var(--border);
border-radius: 6px;
background: transparent;
color: color-mix(in srgb, var(--fg) 55%, transparent);
cursor: pointer;
transition: border-color 0.12s, color 0.12s, background 0.12s;
position: relative;
top: -6px;
/* Glyph baseline trim: nudge × up 1px inside the button without moving the
button. line-height < 1 lets the glyph float toward the top of its line box. */
line-height: 0.85;
}
.settings-fallback-remove:hover {
border-color: var(--red);