mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-06 15:02:20 +02:00
style-part-01..08 were arbitrary 6,000-line cuts, so the names said nothing and a reader had no way to guess which file held a rule. The original stylesheet turns out to be roughly area-grouped already, so cutting where the content changes rather than every 6,000 lines produces boundaries worth naming. Classifying every top-level rule by selector prefix and smoothing over a 40-rule window gives 17 stable runs: agent-chat, compare, memory, documents, admin-settings, skills, gallery, cookbook, tasks, image-editor, email, notes, calendar, research. The numeric prefix stays because load order is load-bearing, and it also disambiguates the areas that appear twice: the original interleaves, and merging non-adjacent blocks of the same area would reorder the cascade. The names describe where a file sits, not a claim that it holds every rule for that area or only rules for it. The header in each file says so, because that is the misreading this naming invites. Reconstruction was checked against lab's style.css before rewriting: identical after whitespace normalisation, all 47,528 lines accounted for. The computed style baseline still reproduces exactly.
1806 lines
68 KiB
CSS
1806 lines
68 KiB
CSS
/* 02-compare - part of the former static/style.css.
|
|
*
|
|
* The stylesheet is split by area, but the split is mechanical: rules were
|
|
* moved verbatim and NOT regrouped. The numeric prefix is the load order, and
|
|
* that order is what preserves the cascade. A rule sits in the file its
|
|
* original position fell into, so an area's rules are not all in its file and
|
|
* a file is not only that area's rules.
|
|
*
|
|
* Do not reorder the <link> tags in static/index.html, and do not move a rule
|
|
* between files: with 1,151 redeclarations and 1,886 !important in this
|
|
* cascade, either can change which declaration wins.
|
|
*
|
|
* static/index.html and the PRECACHE list in static/sw.js must agree on this
|
|
* order. tests/test_static_stylesheet_manifest.py and
|
|
* tests/test_css_computed_style_snapshot.py fail if that drifts.
|
|
*/
|
|
.harmony-generate-btn:hover { background: color-mix(in srgb, var(--red) 11%, transparent); }
|
|
.harmony-preview {
|
|
display: flex; height: 20px; border-radius: 6px; overflow: hidden;
|
|
margin-top: 8px; border: 1px solid var(--border);
|
|
}
|
|
.harmony-preview:empty { display: none; border: none; }
|
|
.harmony-preview span { flex: 1; }
|
|
#theme-reset-btn {
|
|
margin-top: 6px; width: 100%; padding: 6px; border: 1px solid var(--border);
|
|
border-radius: 6px; background: var(--bg); color: var(--fg); cursor: pointer;
|
|
font-size: 12px; font-family: inherit; opacity: 0.7; transition: opacity 0.15s;
|
|
}
|
|
#theme-reset-btn:hover { opacity: 1; }
|
|
.theme-adv-toggle {
|
|
margin-top: 10px; margin-bottom: 10px;
|
|
padding: 6px 8px; cursor: pointer;
|
|
font-size: 11px; color: var(--red); opacity: 0.8;
|
|
border: 1px solid var(--border); border-radius: 6px;
|
|
transition: opacity 0.15s, background 0.15s;
|
|
user-select: none;
|
|
}
|
|
.theme-adv-toggle:hover { opacity: 1; background: color-mix(in srgb, var(--fg) 4%, transparent); }
|
|
.theme-adv-toggle .theme-adv-arrow {
|
|
display: inline-block; transition: transform 0.2s; font-size: 10px;
|
|
margin-right: 4px;
|
|
}
|
|
.theme-adv-toggle.open .theme-adv-arrow { transform: rotate(90deg); }
|
|
.theme-adv-section { margin-top: 8px; margin-bottom: 10px; }
|
|
.theme-adv-section.hidden { display: none; }
|
|
.theme-adv-group { margin-bottom: 8px; }
|
|
.theme-adv-group-label {
|
|
font-size: 10px; color: var(--fg); opacity: 0.5;
|
|
text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 4px;
|
|
}
|
|
.theme-adv-clear-btn {
|
|
margin-top: 6px; width: 100%; padding: 5px; border: 1px solid var(--border);
|
|
border-radius: 6px; background: transparent; color: var(--fg); opacity: 0.5;
|
|
cursor: pointer; font-size: 12px; font-family: inherit; transition: opacity 0.15s;
|
|
}
|
|
.theme-adv-clear-btn:hover { opacity: 1; }
|
|
|
|
/* Customization is an editor, so keep its sections visually related while
|
|
preserving the existing controls and their order. */
|
|
#theme-tab-customize {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
#theme-tab-customize > .admin-card,
|
|
#theme-tab-customize > .theme-adv-toggle,
|
|
#theme-tab-customize > .theme-adv-section {
|
|
margin-top: 0;
|
|
margin-bottom: 0;
|
|
}
|
|
#theme-tab-customize > .admin-card {
|
|
padding: 12px;
|
|
}
|
|
#theme-tab-customize > .admin-card > h2 {
|
|
display: flex;
|
|
align-items: center;
|
|
min-height: 20px;
|
|
margin: 0 0 10px;
|
|
padding-bottom: 7px;
|
|
border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
|
|
font-size: 13px;
|
|
}
|
|
#theme-tab-customize .theme-custom {
|
|
gap: 6px 14px;
|
|
}
|
|
#theme-tab-customize .color-row {
|
|
min-height: 30px;
|
|
padding: 3px 6px;
|
|
box-sizing: border-box;
|
|
border: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
|
|
background: color-mix(in srgb, var(--fg) 2%, transparent);
|
|
}
|
|
#theme-tab-customize .color-row label {
|
|
font-size: 12px;
|
|
}
|
|
#theme-tab-customize .theme-adv-toggle {
|
|
flex-shrink: 0;
|
|
margin: 0;
|
|
background: color-mix(in srgb, var(--fg) 2%, transparent);
|
|
}
|
|
#theme-tab-customize .theme-adv-section {
|
|
padding: 10px 12px 2px;
|
|
border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
|
|
border-radius: 7px;
|
|
background: color-mix(in srgb, var(--panel) 55%, transparent);
|
|
}
|
|
#theme-tab-customize .theme-adv-group {
|
|
margin: 0;
|
|
padding: 0 0 9px;
|
|
border-bottom: 1px solid color-mix(in srgb, var(--border) 48%, transparent);
|
|
}
|
|
#theme-tab-customize .theme-adv-group + .theme-adv-group {
|
|
padding-top: 9px;
|
|
}
|
|
#theme-tab-customize .theme-adv-group:last-of-type {
|
|
border-bottom: 0;
|
|
}
|
|
#theme-tab-customize .theme-adv-group-label {
|
|
margin-bottom: 6px;
|
|
color: var(--red);
|
|
opacity: 0.8;
|
|
font-weight: 600;
|
|
}
|
|
#theme-tab-customize .theme-fd-row,
|
|
#theme-tab-customize .theme-harmony-row {
|
|
gap: 12px;
|
|
margin-bottom: 10px;
|
|
}
|
|
#theme-tab-customize .theme-fd-row:last-child,
|
|
#theme-tab-customize .theme-harmony-row:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
#theme-tab-customize .theme-fd-group {
|
|
min-width: 0;
|
|
}
|
|
#theme-tab-customize .theme-fd-select {
|
|
min-height: 30px;
|
|
}
|
|
#theme-tab-customize #theme-harmony-card .theme-fd-label {
|
|
font-size: 11px;
|
|
}
|
|
#theme-tab-customize .theme-save-row,
|
|
#theme-tab-customize .theme-io-row {
|
|
gap: 8px;
|
|
}
|
|
#theme-tab-customize #theme-reset-btn {
|
|
margin-top: 8px;
|
|
}
|
|
@media (max-width: 560px) {
|
|
#theme-tab-customize .theme-custom {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
#theme-tab-customize .theme-fd-row,
|
|
#theme-tab-customize .theme-harmony-row {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
}
|
|
#theme-tab-customize .theme-fd-group,
|
|
#theme-tab-customize .theme-harmony-row .theme-fd-group {
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
|
|
/* Mobile: bottom sheet modals — slide up from bottom */
|
|
@media (max-width: 768px) {
|
|
.modal {
|
|
align-items: flex-end;
|
|
background: rgba(0,0,0,0.4);
|
|
pointer-events: auto;
|
|
/* Anchor the bottom sheet to the DYNAMIC viewport. The base overlay is
|
|
position:fixed; height:100% = the layout viewport, whose bottom sits
|
|
UNDER Firefox Android's bottom URL bar — so flex-end parked the sheet
|
|
(and its footer / Start button) beneath the bar. dvh excludes the bar
|
|
so the footer lands above it. Extra safe-area pad for iOS home bar. */
|
|
height: 100dvh;
|
|
padding-bottom: env(safe-area-inset-bottom, 0px);
|
|
}
|
|
/* Confirm dialog stays centered, not a bottom sheet */
|
|
#styled-confirm-overlay {
|
|
align-items: center;
|
|
}
|
|
.styled-confirm-box {
|
|
border-radius: 12px !important;
|
|
border: 1px solid var(--border) !important;
|
|
animation: modal-enter 0.25s ease-out both !important;
|
|
max-height: none !important;
|
|
}
|
|
.styled-confirm-box.modal-closing {
|
|
animation: modal-exit 0.18s ease-in both !important;
|
|
}
|
|
.styled-confirm-box::before {
|
|
display: none !important;
|
|
}
|
|
.styled-confirm-box .close-btn {
|
|
display: none !important;
|
|
}
|
|
#theme-popup {
|
|
width: 100% !important;
|
|
height: 65vh !important;
|
|
max-height: 65vh !important;
|
|
top: auto !important; left: 0 !important; right: 0 !important; bottom: 0 !important;
|
|
position: fixed !important;
|
|
border-radius: 14px 14px 0 0;
|
|
border: none;
|
|
border-top: 1px solid var(--border);
|
|
padding: 6px 12px 12px;
|
|
animation: sheet-enter 0.2s ease-out forwards;
|
|
overflow-y: hidden !important;
|
|
}
|
|
#theme-popup .theme-tab-panel {
|
|
touch-action: pan-y;
|
|
overscroll-behavior: contain;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
#theme-popup.sheet-ready {
|
|
animation: none;
|
|
}
|
|
#theme-popup.modal-closing {
|
|
animation: sheet-exit 0.15s ease-in both !important;
|
|
}
|
|
.modal-content,
|
|
.memory-modal-content,
|
|
.settings-modal-content,
|
|
#compare-model-overlay .modal-content {
|
|
width: 100% !important;
|
|
/* 85dvh leaves comfortable headroom above the sheet so the user can
|
|
still see the chat behind it and the drag handle has breathing
|
|
room. Was 65vh (too short, content clipped) → 90vh (too tall, top
|
|
hugged the status bar). */
|
|
max-height: 85dvh !important;
|
|
max-height: 85vh !important; /* fallback for browsers without dvh */
|
|
height: auto !important;
|
|
border-radius: 14px 14px 0 0;
|
|
border: none;
|
|
border-top: 1px solid var(--border);
|
|
padding-top: 6px !important;
|
|
/* Clip children to the rounded top corners — otherwise the sticky
|
|
modal-header's var(--panel) background paints a darker
|
|
rectangle past the radius and the corners look square again. */
|
|
overflow: hidden;
|
|
animation: sheet-enter 0.2s ease-out forwards;
|
|
}
|
|
/* Keep the tall tool drawers on a shared mobile height ceiling. The
|
|
final mobile drawer rule below makes this content-sized so shorter
|
|
tools remain compact while tall ones leave a visible top gap. */
|
|
#cookbook-modal .modal-content,
|
|
#tasks-modal .modal-content,
|
|
#calendar-modal .modal-content,
|
|
#memory-modal .memory-modal-content,
|
|
#settings-modal .settings-modal-content,
|
|
#email-lib-modal .modal-content,
|
|
#doclib-modal .doclib-modal-content {
|
|
max-height: 90vh !important;
|
|
max-height: 90dvh !important;
|
|
height: auto !important;
|
|
/* Reserve the iOS home-indicator / bottom-bar strip so an expanded
|
|
skill card's footer (Delete / Edit / Run) isn't hidden under it.
|
|
dvh already excludes the URL bar; this handles the safe area. */
|
|
padding-bottom: env(safe-area-inset-bottom, 0px) !important;
|
|
}
|
|
/* Grab handle pill on the non-standard content classes too. Memory's
|
|
desktop rule defines a radial-glow ::before later in the file —
|
|
these body-prefixed selectors win the specificity battle on mobile. */
|
|
body .memory-modal-content::before,
|
|
body .settings-modal-content::before {
|
|
content: '';
|
|
display: block;
|
|
position: static;
|
|
inset: auto;
|
|
width: 36px; height: 4px;
|
|
background: var(--fg);
|
|
opacity: 0.25;
|
|
border-radius: 2px;
|
|
margin: 0 auto 4px;
|
|
flex-shrink: 0;
|
|
padding: 0;
|
|
border-top: 10px solid transparent;
|
|
border-bottom: 6px solid transparent;
|
|
background-clip: padding-box;
|
|
animation: none;
|
|
}
|
|
.memory-modal-content .close-btn,
|
|
.memory-modal-content .modal-close,
|
|
.settings-modal-content .close-btn,
|
|
.settings-modal-content .modal-close {
|
|
display: none !important;
|
|
}
|
|
.memory-modal-content,
|
|
.settings-modal-content {
|
|
touch-action: pan-y;
|
|
overscroll-behavior: contain;
|
|
}
|
|
/* Library modals use the same bottom-sheet sizing as the other tools.
|
|
The shared mobile drawer rule below provides the top breathing room. */
|
|
#cookbook-modal .modal-content,
|
|
#calendar-modal .modal-content,
|
|
#email-lib-modal .modal-content,
|
|
#doclib-modal .modal-content,
|
|
#gallery-modal .modal-content,
|
|
#tasks-modal .modal-content {
|
|
/* vh-first as fallback for very old browsers, then dvh wins so
|
|
the modal shrinks/grows with the mobile URL bar. Wrong order
|
|
previously made the expanded chat preview extend below the
|
|
visible viewport on Chrome/Safari mobile (URL bar covered the
|
|
action buttons row). */
|
|
max-height: 90vh !important;
|
|
max-height: 90dvh !important;
|
|
height: auto !important;
|
|
}
|
|
/* Anchor those modals to the top so the full height is usable */
|
|
#cookbook-modal,
|
|
#calendar-modal,
|
|
#email-lib-modal,
|
|
#doclib-modal,
|
|
#gallery-modal,
|
|
#tasks-modal {
|
|
padding-top: 0 !important;
|
|
align-items: stretch !important;
|
|
}
|
|
/* Deep Research already gets the swipe grab-handle pill from the
|
|
shared `.modal-content::before` rule (the pane carries that class).
|
|
The previous header-level pill was redundant and rendered as a
|
|
SECOND pill stacked above the real one — removed. */
|
|
/* The inner body must flex to fill the new full height, and the
|
|
tasks list inside it must scroll independently — otherwise the
|
|
list crops at whatever pre-mobile height the desktop layout had. */
|
|
#tasks-modal .modal-content {
|
|
display: flex !important;
|
|
flex-direction: column !important;
|
|
}
|
|
#tasks-modal .modal-body {
|
|
flex: 1 1 auto !important;
|
|
min-height: 0 !important;
|
|
}
|
|
/* Memory/Skills: the body lacks flex:1, so on the fixed-height mobile
|
|
sheet (overflow:hidden) it grew past the viewport and clipped the
|
|
bottom of the skills list + its row action buttons with no way to
|
|
scroll there. Bound the body so the inner list scrolls internally. */
|
|
#memory-modal .memory-modal-content {
|
|
display: flex !important;
|
|
flex-direction: column !important;
|
|
}
|
|
/* flex-basis MUST be 0 (not auto) — matches the working #doclib-modal
|
|
.modal-body. With basis:auto, Firefox (incl. mobile) sizes the body
|
|
to its content (~half height) instead of filling, while Chromium
|
|
fills it regardless — which is exactly why the skill expand worked
|
|
on desktop/Chromium but stuck at ~50% on Firefox mobile. */
|
|
#memory-modal .memory-modal-body {
|
|
flex: 1 1 0 !important;
|
|
min-height: 0 !important;
|
|
overflow: hidden !important;
|
|
}
|
|
/* Same basis:0 fix down the rest of the skills chain so every layer
|
|
fills instead of sizing to content under Firefox. */
|
|
#memory-modal .memory-tab-panel[data-memory-panel="skills"] {
|
|
flex: 1 1 0 !important;
|
|
min-height: 0 !important;
|
|
}
|
|
#memory-modal .memory-tab-panel[data-memory-panel="skills"] > .admin-card {
|
|
flex: 1 1 0 !important;
|
|
min-height: 0 !important;
|
|
}
|
|
/* The skills modal carries an extra toolbar row (search/sort/select +
|
|
bulk bar) the doc/email libraries don't, so the shared 82dvh preview
|
|
min-height overflowed here and pushed the expanded footer (Delete /
|
|
Edit / Run) off the bottom of the screen. Let flexbox size it from
|
|
the resolved card height instead, so the footer always pins inside
|
|
the visible area. */
|
|
#memory-modal .doclib-card.doclib-card-expanded .doclib-card-preview {
|
|
min-height: 0 !important;
|
|
}
|
|
/* Once enter animation finishes, clear it so inline transform works for dragging */
|
|
.modal-content.sheet-ready {
|
|
animation: none;
|
|
}
|
|
.modal-content.modal-closing {
|
|
animation: sheet-exit 0.15s ease-in both !important;
|
|
}
|
|
/* Grab handle — large touch target, visible pill */
|
|
#theme-popup::before,
|
|
.modal-content::before {
|
|
content: '';
|
|
display: block;
|
|
width: 36px; height: 4px;
|
|
background: var(--fg); opacity: 0.25;
|
|
border-radius: 2px;
|
|
margin: 0 auto 4px;
|
|
flex-shrink: 0;
|
|
padding: 0;
|
|
/* Expand touch target without changing visual size */
|
|
border-top: 10px solid transparent;
|
|
border-bottom: 6px solid transparent;
|
|
background-clip: padding-box;
|
|
}
|
|
/* Hide close X on mobile — swipe down to dismiss */
|
|
.modal-content .close-btn,
|
|
.modal-content .modal-close,
|
|
#theme-popup .close-btn {
|
|
display: none !important;
|
|
}
|
|
/* Hide the auto-injected minimize (_) button on mobile — the dock
|
|
chip already represents the minimized state, and the swipe-down
|
|
gesture is the canonical minimize action. */
|
|
.modal-minimize-btn,
|
|
.minimize-btn,
|
|
[data-minimize] {
|
|
display: none !important;
|
|
}
|
|
/* Lock modals to vertical touch only, prevent horizontal dragging */
|
|
.modal-content {
|
|
touch-action: pan-y;
|
|
overscroll-behavior: contain;
|
|
}
|
|
.modal-content .cookbook-body,
|
|
.modal-content .modal-body {
|
|
touch-action: pan-y;
|
|
overscroll-behavior: contain;
|
|
}
|
|
.modal-header {
|
|
cursor: default;
|
|
touch-action: none;
|
|
}
|
|
@keyframes sheet-enter {
|
|
from { transform: translateY(100%); }
|
|
to { transform: translateY(0); }
|
|
}
|
|
@keyframes sheet-exit {
|
|
from { transform: translateY(0); }
|
|
to { transform: translateY(100%); }
|
|
}
|
|
}
|
|
|
|
/* ── Model A/B Comparison ── */
|
|
|
|
/* -- Extracted inline-style classes -- */
|
|
.cmp-header-action-btn {
|
|
background: none; border: 1px solid var(--border); color: var(--fg);
|
|
cursor: pointer; padding: 3px 10px; font-size: 11px; font-weight: 600;
|
|
opacity: 0.7; transition: all 0.15s; line-height: 1; border-radius: 4px;
|
|
display: inline-flex; align-items: center; font-family: inherit;
|
|
}
|
|
.cmp-form-control {
|
|
padding: 8px; background: var(--bg); color: var(--fg);
|
|
border: 1px solid var(--border); border-radius: 6px; font-size: 0.85em;
|
|
}
|
|
.cmp-btn-secondary {
|
|
background: transparent; color: var(--fg); border: 1px solid var(--border);
|
|
border-radius: 6px; cursor: pointer;
|
|
}
|
|
.cmp-btn-primary {
|
|
background: var(--fg); color: var(--bg); border: none;
|
|
border-radius: 6px; cursor: pointer; font-weight: 600;
|
|
transition: filter 0.12s, background 0.12s, color 0.12s;
|
|
}
|
|
/* Override global button:hover (which switches bg to var(--panel) =
|
|
very dark) — keep the bright primary look and just brighten slightly. */
|
|
.cmp-btn-primary:hover:not(:disabled) {
|
|
background: var(--fg); color: var(--bg);
|
|
filter: brightness(1.1);
|
|
}
|
|
.cmp-btn-primary:active:not(:disabled) { filter: brightness(0.95); }
|
|
.cmp-btn-secondary:hover:not(:disabled) {
|
|
background: color-mix(in srgb, var(--fg) 8%, transparent);
|
|
border-color: var(--fg); color: var(--fg);
|
|
}
|
|
.cmp-model-row {
|
|
display: flex; align-items: center; gap: 8px; margin-bottom: 8px;
|
|
flex-wrap: wrap;
|
|
padding: 2px 0;
|
|
transition: margin-left 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.15s, border-color 0.15s;
|
|
}
|
|
.cmp-model-row-duplicate {
|
|
margin-left: -4px;
|
|
margin-right: -4px;
|
|
padding: 4px;
|
|
border-radius: 6px;
|
|
background: color-mix(in srgb, var(--color-error) 8%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--color-error) 20%, transparent);
|
|
}
|
|
.cmp-model-row-swap-target {
|
|
margin-left: -4px;
|
|
margin-right: -4px;
|
|
padding: 4px;
|
|
border-radius: 6px;
|
|
background: color-mix(in srgb, var(--accent, var(--red)) 8%, transparent);
|
|
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent, var(--red)) 42%, transparent);
|
|
}
|
|
.cmp-model-row-swap-target .cmp-row-label {
|
|
color: var(--accent, var(--red));
|
|
opacity: 1;
|
|
}
|
|
.cmp-row-label {
|
|
color: var(--fg); font-size: 0.82em; font-weight: 600; min-width: 20px;
|
|
opacity: 0.4; text-align: center; flex-shrink: 0;
|
|
}
|
|
.cmp-model-meta {
|
|
order: 3;
|
|
flex: 1 0 calc(100% - 28px);
|
|
margin-left: 28px;
|
|
margin-top: -4px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 5px;
|
|
min-width: 0;
|
|
font-size: 10px;
|
|
line-height: 1.2;
|
|
}
|
|
.cmp-model-meta-chip,
|
|
.cmp-model-meta-warning,
|
|
.cmp-model-meta-muted {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
max-width: 100%;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
border-radius: 999px;
|
|
padding: 1px 6px;
|
|
letter-spacing: 0;
|
|
}
|
|
.cmp-model-meta-chip {
|
|
color: color-mix(in srgb, var(--fg) 60%, transparent);
|
|
background: color-mix(in srgb, var(--fg) 5%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
|
|
}
|
|
.cmp-model-meta-warning {
|
|
color: var(--color-error);
|
|
background: color-mix(in srgb, var(--color-error) 10%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--color-error) 24%, transparent);
|
|
font-weight: 600;
|
|
}
|
|
.cmp-model-meta-muted {
|
|
color: color-mix(in srgb, var(--fg) 36%, transparent);
|
|
}
|
|
.cmp-rm-btn {
|
|
background: none; border: none; color: var(--accent, var(--red)); cursor: pointer;
|
|
min-width: 20px; font-size: 16px; font-weight: 600; opacity: 0.3;
|
|
transition: all 0.15s; padding: 0; line-height: 1; text-align: center;
|
|
position: relative; top: -2px;
|
|
order: 2;
|
|
margin-left: auto;
|
|
align-self: center;
|
|
}
|
|
.cmp-prov-select {
|
|
flex: 0 0 auto; width: 120px; font-size: 0.8em;
|
|
}
|
|
/* Eval-prompts picker — only shown during compare; absolute top-right
|
|
inside .chat-input-top, matching .model-picker-wrap's slot. */
|
|
.chat-input-top > .cmp-eval-wrap {
|
|
position: relative;
|
|
grid-column: 2;
|
|
grid-row: 1;
|
|
top: -2px; right: 0;
|
|
z-index: 2;
|
|
}
|
|
.cmp-eval-btn {
|
|
display: inline-flex; align-items: center; gap: 4px;
|
|
padding: 4px 8px;
|
|
background: transparent;
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
color: var(--fg);
|
|
font-size: 11px; font-weight: 500;
|
|
font-family: inherit;
|
|
cursor: pointer; opacity: 0.75;
|
|
transition: opacity 0.15s, border-color 0.15s;
|
|
}
|
|
.cmp-eval-btn:hover { opacity: 1; border-color: var(--fg); }
|
|
.cmp-eval-clear {
|
|
display: inline-flex; align-items: center; gap: 4px; margin-left: 4px;
|
|
border: 0; background: transparent; color: var(--fg); opacity: .55;
|
|
padding: 3px 5px; font: inherit; font-size: 10px; cursor: pointer;
|
|
}
|
|
.cmp-eval-clear:hover { opacity: 1; }
|
|
.cmp-eval-caret { opacity: 0.7; transform: rotate(180deg); }
|
|
.cmp-eval-menu {
|
|
position: absolute; bottom: calc(100% + 4px); right: 0;
|
|
min-width: 220px; max-width: 280px;
|
|
max-height: 360px; overflow-y: auto;
|
|
background: var(--panel);
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
box-shadow: 0 -4px 16px rgba(0,0,0,0.3);
|
|
padding: 4px;
|
|
z-index: 1000;
|
|
}
|
|
.cmp-eval-menu.hidden { display: none; }
|
|
.cmp-eval-group-label {
|
|
font-size: 9px; text-transform: uppercase; letter-spacing: 0.5px;
|
|
opacity: 0.45; font-weight: 600;
|
|
padding: 6px 8px 2px;
|
|
}
|
|
.cmp-eval-item {
|
|
display: block; width: 100%;
|
|
text-align: left;
|
|
padding: 5px 8px;
|
|
background: none; border: none;
|
|
color: var(--fg); font-size: 11px;
|
|
font-family: inherit;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
}
|
|
.cmp-eval-item:hover {
|
|
background: color-mix(in srgb, var(--fg) 8%, transparent);
|
|
}
|
|
.cmp-eval-empty {
|
|
padding: 10px; text-align: center;
|
|
font-size: 11px; opacity: 0.5;
|
|
}
|
|
/* Tick on items that ship a known expected answer */
|
|
.cmp-eval-item-tick {
|
|
float: right;
|
|
margin-left: 6px;
|
|
font-size: 10px;
|
|
color: var(--color-success, #4caf50);
|
|
opacity: 0.8;
|
|
}
|
|
/* Expected-answer panel — floats as its own little window above the
|
|
chat-input-bar. Distinct surface, padded, drop-shadow, slightly
|
|
lifted so it reads as a separate UI element, not part of the input. */
|
|
.chat-input-bar:has(.cmp-eval-expected) { position: relative; }
|
|
.cmp-eval-expected {
|
|
position: absolute;
|
|
bottom: calc(100% + 8px);
|
|
right: 0;
|
|
display: inline-flex; align-items: center; gap: 8px;
|
|
padding: 8px 12px;
|
|
font-size: 11px;
|
|
background: var(--panel);
|
|
border: 1px solid color-mix(in srgb, var(--color-success, #4caf50) 50%, transparent);
|
|
border-radius: 8px;
|
|
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
color: var(--fg);
|
|
width: fit-content;
|
|
z-index: 5;
|
|
pointer-events: auto;
|
|
}
|
|
.cmp-eval-expected.hidden { display: none; }
|
|
.cmp-eval-expected-label {
|
|
opacity: 0.6;
|
|
text-transform: uppercase;
|
|
font-size: 9px;
|
|
letter-spacing: 0.5px;
|
|
font-weight: 600;
|
|
}
|
|
.cmp-eval-expected-value {
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
font-size: 11px;
|
|
}
|
|
.cmp-eval-expected-close {
|
|
background: none; border: none; color: var(--fg);
|
|
font-size: 14px; line-height: 1; padding: 0 0 0 4px;
|
|
opacity: 0.5; cursor: pointer; font-family: inherit;
|
|
}
|
|
.cmp-eval-expected-close:hover { opacity: 1; }
|
|
/* Auto-grade badge — stamped on a pane after stream completes when an
|
|
eval prompt with a known expected answer was used. */
|
|
.pane-grade-badge {
|
|
display: inline-flex; align-items: center; justify-content: center;
|
|
width: 18px; height: 18px;
|
|
margin: 0 4px;
|
|
font-size: 12px; font-weight: 700;
|
|
border-radius: 50%;
|
|
border: 1px solid currentColor;
|
|
flex-shrink: 0;
|
|
}
|
|
.pane-grade-badge.pass {
|
|
color: var(--color-success, #4caf50);
|
|
background: color-mix(in srgb, var(--color-success, #4caf50) 12%, transparent);
|
|
}
|
|
.pane-grade-badge.fail {
|
|
color: var(--color-error, #e55);
|
|
background: color-mix(in srgb, var(--color-error, #e55) 12%, transparent);
|
|
}
|
|
|
|
/* Compare probe overlay */
|
|
.compare-probe-overlay {
|
|
position: fixed; inset: 0; z-index: 300;
|
|
background: rgba(0,0,0,0.5); display: flex;
|
|
align-items: center; justify-content: center;
|
|
padding: 12px;
|
|
box-sizing: border-box;
|
|
}
|
|
.compare-probe-card {
|
|
width: min(460px, calc(100% - 16px));
|
|
max-height: min(620px, calc(100dvh - 24px));
|
|
box-sizing: border-box;
|
|
background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 14px;
|
|
display: flex; flex-direction: column; align-items: stretch; gap: 10px;
|
|
min-width: 280px; box-shadow: 0 8px 28px rgba(0,0,0,0.28);
|
|
overflow: hidden;
|
|
font-family: inherit;
|
|
}
|
|
.compare-probe-title {
|
|
font-size: 13px; font-weight: 400; color: var(--fg);
|
|
}
|
|
.compare-probe-title-label { font-weight: 600; }
|
|
.compare-probe-title-status { font-weight: 400; }
|
|
.compare-probe-list {
|
|
display: grid; grid-template-columns: 1fr 1fr; gap: 6px; min-width: 0; width: 100%;
|
|
overflow-y: auto;
|
|
}
|
|
.compare-probe-row {
|
|
display: flex; align-items: center; gap: 6px; padding: 6px 10px;
|
|
border-radius: 6px; background: color-mix(in srgb, var(--fg) 4%, transparent);
|
|
font-size: 12px; transition: background 0.2s; overflow: hidden;
|
|
}
|
|
.compare-probe-row.fail {
|
|
background: color-mix(in srgb, var(--color-error, #f44) 8%, transparent);
|
|
}
|
|
.compare-probe-spinner {
|
|
width: 24px; text-align: center; font-size: 10px; flex-shrink: 0;
|
|
letter-spacing: -1px; opacity: 0.6;
|
|
}
|
|
.compare-probe-spinner.ok { color: var(--color-success); animation: none; }
|
|
.compare-probe-spinner.fail { color: var(--color-error, #f44); animation: none; }
|
|
.compare-probe-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
.compare-probe-status { font-size: 11px; opacity: 0.5; flex-shrink: 0; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
.compare-probe-status.ok { color: var(--color-success); opacity: 1; }
|
|
.compare-probe-status.fail { color: var(--color-error, #f44); opacity: 1; }
|
|
.compare-probe-action-btn {
|
|
display: inline-flex; align-items: center; gap: 5px;
|
|
min-height: 25px; padding: 3px 8px; background: transparent; color: var(--fg); border: 1px solid var(--border);
|
|
border-radius: 5px; cursor: pointer; font-size: 10px; font-family: inherit;
|
|
opacity: 0.78; transition: opacity 0.15s, border-color 0.15s, background 0.15s; white-space: nowrap; flex-shrink: 0;
|
|
}
|
|
.compare-probe-action-btn svg,
|
|
.compare-probe-footer-btn svg { width: 12px; height: 12px; flex: 0 0 auto; color: var(--accent, var(--red)); }
|
|
.compare-probe-action-btn:hover { opacity: 1; border-color: var(--accent, var(--red)); background: color-mix(in srgb, var(--fg) 5%, transparent); }
|
|
.compare-probe-feedback { display: flex; flex-direction: column; gap: 5px; }
|
|
.compare-probe-feedback:empty { display: none; }
|
|
.compare-probe-detail {
|
|
display: flex; align-items: center; gap: 6px; min-width: 0;
|
|
padding: 6px 8px; font-size: 10px;
|
|
background: color-mix(in srgb, var(--color-error, #f44) 6%, transparent);
|
|
border-left: 2px solid color-mix(in srgb, var(--color-error, #f44) 72%, transparent);
|
|
border-radius: 4px;
|
|
}
|
|
.compare-probe-detail-icon {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex: 0 0 14px;
|
|
width: 14px;
|
|
height: 14px;
|
|
color: var(--accent, var(--red));
|
|
font-family: inherit;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
line-height: 1;
|
|
}
|
|
.compare-probe-detail-message { flex: 1 1 auto; min-width: 0; line-height: 1.35; color: color-mix(in srgb, var(--fg) 72%, transparent); overflow-wrap: anywhere; }
|
|
.compare-probe-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; margin-top: 2px; }
|
|
.compare-probe-footer-btn {
|
|
display: inline-flex; align-items: center; gap: 6px; min-height: 30px; padding: 5px 10px;
|
|
font-family: inherit; font-size: 11px; font-weight: 600; line-height: 1;
|
|
}
|
|
.compare-probe-start-anyway,
|
|
.compare-probe-start-anyway:hover:not(:disabled) {
|
|
background: var(--accent, var(--red));
|
|
border: 1px solid var(--accent, var(--red));
|
|
color: var(--bg);
|
|
}
|
|
.compare-probe-start-anyway svg { color: currentColor; }
|
|
.compare-probe-start-anyway span { font-weight: 700; }
|
|
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
@keyframes pane-shake {
|
|
0%, 100% { transform: translateX(0); }
|
|
15% { transform: translateX(-3px) rotate(-0.5deg); }
|
|
30% { transform: translateX(3px) rotate(0.5deg); }
|
|
45% { transform: translateX(-2px); }
|
|
60% { transform: translateX(2px); }
|
|
75% { transform: translateX(-1px); }
|
|
}
|
|
|
|
.chat-container.compare-active {
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding: 0;
|
|
overflow: hidden;
|
|
animation: compare-enter 0.3s ease-out;
|
|
}
|
|
@keyframes compare-enter {
|
|
from { opacity: 0; transform: translateY(8px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
.chat-container.compare-active .chat-input-bar {
|
|
margin-bottom: 0;
|
|
}
|
|
.chat-container.compare-active #model-picker-wrap {
|
|
display: none !important;
|
|
}
|
|
.compare-grid {
|
|
display: grid;
|
|
gap: 4px;
|
|
flex: 1 1 0;
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
.compare-mobile-tabs { display: none; }
|
|
.compare-grid[data-cols="2"] { grid-template-columns: 1fr 1fr; }
|
|
.compare-grid[data-cols="3"] { grid-template-columns: 1fr 1fr 1fr; }
|
|
.compare-grid[data-cols="4"] { grid-template-columns: repeat(4, 1fr); }
|
|
.compare-grid[data-cols="5"] { grid-template-columns: repeat(4, 1fr); }
|
|
.compare-grid[data-cols="6"] { grid-template-columns: repeat(4, 1fr); }
|
|
.compare-grid[data-cols="7"] { grid-template-columns: repeat(4, 1fr); }
|
|
.compare-grid[data-cols="8"] { grid-template-columns: repeat(4, 1fr); }
|
|
.compare-grid { grid-auto-rows: 1fr; }
|
|
.compare-shuffle-notice {
|
|
position: absolute;
|
|
left: 50%;
|
|
top: 50%;
|
|
transform: translate(-50%, -50%) scale(0.94);
|
|
z-index: 30;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 10px 14px;
|
|
border: 1px solid color-mix(in srgb, var(--red) 28%, var(--border));
|
|
border-radius: 8px;
|
|
background: color-mix(in srgb, var(--panel, var(--bg)) 92%, transparent);
|
|
color: var(--fg);
|
|
box-shadow: 0 10px 30px color-mix(in srgb, #000 24%, transparent);
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
line-height: 1;
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: opacity 0.14s ease, transform 0.14s ease;
|
|
}
|
|
.compare-shuffle-notice.show {
|
|
opacity: 1;
|
|
transform: translate(-50%, -50%) scale(1);
|
|
}
|
|
.compare-shuffle-notice-icon {
|
|
display: inline-flex;
|
|
color: var(--red);
|
|
animation: compare-shuffle-dice 0.56s ease both;
|
|
}
|
|
.compare-shuffle-notice-icon svg {
|
|
display: block;
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
@keyframes compare-shuffle-dice {
|
|
0% { transform: rotate(-18deg) scale(0.9); }
|
|
55% { transform: rotate(380deg) scale(1.08); }
|
|
100% { transform: rotate(360deg) scale(1); }
|
|
}
|
|
/* Sequential waterfall layout — stacked rows, staggered left, flush right */
|
|
.compare-grid.sequential-layout {
|
|
display: flex !important;
|
|
flex-direction: column !important;
|
|
grid-template-columns: none !important;
|
|
gap: 4px;
|
|
overflow-y: auto;
|
|
}
|
|
.compare-grid.sequential-layout .compare-pane {
|
|
flex-shrink: 0;
|
|
min-height: 200px;
|
|
transition: margin-left 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.3s ease;
|
|
}
|
|
/* Herringbone diagonal cut on left side of sequential pane headers */
|
|
.compare-grid.sequential-layout .compare-pane .pane-header {
|
|
clip-path: polygon(20px 0, 100% 0, 100% 100%, 0 100%);
|
|
padding-left: 26px;
|
|
}
|
|
.compare-pane {
|
|
display: flex;
|
|
flex-direction: column;
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
overflow: hidden;
|
|
min-height: 0;
|
|
min-width: 0;
|
|
position: relative;
|
|
transition: border-color 0.18s ease, box-shadow 0.18s ease, opacity 0.18s ease;
|
|
}
|
|
.compare-pane::before {
|
|
content: "";
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 2px;
|
|
z-index: 2;
|
|
pointer-events: none;
|
|
background: transparent;
|
|
transform-origin: left center;
|
|
}
|
|
.compare-pane.is-streaming {
|
|
border-color: color-mix(in srgb, var(--accent, var(--red)) 34%, var(--border));
|
|
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--accent, var(--red)) 12%, transparent);
|
|
}
|
|
.compare-pane.is-streaming::before {
|
|
background: linear-gradient(90deg, transparent 0%, var(--accent, var(--red)) 35%, var(--red) 50%, var(--accent, var(--red)) 65%, transparent 100%);
|
|
animation: compare-pane-progress 1.25s linear infinite;
|
|
}
|
|
.compare-pane.is-awaiting-input {
|
|
border-color: color-mix(in srgb, var(--red) 42%, var(--border));
|
|
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--red) 12%, transparent);
|
|
}
|
|
.compare-pane.is-awaiting-input::before {
|
|
background: var(--red);
|
|
animation: none;
|
|
}
|
|
.compare-pane.is-done {
|
|
border-color: color-mix(in srgb, var(--green, #50fa7b) 20%, var(--border));
|
|
}
|
|
.compare-pane.is-failed {
|
|
border-color: color-mix(in srgb, var(--color-error) 42%, var(--border));
|
|
}
|
|
.compare-pane.is-failed::before {
|
|
background: var(--color-error);
|
|
}
|
|
@keyframes compare-pane-progress {
|
|
from { transform: translateX(-100%); }
|
|
to { transform: translateX(100%); }
|
|
}
|
|
.compare-pane .pane-header {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
gap: 4px;
|
|
padding: 4px 10px;
|
|
background: color-mix(in srgb, var(--fg) 4%, transparent);
|
|
border-bottom: 1px solid var(--border);
|
|
font-size: 0.82em;
|
|
font-weight: 600;
|
|
color: var(--fg);
|
|
transition: background 0.4s;
|
|
flex-shrink: 0;
|
|
overflow: visible;
|
|
min-width: 0;
|
|
flex-wrap: nowrap;
|
|
}
|
|
.pane-header-row { display: flex; align-items: center; width: 100%; min-width: 0; }
|
|
.pane-header-primary { min-height: 24px; }
|
|
.pane-header-secondary { min-height: 20px; }
|
|
.pane-primary-actions, .pane-stats { display: flex; align-items: center; gap: 4px; min-width: 0; }
|
|
.pane-primary-actions { margin-left: auto; flex: 0 0 auto; }
|
|
.pane-stats { flex: 1 1 auto; overflow: hidden; }
|
|
.compare-header-bar button:hover,
|
|
.compare-header-bar button:focus-visible {
|
|
background: color-mix(in srgb, var(--accent, var(--red)) 14%, transparent) !important;
|
|
border-color: color-mix(in srgb, var(--accent, var(--red)) 55%, var(--border)) !important;
|
|
color: var(--fg) !important;
|
|
opacity: 1 !important;
|
|
outline: none;
|
|
}
|
|
.compare-header-bar button:active {
|
|
background: color-mix(in srgb, var(--accent, var(--red)) 24%, transparent) !important;
|
|
transform: scale(0.96);
|
|
}
|
|
.compare-more-wrap { position: relative; display: inline-flex; }
|
|
.compare-more-btn {
|
|
display: inline-flex; align-items: center; justify-content: center;
|
|
width: 28px; height: 24px; padding: 0 !important;
|
|
border: 1px solid transparent; border-radius: 5px;
|
|
background: none; color: var(--fg); cursor: pointer;
|
|
opacity: 0.5; transition: opacity .15s, background .15s;
|
|
}
|
|
.compare-header-bar .compare-close-btn {
|
|
width: 24px; height: 24px; min-width: 24px; padding: 0;
|
|
border-radius: 999px; font-size: 0; display: inline-flex;
|
|
align-items: center; justify-content: center;
|
|
}
|
|
.compare-header-bar .compare-close-btn:hover,
|
|
.compare-header-bar .compare-close-btn:focus-visible {
|
|
background: color-mix(in srgb, var(--fg) 10%, transparent) !important;
|
|
border-color: transparent !important;
|
|
color: var(--fg) !important;
|
|
opacity: 1 !important;
|
|
outline: none;
|
|
}
|
|
.compare-header-bar .compare-more-btn:hover,
|
|
.compare-header-bar .compare-more-btn:focus-visible,
|
|
.compare-header-bar .compare-more-btn[aria-expanded="true"] {
|
|
background: color-mix(in srgb, var(--fg) 10%, transparent) !important;
|
|
border-color: transparent !important;
|
|
color: var(--fg) !important;
|
|
opacity: 1 !important;
|
|
outline: none;
|
|
}
|
|
.compare-more-menu {
|
|
position: absolute; top: calc(100% + 5px); right: 0; z-index: 10002;
|
|
display: none; flex-direction: column; gap: 3px; min-width: 132px;
|
|
padding: 5px; border: 1px solid var(--border); border-radius: 8px;
|
|
background: var(--panel, var(--bg)); box-shadow: 0 8px 24px rgba(0,0,0,.3);
|
|
}
|
|
.compare-more-menu.is-open { display: flex; }
|
|
.compare-more-menu > .compare-export-wrap,
|
|
.compare-more-menu > button {
|
|
width: 100%; display: flex; align-items: center;
|
|
}
|
|
.compare-more-menu #compare-export-btn,
|
|
.compare-more-menu #compare-shuffle-btn,
|
|
.compare-more-menu #compare-check-btn,
|
|
.compare-more-menu #compare-add-menu-btn {
|
|
width: 100%; min-height: 32px; height: 32px;
|
|
box-sizing: border-box; justify-content: flex-start; gap: 7px;
|
|
padding: 7px 9px !important;
|
|
border: 1px solid transparent !important; border-radius: 6px;
|
|
background: transparent !important; color: var(--fg) !important;
|
|
font-size: 11px; font-weight: 500; opacity: .72;
|
|
transition: background .12s ease, opacity .12s ease, color .12s ease;
|
|
}
|
|
.compare-more-menu #compare-export-btn:hover,
|
|
.compare-more-menu #compare-shuffle-btn:hover,
|
|
.compare-more-menu #compare-check-btn:hover,
|
|
.compare-more-menu #compare-add-menu-btn:hover,
|
|
.compare-more-menu #compare-export-btn:focus-visible,
|
|
.compare-more-menu #compare-shuffle-btn:focus-visible,
|
|
.compare-more-menu #compare-check-btn:focus-visible,
|
|
.compare-more-menu #compare-add-menu-btn:focus-visible {
|
|
opacity: 1; background: color-mix(in srgb, var(--red) 10%, transparent) !important;
|
|
border-color: transparent !important; color: var(--fg) !important; outline: none;
|
|
}
|
|
.compare-more-menu #compare-export-btn svg,
|
|
.compare-more-menu #compare-shuffle-btn svg,
|
|
.compare-more-menu #compare-check-btn svg,
|
|
.compare-more-menu #compare-add-menu-btn svg { flex: 0 0 auto; opacity: .65; }
|
|
.compare-more-menu #compare-export-btn span,
|
|
.compare-more-menu #compare-shuffle-btn span,
|
|
.compare-more-menu #compare-check-btn span,
|
|
.compare-more-menu #compare-add-menu-btn span {
|
|
font-size: 11px !important; margin-left: 0 !important;
|
|
color: var(--fg) !important; opacity: 1 !important; font-weight: 500 !important;
|
|
}
|
|
.compare-more-menu #compare-export-btn,
|
|
.compare-more-menu #compare-shuffle-btn,
|
|
.compare-more-menu #compare-check-btn,
|
|
.compare-more-menu #compare-add-menu-btn {
|
|
color: var(--fg) !important; opacity: 1 !important; font-weight: 500 !important;
|
|
}
|
|
.compare-more-menu #compare-export-btn svg,
|
|
.compare-more-menu #compare-shuffle-btn svg,
|
|
.compare-more-menu #compare-check-btn svg,
|
|
.compare-more-menu #compare-add-menu-btn svg { color: var(--fg) !important; opacity: .65 !important; }
|
|
.compare-export-item:hover,
|
|
.compare-export-item:focus-visible {
|
|
background: color-mix(in srgb, var(--red) 10%, transparent) !important;
|
|
border-color: transparent !important; outline: none;
|
|
}
|
|
.compare-export-item { display: flex; align-items: center; gap: 8px; }
|
|
.compare-export-item > svg { flex: 0 0 auto; opacity: .65; }
|
|
.compare-export-menu .compare-export-item,
|
|
.compare-export-menu .compare-export-item > span {
|
|
color: var(--fg) !important;
|
|
opacity: 1 !important;
|
|
}
|
|
.compare-add-flap {
|
|
position: absolute; z-index: 20; right: -8px; top: 50%;
|
|
width: 34px; min-width: 34px; height: 30px; box-sizing: border-box;
|
|
padding: 0 !important;
|
|
display: inline-flex; flex-direction: row; align-items: center; justify-content: center;
|
|
gap: 0; border: 1px solid var(--border);
|
|
border-radius: 0 7px 7px 0; background: var(--panel, var(--bg));
|
|
color: var(--fg); cursor: pointer; opacity: .7;
|
|
box-shadow: 3px 2px 9px color-mix(in srgb, var(--fg) 12%, transparent);
|
|
transform: translate(0, -50%); transition: width .18s ease, opacity .15s, background .15s, box-shadow .15s;
|
|
}
|
|
.compare-add-flap:hover, .compare-add-flap:focus-visible {
|
|
width: 70px; opacity: 1; background: color-mix(in srgb, var(--fg) 8%, var(--panel));
|
|
box-shadow: 4px 3px 12px color-mix(in srgb, var(--fg) 18%, transparent);
|
|
outline: none;
|
|
}
|
|
.compare-add-flap span {
|
|
max-width: 0; overflow: hidden; white-space: nowrap; margin-left: 0 !important;
|
|
font-size: 10px; opacity: 0; transition: max-width .18s ease, margin-left .18s ease, opacity .12s;
|
|
}
|
|
.compare-add-flap:hover span, .compare-add-flap:focus-visible span {
|
|
max-width: 32px; margin-left: 3px !important; opacity: 1;
|
|
}
|
|
.compare-add-flap svg { flex-shrink: 0; position: relative; left: -3px; }
|
|
@media (max-width: 768px) {
|
|
.compare-add-flap {
|
|
top: 8px; right: 8px; width: auto; min-width: 32px; height: 32px;
|
|
padding: 5px 8px !important; flex-direction: row; transform: none;
|
|
border-right: 1px solid var(--border); border-radius: 6px;
|
|
}
|
|
.compare-add-flap span { opacity: 1; }
|
|
}
|
|
.pane-actions {
|
|
display: flex; gap: 4px; align-items: center; margin-left: auto; flex-shrink: 0;
|
|
}
|
|
.compare-pane-footer {
|
|
font-size: 0.72em; opacity: 0.4; padding: 4px 10px;
|
|
border-top: 1px solid color-mix(in srgb, var(--border) 40%, transparent);
|
|
text-align: center; flex-shrink: 0;
|
|
}
|
|
/* Per-pane vote button. Sits at the bottom of each compare pane so
|
|
the action lives right under the response it judges. */
|
|
.pane-vote-footer {
|
|
padding: 6px 8px;
|
|
border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
|
|
background: color-mix(in srgb, var(--fg) 3%, transparent);
|
|
flex-shrink: 0;
|
|
}
|
|
.pane-vote-btn {
|
|
width: 100%;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 4px;
|
|
background: var(--bg);
|
|
color: var(--fg);
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
padding: 6px 10px;
|
|
font-family: inherit;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: background 0.15s, border-color 0.15s, opacity 0.15s;
|
|
}
|
|
.pane-vote-btn:hover:not(:disabled) {
|
|
background: color-mix(in srgb, var(--accent, var(--fg)) 12%, var(--bg));
|
|
border-color: var(--accent, var(--fg));
|
|
}
|
|
.pane-vote-btn:disabled { cursor: not-allowed; }
|
|
.pane-vote-label {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
min-width: 0;
|
|
}
|
|
.pane-action-btn {
|
|
background: none; border: none; color: var(--fg); cursor: pointer;
|
|
opacity: 0.3; padding: 2px; border-radius: 4px;
|
|
display: flex; align-items: center; transition: all 0.15s;
|
|
}
|
|
.pane-action-btn:hover { opacity: 0.8; background: color-mix(in srgb, var(--fg) 6%, transparent); }
|
|
/* Pane title as clickable model-swap button */
|
|
.pane-title-btn {
|
|
background: none; border: none; cursor: pointer;
|
|
font-size: 10px; font-weight: 400; font-family: inherit;
|
|
color: var(--fg); padding: 0;
|
|
text-align: left; display: flex; align-items: center; gap: 4px;
|
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
transition: opacity 0.15s;
|
|
min-width: 0; flex: 1 1 0;
|
|
}
|
|
.pane-title-btn:hover { opacity: 0.7; }
|
|
.pane-title-caret { font-size: 0.6em; opacity: 0.35; flex-shrink: 0; position: relative; top: 2px; }
|
|
.pane-title-btn:hover .pane-title-caret { opacity: 0.7; }
|
|
.pane-mode-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
flex: 0 0 auto;
|
|
height: 18px;
|
|
padding: 0 6px;
|
|
border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
|
|
border-radius: 999px;
|
|
background: color-mix(in srgb, var(--fg) 3%, var(--bg));
|
|
color: color-mix(in srgb, var(--fg) 76%, transparent);
|
|
font-size: 9px;
|
|
font-weight: 600;
|
|
line-height: 1;
|
|
letter-spacing: 0;
|
|
white-space: nowrap;
|
|
}
|
|
.pane-mode-dot {
|
|
width: 5px;
|
|
height: 5px;
|
|
border-radius: 50%;
|
|
background: currentColor;
|
|
opacity: 0.75;
|
|
flex: 0 0 auto;
|
|
}
|
|
.pane-mode-detail {
|
|
opacity: 0.52;
|
|
font-weight: 500;
|
|
}
|
|
.pane-mode-badge.pane-mode-icon-only {
|
|
width: 20px;
|
|
padding: 0;
|
|
justify-content: center;
|
|
}
|
|
.pane-mode-settings {
|
|
opacity: 0.65;
|
|
cursor: pointer;
|
|
}
|
|
.pane-settings-btn { width: 20px; height: 20px; justify-content: center; }
|
|
.pane-settings-btn[aria-expanded="true"] { opacity: 1; background: color-mix(in srgb, var(--fg) 9%, transparent); }
|
|
.response-metrics[data-action="settings"] { cursor: pointer; }
|
|
.response-thinking-state { color: color-mix(in srgb, var(--fg) 55%, transparent); }
|
|
.pane-mode-settings:hover,
|
|
.pane-mode-settings:focus-visible,
|
|
.pane-mode-settings[aria-expanded="true"] {
|
|
opacity: 1;
|
|
color: var(--fg);
|
|
background: color-mix(in srgb, var(--fg) 9%, var(--bg));
|
|
border-color: color-mix(in srgb, var(--accent, var(--fg)) 45%, var(--border));
|
|
outline: none;
|
|
}
|
|
.pane-mode-icon,
|
|
.pane-mode-icon svg {
|
|
display: block;
|
|
width: 12px;
|
|
height: 12px;
|
|
}
|
|
.pane-mode-agent {
|
|
color: color-mix(in srgb, var(--fg) 76%, transparent);
|
|
background: color-mix(in srgb, var(--fg) 3%, var(--bg));
|
|
border-color: color-mix(in srgb, var(--border) 70%, transparent);
|
|
}
|
|
.pane-mode-search {
|
|
color: color-mix(in srgb, var(--accent, var(--red)) 82%, var(--fg));
|
|
background: color-mix(in srgb, var(--accent, var(--red)) 10%, var(--bg));
|
|
border-color: color-mix(in srgb, var(--accent, var(--red)) 28%, var(--border));
|
|
}
|
|
.pane-mode-research {
|
|
color: color-mix(in srgb, #36c48f 82%, var(--fg));
|
|
background: color-mix(in srgb, #36c48f 10%, var(--bg));
|
|
border-color: color-mix(in srgb, #36c48f 28%, var(--border));
|
|
}
|
|
.compare-check-label {
|
|
position: relative;
|
|
top: -2px;
|
|
font-size: 11px;
|
|
margin-left: 3px;
|
|
}
|
|
.compare-check-icon {
|
|
position: relative;
|
|
top: 1px;
|
|
}
|
|
#compare-check-btn > .spinner-whirlpool {
|
|
position: relative;
|
|
top: -2px;
|
|
transform: none;
|
|
}
|
|
.compare-pane .pane-close-btn { opacity: 0.3; }
|
|
.compare-pane .pane-close-btn:hover { opacity: 1; color: var(--color-error); }
|
|
/* Model swap dropdown under pane title */
|
|
.pane-model-dropdown {
|
|
position: absolute;
|
|
z-index: 1000;
|
|
min-width: 220px;
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
background: var(--bg);
|
|
border: 1px solid var(--border);
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 16px rgba(0,0,0,0.3);
|
|
padding: 4px;
|
|
}
|
|
.pane-model-item {
|
|
display: block; width: 100%;
|
|
box-sizing: border-box;
|
|
padding: 8px 10px; font-size: 11px; line-height: 1.3;
|
|
text-align: left; background: none; border: none; border-radius: 6px;
|
|
color: var(--fg); cursor: pointer; transition: background 0.12s ease;
|
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
}
|
|
.pane-model-item:hover,
|
|
.pane-model-item:focus-visible { background: color-mix(in srgb, var(--red) 10%, transparent); outline: none; }
|
|
.pane-model-item.current { color: var(--red); font-weight: 600; }
|
|
.pane-timer {
|
|
font-size: 10px; font-weight: 400; opacity: 0.45; font-variant-numeric: tabular-nums;
|
|
white-space: nowrap; padding-right: 4px;
|
|
}
|
|
.pane-summary {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
position: relative;
|
|
top: 1px;
|
|
min-height: 16px;
|
|
max-width: 150px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
padding: 0 5px;
|
|
border-radius: 999px;
|
|
background: color-mix(in srgb, var(--fg) 4%, transparent);
|
|
color: color-mix(in srgb, var(--fg) 58%, transparent);
|
|
font-size: 9px;
|
|
font-weight: 500;
|
|
line-height: 1;
|
|
font-variant-numeric: tabular-nums;
|
|
cursor: pointer;
|
|
transition: max-width .15s ease, white-space .15s ease;
|
|
}
|
|
.pane-summary:empty { display: none; }
|
|
.pane-stats-popup {
|
|
position: fixed; z-index: 10040; width: 210px; padding: 6px;
|
|
background: var(--panel, var(--bg)); color: var(--fg);
|
|
border: 1px solid var(--border); border-radius: 7px;
|
|
box-shadow: 0 8px 24px rgba(0,0,0,.3); font-size: 11px;
|
|
}
|
|
.pane-stats-popup-title { padding: 4px 6px 7px; font-weight: 600; border-bottom: 1px solid var(--border); }
|
|
.pane-stats-popup-row { display: flex; justify-content: space-between; gap: 12px; padding: 6px; }
|
|
.pane-stats-popup-row span { color: color-mix(in srgb, var(--fg) 55%, transparent); }
|
|
.pane-stats-popup-row strong { font-weight: 500; font-variant-numeric: tabular-nums; text-align: right; }
|
|
/* Metrics stay on the lower row even in dense comparisons. */
|
|
.compare-grid[data-cols="4"] .pane-timer,
|
|
.compare-grid[data-cols="5"] .pane-timer,
|
|
.compare-grid[data-cols="6"] .pane-timer {
|
|
width: auto; order: initial; margin-top: 0; padding-bottom: 0; padding-left: 0;
|
|
}
|
|
.pane-finish-badge {
|
|
font-weight: 600; color: var(--green, #50fa7b);
|
|
position: relative;
|
|
top: 2px;
|
|
}
|
|
.compare-pane.winner .pane-header {
|
|
background: color-mix(in srgb, var(--green, #50fa7b) 12%, transparent);
|
|
border-bottom-color: color-mix(in srgb, var(--green, #50fa7b) 30%, var(--border));
|
|
}
|
|
.compare-pane.winner .pane-title {
|
|
color: var(--green, #50fa7b);
|
|
}
|
|
.compare-pane.loser .pane-header {
|
|
opacity: 0.5;
|
|
}
|
|
.confetti-piece {
|
|
position: fixed;
|
|
pointer-events: none;
|
|
z-index: 1000000;
|
|
}
|
|
.compare-pane.expanded { grid-column: 1 / -1; }
|
|
.compare-pane .chat-history {
|
|
flex: 1 1 0;
|
|
min-height: 0;
|
|
overflow-y: auto !important;
|
|
overflow-x: hidden;
|
|
padding: 8px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.compare-pane .chat-history .msg {
|
|
flex-shrink: 0;
|
|
}
|
|
.compare-gen-image {
|
|
max-width: 100%;
|
|
max-height: 100%;
|
|
object-fit: contain;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
}
|
|
.compare-section {
|
|
margin-bottom: 14px;
|
|
}
|
|
.compare-section:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
.compare-section-label {
|
|
font-size: 9px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.6px;
|
|
opacity: 0.5;
|
|
margin-bottom: 5px;
|
|
font-weight: 600;
|
|
}
|
|
/* Active-type/mode readout next to "Type:"/"Mode:" — only needed on mobile
|
|
(where the tab/toggle text labels are hidden); hidden on desktop. */
|
|
.compare-type-current,
|
|
.compare-mode-current { display: none; }
|
|
/* Contextual one-liner under the mode toggles describing what you just
|
|
changed — empty until the first toggle, then a subtle hint. */
|
|
.compare-mode-hint {
|
|
font-size: 11px;
|
|
opacity: 0.55;
|
|
margin-top: 6px;
|
|
min-height: 0;
|
|
line-height: 1.3;
|
|
}
|
|
.compare-mode-hint:empty { display: none; }
|
|
.compare-type-tabs .compare-mode-tab > svg,
|
|
.compare-type-current > svg {
|
|
color: var(--accent, var(--red));
|
|
}
|
|
|
|
.compare-mode-tabs {
|
|
display: flex;
|
|
gap: 4px;
|
|
flex-wrap: wrap;
|
|
min-width: 0;
|
|
}
|
|
/* Type tabs match Mode toggles 1:1 (same flex column layout, same metrics) */
|
|
.compare-mode-tab {
|
|
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
|
width: 56px; height: 38px; flex: 1 1 0;
|
|
padding: 5px 4px 4px; border: 1px solid var(--border); border-radius: 6px;
|
|
cursor: pointer; user-select: none; transition: all 0.15s;
|
|
background: none; color: var(--fg); opacity: 0.35;
|
|
flex-shrink: 0; gap: 0;
|
|
font-family: inherit;
|
|
}
|
|
.compare-mode-tab > svg {
|
|
width: 13px; height: 13px; flex: 0 0 13px;
|
|
}
|
|
.compare-mode-tab:hover {
|
|
opacity: 0.7; background: color-mix(in srgb, var(--fg) 6%, transparent);
|
|
}
|
|
.compare-mode-tab.active {
|
|
opacity: 1; border-color: var(--fg);
|
|
background: color-mix(in srgb, var(--fg) 10%, transparent);
|
|
}
|
|
.compare-sources-box {
|
|
display: flex; align-items: center; gap: 6px;
|
|
padding: 6px 10px; margin-bottom: 8px;
|
|
border-radius: 6px; font-size: 0.78em;
|
|
background: color-mix(in srgb, var(--red) 8%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--red) 20%, transparent);
|
|
color: color-mix(in srgb, var(--fg) 70%, transparent);
|
|
cursor: default;
|
|
}
|
|
.compare-sources-box .sources-label { font-weight: 600; }
|
|
/* Compact tool blocks inside compare panes */
|
|
.compare-pane .agent-thread-node {
|
|
margin: 4px 0; font-size: 0.85em;
|
|
}
|
|
.compare-pane .agent-thread-cmd {
|
|
max-height: 80px; overflow-y: auto;
|
|
}
|
|
.compare-pane .agent-tool-output pre {
|
|
max-height: 120px; overflow-y: auto;
|
|
}
|
|
.compare-vote-bar {
|
|
display: flex; justify-content: center; gap: 8px;
|
|
padding: 8px; border-top: 1px solid var(--border);
|
|
flex-shrink: 0; flex-wrap: wrap;
|
|
}
|
|
.compare-vote-bar.hidden { display: none; }
|
|
.compare-vote-btn {
|
|
padding: 6px 13px; border: 1px solid var(--border); border-radius: 6px;
|
|
background: var(--panel); color: var(--fg); cursor: pointer; font-size: 0.8em;
|
|
transition: all 0.15s; white-space: nowrap;
|
|
}
|
|
.compare-score-label {
|
|
position: relative;
|
|
top: -2px;
|
|
display: inline-block;
|
|
}
|
|
.compare-vote-btn:hover { border-color: var(--red); background: color-mix(in srgb, var(--red) 11%, transparent); }
|
|
.compare-vote-tie { opacity: 0.7; }
|
|
.compare-rematch-btn {
|
|
display: flex; align-items: center; gap: 6px; margin-left: 8px;
|
|
border-color: color-mix(in srgb, var(--accent, var(--red)) 60%, var(--border));
|
|
background: color-mix(in srgb, var(--accent, var(--red)) 14%, transparent);
|
|
color: var(--fg); opacity: 1; font-weight: 600;
|
|
}
|
|
.compare-rematch-btn:hover { border-color: var(--accent, var(--red)); background: color-mix(in srgb, var(--accent, var(--red)) 24%, transparent); }
|
|
/* Preview button accent in pane header */
|
|
.pane-preview-btn.active { color: var(--red); }
|
|
/* Full-pane iframe for HTML preview */
|
|
.compare-pane-iframe {
|
|
flex: 1;
|
|
width: 100%;
|
|
border: none;
|
|
border-radius: 0 0 8px 8px;
|
|
background: #fff;
|
|
}
|
|
/* ---- Add-pane "+" button in pane header (last pane only) ---- */
|
|
.pane-add-btn { display: none !important; font-size: 16px; font-weight: 600; }
|
|
.compare-pane:last-child .pane-add-btn { display: flex !important; }
|
|
/* Dropdown for adding a pane */
|
|
.add-pane-dropdown {
|
|
position: absolute;
|
|
right: 0;
|
|
z-index: 100;
|
|
background: var(--panel, var(--bg));
|
|
border: 1px solid var(--border);
|
|
border-radius: 10px;
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
min-width: 220px;
|
|
box-shadow: 0 8px 24px rgba(0,0,0,0.3), 0 0 0 1px color-mix(in srgb, var(--fg) 5%, transparent);
|
|
padding: 6px;
|
|
backdrop-filter: blur(12px);
|
|
animation: dropdown-in 0.15s ease-out;
|
|
}
|
|
.add-pane-search {
|
|
width: 100%;
|
|
padding: 6px 8px;
|
|
border: 1px solid var(--border);
|
|
border-radius: 4px;
|
|
background: var(--bg);
|
|
color: var(--fg);
|
|
font-size: 0.85em;
|
|
box-sizing: border-box;
|
|
margin-bottom: 4px;
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 1;
|
|
}
|
|
/* Compare toggle buttons — icon + label stacked */
|
|
.compare-toggle-label {
|
|
display: block;
|
|
font-size: 9px;
|
|
line-height: 1;
|
|
margin-top: 2px;
|
|
font-weight: 500;
|
|
}
|
|
.compare-blind-toggle,
|
|
.compare-save-toggle,
|
|
.compare-dice-toggle,
|
|
.compare-parallel-toggle,
|
|
.compare-reset-toggle {
|
|
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
|
width: 56px; height: auto; flex: 1 1 0;
|
|
padding: 5px 4px 4px; border: 1px solid var(--border); border-radius: 6px;
|
|
cursor: pointer; user-select: none; transition: all 0.15s;
|
|
background: none; color: var(--fg); opacity: 0.35;
|
|
flex-shrink: 0; gap: 0;
|
|
}
|
|
.compare-blind-toggle:hover,
|
|
.compare-save-toggle:hover,
|
|
.compare-dice-toggle:hover,
|
|
.compare-parallel-toggle:hover,
|
|
.compare-reset-toggle:hover {
|
|
opacity: 0.7; background: color-mix(in srgb, var(--fg) 6%, transparent);
|
|
}
|
|
.compare-blind-toggle.active {
|
|
opacity: 1; color: var(--accent, var(--red)); border-color: var(--accent, var(--red));
|
|
background: color-mix(in srgb, var(--accent, var(--red)) 10%, transparent);
|
|
}
|
|
.compare-blind-toggle.active > svg {
|
|
color: var(--accent, var(--red));
|
|
}
|
|
.compare-save-toggle.active {
|
|
opacity: 1; color: var(--color-save-green); border-color: var(--color-save-green);
|
|
background: color-mix(in srgb, var(--red) 10%, transparent);
|
|
}
|
|
.compare-dice-toggle.active {
|
|
opacity: 1; color: var(--red); border-color: var(--red);
|
|
background: color-mix(in srgb, var(--red) 10%, transparent);
|
|
}
|
|
.compare-parallel-toggle {
|
|
opacity: 1; color: #e0a050; border-color: #e0a050;
|
|
background: rgba(224, 160, 80, 0.1);
|
|
}
|
|
.compare-parallel-toggle.active {
|
|
color: var(--accent, var(--red)); border-color: var(--accent, var(--red));
|
|
background: color-mix(in srgb, var(--accent, var(--red)) 10%, transparent);
|
|
}
|
|
@media (max-width: 520px) {
|
|
.compare-toggle-label { display: none; }
|
|
/* Tab text labels are hidden on mobile, so spell out the active type next
|
|
to "Type:" with its icon. */
|
|
.compare-type-current {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
margin-left: 5px;
|
|
font-weight: 600;
|
|
vertical-align: -3px;
|
|
}
|
|
.compare-type-current svg { width: 14px; height: 14px; }
|
|
/* Mode list — comma-separated, each name already coloured inline. */
|
|
.compare-mode-current {
|
|
display: inline;
|
|
margin-left: 5px;
|
|
font-weight: 600;
|
|
}
|
|
.compare-blind-toggle,
|
|
.compare-save-toggle,
|
|
.compare-dice-toggle,
|
|
.compare-parallel-toggle,
|
|
.compare-reset-toggle {
|
|
width: 32px; height: 32px; min-width: 32px; padding: 0;
|
|
}
|
|
/* The Group tab's seq/parallel toggle is a single full-width button (not
|
|
a row of compact icons like the Compare header), so keep its label and
|
|
make it a comfortable touch target with the text beside the icon. */
|
|
#group-mode-btn {
|
|
flex-direction: row !important;
|
|
width: auto !important;
|
|
height: auto !important;
|
|
min-height: 44px;
|
|
padding: 8px 14px !important;
|
|
gap: 8px !important;
|
|
font-size: 13px;
|
|
}
|
|
#group-mode-btn .compare-toggle-label {
|
|
display: inline !important;
|
|
font-size: 13px;
|
|
margin-top: 0;
|
|
}
|
|
#group-mode-btn svg { width: 18px; height: 18px; }
|
|
/* Compare header: hide labels + close button, show icons only */
|
|
#compare-shuffle-btn span {
|
|
display: none;
|
|
}
|
|
#compare-shuffle-btn,
|
|
#compare-check-btn,
|
|
#compare-add-btn {
|
|
padding: 3px 6px;
|
|
}
|
|
/* Save space so the header buttons fit on one row: tighter padding +
|
|
smaller labels (icons kept full size). (Score now lives in the vote bar.) */
|
|
.compare-header-bar button { padding: 3px 5px !important; }
|
|
.compare-header-bar #compare-check-btn > span,
|
|
.compare-header-bar #compare-add-btn > span {
|
|
font-size: 10px; margin-left: 2px;
|
|
}
|
|
/* Compare mobile: keep the close X visible — it's the only way out
|
|
now that the hamburger is hidden during compare mode. */
|
|
.compare-header-bar {
|
|
padding: 14px 8px 10px 8px !important;
|
|
min-height: 44px;
|
|
}
|
|
.compare-pane .pane-header {
|
|
align-items: stretch;
|
|
row-gap: 3px;
|
|
}
|
|
.compare-pane .pane-title-btn {
|
|
flex: 1 1 auto;
|
|
width: auto;
|
|
padding-right: 2px;
|
|
}
|
|
/* Compare is already visibly in chat mode; the Chat speech-bubble
|
|
badge adds a redundant second row on narrow screens. */
|
|
.compare-pane .pane-mode-chat { display: none; }
|
|
.compare-pane .pane-timer,
|
|
.compare-pane .pane-summary,
|
|
.compare-pane .pane-finish-badge,
|
|
.compare-pane .pane-mode-badge,
|
|
.compare-pane .pane-actions {
|
|
order: 1;
|
|
align-self: center;
|
|
}
|
|
.compare-pane .pane-finish-badge { top: 0; }
|
|
.compare-pane .pane-summary {
|
|
max-width: 110px;
|
|
}
|
|
.compare-pane .pane-mode-detail {
|
|
display: none;
|
|
}
|
|
.compare-grid[data-cols="4"] .compare-pane .pane-timer,
|
|
.compare-grid[data-cols="5"] .compare-pane .pane-timer,
|
|
.compare-grid[data-cols="6"] .compare-pane .pane-timer {
|
|
width: auto;
|
|
order: 1;
|
|
margin-top: 0;
|
|
padding-bottom: 0;
|
|
padding-left: 0;
|
|
}
|
|
.compare-pane .pane-actions {
|
|
margin-left: auto;
|
|
}
|
|
/* Mode tabs: icons only, centered */
|
|
.compare-mode-tab span { display: none; }
|
|
.compare-mode-tabs { justify-content: center; }
|
|
/* Header action buttons: hide text labels on Export / Shuffle /
|
|
Model on mobile so the close X fits on the right. Score keeps
|
|
its "Score" label because its icon (4-square grid) reads too
|
|
similar to Shuffle's icon without text. */
|
|
.compare-header-bar #compare-export-btn > span,
|
|
.compare-header-bar #compare-shuffle-btn > span {
|
|
display: none;
|
|
}
|
|
/* Override the desktop override: on mobile the model picker overlay
|
|
MUST cap its height to the viewport so the dropdown doesn't run
|
|
past the bottom of the screen. */
|
|
#compare-model-overlay .modal-content {
|
|
max-height: 85dvh !important;
|
|
max-height: 85vh !important;
|
|
overflow: hidden !important;
|
|
}
|
|
#compare-model-overlay .modal-body {
|
|
overflow: auto !important;
|
|
flex: 1 1 auto !important;
|
|
min-height: 0 !important;
|
|
}
|
|
}
|
|
/* Hide number input spinners */
|
|
input[type="number"]::-webkit-inner-spin-button,
|
|
input[type="number"]::-webkit-outer-spin-button {
|
|
-webkit-appearance: none; margin: 0;
|
|
}
|
|
|
|
/* ── Sensitive info censor ── */
|
|
.censored-item {
|
|
filter: blur(5px);
|
|
cursor: pointer;
|
|
transition: filter 0.2s;
|
|
border-radius: 2px;
|
|
padding: 0 2px;
|
|
background: rgba(255,100,100,0.08);
|
|
user-select: none;
|
|
}
|
|
.censored-item:hover { filter: blur(3px); background: rgba(255,100,100,0.15); }
|
|
.censored-item.revealed {
|
|
filter: none;
|
|
background: rgba(100,255,100,0.08);
|
|
user-select: auto;
|
|
cursor: text;
|
|
}
|
|
|
|
#settings-menu-list .list-item.active {
|
|
background: color-mix(in srgb, var(--accent) 10%, transparent);
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
/* ── Print / PDF Export ── */
|
|
@media print {
|
|
body { background: #fff !important; color: #000 !important; }
|
|
#sidebar, .sidebar, #icon-rail, .hamburger-btn, #sidebar-backdrop, .chat-input-bar, .input-bar-wrapper,
|
|
#welcome-screen, .chat-top-bar, .chat-meta-overlay, .msg-footer,
|
|
.modal, .toast, .overflow-wrapper, .mode-toggle, .incognito-btn,
|
|
button, .dropdown, .session-dropdown,
|
|
.agent-tool-spinner, .agent-thread-node.running { display: none !important; }
|
|
main.chat-container { width: 100% !important; margin: 0 !important; padding: 0 !important; max-height: none !important; overflow: visible !important; }
|
|
#chat-history { max-height: none !important; overflow: visible !important; height: auto !important; padding: 0 !important; }
|
|
.msg { break-inside: avoid; page-break-inside: avoid; border: none !important; box-shadow: none !important; }
|
|
.msg-ai { background: #f5f5f5 !important; color: #000 !important; }
|
|
.msg-user { background: #e8e8e8 !important; color: #000 !important; }
|
|
.msg .role { color: #333 !important; font-weight: bold; }
|
|
.msg .body { color: #000 !important; }
|
|
pre, code { background: #f0f0f0 !important; color: #000 !important; border: 1px solid #ccc !important; }
|
|
details { display: block !important; }
|
|
details[open] summary ~ * { display: block !important; }
|
|
details > summary { list-style: none; }
|
|
details > summary::before { content: "" !important; }
|
|
#chat-history::before { content: attr(data-print-title); display: block; font-size: 1.3em; font-weight: bold; margin-bottom: 1em; color: #000; }
|
|
a { color: #000 !important; text-decoration: underline; }
|
|
}
|
|
|
|
|
|
/* ── Components (from style.css) ── */
|
|
|
|
/* Self-hosted Fira Code font */
|
|
@font-face { font-family: 'Fira Code'; font-weight: 300; font-style: normal; font-display: swap; src: url('/static/fonts/FiraCode-Light.woff2') format('woff2'); }
|
|
@font-face { font-family: 'Fira Code'; font-weight: 400; font-style: normal; font-display: swap; src: url('/static/fonts/FiraCode-Regular.woff2') format('woff2'); }
|
|
@font-face { font-family: 'Fira Code'; font-weight: 600; font-style: normal; font-display: swap; src: url('/static/fonts/FiraCode-SemiBold.woff2') format('woff2'); }
|
|
|
|
/* Scrollbar styling */
|
|
|
|
/* Code block styling */
|
|
pre, code, .hljs {
|
|
font-size: 11px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
/* WebKit (Chrome, Edge, Safari) */
|
|
/* Utility class for red text */
|
|
.red-text {
|
|
color: var(--red);
|
|
}
|
|
|
|
/* Internal chat links (search results, session references) */
|
|
a.chat-link {
|
|
color: var(--hl-function);
|
|
text-decoration: none;
|
|
border-bottom: 1px dotted var(--hl-function);
|
|
cursor: pointer;
|
|
}
|
|
a.chat-link:hover {
|
|
opacity: 0.8;
|
|
border-bottom-style: solid;
|
|
}
|
|
|
|
a.chat-link[href^="#email-"] {
|
|
display: inline;
|
|
padding: 1px 5px;
|
|
border: 1px solid color-mix(in srgb, var(--accent, var(--red)) 34%, transparent);
|
|
border-radius: 5px;
|
|
background: color-mix(in srgb, var(--accent, var(--red)) 8%, transparent);
|
|
color: var(--fg);
|
|
font-weight: 600;
|
|
border-bottom-style: solid;
|
|
}
|
|
a.chat-link[href^="#email-"]:hover {
|
|
opacity: 1;
|
|
background: color-mix(in srgb, var(--accent, var(--red)) 14%, transparent);
|
|
border-color: color-mix(in srgb, var(--accent, var(--red)) 55%, transparent);
|
|
}
|
|
|
|
a.chat-link[href^="#notes-more-"],
|
|
a.chat-link[href^="#skills-more-"],
|
|
a.chat-link[href^="#memories-more-"],
|
|
a.chat-link[href^="#events-more-"],
|
|
a.chat-link[href^="#sessions-more-"] {
|
|
color: var(--muted);
|
|
border-bottom: 1px dotted color-mix(in srgb, var(--muted) 55%, transparent);
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
}
|
|
a.chat-link[href^="#notes-more-"]:hover,
|
|
a.chat-link[href^="#skills-more-"]:hover,
|
|
a.chat-link[href^="#memories-more-"]:hover,
|
|
a.chat-link[href^="#events-more-"]:hover,
|
|
a.chat-link[href^="#sessions-more-"]:hover {
|
|
color: var(--fg);
|
|
opacity: 1;
|
|
border-bottom-style: solid;
|
|
}
|
|
.more-list-expanded {
|
|
display: block;
|
|
max-height: 0;
|
|
overflow: hidden;
|
|
opacity: 0;
|
|
color: inherit;
|
|
font: inherit;
|
|
line-height: inherit;
|
|
transition: max-height 220ms ease, opacity 160ms ease;
|
|
}
|
|
.more-list-expanded.is-open {
|
|
opacity: 1;
|
|
}
|