feat: refonte mobile de la section Configurations #114
This commit is contained in:
+272
-38
@@ -3164,6 +3164,23 @@ select {
|
||||
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;
|
||||
@@ -4777,22 +4794,204 @@ body.resizing-v {
|
||||
}
|
||||
}
|
||||
|
||||
/* BUG-071: Configurations modal — mobile usability (viewport ≤ 768px).
|
||||
#config-nav shares the .help-nav rule that hides it, but the config modal
|
||||
had no toggle (unlike the help modal): the header hamburger
|
||||
(#config-hamburger, same .help-hamburger treatment) reveals it as a
|
||||
collapsible top block. Two-column grids and fixed-width add-rows are
|
||||
stacked/wrapped so nothing overflows a 360px viewport. */
|
||||
/* --- #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) {
|
||||
/* TOC as a collapsible top block (JS toggles inline display flex/none,
|
||||
which wins over the hiding rule); the list scrolls within a capped nav. */
|
||||
#config-modal #config-nav {
|
||||
/* 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;
|
||||
}
|
||||
#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;
|
||||
max-width: 100%;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid var(--border);
|
||||
max-height: 46vh;
|
||||
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,
|
||||
@@ -4851,6 +5050,61 @@ body.resizing-v {
|
||||
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 --- */
|
||||
@@ -5819,28 +6073,6 @@ body.resizing-v {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.config-btn-add {
|
||||
padding: 6px 12px;
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
transition: all 150ms ease;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.config-btn-add:hover {
|
||||
background: color-mix(in srgb, var(--accent) 85%, black);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.config-btn-add:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
Utility — hidden class
|
||||
--------------------------------------------------------------------------- */
|
||||
@@ -7907,7 +8139,6 @@ body.popup-mode .content-area {
|
||||
.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; }
|
||||
.config-btn-add { padding: 6px 14px; background: var(--accent); color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 0.8rem; }
|
||||
|
||||
/* ── API/MCP tokens UI (#107) ── */
|
||||
.token-item {
|
||||
@@ -8506,9 +8737,13 @@ body.desktop-mode .editor-container {
|
||||
|
||||
.help-hamburger {
|
||||
display: inline-flex;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
min-width: 44px;
|
||||
}
|
||||
|
||||
/* TOC: collapsible block at top (not slide-over) */
|
||||
/* 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%;
|
||||
@@ -10763,7 +10998,6 @@ body.desktop-mode .editor-container {
|
||||
}
|
||||
.mfa-link-btn:hover { opacity: 0.8; }
|
||||
.mfa-error { color: #e74c3c; font-size: 13px; margin-top: 8px; }
|
||||
.mfa-recovery-input { width: 200px; font-size: 20px; letter-spacing: 4px; }
|
||||
|
||||
/* MFA Settings (Security tab) */
|
||||
.mfa-status-section { padding: 16px 0; }
|
||||
|
||||
Reference in New Issue
Block a user