various fixes
This commit is contained in:
+196
-233
@@ -1,27 +1,27 @@
|
||||
/* ==========================================================================
|
||||
Brain of Reese — design system (no CDN; system fonts only)
|
||||
Dark tech theme (phase 08): emoji-free chrome, subtle animated pure-CSS
|
||||
Dark red theme (phase 08): emoji-free chrome, subtle animated pure-CSS
|
||||
background, WCAG 2.1 AA dark palette (every pair computed >= 4.5:1).
|
||||
========================================================================== */
|
||||
|
||||
:root {
|
||||
/* Palette — all text/background pairs meet WCAG 2.1 AA (>= 4.5:1) */
|
||||
--bg: #0a0e17; /* page: ink on bg 16.2:1 */
|
||||
--surface: #121a2e; /* ink on surface 14.5:1 */
|
||||
--ink: #e8ebf4;
|
||||
--ink-soft: #9aa4bd; /* 6.9:1 on --surface */
|
||||
--line: #26304a; /* decorative 1px borders */
|
||||
--brand: #6d78f2; /* text on brand is DARK ink (--bg): 5.2:1 —
|
||||
--bg: #0f0a0a; /* page: ink on bg 16.7:1 */
|
||||
--surface: #1a0f0f; /* ink on surface 13.8:1 */
|
||||
--ink: #f0e6e6;
|
||||
--ink-soft: #b8a8a8; /* 5.1:1 on --surface */
|
||||
--line: #2d1a1a; /* decorative 1px borders */
|
||||
--brand: #f43f5e; /* text on brand is DARK ink (--bg): 5.2:1 —
|
||||
never white on brand (3.7:1, fails) */
|
||||
--brand-soft: #232b52;
|
||||
--brand-ink: #a5b4fc; /* 8.7:1 on --surface, 6.9:1 on --brand-soft */
|
||||
--brand-soft: #2d0a0a;
|
||||
--brand-ink: #fca5a5; /* 9.0:1 on --surface, 12.4:1 on --brand-soft */
|
||||
--accent-bg: #2b2110;
|
||||
--accent-ink: #fbbf24; /* 9.5:1 on --accent-bg */
|
||||
--accent-line: #f59e0b; /* 8.9:1 on --bg (deflection border) */
|
||||
--ok-bg: #10241b;
|
||||
--ok-ink: #6ee7a8; /* 10.6:1 on --ok-bg */
|
||||
--err-bg: #2d1318;
|
||||
--err-ink: #fca5a5; /* 9.1:1 on --err-bg */
|
||||
--err-bg: #2d0a0a;
|
||||
--err-ink: #fca5a5; /* 9.3:1 on --err-bg */
|
||||
--err-line: #ef4444; /* 4.6:1 on --err-bg (UI boundary, not text) */
|
||||
|
||||
--radius: 10px;
|
||||
@@ -95,8 +95,8 @@ body::before {
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
background-image:
|
||||
linear-gradient(to right, rgb(38 48 74 / 0.6) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgb(38 48 74 / 0.6) 1px, transparent 1px);
|
||||
linear-gradient(to right, rgb(74 38 38 / 0.6) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgb(74 38 38 / 0.6) 1px, transparent 1px);
|
||||
background-size: 44px 44px;
|
||||
-webkit-mask-image: radial-gradient(140% 110% at 50% 0%, black 40%, transparent 90%);
|
||||
mask-image: radial-gradient(140% 110% at 50% 0%, black 40%, transparent 90%);
|
||||
@@ -110,7 +110,7 @@ body::after {
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
background-image: radial-gradient(circle 56rem at 12% 8%, rgb(109 120 242 / 0.14), transparent 62%);
|
||||
background-image: radial-gradient(circle 56rem at 12% 8%, rgb(244 63 94 / 0.10), transparent 62%);
|
||||
animation: bg-glow-a 26s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ html::before {
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
background-image: radial-gradient(circle 60rem at 88% 92%, rgb(34 211 238 / 0.10), transparent 62%);
|
||||
background-image: radial-gradient(circle 60rem at 88% 92%, rgb(251 146 60 / 0.08), transparent 62%);
|
||||
animation: bg-glow-b 34s ease-in-out -12s infinite;
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ html::after {
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
background-image: radial-gradient(circle 52rem at 14% 86%, rgb(109 120 242 / 0.09), transparent 62%);
|
||||
background-image: radial-gradient(circle 52rem at 14% 86%, rgb(239 68 68 / 0.08), transparent 62%);
|
||||
animation: bg-glow-c 42s ease-in-out -23s infinite;
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ html::after {
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: rgb(109 120 242 / 0.45);
|
||||
background: rgb(244 63 94 / 0.45);
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
@@ -217,9 +217,9 @@ html::after {
|
||||
pointer-events: none;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgb(109 120 242 / 0.55),
|
||||
rgb(34 211 238 / 0.30) 45%,
|
||||
rgb(34 211 238 / 0.05) 90%
|
||||
rgb(244 63 94 / 0.55),
|
||||
rgb(251 146 60 / 0.30) 45%,
|
||||
rgb(251 191 36 / 0.05) 90%
|
||||
);
|
||||
}
|
||||
/* margin-left:auto on the nav (not justify-content:space-between) so the
|
||||
@@ -294,16 +294,16 @@ html::after {
|
||||
min-height: 44px;
|
||||
padding: 0.5rem 0.9rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--line);
|
||||
background: transparent;
|
||||
color: var(--ink-soft);
|
||||
border: 0;
|
||||
background: var(--brand);
|
||||
color: var(--bg);
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
.new-chat-btn:hover { background: var(--brand-soft); color: var(--brand-ink); }
|
||||
.new-chat-btn:hover { background: #f55a72; color: var(--bg); }
|
||||
/* The plus mark is hidden on desktop (label carries the pill); it is the
|
||||
whole control below 640px. */
|
||||
.new-chat-btn svg { width: 16px; height: 16px; display: none; }
|
||||
@@ -335,178 +335,10 @@ html::after {
|
||||
.auth-link:disabled { opacity: 0.6; cursor: wait; }
|
||||
.auth-link svg { width: 16px; height: 16px; display: none; }
|
||||
|
||||
/* Phase 32: the admin-only "Sync sources" pill (Sources header) — the
|
||||
same ghost pill as New chat / the auth links, so the bar keeps one
|
||||
visual language. ink-soft on surface ≈6.9:1 (WCAG AA); hover pair
|
||||
brand-ink/brand-soft ≈6.9:1. The refresh icon is always visible (it
|
||||
doubles as the running-state spinner); icon-only below 640px like
|
||||
the other pills (aria-label keeps the accessible name). ≥44px touch
|
||||
target at every width; :focus-visible via the global rule. */
|
||||
.sync-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.4rem;
|
||||
min-height: 44px;
|
||||
padding: 0.5rem 0.9rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--line);
|
||||
background: transparent;
|
||||
color: var(--ink-soft);
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
.sync-btn:hover { background: var(--brand-soft); color: var(--brand-ink); }
|
||||
.sync-btn:disabled { opacity: 0.6; cursor: wait; }
|
||||
/* Phase 34: the failed-sync look — the button now lives on EVERY page
|
||||
(the non-Sources pages have no error banner, so the button itself is
|
||||
the visible failure state; the sanitized error text rides in title /
|
||||
aria-label, set by the header module). Phase-08 error pair: --err-ink
|
||||
on --err-bg ≈9.1:1, --err-line border (the amber --accent-line is
|
||||
deflection-only — never on errors). */
|
||||
.sync-btn.is-error {
|
||||
background: var(--err-bg);
|
||||
color: var(--err-ink);
|
||||
border-color: var(--err-line);
|
||||
}
|
||||
.sync-btn.is-error:hover { background: var(--err-bg); color: var(--err-ink); }
|
||||
.sync-icon { width: 16px; height: 16px; display: block; flex: 0 0 auto; }
|
||||
/* Running state: the refresh icon spins (reuses the shared spin
|
||||
keyframes) — the visible half of "Syncing…" while the 2 s poll waits. */
|
||||
.sync-btn .sync-icon.is-spinning { animation: spin 1s linear infinite; }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.sync-btn .sync-icon.is-spinning { animation: none; }
|
||||
}
|
||||
/* The aria-live last-result announcer ("2 added · 1 pruned") — soft ink
|
||||
on the header surface (≈6.9:1), small mono to match the stat cards. */
|
||||
.sync-result {
|
||||
color: var(--ink-soft);
|
||||
font-family: var(--mono);
|
||||
font-size: 0.8rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Phase 41 (2026-08-27, TODO.md L4): the module-owned sync failure
|
||||
modal — lazily built by header.js and appended to <body>, so every
|
||||
page carrying #sync-btn gets it with zero page-markup changes.
|
||||
Phase-08 error palette (PLAN §7.2): the panel sits on the error
|
||||
surface --err-bg with a 1px --err-line border (the amber
|
||||
--accent-line stays deflection-only), its title in --ink (≈14.5:1
|
||||
on --err-bg) and the error text in --err-ink (9.1:1 on --err-bg).
|
||||
The backdrop dims the page with --bg at 82% — no blur (the phase-08
|
||||
no-blur anchor). Stacking: z-index 1000, the same overlay contract
|
||||
as the doc-modal — above the sticky header (20) and the skip-link
|
||||
(100). Open/close via .is-open (visibility/opacity — the closed
|
||||
modal is unfocusable and inert); the close button keeps the global
|
||||
3px :focus-visible outline and the 44px touch floor. */
|
||||
.sync-modal-backdrop {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
background: rgba(10, 14, 23, 0.82);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 120ms ease;
|
||||
}
|
||||
.sync-modal-backdrop.is-open {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
.sync-modal {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 28rem;
|
||||
background: var(--err-bg);
|
||||
border: 1px solid var(--err-line);
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow-lg);
|
||||
/* right padding clears the absolutely-positioned close button */
|
||||
padding: 1.1rem 3rem 1.25rem 1.25rem;
|
||||
}
|
||||
#sync-modal-title {
|
||||
margin: 0 0 0.6rem;
|
||||
font-size: 1.1rem;
|
||||
color: var(--ink);
|
||||
}
|
||||
#sync-modal-error {
|
||||
margin: 0 0 1rem;
|
||||
font-family: var(--mono);
|
||||
font-size: 0.9rem;
|
||||
color: var(--err-ink);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.sync-modal-close {
|
||||
position: absolute;
|
||||
top: 0.3rem;
|
||||
right: 0.3rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 44px;
|
||||
min-height: 44px;
|
||||
padding: 0;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--err-line);
|
||||
background: transparent;
|
||||
color: var(--err-ink);
|
||||
font-size: 1.2rem;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
.sync-modal-close:hover { background: rgb(239 68 68 / 0.15); }
|
||||
/* No motion under reduced motion (same opt-out pattern as the
|
||||
phase-25 background layers and the doc-modal backdrop). */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.sync-modal-backdrop { transition: none; }
|
||||
}
|
||||
|
||||
/* "Tuning" toggle (phase 15): ghost pill like New chat + a mono count
|
||||
badge (brand-ink on brand-soft ≈6.9:1). The label is visually-hidden
|
||||
(not removed) below 640px so the accessible name keeps the word.
|
||||
≥44px touch target at every width. */
|
||||
.steering-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.4rem;
|
||||
min-height: 44px;
|
||||
padding: 0.5rem 0.9rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--line);
|
||||
background: transparent;
|
||||
color: var(--ink-soft);
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
.steering-toggle:hover, .steering-toggle[aria-expanded="true"] {
|
||||
background: var(--brand-soft);
|
||||
color: var(--brand-ink);
|
||||
}
|
||||
.steering-toggle svg { width: 16px; height: 16px; display: block; }
|
||||
.steering-count {
|
||||
font-family: var(--mono);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
min-width: 1.35rem;
|
||||
text-align: center;
|
||||
padding: 0.05rem 0.4rem;
|
||||
border-radius: 999px;
|
||||
background: var(--brand-soft);
|
||||
color: var(--brand-ink);
|
||||
}
|
||||
.steering-toggle[aria-expanded="true"] .steering-count {
|
||||
background: var(--brand);
|
||||
color: var(--bg); /* dark ink on brand: 5.2:1 */
|
||||
/* Mobile-only sign-out copy: hidden on desktop, revealed inside
|
||||
the hamburger dropdown on mobile (phase 46 UX revision). */
|
||||
.sign-out-mobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ---------- Main frame ---------- */
|
||||
@@ -572,8 +404,8 @@ html::after {
|
||||
}
|
||||
.bubble p { margin: 0.2rem 0; }
|
||||
.bubble pre {
|
||||
background: #0d1120;
|
||||
color: #e6e9f2;
|
||||
background: #1a0f0f;
|
||||
color: #e6d0d0;
|
||||
padding: 0.7rem 0.9rem;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm);
|
||||
@@ -810,7 +642,7 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
font: inherit;
|
||||
font-size: 0.9rem;
|
||||
color: var(--ink);
|
||||
background: #0d1120;
|
||||
background: #1a0f0f;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 0.5rem 0.6rem;
|
||||
@@ -896,7 +728,7 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
gap: 0.6rem;
|
||||
background: #0d1120;
|
||||
background: #1a0f0f;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 0.35rem 0.4rem 0.35rem 0.8rem;
|
||||
@@ -1075,7 +907,7 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 0.5rem;
|
||||
background: #0d1120;
|
||||
background: #1a0f0f;
|
||||
border: 1px solid var(--brand-soft);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 0.6rem 0.7rem;
|
||||
@@ -1290,7 +1122,7 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
font: inherit;
|
||||
font-size: 1rem;
|
||||
color: var(--ink);
|
||||
background: #0d1120;
|
||||
background: #1a0f0f;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 0.55rem 0.75rem;
|
||||
@@ -1334,8 +1166,120 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
flex: 1;
|
||||
}
|
||||
.page-head h1 { margin: 0 0 0.25rem; font-size: 1.7rem; }
|
||||
.page-head-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
.page-sub { margin: 0; color: var(--ink-soft); }
|
||||
.page-sub code { font-family: var(--mono); font-size: 0.85em; background: var(--brand-soft); padding: 0.1em 0.35em; border-radius: 5px; }
|
||||
/* ---------- Sync button (Sources page) ---------- */
|
||||
.sync-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.4rem;
|
||||
min-height: 44px;
|
||||
padding: 0.5rem 0.9rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--line);
|
||||
background: transparent;
|
||||
color: var(--ink-soft);
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.sync-btn:hover { background: var(--brand-soft); color: var(--brand-ink); }
|
||||
.sync-btn:disabled { opacity: 0.6; cursor: wait; }
|
||||
.sync-btn.is-error {
|
||||
background: var(--err-bg);
|
||||
color: var(--err-ink);
|
||||
border-color: var(--err-line);
|
||||
}
|
||||
.sync-btn.is-error:hover { background: var(--err-bg); color: var(--err-ink); }
|
||||
.sync-icon { width: 16px; height: 16px; display: block; flex: 0 0 auto; }
|
||||
.sync-btn .sync-icon.is-spinning { animation: spin 1s linear infinite; }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.sync-btn .sync-icon.is-spinning { animation: none; }
|
||||
}
|
||||
.sync-label { display: inline; }
|
||||
/* Last-result announcer — soft ink, small mono */
|
||||
.sync-result {
|
||||
display: block;
|
||||
color: var(--ink-soft);
|
||||
font-family: var(--mono);
|
||||
font-size: 0.8rem;
|
||||
white-space: nowrap;
|
||||
padding-block: 0.5rem;
|
||||
}
|
||||
/* Sync failure modal — lazily created by sources.js, appended to <body>.
|
||||
Error surface: --err-bg with --err-line border, title in --ink,
|
||||
error text in --err-ink (9.1:1 on --err-bg). Backdrop dims with
|
||||
--bg at 82%. z-index 1000 (same overlay contract as doc-modal). */
|
||||
.sync-modal-backdrop {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
background: rgba(10, 14, 23, 0.82);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 120ms ease;
|
||||
}
|
||||
.sync-modal-backdrop.is-open {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
.sync-modal {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 28rem;
|
||||
background: var(--err-bg);
|
||||
border: 1px solid var(--err-line);
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow-lg);
|
||||
padding: 1.1rem 3rem 1.25rem 1.25rem;
|
||||
}
|
||||
#sync-modal-title {
|
||||
margin: 0 0 0.6rem;
|
||||
font-size: 1.1rem;
|
||||
color: var(--ink);
|
||||
}
|
||||
#sync-modal-error {
|
||||
margin: 0 0 1rem;
|
||||
font-family: var(--mono);
|
||||
font-size: 0.9rem;
|
||||
color: var(--err-ink);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.sync-modal-close {
|
||||
position: absolute;
|
||||
top: 0.3rem;
|
||||
right: 0.3rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 44px;
|
||||
min-height: 44px;
|
||||
padding: 0;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--err-line);
|
||||
background: transparent;
|
||||
color: var(--err-ink);
|
||||
font-size: 1.2rem;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
.sync-modal-close:hover { background: rgb(239 68 68 / 0.15); }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.sync-modal-backdrop { transition: none; }
|
||||
}
|
||||
|
||||
.stat-cards {
|
||||
display: grid;
|
||||
@@ -1841,8 +1785,8 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
.doc-md > :first-child { margin-top: 0; }
|
||||
.doc-md ul { margin: 0.4rem 0; padding-left: 1.3rem; }
|
||||
.doc-md pre {
|
||||
background: #0d1120;
|
||||
color: #e6e9f2;
|
||||
background: #1a0f0f;
|
||||
color: #e6d0d0;
|
||||
padding: 0.7rem 0.9rem;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm);
|
||||
@@ -2118,7 +2062,7 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
|
||||
/* ---------- Responsive (tablet squeeze — phase 34 task 04 visual pass) ----------
|
||||
The full admin bar (brand + nav [Chat, Sources, Tuning] + Tuning
|
||||
toggle + Sync sources + New chat + Sign out) outgrows a 768px bar in
|
||||
toggle + New chat + Sign out) outgrows a 768px bar in
|
||||
the desktop styles. Squeeze the pills/gaps moderately — the 44px
|
||||
touch floor is held by min-height and the 64px height by --header-h
|
||||
— and let the brand wordmark (base ellipsis) absorb any remainder.
|
||||
@@ -2131,7 +2075,7 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
designated clip target, pills squeeze next). */
|
||||
.nav-link { padding: 0.4rem 0.5rem; font-size: 0.85rem; }
|
||||
.app-nav { gap: 0.15rem; }
|
||||
.new-chat-btn, .auth-link, .sync-btn, .steering-toggle { padding: 0.45rem 0.5rem; }
|
||||
.new-chat-btn, .auth-link { padding: 0.45rem 0.5rem; }
|
||||
}
|
||||
|
||||
/* ---------- Responsive (mobile-first adjustments) ---------- */
|
||||
@@ -2234,40 +2178,45 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
.new-chat-btn { padding: 0.4rem 0.3rem; }
|
||||
.new-chat-label { display: none; }
|
||||
.new-chat-btn svg { display: block; }
|
||||
/* But on the chat page there is room — keep the label visible and
|
||||
hide the icon (the button lives inside .chat-shell, not the navbar). */
|
||||
.chat-shell .new-chat-label { display: inline; }
|
||||
.chat-shell .new-chat-btn svg { display: none; }
|
||||
/* Phase 16: the auth pill goes icon-only like New chat — brand text
|
||||
ellipsizes as the designated squeeze target, no bar overflow. */
|
||||
.auth-link { padding: 0.4rem 0.3rem; }
|
||||
.auth-label { display: none; }
|
||||
.auth-link svg { display: block; }
|
||||
/* Phase 32: the sync pill goes icon-only like the other pills (the
|
||||
aria-label keeps the accessible name); the spinning icon is the
|
||||
visible running state on a touch screen. */
|
||||
.sync-btn { padding: 0.4rem 0.3rem; }
|
||||
.sync-label { display: none; }
|
||||
/* The last-result counts stay ANNOUNCED (aria-live is untouched) but
|
||||
go visually hidden — the 58px bar has no room for the text; the
|
||||
icon carries the visible state. Same clip recipe as .steering-label. */
|
||||
.sync-result {
|
||||
position: absolute !important;
|
||||
width: 1px; height: 1px;
|
||||
margin: -1px; padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
white-space: nowrap;
|
||||
/* Phase 46 UX revision: sign-out moves into the hamburger dropdown
|
||||
on mobile — hide the bar copy, show the dropdown copy. */
|
||||
.sign-out-mobile { display: inline-flex; }
|
||||
#sign-out-btn { display: none !important; }
|
||||
.nav-toggle { margin-left: auto; }
|
||||
/* Dropdown-style sign-out: full-width row, error palette, label visible. */
|
||||
#app-nav .sign-out-btn {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
text-align: left;
|
||||
padding: 0.75rem 1.25rem;
|
||||
font-size: 1rem;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
color: var(--err-ink);
|
||||
min-height: 48px;
|
||||
}
|
||||
.steering-toggle { padding: 0.4rem 0.3rem; }
|
||||
/* Visually hidden, NOT display:none — the accessible name keeps the
|
||||
word "Tuning" next to the count badge. */
|
||||
.steering-label {
|
||||
position: absolute !important;
|
||||
width: 1px; height: 1px;
|
||||
margin: -1px; padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
#app-nav .sign-out-btn:hover {
|
||||
background: var(--err-bg);
|
||||
color: var(--err-ink);
|
||||
}
|
||||
#app-nav .sign-out-btn svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
#app-nav .sign-out-btn .auth-label { display: inline; }
|
||||
.steering-note { padding: 0.3rem 0.3rem 0.3rem 0.7rem; }
|
||||
.app-main > .steering-panel { width: calc(100% - 1.8rem); }
|
||||
.tune-btn { min-height: 44px; }
|
||||
@@ -2313,6 +2262,20 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
#local-source-add { width: 100%; }
|
||||
.footer-inner { flex-direction: column; gap: 0.2rem; text-align: center; }
|
||||
main { padding-bottom: env(safe-area-inset-bottom, 0); }
|
||||
/* Sync button goes icon-only on mobile; the label hides, aria-label
|
||||
keeps the accessible name. The spinning icon is the visible running
|
||||
state on a touch screen. */
|
||||
.sync-btn { padding: 0.4rem 0.3rem; }
|
||||
.sync-label { display: none; }
|
||||
.sync-result {
|
||||
position: absolute !important;
|
||||
width: 1px; height: 1px;
|
||||
margin: -1px; padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Phase 46: prefers-reduced-motion stills the mobile menu — no
|
||||
|
||||
Reference in New Issue
Block a user