diff --git a/.taskfiles/frontend.yml b/.taskfiles/frontend.yml index 6a3e394f6d..e737f897f2 100644 --- a/.taskfiles/frontend.yml +++ b/.taskfiles/frontend.yml @@ -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" diff --git a/frontend/editor/public/css/cookieconsentCustomisation.css b/frontend/editor/public/css/cookieconsentCustomisation.css index 25ec0fd527..78fd3d13d4 100644 --- a/frontend/editor/public/css/cookieconsentCustomisation.css +++ b/frontend/editor/public/css/cookieconsentCustomisation.css @@ -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; -} diff --git a/frontend/editor/src/core/components/fileEditor/FileEditor.module.css b/frontend/editor/src/core/components/fileEditor/FileEditor.module.css index aa89d250e1..c5770f1ea7 100644 --- a/frontend/editor/src/core/components/fileEditor/FileEditor.module.css +++ b/frontend/editor/src/core/components/fileEditor/FileEditor.module.css @@ -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 ========================= */ diff --git a/frontend/editor/src/core/components/filesPage/FilesPage.css b/frontend/editor/src/core/components/filesPage/FilesPage.css index dfdb35dcb7..9de4a276aa 100644 --- a/frontend/editor/src/core/components/filesPage/FilesPage.css +++ b/frontend/editor/src/core/components/filesPage/FilesPage.css @@ -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; diff --git a/frontend/editor/src/core/components/shared/FileSidebar.css b/frontend/editor/src/core/components/shared/FileSidebar.css index 5832609680..7dce3d32b9 100644 --- a/frontend/editor/src/core/components/shared/FileSidebar.css +++ b/frontend/editor/src/core/components/shared/FileSidebar.css @@ -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; } diff --git a/frontend/editor/src/core/components/shared/FileSidebarFileItem.css b/frontend/editor/src/core/components/shared/FileSidebarFileItem.css index 4d742f7be6..d43385ece0 100644 --- a/frontend/editor/src/core/components/shared/FileSidebarFileItem.css +++ b/frontend/editor/src/core/components/shared/FileSidebarFileItem.css @@ -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 { diff --git a/frontend/editor/src/core/components/tools/ToolPanel.css b/frontend/editor/src/core/components/tools/ToolPanel.css index 8a2d17f3fa..5ba31e5b86 100644 --- a/frontend/editor/src/core/components/tools/ToolPanel.css +++ b/frontend/editor/src/core/components/tools/ToolPanel.css @@ -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; diff --git a/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.module.css b/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.module.css index d2ae85a88b..34760f83f2 100644 --- a/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.module.css +++ b/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.module.css @@ -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); diff --git a/frontend/editor/src/core/components/tools/compare/compareView.css b/frontend/editor/src/core/components/tools/compare/compareView.css index aaa703fcc1..c33abfc0ca 100644 --- a/frontend/editor/src/core/components/tools/compare/compareView.css +++ b/frontend/editor/src/core/components/tools/compare/compareView.css @@ -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 */ diff --git a/frontend/editor/src/core/components/tools/validateSignature/reportView/styles.css b/frontend/editor/src/core/components/tools/validateSignature/reportView/styles.css index b4c9e1c815..e6cb96be3b 100644 --- a/frontend/editor/src/core/components/tools/validateSignature/reportView/styles.css +++ b/frontend/editor/src/core/components/tools/validateSignature/reportView/styles.css @@ -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; diff --git a/frontend/editor/src/core/components/viewer/AttachmentSidebar.css b/frontend/editor/src/core/components/viewer/AttachmentSidebar.css index addaca8979..1afd184bc6 100644 --- a/frontend/editor/src/core/components/viewer/AttachmentSidebar.css +++ b/frontend/editor/src/core/components/viewer/AttachmentSidebar.css @@ -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, diff --git a/frontend/editor/src/core/components/viewer/BookmarkSidebar.css b/frontend/editor/src/core/components/viewer/BookmarkSidebar.css index 5d8beab4e0..8ec9b1d1db 100644 --- a/frontend/editor/src/core/components/viewer/BookmarkSidebar.css +++ b/frontend/editor/src/core/components/viewer/BookmarkSidebar.css @@ -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, diff --git a/frontend/editor/src/core/components/viewer/LayerSidebar.css b/frontend/editor/src/core/components/viewer/LayerSidebar.css index 305853ec9f..3b4394d3ad 100644 --- a/frontend/editor/src/core/components/viewer/LayerSidebar.css +++ b/frontend/editor/src/core/components/viewer/LayerSidebar.css @@ -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, diff --git a/frontend/editor/src/core/styles/theme.css b/frontend/editor/src/core/styles/theme.css index c8a1663b4c..de6c18614e 100644 --- a/frontend/editor/src/core/styles/theme.css +++ b/frontend/editor/src/core/styles/theme.css @@ -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); } diff --git a/frontend/editor/src/core/tokens/tokens.css b/frontend/editor/src/core/tokens/tokens.css index 6f4a5f5204..c36fae35fc 100644 --- a/frontend/editor/src/core/tokens/tokens.css +++ b/frontend/editor/src/core/tokens/tokens.css @@ -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); diff --git a/frontend/editor/src/core/ui/Checkbox.css b/frontend/editor/src/core/ui/Checkbox.css index f20358f1aa..44082d51d9 100644 --- a/frontend/editor/src/core/ui/Checkbox.css +++ b/frontend/editor/src/core/ui/Checkbox.css @@ -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 { diff --git a/frontend/editor/src/portal/components/billing/billing.css b/frontend/editor/src/portal/components/billing/billing.css index cfcbf50697..2f39fa0506 100644 --- a/frontend/editor/src/portal/components/billing/billing.css +++ b/frontend/editor/src/portal/components/billing/billing.css @@ -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; diff --git a/frontend/editor/src/portal/views/Sources.css b/frontend/editor/src/portal/views/Sources.css index 5ca4064e65..132c137c89 100644 --- a/frontend/editor/src/portal/views/Sources.css +++ b/frontend/editor/src/portal/views/Sources.css @@ -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. */ diff --git a/frontend/editor/src/proprietary/auth/ui/auth.css b/frontend/editor/src/proprietary/auth/ui/auth.css index e4337af2d6..9bc175efdd 100644 --- a/frontend/editor/src/proprietary/auth/ui/auth.css +++ b/frontend/editor/src/proprietary/auth/ui/auth.css @@ -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; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 86c998e997..1838e5637d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -132,6 +132,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", @@ -546,6 +547,67 @@ "node": ">=18" } }, + "node_modules/@cacheable/memory": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz", + "integrity": "sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.5.0", + "@keyv/bigmap": "^1.3.1", + "hookified": "^1.15.1", + "keyv": "^5.6.0" + } + }, + "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz", + "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.4.0", + "hookified": "^1.15.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "keyv": "^5.6.0" + } + }, + "node_modules/@cacheable/memory/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/@cacheable/utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz", + "integrity": "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.5.1", + "keyv": "^5.6.0" + } + }, + "node_modules/@cacheable/utils/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, "node_modules/@cantoo/pdf-lib": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@cantoo/pdf-lib/-/pdf-lib-2.6.5.tgz", @@ -582,9 +644,9 @@ } }, "node_modules/@csstools/css-calc": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", - "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.3.0.tgz", + "integrity": "sha512-c5ihYsPkdG6JCkU2zTMm4+k6r7RXuGxtWYhu5DHMIiF1FHzrfmHL5so11AoFpUv/tu61xfcmT4AmKoFfMPoqdQ==", "dev": true, "funding": [ { @@ -657,9 +719,9 @@ } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.1.tgz", - "integrity": "sha512-BvqN0AMWNAnLk9G8jnUT77D+mUbY/H2b3uDTvg2isJkHaOufUE2R3AOwxWo7VBQKT1lOdwdvorddo2B/lk64+w==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.7.tgz", + "integrity": "sha512-fQ+05118eQS1cofO3aJpB5efgpBZMvIzwr/sbC8kDLVA5XLG8q1kJV5yzrUAI1f7lvhPnm8fgIjzFB8/O/5Dig==", "dev": true, "funding": [ { @@ -701,6 +763,76 @@ "node": ">=20.19.0" } }, + "node_modules/@csstools/media-query-list-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-5.0.0.tgz", + "integrity": "sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/selector-resolve-nested": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-4.0.1.tgz", + "integrity": "sha512-j3vdQu0XwLME5qOTWxm8cnmvsf423R2YL6DbKklCHZwkDm7UdKNu6RPlw4REIJhSlKBICY3B70/7QZdicLqZgg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.1.1" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-6.0.0.tgz", + "integrity": "sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.1.1" + } + }, "node_modules/@dnd-kit/accessibility": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz", @@ -2894,6 +3026,44 @@ "url": "https://github.com/sponsors/Brooooooklyn" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@open-draft/deferred-promise": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-3.0.0.tgz", @@ -3548,6 +3718,19 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@standard-schema/spec": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", @@ -6849,6 +7032,16 @@ "dev": true, "license": "MIT" }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -7410,6 +7603,20 @@ "node": ">=8" } }, + "node_modules/cacheable": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz", + "integrity": "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/memory": "^2.2.0", + "@cacheable/utils": "^2.5.0", + "hookified": "^1.15.0", + "keyv": "^5.6.0", + "qified": "^0.10.1" + } + }, "node_modules/cacheable-lookup": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", @@ -7446,6 +7653,16 @@ "@keyv/serialize": "^1.1.1" } }, + "node_modules/cacheable/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -7814,6 +8031,13 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true, + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -7941,6 +8165,16 @@ "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", "license": "MIT" }, + "node_modules/css-functions-list": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.3.3.tgz", + "integrity": "sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/css-tree": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", @@ -9389,6 +9623,36 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -9420,6 +9684,23 @@ "fast-string-truncated-width": "^3.0.2" } }, + "node_modules/fast-uri": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fast-wrap-ansi": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.0.tgz", @@ -9430,6 +9711,26 @@ "fast-string-width": "^3.0.2" } }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -9838,6 +10139,54 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/globals": { "version": "17.5.0", "resolved": "https://registry.npmjs.org/globals/-/globals-17.5.0.tgz", @@ -9850,6 +10199,47 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-16.2.2.tgz", + "integrity": "sha512-NLvV9ubZ6NDsJaOpKPy3cQeJpKi9DcWiyCiFUpJPA0YihRqiE6RWaLUmgNNPr8MgPpLZjnBjSmou7uZBRJv9wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.5", + "is-path-inside": "^4.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/unicorn-magic": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true, + "license": "MIT" + }, "node_modules/globrex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", @@ -9957,6 +10347,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hashery": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", + "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^1.15.0" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/hasown": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", @@ -10042,6 +10445,13 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, + "node_modules/hookified": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", + "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", + "dev": true, + "license": "MIT" + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -10094,6 +10504,19 @@ "void-elements": "3.1.0" } }, + "node_modules/html-tags": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-5.1.0.tgz", + "integrity": "sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/html-url-attributes": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", @@ -10275,6 +10698,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -10533,6 +10967,19 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -10875,6 +11322,16 @@ "json-buffer": "3.0.1" } }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -11351,6 +11808,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -11485,6 +11949,17 @@ "node": ">= 0.4" } }, + "node_modules/mathml-tag-names": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-4.0.0.tgz", + "integrity": "sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/mdast-util-find-and-replace": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", @@ -11774,6 +12249,29 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/meow": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-14.1.0.tgz", + "integrity": "sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -12337,6 +12835,20 @@ ], "license": "MIT" }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -12559,9 +13071,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", @@ -13253,9 +13765,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.24.tgz", + "integrity": "sha512-8RyVklq0owXUTa4xlpzu4l9AaVKIdQvAcOHZWaMh98HgySsUtxRVf/chRe3dsSLqb6i40BzGRzEUddRaI+9TSw==", "funding": [ { "type": "opencollective", @@ -13272,7 +13784,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -13471,10 +13983,37 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-safe-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, "node_modules/postcss-selector-parser": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "dev": true, "license": "MIT", "dependencies": { @@ -13801,6 +14340,26 @@ } } }, + "node_modules/qified": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz", + "integrity": "sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^2.1.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/qified/node_modules/hookified": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz", + "integrity": "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==", + "dev": true, + "license": "MIT" + }, "node_modules/qrcode.react": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.2.0.tgz", @@ -13816,6 +14375,27 @@ "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", "license": "MIT" }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", @@ -14659,6 +15239,17 @@ "dev": true, "license": "MIT" }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/robust-predicates": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", @@ -14876,6 +15467,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", @@ -15042,6 +15657,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, "node_modules/slide": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", @@ -15951,6 +16584,132 @@ "inline-style-parser": "0.2.7" } }, + "node_modules/stylelint": { + "version": "17.14.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.14.1.tgz", + "integrity": "sha512-xVQwyiuxALUBNB2fBe0tmNemg9KqLtdj3T64mioFDar79B2cU8LIyz+3KL6LdiHs9NkeNfwxpKSaIVOY8f112g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.2.1", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-syntax-patches-for-csstree": "^1.1.6", + "@csstools/css-tokenizer": "^4.0.0", + "@csstools/media-query-list-parser": "^5.0.0", + "@csstools/selector-resolve-nested": "^4.0.0", + "@csstools/selector-specificity": "^6.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^9.0.2", + "css-functions-list": "^3.3.3", + "css-tree": "^3.2.1", + "debug": "^4.4.3", + "fast-glob": "^3.3.3", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^11.1.5", + "global-modules": "^2.0.0", + "globby": "^16.2.1", + "globjoin": "^0.1.4", + "html-tags": "^5.1.0", + "ignore": "^7.0.5", + "import-meta-resolve": "^4.2.0", + "mathml-tag-names": "^4.0.0", + "meow": "^14.1.0", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.5.16", + "postcss-safe-parser": "^7.0.1", + "postcss-selector-parser": "^7.1.4", + "postcss-value-parser": "^4.2.0", + "string-width": "^8.2.1", + "supports-hyperlinks": "^4.5.0", + "svg-tags": "^1.0.0", + "table": "^6.9.0", + "write-file-atomic": "^7.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/stylelint/node_modules/cosmiconfig": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz", + "integrity": "sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz", + "integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^6.1.23" + } + }, + "node_modules/stylelint/node_modules/flat-cache": { + "version": "6.1.23", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz", + "integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cacheable": "^2.5.0", + "flatted": "^3.4.2", + "hookified": "^1.15.0" + } + }, + "node_modules/stylelint/node_modules/string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", @@ -15993,6 +16752,49 @@ "node": ">=8" } }, + "node_modules/supports-hyperlinks": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-4.5.0.tgz", + "integrity": "sha512-ZW2OvfeCXrNTbLakPUzjQG922EeGCOteFSVoek5DKStTh898wf7zgtuFlzQN8HfZCxC3Eh02yJVrRW51hADf+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^5.0.1", + "supports-color": "^10.2.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", + "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -16043,6 +16845,12 @@ "node": ">= 0.4" } }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -16056,6 +16864,82 @@ "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", "license": "MIT" }, + "node_modules/table": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/tablemark": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/tablemark/-/tablemark-4.1.0.tgz", @@ -17642,6 +18526,19 @@ "dev": true, "license": "ISC" }, + "node_modules/write-file-atomic": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz", + "integrity": "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==", + "dev": true, + "license": "ISC", + "dependencies": { + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/ws": { "version": "8.21.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 404366383a..a527bcf06f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -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", diff --git a/frontend/stylelint.config.mjs b/frontend/stylelint.config.mjs new file mode 100644 index 0000000000..2781e78516 --- /dev/null +++ b/frontend/stylelint.config.mjs @@ -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, + }, +};