mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-02 21:03:34 +03:00
Resolve duplicate CSS selectors reported by Stylelint (#7212)
Fixes #7189 Consolidates all 29 `no-duplicate-selectors` violations across 18 stylesheets by merging later duplicate rule blocks into the first occurrence. Where duplicates had conflicting values, the cascade-winning (later) value was kept, so computed styles are unchanged. Also: - Adds `frontend/stylelint.config.mjs` with only `no-duplicate-selectors` enabled (Prettier and the theme linter own everything else). - Adds a `frontend:lint:css` task, wired into `task frontend:lint` as a blocking check so regressions can't creep back in. - Lints all first-party CSS (`editor/**/*.css`, so `public/css` and any future non-`src` stylesheets are covered too), excluding only the vendored `cookieconsent.css` and build output via `ignoreFiles`. This surfaced and fixed 5 additional duplicate selectors in `cookieconsentCustomisation.css` that weren't in the original issue report. Note: `portal/views/Sources.css` goes beyond dedup — the whole `.portal-sources__connections*` block is deleted as dead code (unreferenced since the S3 connections redesign in #6965; only `-actions` in it was an actual duplicate). 🤖 Generated with [Claude Code](https://claude.ai/code)
This commit is contained in:
@@ -263,6 +263,16 @@ tasks:
|
||||
- task: lint:eslint
|
||||
- task: lint:dpdm
|
||||
- task: lint:colors
|
||||
- task: lint:css
|
||||
|
||||
lint:css:
|
||||
desc: "Lint stylesheets for duplicate selectors"
|
||||
deps: [install]
|
||||
cmds:
|
||||
# Covers the whole editor tree, including the portal/processor layer and
|
||||
# public/css. Vendored CSS and build output are excluded via ignoreFiles
|
||||
# in stylelint.config.mjs.
|
||||
- npx stylelint "editor/**/*.css"
|
||||
|
||||
lint:colors:
|
||||
desc: "Enforce theme tokens — no hardcoded colours or raw primitives in components"
|
||||
|
||||
@@ -130,21 +130,35 @@
|
||||
opacity: 0 !important; /* Keep invisible but functional */
|
||||
}
|
||||
|
||||
/* Track: flat fill in both themes, no outline ring or border */
|
||||
#cc-main .toggle__icon {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: flex-start !important;
|
||||
background: var(--cc-toggle-off-bg) !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
transition: background-color 150ms ease !important;
|
||||
}
|
||||
|
||||
/* Thumb: small plain circle, vertically centred, no drop shadow */
|
||||
#cc-main .toggle__icon-circle {
|
||||
display: block !important;
|
||||
position: absolute !important;
|
||||
transition: transform 0.25s ease !important;
|
||||
width: 14px !important;
|
||||
height: 14px !important;
|
||||
top: 3px !important;
|
||||
left: 2.5px !important;
|
||||
box-shadow: none !important;
|
||||
transition:
|
||||
transform 150ms ease,
|
||||
background-color 150ms ease !important;
|
||||
}
|
||||
|
||||
/* Mantine switches have no check/cross glyph inside the thumb */
|
||||
#cc-main .toggle__icon-on,
|
||||
#cc-main .toggle__icon-off {
|
||||
display: flex !important;
|
||||
display: none !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
position: absolute !important;
|
||||
@@ -152,15 +166,11 @@
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
/* Ensure toggles are visible in both themes */
|
||||
#cc-main .toggle__icon {
|
||||
background: var(--cc-toggle-off-bg) !important;
|
||||
border: 1px solid var(--cc-toggle-off-bg) !important;
|
||||
}
|
||||
|
||||
/* Checked track visible in both themes, same flat Mantine look */
|
||||
#cc-main .section__toggle:checked ~ .toggle__icon {
|
||||
background: var(--cc-toggle-on-bg) !important;
|
||||
border: 1px solid var(--cc-toggle-on-bg) !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* Ensure toggle text is visible */
|
||||
@@ -226,18 +236,6 @@
|
||||
border-radius: 1000px !important;
|
||||
}
|
||||
|
||||
/* Track: flat fill, no outline ring or border */
|
||||
#cc-main .toggle__icon {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
transition: background-color 150ms ease !important;
|
||||
}
|
||||
|
||||
#cc-main .section__toggle:checked ~ .toggle__icon {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* Always-enabled categories = Mantine disabled switch (must out-prioritise
|
||||
the !important checked-track rule above) */
|
||||
#cc-main .section__toggle:checked:disabled ~ .toggle__icon {
|
||||
@@ -250,25 +248,7 @@
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
/* Thumb: small plain circle, vertically centred, no drop shadow */
|
||||
#cc-main .toggle__icon-circle {
|
||||
width: 14px !important;
|
||||
height: 14px !important;
|
||||
top: 3px !important;
|
||||
left: 2.5px !important;
|
||||
box-shadow: none !important;
|
||||
transition:
|
||||
transform 150ms ease,
|
||||
background-color 150ms ease !important;
|
||||
}
|
||||
|
||||
/* Checked thumb travel: 38 − 14 − 2.5 = 21.5px end position */
|
||||
#cc-main .section__toggle:checked ~ .toggle__icon .toggle__icon-circle {
|
||||
transform: translateX(19px) !important;
|
||||
}
|
||||
|
||||
/* Mantine switches have no check/cross glyph inside the thumb */
|
||||
#cc-main .toggle__icon-on,
|
||||
#cc-main .toggle__icon-off {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -320,11 +320,6 @@
|
||||
color: var(--c-text-muted); /* subtitle text */
|
||||
}
|
||||
|
||||
/* Light mode selected header stroke override */
|
||||
:global([data-mantine-color-scheme="light"]) .card[data-selected="true"] {
|
||||
outline-color: var(--c-primary);
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Add File Card Styles
|
||||
========================= */
|
||||
|
||||
@@ -156,6 +156,11 @@
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
min-height: 3rem;
|
||||
/* Safety net - the content should always fit thanks to the shrink rules on
|
||||
`.files-page-toolbar-actions` below, but if a future addition ever breaks
|
||||
that, this stops the action group bleeding into sibling areas (notably the
|
||||
details panel on the right). */
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.files-page-toolbar-info {
|
||||
@@ -210,13 +215,6 @@
|
||||
.files-page-toolbar-actions .mantine-SegmentedControl-root {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* Clip overflow on the toolbar itself as a safety net - the content
|
||||
should always fit thanks to the rules above, but if a future addition
|
||||
ever breaks that, this prevents the action group from bleeding into
|
||||
sibling areas (notably the details panel on the right). */
|
||||
.files-page-toolbar {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.files-page-toolbar-divider {
|
||||
width: 1px;
|
||||
@@ -1319,9 +1317,6 @@
|
||||
gap: 0.3rem;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.files-page-search {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
.files-page-breadcrumbs {
|
||||
font-size: 0.85rem;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
@@ -447,19 +447,14 @@
|
||||
}
|
||||
|
||||
.file-sidebar-section-header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding: 12px 14px 6px 14px;
|
||||
padding: 10px 14px 6px 14px;
|
||||
margin: 4px 0 0 0;
|
||||
}
|
||||
|
||||
.file-sidebar-section-header {
|
||||
position: relative;
|
||||
border-top: 1px solid var(--c-border-subtle);
|
||||
padding-top: 10px;
|
||||
margin-top: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,12 +56,6 @@
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* Always reserve space for action buttons so file name truncation dots (...)
|
||||
never bleed under action buttons or overlap their outline/focus box. */
|
||||
.file-sidebar-file-info {
|
||||
padding-right: 3.75rem;
|
||||
}
|
||||
|
||||
.file-sidebar-file-item:hover:not(.selected) {
|
||||
background-color: color-mix(in srgb, var(--c-primary) 6%, transparent);
|
||||
}
|
||||
@@ -173,6 +167,9 @@
|
||||
.file-sidebar-file-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
/* Always reserve space for action buttons so file name truncation dots (...)
|
||||
never bleed under action buttons or overlap their outline/focus box. */
|
||||
padding-right: 3.75rem;
|
||||
}
|
||||
|
||||
.file-sidebar-file-name {
|
||||
|
||||
@@ -9,113 +9,6 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* CSS Custom Properties for Fullscreen Mode */
|
||||
.tool-panel__fullscreen-surface-inner {
|
||||
--fullscreen-bg-surface-1: color-mix(
|
||||
in srgb,
|
||||
var(--c-bg-raised) 96%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-bg-surface-2: color-mix(in srgb, var(--c-bg) 90%, transparent);
|
||||
--fullscreen-bg-header: var(--c-bg-raised);
|
||||
--fullscreen-bg-controls-1: var(--c-bg-raised);
|
||||
--fullscreen-bg-controls-2: color-mix(
|
||||
in srgb,
|
||||
var(--c-bg-raised) 95%,
|
||||
var(--c-bg)
|
||||
);
|
||||
--fullscreen-bg-body-1: color-mix(in srgb, var(--c-bg) 86%, transparent);
|
||||
--fullscreen-bg-body-2: color-mix(
|
||||
in srgb,
|
||||
var(--c-bg-raised) 78%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-bg-group: color-mix(
|
||||
in srgb,
|
||||
var(--c-bg-raised) 82%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-bg-item: color-mix(in srgb, var(--c-bg-raised) 88%, transparent);
|
||||
--fullscreen-bg-list-item: color-mix(
|
||||
in srgb,
|
||||
var(--c-bg-raised) 86%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-bg-icon-detailed: color-mix(
|
||||
in srgb,
|
||||
var(--c-surface-sunken) 75%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-bg-icon-compact: color-mix(
|
||||
in srgb,
|
||||
var(--c-surface-sunken) 70%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-border-subtle-75: color-mix(
|
||||
in srgb,
|
||||
var(--c-border-subtle) 75%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-border-subtle-70: color-mix(
|
||||
in srgb,
|
||||
var(--c-border-subtle) 70%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-border-subtle-65: color-mix(
|
||||
in srgb,
|
||||
var(--c-border-subtle) 65%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-border-favorites: color-mix(
|
||||
in srgb,
|
||||
var(--special-color-favorites) 25%,
|
||||
var(--c-border-subtle)
|
||||
);
|
||||
--fullscreen-border-recommended: color-mix(
|
||||
in srgb,
|
||||
var(--special-color-recommended) 25%,
|
||||
var(--c-border-subtle)
|
||||
);
|
||||
--fullscreen-shadow-primary: color-mix(
|
||||
in srgb,
|
||||
var(--shadow-color, color-mix(in srgb, black 55%, transparent)) 25%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-shadow-secondary: color-mix(
|
||||
in srgb,
|
||||
var(--shadow-color, color-mix(in srgb, black 35%, transparent)) 30%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-shadow-group: color-mix(
|
||||
in srgb,
|
||||
var(--shadow-color, color-mix(in srgb, black 45%, transparent)) 18%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-accent-hover: color-mix(
|
||||
in srgb,
|
||||
var(--c-text) 20%,
|
||||
var(--c-border-subtle)
|
||||
);
|
||||
--fullscreen-accent-selected: color-mix(
|
||||
in srgb,
|
||||
var(--c-text) 30%,
|
||||
var(--c-border-subtle)
|
||||
);
|
||||
--fullscreen-accent-ring: color-mix(in srgb, var(--c-text) 15%, transparent);
|
||||
--fullscreen-accent-list-bg: color-mix(
|
||||
in srgb,
|
||||
var(--c-text) 8%,
|
||||
var(--c-bg-raised)
|
||||
);
|
||||
--fullscreen-accent-list-border: color-mix(
|
||||
in srgb,
|
||||
var(--c-text) 20%,
|
||||
var(--c-border-subtle)
|
||||
);
|
||||
--fullscreen-text-icon: var(--c-text);
|
||||
--fullscreen-text-icon-compact: var(--c-text);
|
||||
}
|
||||
|
||||
.tool-panel {
|
||||
position: relative;
|
||||
transition:
|
||||
@@ -373,6 +266,110 @@
|
||||
--fullscreen-anim-out-duration: var(--fullscreen-anim-duration-out);
|
||||
animation: tool-panel-fullscreen-slide-in var(--fullscreen-anim-in-duration)
|
||||
ease forwards;
|
||||
|
||||
--fullscreen-bg-surface-1: color-mix(
|
||||
in srgb,
|
||||
var(--c-bg-raised) 96%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-bg-surface-2: color-mix(in srgb, var(--c-bg) 90%, transparent);
|
||||
--fullscreen-bg-header: var(--c-bg-raised);
|
||||
--fullscreen-bg-controls-1: var(--c-bg-raised);
|
||||
--fullscreen-bg-controls-2: color-mix(
|
||||
in srgb,
|
||||
var(--c-bg-raised) 95%,
|
||||
var(--c-bg)
|
||||
);
|
||||
--fullscreen-bg-body-1: color-mix(in srgb, var(--c-bg) 86%, transparent);
|
||||
--fullscreen-bg-body-2: color-mix(
|
||||
in srgb,
|
||||
var(--c-bg-raised) 78%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-bg-group: color-mix(
|
||||
in srgb,
|
||||
var(--c-bg-raised) 82%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-bg-item: color-mix(in srgb, var(--c-bg-raised) 88%, transparent);
|
||||
--fullscreen-bg-list-item: color-mix(
|
||||
in srgb,
|
||||
var(--c-bg-raised) 86%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-bg-icon-detailed: color-mix(
|
||||
in srgb,
|
||||
var(--c-surface-sunken) 75%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-bg-icon-compact: color-mix(
|
||||
in srgb,
|
||||
var(--c-surface-sunken) 70%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-border-subtle-75: color-mix(
|
||||
in srgb,
|
||||
var(--c-border-subtle) 75%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-border-subtle-70: color-mix(
|
||||
in srgb,
|
||||
var(--c-border-subtle) 70%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-border-subtle-65: color-mix(
|
||||
in srgb,
|
||||
var(--c-border-subtle) 65%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-border-favorites: color-mix(
|
||||
in srgb,
|
||||
var(--special-color-favorites) 25%,
|
||||
var(--c-border-subtle)
|
||||
);
|
||||
--fullscreen-border-recommended: color-mix(
|
||||
in srgb,
|
||||
var(--special-color-recommended) 25%,
|
||||
var(--c-border-subtle)
|
||||
);
|
||||
--fullscreen-shadow-primary: color-mix(
|
||||
in srgb,
|
||||
var(--shadow-color, color-mix(in srgb, black 55%, transparent)) 25%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-shadow-secondary: color-mix(
|
||||
in srgb,
|
||||
var(--shadow-color, color-mix(in srgb, black 35%, transparent)) 30%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-shadow-group: color-mix(
|
||||
in srgb,
|
||||
var(--shadow-color, color-mix(in srgb, black 45%, transparent)) 18%,
|
||||
transparent
|
||||
);
|
||||
--fullscreen-accent-hover: color-mix(
|
||||
in srgb,
|
||||
var(--c-text) 20%,
|
||||
var(--c-border-subtle)
|
||||
);
|
||||
--fullscreen-accent-selected: color-mix(
|
||||
in srgb,
|
||||
var(--c-text) 30%,
|
||||
var(--c-border-subtle)
|
||||
);
|
||||
--fullscreen-accent-ring: color-mix(in srgb, var(--c-text) 15%, transparent);
|
||||
--fullscreen-accent-list-bg: color-mix(
|
||||
in srgb,
|
||||
var(--c-text) 8%,
|
||||
var(--c-bg-raised)
|
||||
);
|
||||
--fullscreen-accent-list-border: color-mix(
|
||||
in srgb,
|
||||
var(--c-text) 20%,
|
||||
var(--c-border-subtle)
|
||||
);
|
||||
--fullscreen-text-icon: var(--c-text);
|
||||
--fullscreen-text-icon-compact: var(--c-text);
|
||||
}
|
||||
|
||||
.tool-panel__fullscreen-surface-inner--exiting {
|
||||
@@ -428,8 +425,15 @@
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
/* Used by both FullscreenToolSurface and DetailedToolItem. */
|
||||
.tool-panel__fullscreen-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
text-align: left;
|
||||
/* Prevent long content (names, descriptions, shortcuts) from overflowing */
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
background: transparent;
|
||||
}
|
||||
@@ -639,16 +643,6 @@
|
||||
z-index: var(--z-fullscreen-icon-svg);
|
||||
}
|
||||
|
||||
.tool-panel__fullscreen-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
text-align: left;
|
||||
/* Prevent long content (names, descriptions, shortcuts) from overflowing */
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.tool-panel__fullscreen-name {
|
||||
color: var(--c-text);
|
||||
font-size: 13px !important;
|
||||
|
||||
+1
-5
@@ -52,6 +52,7 @@
|
||||
user-select: none;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* Position numbers at edges within each tile with extra top/bottom spacing */
|
||||
@@ -98,11 +99,6 @@
|
||||
padding-bottom: 4px;
|
||||
} /* bottom-right */
|
||||
|
||||
/* Base padding for all tiles */
|
||||
.gridTile {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.gridTileSelected,
|
||||
.gridTileHovered {
|
||||
border: 2px solid var(--c-primary);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.compare-dropdown-scrollwrap {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.compare-dropdown-sticky {
|
||||
@@ -138,20 +139,11 @@
|
||||
border-radius: 8px !important; /* match dropdown container radius */
|
||||
}
|
||||
|
||||
/* Ensure options text uses full width inside wider dropdown */
|
||||
.compare-dropdown-option__text {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Remove default padding inside Mantine options list so sticky header touches edges */
|
||||
.compare-changes-dropdown .mantine-Combobox-options {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.compare-dropdown-scrollwrap {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Ensure search field sits flush and does not overflow */
|
||||
.compare-changes-dropdown .mantine-Combobox-search {
|
||||
box-sizing: border-box;
|
||||
@@ -435,6 +427,7 @@
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
line-clamp: 3;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Non-sticky in-flow group headers; sticky handled by floating header */
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
color: var(--c-text) !important;
|
||||
}
|
||||
|
||||
.field-value {
|
||||
border: 1px solid rgb(var(--pdf-light-box-border));
|
||||
border: 1px solid var(--c-border) !important;
|
||||
border-radius: 8px;
|
||||
padding: 0.65rem 0.75rem;
|
||||
background-color: rgb(var(--pdf-light-box-bg));
|
||||
background-color: var(--c-surface-raised) !important;
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
@@ -65,16 +66,6 @@
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Keep field blocks stable colors across themes */
|
||||
.field-value {
|
||||
border: 1px solid var(--c-border) !important;
|
||||
background-color: var(--c-surface-raised) !important;
|
||||
}
|
||||
|
||||
.field-container {
|
||||
color: var(--c-text) !important;
|
||||
}
|
||||
|
||||
/* Thumbnail preview styles */
|
||||
.thumbnail-container {
|
||||
width: 140px;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
animation: attachment-fade-in 0.2s ease;
|
||||
}
|
||||
|
||||
/* Attachment Items */
|
||||
@@ -91,10 +92,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.attachment-list {
|
||||
animation: attachment-fade-in 0.2s ease;
|
||||
}
|
||||
|
||||
/* Accessibility & Reduced Motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.attachment-item,
|
||||
|
||||
@@ -108,6 +108,7 @@
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
margin-top: 0.25rem;
|
||||
animation: bookmark-fade-in 0.2s ease;
|
||||
}
|
||||
|
||||
/* Smooth expand/collapse animation */
|
||||
@@ -122,10 +123,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.bookmark-item__children {
|
||||
animation: bookmark-fade-in 0.2s ease;
|
||||
}
|
||||
|
||||
/* Accessibility & Reduced Motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.bookmark-item,
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
color-mix(in srgb, var(--c-border-subtle) 60%, transparent);
|
||||
margin-left: 0.875rem;
|
||||
padding-left: 0.25rem;
|
||||
animation: layer-fade-in 0.15s ease;
|
||||
}
|
||||
|
||||
/* Footer with Apply button */
|
||||
@@ -133,10 +134,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.layer-item__children {
|
||||
animation: layer-fade-in 0.15s ease;
|
||||
}
|
||||
|
||||
/* Accessibility & Reduced Motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.layer-item,
|
||||
|
||||
@@ -49,11 +49,9 @@
|
||||
var(--p-green-500) 30%,
|
||||
transparent
|
||||
); /* Green border for active badge */
|
||||
}
|
||||
|
||||
/* CSS variables for Tailwind + Mantine integration */
|
||||
/* CSS variables for Tailwind + Mantine integration */
|
||||
|
||||
:root {
|
||||
/* Global animation durations */
|
||||
--fullscreen-anim-duration-in: 0.28s;
|
||||
--fullscreen-anim-duration-out: 0.22s;
|
||||
@@ -284,12 +282,25 @@
|
||||
--dropdown-panel-bg: var(--mantine-color-white);
|
||||
--dropdown-panel-border: var(--mantine-color-gray-4);
|
||||
--dropdown-group-label: var(--mantine-color-gray-6);
|
||||
}
|
||||
|
||||
/* Onboarding (light mode) */
|
||||
:root {
|
||||
/* Onboarding (light mode) */
|
||||
--onboarding-step-active: var(--p-gray-800);
|
||||
--onboarding-step-inactive: var(--p-gray-300);
|
||||
|
||||
/* PDF Link Overlay (viewer) */
|
||||
--link-hover-bg: color-mix(in srgb, var(--p-blue-500) 10%, transparent);
|
||||
--link-hover-border: color-mix(in srgb, var(--p-blue-500) 32%, transparent);
|
||||
--link-hover-shadow:
|
||||
inset 0 0 0 1px rgba(255, 255, 255, 0.35),
|
||||
0 1px 4px color-mix(in srgb, var(--p-azure-500) 12%, transparent);
|
||||
--link-focus-ring: color-mix(in srgb, var(--p-blue-500) 25%, transparent);
|
||||
--link-toolbar-bg: color-mix(in srgb, var(--p-blue-700) 88%, transparent);
|
||||
--link-toolbar-border: rgba(255, 255, 255, 0.1);
|
||||
--link-toolbar-shadow:
|
||||
0 12px 40px rgba(0, 0, 0, 0.2), 0 4px 12px rgba(0, 0, 0, 0.16),
|
||||
0 0 0 0.5px rgba(255, 255, 255, 0.05);
|
||||
|
||||
--shadow-color: color-mix(in srgb, var(--p-blue-700) 55%, transparent);
|
||||
}
|
||||
|
||||
[data-mantine-color-scheme="dark"] {
|
||||
@@ -484,6 +495,19 @@
|
||||
--dropdown-panel-bg: var(--mantine-color-dark-7);
|
||||
--dropdown-panel-border: var(--mantine-color-dark-4);
|
||||
--dropdown-group-label: var(--mantine-color-dark-2);
|
||||
|
||||
/* PDF Link Overlay (viewer) */
|
||||
--link-hover-bg: color-mix(in srgb, var(--p-blue-500) 14%, transparent);
|
||||
--link-hover-border: color-mix(in srgb, var(--p-blue-500) 38%, transparent);
|
||||
--link-hover-shadow:
|
||||
inset 0 0 0 1px rgba(255, 255, 255, 0.1),
|
||||
0 1px 4px color-mix(in srgb, var(--p-c-4f8ef5) 18%, transparent);
|
||||
--link-focus-ring: color-mix(in srgb, var(--p-blue-500) 30%, transparent);
|
||||
--link-toolbar-bg: color-mix(in srgb, var(--p-blue-700) 94%, transparent);
|
||||
--link-toolbar-border: rgba(255, 255, 255, 0.07);
|
||||
--link-toolbar-shadow:
|
||||
0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.35),
|
||||
0 0 0 0.5px rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
/* Dropzone drop state styling */
|
||||
@@ -581,34 +605,6 @@
|
||||
border-color 0.2s ease;
|
||||
}
|
||||
/* ── PDF Link Overlay (viewer) ── */
|
||||
:root {
|
||||
--link-hover-bg: color-mix(in srgb, var(--p-blue-500) 10%, transparent);
|
||||
--link-hover-border: color-mix(in srgb, var(--p-blue-500) 32%, transparent);
|
||||
--link-hover-shadow:
|
||||
inset 0 0 0 1px rgba(255, 255, 255, 0.35),
|
||||
0 1px 4px color-mix(in srgb, var(--p-azure-500) 12%, transparent);
|
||||
--link-focus-ring: color-mix(in srgb, var(--p-blue-500) 25%, transparent);
|
||||
--link-toolbar-bg: color-mix(in srgb, var(--p-blue-700) 88%, transparent);
|
||||
--link-toolbar-border: rgba(255, 255, 255, 0.1);
|
||||
--link-toolbar-shadow:
|
||||
0 12px 40px rgba(0, 0, 0, 0.2), 0 4px 12px rgba(0, 0, 0, 0.16),
|
||||
0 0 0 0.5px rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
[data-mantine-color-scheme="dark"] {
|
||||
--link-hover-bg: color-mix(in srgb, var(--p-blue-500) 14%, transparent);
|
||||
--link-hover-border: color-mix(in srgb, var(--p-blue-500) 38%, transparent);
|
||||
--link-hover-shadow:
|
||||
inset 0 0 0 1px rgba(255, 255, 255, 0.1),
|
||||
0 1px 4px color-mix(in srgb, var(--p-c-4f8ef5) 18%, transparent);
|
||||
--link-focus-ring: color-mix(in srgb, var(--p-blue-500) 30%, transparent);
|
||||
--link-toolbar-bg: color-mix(in srgb, var(--p-blue-700) 94%, transparent);
|
||||
--link-toolbar-border: rgba(255, 255, 255, 0.07);
|
||||
--link-toolbar-shadow:
|
||||
0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.35),
|
||||
0 0 0 0.5px rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
/* ── Link hit-area ── */
|
||||
.pdf-link-overlay {
|
||||
position: absolute;
|
||||
@@ -739,28 +735,13 @@
|
||||
|
||||
.pdf-link-toolbar-btn:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.pdf-link-toolbar-btn--delete:hover {
|
||||
background: color-mix(in srgb, var(--p-red-500) 15%, transparent);
|
||||
color: var(--p-art-red-light);
|
||||
}
|
||||
|
||||
.pdf-link-toolbar-sep {
|
||||
width: 1px;
|
||||
height: 12px;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
margin: 0 4px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.pdf-link-toolbar-btn:last-child {
|
||||
border-radius: 0 9px 9px 0;
|
||||
}
|
||||
|
||||
.pdf-link-toolbar-btn:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.pdf-link-toolbar-btn--delete {
|
||||
padding: 0 10px;
|
||||
}
|
||||
@@ -770,25 +751,22 @@
|
||||
color: var(--p-red-400);
|
||||
}
|
||||
|
||||
.pdf-link-toolbar-btn--go:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.pdf-link-toolbar-btn--go {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.pdf-link-toolbar-btn--go:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.pdf-link-toolbar-sep {
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
margin: 0 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--shadow-color: color-mix(in srgb, var(--p-blue-700) 55%, transparent);
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
--shadow-color: rgba(0, 0, 0, 0.88);
|
||||
}
|
||||
|
||||
@@ -153,6 +153,27 @@
|
||||
var(--p-red-500) 50%,
|
||||
var(--p-red-600) 100%
|
||||
);
|
||||
|
||||
/* Code palette — theme-aware: a light GitHub-style box in light mode, the
|
||||
dark terminal palette in dark mode. (CodeBlock renders plain text, so only
|
||||
the base colours are load-bearing; the syntax slots are kept for future
|
||||
Shiki. */
|
||||
--code-bg: var(--p-c-f6f8fa);
|
||||
--code-bg-alt: var(--p-c-eef1f4);
|
||||
--code-bg-header: var(--p-c-eaeef2);
|
||||
--code-text: var(--p-c-1f2328);
|
||||
--code-dim: var(--p-c-656d76);
|
||||
--code-muted: var(--p-c-8c959f);
|
||||
--code-keyword: var(--p-c-cf222e);
|
||||
--code-string: var(--p-code-string);
|
||||
--code-number: var(--p-c-0550ae);
|
||||
--code-fn: var(--p-c-8250df);
|
||||
--code-type: var(--p-code-type);
|
||||
--code-property: var(--p-c-0550ae);
|
||||
--code-comment: var(--p-c-6e7781);
|
||||
--code-border: var(--p-c-d0d7de);
|
||||
/* Window-chrome traffic-light dots in the code-block header. */
|
||||
--code-dot: var(--p-c-d0d7de);
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
@@ -224,31 +245,8 @@
|
||||
var(--p-blue-600) 50%,
|
||||
var(--p-blue-700) 100%
|
||||
);
|
||||
}
|
||||
|
||||
/* Code palette — theme-aware: a light GitHub-style box in light mode, the dark
|
||||
terminal palette in dark mode. (CodeBlock renders plain text, so only the
|
||||
base colours are load-bearing; the syntax slots are kept for future Shiki. */
|
||||
:root,
|
||||
[data-theme="light"] {
|
||||
--code-bg: var(--p-c-f6f8fa);
|
||||
--code-bg-alt: var(--p-c-eef1f4);
|
||||
--code-bg-header: var(--p-c-eaeef2);
|
||||
--code-text: var(--p-c-1f2328);
|
||||
--code-dim: var(--p-c-656d76);
|
||||
--code-muted: var(--p-c-8c959f);
|
||||
--code-keyword: var(--p-c-cf222e);
|
||||
--code-string: var(--p-code-string);
|
||||
--code-number: var(--p-c-0550ae);
|
||||
--code-fn: var(--p-c-8250df);
|
||||
--code-type: var(--p-code-type);
|
||||
--code-property: var(--p-c-0550ae);
|
||||
--code-comment: var(--p-c-6e7781);
|
||||
--code-border: var(--p-c-d0d7de);
|
||||
/* Window-chrome traffic-light dots in the code-block header. */
|
||||
--code-dot: var(--p-c-d0d7de);
|
||||
}
|
||||
[data-theme="dark"] {
|
||||
/* Code palette */
|
||||
--code-bg: var(--p-c-0f172a);
|
||||
--code-bg-alt: var(--p-c-1e293b);
|
||||
--code-bg-header: var(--p-c-1a2332);
|
||||
|
||||
@@ -61,18 +61,16 @@
|
||||
.sui-check--mixed .sui-check__tick {
|
||||
opacity: 0;
|
||||
}
|
||||
.sui-check--mixed .sui-check__dash {
|
||||
position: absolute;
|
||||
width: 0.5rem;
|
||||
height: 2px;
|
||||
background: var(--color-text-on-accent);
|
||||
border-radius: 1px;
|
||||
}
|
||||
.sui-check__dash {
|
||||
display: none;
|
||||
}
|
||||
.sui-check--mixed .sui-check__dash {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 0.5rem;
|
||||
height: 2px;
|
||||
background: var(--color-text-on-accent);
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.sui-check__icon {
|
||||
|
||||
@@ -1276,10 +1276,12 @@
|
||||
flex-direction: column;
|
||||
gap: 1.25rem;
|
||||
}
|
||||
/* Shared by the calculator and payment steps, kept compact so the payment step
|
||||
fits without scrolling. */
|
||||
.portal-billing__bundle-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
gap: 0.625rem;
|
||||
}
|
||||
.portal-billing__bundle-field-label {
|
||||
font-size: 0.8125rem;
|
||||
@@ -1460,12 +1462,6 @@
|
||||
padding-top: 0.75rem;
|
||||
border-top: 1px solid var(--c-border-subtle);
|
||||
}
|
||||
/* Recipient fields on the payment step, kept compact so the step fits without scrolling. */
|
||||
.portal-billing__bundle-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.625rem;
|
||||
}
|
||||
/* Company name + PO number share a row. */
|
||||
.portal-billing__bundle-field-row {
|
||||
display: flex;
|
||||
|
||||
@@ -560,70 +560,6 @@
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
.portal-sources__connections {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.portal-sources__connections-title {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
color: var(--c-text-muted);
|
||||
margin: 0 0 0.5rem;
|
||||
}
|
||||
|
||||
.portal-sources__connections-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.portal-sources__connections-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.375rem 0;
|
||||
border-bottom: 1px solid var(--color-border-2);
|
||||
}
|
||||
|
||||
.portal-sources__connections-name {
|
||||
font-weight: 500;
|
||||
color: var(--c-text);
|
||||
}
|
||||
|
||||
.portal-sources__connections-bucket {
|
||||
color: var(--c-text-subtle);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.portal-sources__connections-actions {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.portal-sources__connections-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.portal-sources__connections-sub {
|
||||
color: var(--c-text-subtle);
|
||||
font-size: 0.875rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.portal-sources__connections-actions {
|
||||
display: inline-flex;
|
||||
gap: 0.25rem;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* ---- Integration picker ---------------------------------------------------------------------
|
||||
A searchable grid of what we can connect to. Sized so a full category is visible without
|
||||
scrolling on a laptop, and so the search box is the first thing focus lands on. */
|
||||
|
||||
@@ -766,12 +766,6 @@
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.oauth-container-fullwidth {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.oauth-button-fullwidth {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
Generated
+913
-16
File diff suppressed because it is too large
Load Diff
@@ -154,6 +154,7 @@
|
||||
"puppeteer": "^24.25.0",
|
||||
"rollup-plugin-visualizer": "^7.0.1",
|
||||
"storybook": "^9.1.20",
|
||||
"stylelint": "^17.14.1",
|
||||
"tsx": "^4.22.4",
|
||||
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
||||
"typescript-eslint": "^8.61.1",
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Deliberately minimal: Prettier owns formatting and `task frontend:lint:colors`
|
||||
// owns the theme tokens, so this only carries rules that catch real bugs.
|
||||
export default {
|
||||
ignoreFiles: [
|
||||
"**/dist/**",
|
||||
"**/src-tauri/**",
|
||||
// Vendored third-party CSS (its first-party customisation file IS linted).
|
||||
"**/editor/public/css/cookieconsent.css",
|
||||
],
|
||||
rules: {
|
||||
"no-duplicate-selectors": true,
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user