merge(dev): integrate reviewed preview UI changes

This commit is contained in:
Alexandre Teixeira
2026-10-29 01:12:08 +00:00
487 changed files with 67762 additions and 2026 deletions
+33 -7
View File
@@ -315,7 +315,7 @@ body.bg-pattern-ascii-fireflies {
width: 240px;
background: var(--sidebar-bg, var(--panel));
border-right: 1px solid var(--border);
transition: width 0.25s ease, opacity 0.2s ease, padding 0.25s ease;
transition: width 0.25s ease, opacity 0.2s ease, padding 0.25s ease, visibility 0.25s;
display: flex;
flex-direction: column;
flex-shrink: 0;
@@ -361,12 +361,23 @@ body.bg-pattern-ascii-fireflies {
/* !important so it beats the inline width init.js restores from storage —
otherwise the width never changes and only opacity animates, making the
collapse look instant. With this, width animates from the inline value
down to 0 via the .sidebar width transition. */
down to 0 via the .sidebar width transition.
display overrides the global .hidden utility, which would otherwise
remove the box before any transition can run. visibility (transitioned
on .sidebar) flips to hidden only once the collapse has finished,
taking the closed sidebar out of the tab order. */
display: flex;
width: 0 !important;
padding: 0 !important;
border: none;
overflow: hidden;
opacity: 0;
visibility: hidden;
pointer-events: none;
}
/* IDs so this also beats the mobile drawer's !important transition. */
@media (prefers-reduced-motion: reduce) {
#sidebar, #icon-rail { transition: none !important; }
}
/* ===== Sidebar User Bar ===== */
.sidebar-user-bar {
@@ -449,10 +460,6 @@ body.bg-pattern-ascii-fireflies {
}
.sidebar.hidden .sidebar-user-bar {
display: none;
}
/* Sticky sidebar header — logo, never scrolls */
.sidebar-header {
display: flex;
@@ -673,6 +680,24 @@ body.bg-pattern-ascii-fireflies {
margin-bottom: calc(-1 * var(--safe-bottom));
padding-bottom: calc(8px + var(--safe-bottom));
}
/* Tuck the rail under the sidebar (which paints above it) and slide it
out as the sidebar collapses, so the combined width eases instead of
jumping by the rail's 48px when the two swap. */
.icon-rail,
.icon-rail.right-side {
margin-inline-end: -48px;
transition: margin-inline-end 0.25s ease, display 0.25s allow-discrete;
}
body.sidebar-collapsed:not(.hamburger-only) .icon-rail,
html.ody-sidebar-mini .icon-rail {
margin-inline-end: 0;
}
@starting-style {
body.sidebar-collapsed:not(.hamburger-only) .icon-rail,
html.ody-sidebar-mini .icon-rail {
margin-inline-end: -48px;
}
}
}
.icon-rail-divider {
width: 24px;
@@ -5116,7 +5141,7 @@ body.bg-pattern-ascii-fireflies {
width: 80% !important;
max-width: 340px;
box-shadow: 4px 0 20px rgba(0,0,0,0.5);
transition: transform 0.25s ease, opacity 0.25s ease !important;
transition: transform 0.25s ease, opacity 0.25s ease, visibility 0.25s !important;
opacity: 1 !important;
overflow: visible !important;
/* Force opaque background — Firefox mobile renders the
@@ -5147,6 +5172,7 @@ body.bg-pattern-ascii-fireflies {
}
html.ody-sidebar-off .sidebar,
html.ody-mobile-startup-sidebar-hidden .sidebar {
width: 80% !important;
transform: translateX(-100%) !important;
pointer-events: none !important;
opacity: 0 !important;
-6
View File
@@ -90,12 +90,6 @@
.lib-tabs,
.gallery-tabs,
.preset-tabs {
/* A flex-item tab strip defaults to min-width:auto, so it grows to its
content width inside a narrow modal and the end tabs get clipped by the
modal's overflow instead of scrolling. min-width:0 lets the strip shrink
to the container so the overflow-x:auto below actually engages. */
min-width: 0;
max-width: 100%;
flex-wrap: nowrap !important;
overflow-x: auto !important;
overflow-y: hidden;
File diff suppressed because it is too large Load Diff
+340
View File
@@ -978,3 +978,343 @@ body.doc-find-active mark.doc-find-mark.current {
color: var(--accent, var(--red));
vertical-align: -2px;
}
/* Colour chips: every pickable colour input renders as a circle, regardless of
the container it sits in (options bar .ge-text-field, Character panel,
gradient stops, export matte, etc.). Forced with !important so parent
input[type="color"] rules can't square them off. */
input.ge-color-picker,
input.ge-color-picker.cp-swatch-input,
.ge-text-field input.ge-color-picker,
.ge-swatch input.ge-color-picker,
.ge-filter-row input.ge-color-picker,
.ge-gradient-color-row input.ge-color-picker {
border-radius: 50% !important;
}
input.ge-color-picker::-webkit-color-swatch {
border: 0 !important;
border-radius: 50% !important;
}
input.ge-color-picker::-moz-color-swatch {
border: 0 !important;
border-radius: 50% !important;
}
/* ---------------------------------------------------------------------------
Editor theme alignment: map the editor's controls onto the app's design
tokens (static/css/00-tokens.css) so the editor matches the rest of the
product. No new colours — only the shared CSS variables.
--------------------------------------------------------------------------- */
/* Checkboxes + radios → the app's circular dot (see 17-research.css). */
body.ge-editor-open input[type="checkbox"],
body.ge-editor-open input[type="radio"] {
-webkit-appearance: none;
appearance: none;
width: 14px;
height: 14px;
margin: 0;
padding: 0;
border: 1.5px solid var(--border);
border-radius: 50%;
background: var(--bg);
cursor: pointer;
position: relative;
flex: 0 0 auto;
vertical-align: middle;
transition: background 0.12s ease, border-color 0.12s ease;
}
body.ge-editor-open input[type="checkbox"]:checked,
body.ge-editor-open input[type="radio"]:checked {
background: var(--fg);
border-color: var(--fg);
}
body.ge-editor-open input[type="checkbox"]:focus-visible,
body.ge-editor-open input[type="radio"]:focus-visible {
outline: 2px solid var(--red);
outline-offset: 1px;
}
/* Selects → the app's select tokens. */
body.ge-editor-open select {
background: var(--select-bg, var(--bg));
color: var(--select-fg, var(--fg));
border: 1px solid var(--border);
border-radius: 6px;
}
body.ge-editor-open select option {
background: var(--select-option-bg, var(--panel));
color: var(--select-option-fg, var(--fg));
}
body.ge-editor-open select option:checked,
body.ge-editor-open select option:hover {
background: var(--select-option-active-bg, var(--panel));
}
body.ge-editor-open select:focus-visible {
outline: 1px solid var(--red);
outline-offset: 1px;
}
/* Text / number inputs → token background, border and focus ring. */
body.ge-editor-open input[type="text"],
body.ge-editor-open input[type="number"],
body.ge-editor-open input[type="search"],
body.ge-editor-open textarea {
background: var(--bg);
color: var(--fg);
border: 1px solid var(--border);
border-radius: 6px;
}
body.ge-editor-open input[type="text"]:focus-visible,
body.ge-editor-open input[type="number"]:focus-visible,
body.ge-editor-open input[type="search"]:focus-visible,
body.ge-editor-open textarea:focus-visible {
outline: 1px solid var(--red);
outline-offset: 1px;
}
/* Range sliders → the app's accent. */
body.ge-editor-open input[type="range"] {
accent-color: var(--accent, var(--red));
}
/* Scrollbars → the app's 8px red-thumb recipe (00-tokens.css). */
body.ge-editor-open * {
scrollbar-width: thin;
scrollbar-color: var(--red) var(--panel);
}
body.ge-editor-open *::-webkit-scrollbar {
width: 8px;
height: 8px;
}
body.ge-editor-open *::-webkit-scrollbar-track {
background: var(--panel);
}
body.ge-editor-open *::-webkit-scrollbar-thumb {
background-color: var(--red);
border-radius: 4px;
border: 2px solid var(--panel);
}
body.ge-editor-open *::-webkit-scrollbar-thumb:hover {
background-color: color-mix(in srgb, var(--red) 80%, white);
}
/* ---------------------------------------------------------------------------
Editor theme alignment (part 2): buttons, segmented toggles, tabs, list
rows, panel headers, badges, focus rings, number fields and colour-picker
chrome mapped onto the app's shared design tokens. Existing tokens only —
no new colours, and no geometry beyond colour / border / radius / focus.
--------------------------------------------------------------------------- */
/* The editor references two secondary / muted variables that the app token
layer never defines; map them onto the real tokens so every
var(--fg-muted) / var(--bg-secondary) editor rule resolves. */
body.ge-editor-open {
--fg-muted: var(--color-muted);
--bg-secondary: var(--panel);
}
/* Buttons → the app's `.cal-btn` recipe (5px radius; the primary button
uses the accent fill with a --bg foreground instead of a hard-coded #fff). */
body.ge-editor-open .ge-btn {
border-radius: 5px;
}
body.ge-editor-open .ge-btn-primary {
background: var(--accent, var(--red));
border-color: var(--accent, var(--red));
color: var(--bg);
}
body.ge-editor-open .ge-btn-primary:hover {
background: var(--accent, var(--red));
opacity: 0.9;
}
body.ge-editor-open .ge-win-close:hover {
background: var(--accent, var(--red));
color: var(--bg);
}
/* Segmented / option toggles, command palette and channel rows → the app's
accent token (--red) instead of the editor's blue #4c8bf5 fallback. */
body.ge-editor-open .ge-opt-mode.active,
body.ge-editor-open .ge-crop-preset.active,
body.ge-editor-open .ge-command-item.active,
body.ge-editor-open .ge-command-item:hover {
background: var(--accent, var(--red));
border-color: var(--accent, var(--red));
color: var(--bg);
}
body.ge-editor-open .ge-channel-row.active,
body.ge-editor-open .ge-dock-tabs-menu-item:hover,
body.ge-editor-open .ge-filter-menu .dropdown-item-compact:focus-visible,
body.ge-editor-open .ge-view-menu .dropdown-item-compact:focus-visible,
body.ge-editor-open .ge-window-menu .dropdown-item-compact:focus-visible,
body.ge-editor-open .ge-help-menu .dropdown-item-compact:focus-visible,
body.ge-editor-open .ge-3d-menu .dropdown-item-compact:focus-visible,
body.ge-editor-open .ge-plugins-menu .dropdown-item-compact:focus-visible {
background: color-mix(in srgb, var(--accent, var(--red)) 22%, transparent);
}
body.ge-editor-open .ge-sam-brush-add.active,
body.ge-editor-open .ge-sam-brush-subtract.active,
body.ge-editor-open .ge-actions-controls .ge-btn.active {
border-color: var(--accent, var(--red));
color: var(--accent, var(--red));
}
/* Tabs → the app tab convention: the active tab's underline is the accent. */
body.ge-editor-open .ge-dock-tab.active {
border-bottom-color: var(--accent, var(--red));
}
/* Colour-picker chrome → the token accent instead of the blue fallback. */
body.ge-editor-open .ge-swatch.active {
outline-color: var(--accent, var(--red));
}
/* Badges / status pills → the app's --bg foreground on an accent fill. */
body.ge-editor-open .ge-tool-clear {
color: var(--bg);
}
/* Panel headers → the app's muted section-title token. */
body.ge-editor-open .ge-panel-title,
body.ge-editor-open .ge-info-label {
color: var(--color-muted);
}
/* Focus rings → the app's 1px --red ring (matching the earlier input/select
block) on the controls that previously fell back to the UA outline. */
body.ge-editor-open .ge-btn:focus-visible,
body.ge-editor-open .ge-tool-btn:focus-visible,
body.ge-editor-open .ge-doc-tab:focus-visible,
body.ge-editor-open .ge-history-row:focus-visible,
body.ge-editor-open .ge-swatch:focus-visible,
body.ge-editor-open .ge-opt-mode:focus-visible,
body.ge-editor-open .ge-stepper button:focus-visible {
outline: 1px solid var(--red);
outline-offset: 1px;
}
/* ---------------------------------------------------------------------------
Editor theme alignment (part 3): the setup / preflight checklist and the
remaining checkbox list-row / badge chrome mapped onto the app's shared
design tokens. Existing tokens only — no new colours, and no geometry beyond
colour / border / radius / focus. Scoped to body.ge-editor-open.
--------------------------------------------------------------------------- */
/* Checklist card + rows → the app's panel / border / muted tokens. */
body.ge-editor-open .ge-preflight-card {
background: var(--panel);
color: var(--fg);
border-color: var(--border);
}
body.ge-editor-open .ge-preflight-head p,
body.ge-editor-open .ge-preflight-hint,
body.ge-editor-open .ge-preflight-detail,
body.ge-editor-open .ge-preflight-remember,
body.ge-editor-open .ge-preflight-close {
color: var(--color-muted);
}
body.ge-editor-open .ge-preflight-close:hover {
background: color-mix(in srgb, var(--fg) 8%, transparent);
color: var(--fg);
}
body.ge-editor-open .ge-preflight-row {
background: color-mix(in srgb, var(--panel) 92%, var(--fg) 4%);
border-color: var(--border);
}
body.ge-editor-open .ge-preflight-row.is-done {
border-color: color-mix(in srgb, var(--green) 45%, var(--border));
}
body.ge-editor-open .ge-preflight-row.is-todo {
border-color: var(--red);
}
body.ge-editor-open .ge-preflight-row.is-optional {
border-color: color-mix(in srgb, var(--accent-warm) 45%, var(--border));
}
/* Row badges → the semantic tokens (done = green, todo = red, optional = warm). */
body.ge-editor-open .ge-preflight-badge {
background: color-mix(in srgb, var(--fg) 10%, transparent);
color: var(--fg);
}
body.ge-editor-open .ge-preflight-row.is-done .ge-preflight-badge {
background: color-mix(in srgb, var(--green) 20%, transparent);
color: var(--green);
}
body.ge-editor-open .ge-preflight-row.is-todo .ge-preflight-badge {
background: color-mix(in srgb, var(--red) 18%, transparent);
color: var(--red);
}
body.ge-editor-open .ge-preflight-row.is-optional .ge-preflight-badge {
background: color-mix(in srgb, var(--accent-warm) 16%, transparent);
color: var(--accent-warm);
}
body.ge-editor-open .ge-preflight-opt {
background: color-mix(in srgb, var(--fg) 8%, transparent);
color: var(--color-muted);
}
/* Checklist actions / footer → token buttons and borders. */
body.ge-editor-open .ge-preflight-act {
background: color-mix(in srgb, var(--fg) 8%, transparent);
border-color: var(--border);
color: var(--fg);
}
body.ge-editor-open .ge-preflight-act:hover {
background: color-mix(in srgb, var(--fg) 16%, transparent);
}
body.ge-editor-open .ge-preflight-foot {
border-top-color: var(--border);
}
body.ge-editor-open .ge-preflight-summary {
color: var(--green);
}
body.ge-editor-open .ge-preflight-start {
background: var(--accent, var(--red));
color: var(--bg);
}
body.ge-editor-open .ge-preflight-start:hover {
background: var(--accent, var(--red));
opacity: 0.9;
}
body.ge-editor-open .ge-setup-btn {
border-color: var(--border);
color: var(--color-muted);
}
body.ge-editor-open .ge-setup-btn:hover {
background: color-mix(in srgb, var(--fg) 10%, transparent);
color: var(--fg);
}
/* The options-bar checkbox overrode the shared dot with a square + a drawn
::after tick; force it back to the app's 14px circular dot, filled with the
highlight (accent) colour when checked (part 1). */
body.ge-editor-open .ge-opt input[type="checkbox"],
body.ge-editor-open .ge-opt input[type="radio"] {
border-radius: 50%;
border-width: 1.5px;
}
body.ge-editor-open .ge-opt input[type="checkbox"]:checked,
body.ge-editor-open .ge-opt input[type="radio"]:checked {
background: var(--accent, var(--red));
border-color: var(--accent, var(--red));
}
body.ge-editor-open .ge-opt input[type="checkbox"]:checked::after {
content: none;
}
/* Remaining list-row / thumbnail chrome → panel + border + muted tokens. */
body.ge-editor-open .ge-history-row-dot {
background: var(--color-muted);
}
body.ge-editor-open .ge-layer-inline-thumb {
background: var(--panel);
border-color: var(--border);
}
body.ge-editor-open .ge-channel-row,
body.ge-editor-open .ge-channel-name {
color: var(--fg);
}
body.ge-editor-open .ge-channel-eye {
color: var(--color-muted);
}