From d196af28d4dc3b15c21a095f7d7a0b8920bac354 Mon Sep 17 00:00:00 2001 From: Alexander Rybakov Date: Wed, 18 Mar 2026 17:04:56 +0200 Subject: [PATCH 1/5] separate public ui and cms ui styles --- packages/cmsui/routes/layout.tsx | 3 --- packages/cmsui/styles/cmsui.css | 12 ++++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/cmsui/routes/layout.tsx b/packages/cmsui/routes/layout.tsx index 16739b421ad..e3f049f41ba 100644 --- a/packages/cmsui/routes/layout.tsx +++ b/packages/cmsui/routes/layout.tsx @@ -18,8 +18,6 @@ import { useAtom } from 'jotai'; import { clsx } from 'clsx'; import config from '@plone/registry'; -// eslint-disable-next-line import/no-unresolved -import publicStylesheet from 'seven/.plone/publicui.css?url'; // eslint-disable-next-line import/no-unresolved import stylesheet from 'seven/.plone/cmsui.css?url'; @@ -39,7 +37,6 @@ export const meta: MetaFunction = ({ }; export const links: LinksFunction = () => [ - { rel: 'stylesheet', href: publicStylesheet }, { rel: 'stylesheet', href: stylesheet }, { rel: 'icon', diff --git a/packages/cmsui/styles/cmsui.css b/packages/cmsui/styles/cmsui.css index 23793763b30..ffc7cc982a7 100644 --- a/packages/cmsui/styles/cmsui.css +++ b/packages/cmsui/styles/cmsui.css @@ -3,12 +3,12 @@ @source '../node_modules/@plone/components/dist/quanta'; -@layer cmsui { - @import 'tailwindcss/theme.css'; - @import 'tailwindcss/preflight.css'; - @import 'tailwindcss/utilities.css'; +@import 'tailwindcss/theme.css' layer(theme); +@import 'tailwindcss/preflight.css' layer(base); +@import 'tailwindcss/utilities.css' layer(utilities); - :root { +@layer cmsui { + body.cmsui { --background: hsl(0 0% 100%); --foreground: hsl(222.2 84% 4.9%); --card: hsl(0 0% 100%); @@ -37,7 +37,7 @@ /* --radius: 0.6rem; */ } - .dark { + body.cmsui.dark { --background: hsl(222.2 84% 4.9%); --foreground: hsl(210 40% 98%); --card: hsl(222.2 84% 4.9%); From 8a135d72121ed8ac19823534ddb9a7684d8e29b5 Mon Sep 17 00:00:00 2001 From: Alexander Rybakov Date: Wed, 18 Mar 2026 17:05:46 +0200 Subject: [PATCH 2/5] added news --- packages/cmsui/news/8012.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/cmsui/news/8012.bugfix diff --git a/packages/cmsui/news/8012.bugfix b/packages/cmsui/news/8012.bugfix new file mode 100644 index 00000000000..5b2aee1f0d2 --- /dev/null +++ b/packages/cmsui/news/8012.bugfix @@ -0,0 +1 @@ +Separate public UI and CMS UI styles. @arybakov05 \ No newline at end of file From a50ff8c9d00325c401d36ad053d905aa44782451 Mon Sep 17 00:00:00 2001 From: Alexander Rybakov Date: Wed, 18 Mar 2026 17:24:31 +0200 Subject: [PATCH 3/5] clean up old styles on ui switch --- packages/cmsui/routes/layout.tsx | 7 +++++++ packages/publicui/routes/index.tsx | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/packages/cmsui/routes/layout.tsx b/packages/cmsui/routes/layout.tsx index e3f049f41ba..249d3d8e641 100644 --- a/packages/cmsui/routes/layout.tsx +++ b/packages/cmsui/routes/layout.tsx @@ -15,6 +15,7 @@ import Toolbar from '../components/Toolbar/Toolbar'; import Sidebar, { sidebarAtom } from '../components/Sidebar/Sidebar'; import TopNavBar from '../components/Layout/TopNavBar'; import { useAtom } from 'jotai'; +import { useLayoutEffect } from 'react'; import { clsx } from 'clsx'; import config from '@plone/registry'; @@ -70,6 +71,12 @@ export default function Index() { const { i18n } = useTranslation(); const [collapsed] = useAtom(sidebarAtom); + useLayoutEffect(() => { + document + .querySelectorAll('link[href*="publicui.css"]') + .forEach((el) => el.remove()); + }, []); + if (!rootData) { return null; } diff --git a/packages/publicui/routes/index.tsx b/packages/publicui/routes/index.tsx index e3aae75a251..2da0b2f4f1c 100644 --- a/packages/publicui/routes/index.tsx +++ b/packages/publicui/routes/index.tsx @@ -15,6 +15,7 @@ import { type LinksFunction, type MetaFunction, } from 'react-router'; +import { useLayoutEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { RouterProvider as RACRouterProvider } from 'react-aria-components'; import type { RootLoader } from 'seven/app/root'; @@ -81,6 +82,12 @@ export default function Index() { .filter((match) => match.handle?.bodyClass) .map((match) => match.handle?.bodyClass); + useLayoutEffect(() => { + document + .querySelectorAll('link[href*="cmsui.css"]') + .forEach((el) => el.remove()); + }, []); + if (!rootData) { return null; } From d33393818d15c08f2ba7e8c4cca6004899564d51 Mon Sep 17 00:00:00 2001 From: Alexander Rybakov Date: Wed, 18 Mar 2026 17:29:04 +0200 Subject: [PATCH 4/5] added news --- packages/publicui/news/8012.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/publicui/news/8012.bugfix diff --git a/packages/publicui/news/8012.bugfix b/packages/publicui/news/8012.bugfix new file mode 100644 index 00000000000..5b2aee1f0d2 --- /dev/null +++ b/packages/publicui/news/8012.bugfix @@ -0,0 +1 @@ +Separate public UI and CMS UI styles. @arybakov05 \ No newline at end of file From d7f5c9cbcd6a73a59caa4c30080f8cab7425b2b8 Mon Sep 17 00:00:00 2001 From: Alexander Rybakov Date: Thu, 19 Mar 2026 10:08:24 +0200 Subject: [PATCH 5/5] merge branch 'seven' into '88012-styles_separation' --- packages/blocks/Image/ImageBlockView.tsx | 20 +- packages/blocks/Text/TextBlockEdit.tsx | 21 - packages/blocks/Text/TextBlockView.tsx | 16 - packages/blocks/Text/index.ts | 15 - packages/blocks/Title/TitleBlockEdit.tsx | 163 - packages/blocks/Title/TitleBlockView.tsx | 16 - packages/blocks/Title/index.ts | 37 - .../blocks/hooks/use-stable-plate-value.ts | 39 - packages/blocks/index.ts | 4 - packages/blocks/news/8008.bugfix | 1 + packages/blocks/news/8015.breaking | 1 + packages/blocks/package.json | 3 - packages/cmsui/acceptance/tests/edit.test.ts | 3 +- .../acceptance/tests/image-block.test.ts | 22 +- .../acceptance/tests/teaser-block.test.ts | 6 +- .../acceptance/tests/title-block-sync.test.ts | 15 +- .../components/ImageWidget/ImageWidget.tsx | 7 +- .../cmsui/components/Layout/TopNavBar.tsx | 5 - .../ObjectBrowserWidget.tsx | 7 +- packages/cmsui/components/Sidebar/Sidebar.tsx | 25 +- .../TextField/TextField.stories.tsx | 90 - .../cmsui/components/TextField/TextField.tsx | 55 - packages/cmsui/components/Toolbar/Toolbar.tsx | 45 - packages/cmsui/config/widgets.ts | 2 +- packages/cmsui/index.ts | 28 - packages/cmsui/locales/en/common.json | 7 + packages/cmsui/locales/it/common.json | 30 +- packages/cmsui/news/6649.feature | 1 + packages/cmsui/news/7355.feature | 1 + packages/cmsui/news/8015.breaking | 1 + packages/cmsui/routes/auth/login.tsx | 7 +- packages/cmsui/routes/controlpanel.tsx | 107 +- packages/cmsui/routes/controlpanels.tsx | 4 +- packages/cmsui/routes/edit.tsx | 150 +- packages/cmsui/routes/layout.tsx | 56 +- packages/cmsui/styles/cmsui.css | 6 + .../layout/components/Toolbar/Toolbar.css | 100 + .../layout/components/Toolbar/Toolbar.tsx | 90 + packages/layout/helpers/index.ts | 9 + packages/layout/locales/en/common.json | 3 + packages/layout/locales/it/common.json | 3 + packages/layout/news/6649.feature | 1 + .../editor/plugins/media-base-kit.tsx | 6 +- .../components/editor/plugins/media-kit.tsx | 18 +- packages/plate/input.css | 17 - packages/plate/news/8015.breaking | 2 + packages/plate/output.css | 4305 ----------------- packages/plate/package.json | 1 - packages/publicui/news/6649.feature | 1 + packages/publicui/routes/index.tsx | 72 +- packages/publicui/styles/publicui.css | 5 + packages/theming/news/6649.feature | 1 + packages/theming/styles/tailwind.css | 2 + packages/theming/styles/theme.css | 2 + pnpm-lock.yaml | 21 - 55 files changed, 577 insertions(+), 5098 deletions(-) delete mode 100644 packages/blocks/Text/TextBlockEdit.tsx delete mode 100644 packages/blocks/Text/TextBlockView.tsx delete mode 100644 packages/blocks/Text/index.ts delete mode 100644 packages/blocks/Title/TitleBlockEdit.tsx delete mode 100644 packages/blocks/Title/TitleBlockView.tsx delete mode 100644 packages/blocks/Title/index.ts delete mode 100644 packages/blocks/hooks/use-stable-plate-value.ts create mode 100644 packages/blocks/news/8008.bugfix create mode 100644 packages/blocks/news/8015.breaking delete mode 100644 packages/cmsui/components/Layout/TopNavBar.tsx delete mode 100644 packages/cmsui/components/TextField/TextField.stories.tsx delete mode 100644 packages/cmsui/components/TextField/TextField.tsx delete mode 100644 packages/cmsui/components/Toolbar/Toolbar.tsx create mode 100644 packages/cmsui/news/6649.feature create mode 100644 packages/cmsui/news/7355.feature create mode 100644 packages/cmsui/news/8015.breaking create mode 100644 packages/layout/components/Toolbar/Toolbar.css create mode 100644 packages/layout/components/Toolbar/Toolbar.tsx create mode 100644 packages/layout/news/6649.feature delete mode 100644 packages/plate/input.css create mode 100644 packages/plate/news/8015.breaking delete mode 100644 packages/plate/output.css create mode 100644 packages/publicui/news/6649.feature create mode 100644 packages/theming/news/6649.feature diff --git a/packages/blocks/Image/ImageBlockView.tsx b/packages/blocks/Image/ImageBlockView.tsx index 84a67acc216..448d3019b01 100644 --- a/packages/blocks/Image/ImageBlockView.tsx +++ b/packages/blocks/Image/ImageBlockView.tsx @@ -1,17 +1,23 @@ -import type { BlockViewProps } from '@plone/types'; +import type { BlockViewProps, ContainedItem } from '@plone/types'; +import Image from '@plone/layout/components/Image/Image'; const ImageBlockView = (props: BlockViewProps) => { const { data } = props; if (!data.url) return null; - const url = data.image_scales - ? `${data.url}/${data.image_scales[data.image_field || 'image'][0].scales.larger.download}` - : data.url; - // data.preview_image?.[0]?.['@id'] || - // `/++api++${data.href[0]?.image_scales[data.href[0].image_field][0].base_path}/${data.href[0]?.image_scales[data.href[0].image_field][0].download}`; + + const item = { + '@id': data.url, + image_field: data.image_field, + image_scales: data.image_scales, + } as ContainedItem; return (
- {data.alt} + {(data.alt
); }; diff --git a/packages/blocks/Text/TextBlockEdit.tsx b/packages/blocks/Text/TextBlockEdit.tsx deleted file mode 100644 index f8326413db3..00000000000 --- a/packages/blocks/Text/TextBlockEdit.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import type { BlockEditProps } from '@plone/types'; -import { PlateEditor, type Value } from '@plone/plate/components/editor'; -import plateBlockConfig from '@plone/plate/config/presets/block-editor'; -import { useStablePlateValue } from '../hooks/use-stable-plate-value'; - -const TextBlockEdit = (props: BlockEditProps) => { - const { data, setBlock } = props; - const stableValue = useStablePlateValue(data.value as Value | undefined); - - return ( - { - setBlock({ ...data, value: options.value }); - }} - /> - ); -}; - -export default TextBlockEdit; diff --git a/packages/blocks/Text/TextBlockView.tsx b/packages/blocks/Text/TextBlockView.tsx deleted file mode 100644 index 52785ab6f24..00000000000 --- a/packages/blocks/Text/TextBlockView.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import type { BlockViewProps } from '@plone/types'; -import { PlateRenderer, type Value } from '@plone/plate/components/editor'; -import plateBlockConfig from '@plone/plate/config/presets/block-renderer'; - -const TextBlockView = (props: BlockViewProps) => { - const { data } = props; - - return data?.value ? ( - - ) : null; -}; - -export default TextBlockView; diff --git a/packages/blocks/Text/index.ts b/packages/blocks/Text/index.ts deleted file mode 100644 index af7e409602f..00000000000 --- a/packages/blocks/Text/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; - -const TextBlockInfo = { - id: 'slate', - title: 'Rich text', - view: React.lazy( - () => import(/* webpackChunkName: "plone-blocks" */ './TextBlockView'), - ), - edit: React.lazy( - () => import(/* webpackChunkName: "plone-blocks" */ './TextBlockEdit'), - ), - category: 'text', -}; - -export default TextBlockInfo; diff --git a/packages/blocks/Title/TitleBlockEdit.tsx b/packages/blocks/Title/TitleBlockEdit.tsx deleted file mode 100644 index f0e852cf4af..00000000000 --- a/packages/blocks/Title/TitleBlockEdit.tsx +++ /dev/null @@ -1,163 +0,0 @@ -import { useEffect, useRef } from 'react'; -import type { Content } from '@plone/types/src/content'; -import type { BlockEditProps } from '@plone/types/src/blocks'; -import { useFieldFocusedAtom } from '@plone/helpers'; -import config from '@plone/registry'; -import { clsx } from 'clsx'; - -/** - * Single-line, plain-text, fixed-style editable heading using bare contentEditable. - * - Prevents Enter/newlines. - * - Strips formatting on paste (plain text only). - * - Collapses any injected newlines into spaces. - * - Optional maxLength. - * - * This component has been AI generated. - */ -export function SingleLineH1({ - value, - onChange, - placeholder = 'Type a title…', - maxLength = 120, - className = '', -}: { - value: string; - onChange: (value: string) => void; - placeholder?: string; - maxLength?: number; - className?: string; -}) { - const ref = useRef(null); - - // Keep DOM in sync with value when controlled externally - useEffect(() => { - const el = ref.current; - if (!el) return; - if (el.innerText !== (value ?? '')) { - el.innerText = value ?? ''; - } - }, [value]); - - const getSanitized = (text) => { - if (typeof text !== 'string') return ''; - // Replace any newlines/tabs with single spaces and trim extra spaces - const collapsed = text.replace(/[\n\r\t]+/g, ' ').replace(/\s{2,}/g, ' '); - return collapsed.slice(0, maxLength); - }; - - const emitChange = () => { - const el = ref.current; - if (!el) return; - const sanitized = getSanitized(el.innerText); - if (el.innerText !== sanitized) { - el.innerText = sanitized; - } - onChange?.(sanitized); - }; - - const onKeyDown = (e) => { - // Block Enter/Return from creating new lines - if (e.key === 'Enter') { - e.preventDefault(); - return; - } - // Optionally prevent line breaks via Shift+Enter on some platforms - if (e.key === 'Enter' && (e.shiftKey || e.ctrlKey || e.metaKey)) { - e.preventDefault(); - return; - } - // Enforce max length in a simple way for common typing - const el = ref.current; - if (!el) return; - const sel = window.getSelection(); - const isPrintable = - e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey; - const len = el.innerText.length; - const selectionLength = sel && sel.toString ? sel.toString().length : 0; - if (isPrintable && len - selectionLength >= maxLength) { - e.preventDefault(); - } - }; - - const onPaste = (e) => { - // Force plain text paste, collapse newlines, enforce max length - e.preventDefault(); - const text = e.clipboardData.getData('text/plain') || ''; - const toInsert = getSanitized(text); - - // Insert at caret position without formatting - const sel = window.getSelection(); - if (!sel || sel.rangeCount === 0) return; - const range = sel.getRangeAt(0); - range.deleteContents(); - range.insertNode(document.createTextNode(toInsert)); - - // Move caret to end of inserted text - range.setStartAfter(range.endContainer); - range.collapse(true); - sel.removeAllRanges(); - sel.addRange(range); - - // Emit sanitized content - requestAnimationFrame(emitChange); - }; - - const onInput = () => { - emitChange(); - }; - - return ( - // eslint-disable-next-line jsx-a11y/heading-has-content -

- ); -} - -export default function TitleBlockEdit(props: BlockEditProps) { - const formAtom = config - .getUtility({ - name: 'formAtom', - type: 'atom', - }) - ?.method(); - - const [titleValue, setTitle] = useFieldFocusedAtom( - formAtom, - 'title', - ); - - return ( - setTitle(value)} - value={titleValue as string} - /> - ); -} diff --git a/packages/blocks/Title/TitleBlockView.tsx b/packages/blocks/Title/TitleBlockView.tsx deleted file mode 100644 index 6f29450ff55..00000000000 --- a/packages/blocks/Title/TitleBlockView.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import type { BlockViewProps } from '@plone/types'; - -/** - * View title block component. - * @class View - * @extends Component - */ -const TitleBlockView = ({ properties, metadata }: BlockViewProps) => { - return ( -

- {(metadata || properties)['title'] || ''} -

- ); -}; - -export default TitleBlockView; diff --git a/packages/blocks/Title/index.ts b/packages/blocks/Title/index.ts deleted file mode 100644 index d25d498a4a0..00000000000 --- a/packages/blocks/Title/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; - -const TitleBlockInfo = { - id: 'title', - title: 'Title', - view: React.lazy( - () => import(/* webpackChunkName: "plone-blocks" */ './TitleBlockView'), - ), - edit: React.lazy( - () => import(/* webpackChunkName: "plone-blocks" */ './TitleBlockEdit'), - ), - // Just for testing purposes, we must remove this - // Uncomment and define blockSchema if needed - // blockSchema: { - // fieldsets: [ - // { - // id: 'default', - // title: 'Default', - // fields: ['title', 'description'], // Example fields, adjust as needed - // }, - // ], - // properties: { - // title: { - // type: 'string', - // title: 'Title', - // }, - // description: { - // type: 'string', - // title: 'Description', - // }, - // }, - // required: ['title'], - // }, - category: 'heading', -}; - -export default TitleBlockInfo; diff --git a/packages/blocks/hooks/use-stable-plate-value.ts b/packages/blocks/hooks/use-stable-plate-value.ts deleted file mode 100644 index 08c2f8ff8c9..00000000000 --- a/packages/blocks/hooks/use-stable-plate-value.ts +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from 'react'; - -import type { Value } from 'platejs'; - -import { normalizeLegacyValue } from '@plone/plate/components/editor/plugins/normalize-legacy'; - -/** - * Normalize a Plate value once (for legacy Slate shapes) and keep a stable - * reference for the lifetime of the editor. Accepts an optional cloneFn if you - * don't want to mutate the source (e.g., Redux state). - */ -export function useStablePlateValue( - rawValue?: Value, - cloneFn: (val: Value) => Value = defaultClone, -): Value | undefined { - const valueRef = React.useRef(); - const initializedRef = React.useRef(false); - - if (!initializedRef.current) { - if (rawValue) { - // Clone to avoid mutating upstream state, then normalize once. - const writable = cloneFn(rawValue); - valueRef.current = normalizeLegacyValue(writable); - } else { - valueRef.current = rawValue as Value | undefined; - } - initializedRef.current = true; - } - - return valueRef.current; -} - -function defaultClone(val: Value): Value { - try { - return structuredClone(val) as Value; - } catch { - return JSON.parse(JSON.stringify(val)) as Value; - } -} diff --git a/packages/blocks/index.ts b/packages/blocks/index.ts index dffe46796ff..ce96366d13f 100644 --- a/packages/blocks/index.ts +++ b/packages/blocks/index.ts @@ -1,7 +1,5 @@ import type { ConfigType } from '@plone/registry'; -import TitleBlockInfo from './Title'; -import TextBlockInfo from './Text'; import ImageBlockInfo from './Image'; import TeaserBlockInfo from './Teaser'; import ListingBlockInfo from './Listing'; @@ -13,8 +11,6 @@ export default function install(config: ConfigType) { // other package that wants to add blocks. config.blocks.blocksConfig = {}; - config.blocks.blocksConfig.title = TitleBlockInfo; - config.blocks.blocksConfig.slate = TextBlockInfo; config.blocks.blocksConfig.image = ImageBlockInfo; config.blocks.blocksConfig.teaser = TeaserBlockInfo; config.blocks.blocksConfig.listing = ListingBlockInfo; diff --git a/packages/blocks/news/8008.bugfix b/packages/blocks/news/8008.bugfix new file mode 100644 index 00000000000..b415215094a --- /dev/null +++ b/packages/blocks/news/8008.bugfix @@ -0,0 +1 @@ +Use Image component in ImageBlockView instead of manually constructing image scale URLs. @jmevissen diff --git a/packages/blocks/news/8015.breaking b/packages/blocks/news/8015.breaking new file mode 100644 index 00000000000..62be7ac120f --- /dev/null +++ b/packages/blocks/news/8015.breaking @@ -0,0 +1 @@ +Remove Text block from @plone/blocks, remove dependency on @plone/plate @sneridagh diff --git a/packages/blocks/package.json b/packages/blocks/package.json index 3fb5df0ee7c..b1b3938e1b5 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -49,10 +49,8 @@ }, "dependencies": { "@plone/components": "workspace:*", - "@plone/plate": "workspace:*", "@plone/registry": "workspace:*", "clsx": "^2.1.1", - "lodash.clonedeep": "^4.5.0", "react-i18next": "catalog:" }, "devDependencies": { @@ -63,7 +61,6 @@ "@testing-library/jest-dom": "6.4.2", "@testing-library/react": "catalog:", "@types/jest-axe": "^3.5.7", - "@types/lodash.clonedeep": "4.5.6", "@types/node": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", diff --git a/packages/cmsui/acceptance/tests/edit.test.ts b/packages/cmsui/acceptance/tests/edit.test.ts index 9a8e6c98b62..fb8f708253c 100644 --- a/packages/cmsui/acceptance/tests/edit.test.ts +++ b/packages/cmsui/acceptance/tests/edit.test.ts @@ -13,7 +13,8 @@ test('GET / shows Homepage', async ({ page }) => { await expect(page.getByText('Home')).toBeVisible(); }); -test('GET /mypage shows a document', async ({ page }) => { +// Skipping this test until we have in place the runtime migration +test.skip('GET /mypage shows a document', async ({ page }) => { await createContent(page, { contentType: 'Document', contentId: 'mypage', diff --git a/packages/cmsui/acceptance/tests/image-block.test.ts b/packages/cmsui/acceptance/tests/image-block.test.ts index 196b85e2bf7..06d9359d7b7 100644 --- a/packages/cmsui/acceptance/tests/image-block.test.ts +++ b/packages/cmsui/acceptance/tests/image-block.test.ts @@ -62,7 +62,7 @@ async function setupImageBlockPage(page: Parameters[0]['page']) { }); await page.goto(`/@@edit/${PAGE_ID}`); - await page.locator('[data-slate-editor]').waitFor({ state: 'visible' }); + await waitForPlateEditorReady(page); } test('Image block can select a pre-uploaded local image URL', async ({ @@ -70,7 +70,10 @@ test('Image block can select a pre-uploaded local image URL', async ({ }) => { await login(page); await setupImageBlockPage(page); - await page.getByLabel('Settings').first().click(); + await page + .locator('#toolbar') + .getByRole('button', { name: 'Settings' }) + .click(); await page.getByText('Browse the site, drop an image, or use a URL').click(); await expect(page.locator('#sidebar form')).toHaveCount(1); @@ -89,7 +92,10 @@ test('Image block selection, arrows, enter, and sidebar lifecycle', async ({ }) => { await login(page); await setupImageBlockPage(page); - await page.getByLabel('Settings').first().click(); + await page + .locator('#toolbar') + .getByRole('button', { name: 'Settings' }) + .click(); await page.getByText('Browse the site, drop an image, or use a URL').click(); await expect(page.locator('#sidebar form')).toHaveCount(1); @@ -130,7 +136,10 @@ test('Image block saves alt text in block data', async ({ page }) => { await setupImageBlockPage(page); await waitForPlateEditorReady(page); const editorHandle = await getEditorHandle(page); - await page.getByLabel('Settings').first().click(); + await page + .locator('#toolbar') + .getByRole('button', { name: 'Settings' }) + .click(); await page.getByText('Browse the site, drop an image, or use a URL').click(); await expect(page.locator('#sidebar form')).toHaveCount(1); @@ -171,7 +180,10 @@ test('Image block can upload an image using the upload button', async ({ }) => { await login(page); await setupImageBlockPage(page); - await page.getByLabel('Settings').first().click(); + await page + .locator('#toolbar') + .getByRole('button', { name: 'Settings' }) + .click(); await page.getByText('Browse the site, drop an image, or use a URL').click(); await expect(page.locator('#sidebar form')).toHaveCount(1); diff --git a/packages/cmsui/acceptance/tests/teaser-block.test.ts b/packages/cmsui/acceptance/tests/teaser-block.test.ts index 7ad798041be..c1d33b8bbf7 100644 --- a/packages/cmsui/acceptance/tests/teaser-block.test.ts +++ b/packages/cmsui/acceptance/tests/teaser-block.test.ts @@ -55,9 +55,11 @@ async function setupTeaserBlockPage(page: Parameters[0]['page']) { }); await page.goto(`/@@edit/${PAGE_ID}`); - await page.locator('[data-slate-editor]').waitFor({ state: 'visible' }); await waitForPlateEditorReady(page); - await page.getByLabel('Settings').first().click(); + await page + .locator('#toolbar') + .getByRole('button', { name: 'Settings' }) + .click(); } test('Teaser block shows placeholder while source is not selected', async ({ diff --git a/packages/cmsui/acceptance/tests/title-block-sync.test.ts b/packages/cmsui/acceptance/tests/title-block-sync.test.ts index 54981a9b93d..f93578af15a 100644 --- a/packages/cmsui/acceptance/tests/title-block-sync.test.ts +++ b/packages/cmsui/acceptance/tests/title-block-sync.test.ts @@ -33,13 +33,16 @@ test('Title block and metadata title stay in sync', async ({ page }) => { await page.goto('/@@edit/title-sync-page'); await waitForPlateEditorReady(page); + await page.getByRole('tab', { name: 'Content' }).click(); const metadataTitleInput = page.locator('input[name="title"]').first(); - const editorTitle = page.locator('[data-slate-editor] h1').first(); - await metadataTitleInput.fill('Metadata updated title'); - await expect(editorTitle).toHaveText('Metadata updated title'); + await page.getByRole('tab', { name: 'Blocks' }).click(); + const editorTitle = page.locator('[data-slate-editor] h1').first(); + await expect(editorTitle).toHaveText('Metadata updated title'); await editorTitle.fill('Editor updated title'); + + await page.getByRole('tab', { name: 'Content' }).click(); await expect(metadataTitleInput).toHaveValue('Editor updated title'); }); @@ -69,12 +72,14 @@ test('Newly created title block is initialized from metadata title', async ({ await page.goto('/@@edit/title-sync-no-title-block'); await waitForPlateEditorReady(page); - const metadataTitleInput = page.locator('input[name="title"]').first(); const editorTitle = page.locator('[data-slate-editor] h1').first(); - await expect(editorTitle).toHaveText('Initial title'); + + await page.getByRole('tab', { name: 'Content' }).click(); + const metadataTitleInput = page.locator('input[name="title"]').first(); await metadataTitleInput.fill('Seeded metadata title'); + await page.getByRole('tab', { name: 'Blocks' }).click(); await expect(editorTitle).toHaveText('Seeded metadata title'); }); diff --git a/packages/cmsui/components/ImageWidget/ImageWidget.tsx b/packages/cmsui/components/ImageWidget/ImageWidget.tsx index 90573822426..2bdefe47a5e 100644 --- a/packages/cmsui/components/ImageWidget/ImageWidget.tsx +++ b/packages/cmsui/components/ImageWidget/ImageWidget.tsx @@ -9,6 +9,7 @@ import { import { useFetcher } from 'react-router'; import { DialogTrigger } from 'react-aria-components'; import { Button, Input } from '@plone/components/quanta'; +import type { TextFieldProps as QuantaTextFieldProps } from '@plone/components/quanta'; import { BinIcon, ImageIcon, @@ -17,7 +18,6 @@ import { UploadIcon, } from '@plone/components/Icons'; import type { Brain } from '@plone/types'; -import type { BaseFormFieldProps } from '../TextField/TextField'; import { Description, FieldError, Label } from '../Field/Field'; import { ObjectBrowserModal } from '../ObjectBrowserWidget/ObjectBrowserModal'; import { @@ -25,6 +25,11 @@ import { useObjectBrowserContext, } from '../ObjectBrowserWidget/ObjectBrowserContext'; +type BaseFormFieldProps = Pick< + QuantaTextFieldProps, + 'label' | 'description' | 'errorMessage' | 'placeholder' +>; + type ImageChangeExtras = { title?: string; image_field?: string; diff --git a/packages/cmsui/components/Layout/TopNavBar.tsx b/packages/cmsui/components/Layout/TopNavBar.tsx deleted file mode 100644 index 9ad4a57ec21..00000000000 --- a/packages/cmsui/components/Layout/TopNavBar.tsx +++ /dev/null @@ -1,5 +0,0 @@ -const TopNavBar = () => { - return
; -}; - -export default TopNavBar; diff --git a/packages/cmsui/components/ObjectBrowserWidget/ObjectBrowserWidget.tsx b/packages/cmsui/components/ObjectBrowserWidget/ObjectBrowserWidget.tsx index ae5f666a389..d1113ca5921 100644 --- a/packages/cmsui/components/ObjectBrowserWidget/ObjectBrowserWidget.tsx +++ b/packages/cmsui/components/ObjectBrowserWidget/ObjectBrowserWidget.tsx @@ -1,4 +1,4 @@ -import type { BaseFormFieldProps } from '../TextField/TextField'; +import type { TextFieldProps as QuantaTextFieldProps } from '@plone/components/quanta'; import { Description, fieldBorderStyles, @@ -16,6 +16,11 @@ import { ObjectBrowserTrigger } from './ObjectBrowserTrigger'; import { ObjectBrowserModal } from './ObjectBrowserModal'; import { useFocusRing, useId } from 'react-aria'; +type BaseFormFieldProps = Pick< + QuantaTextFieldProps, + 'label' | 'description' | 'errorMessage' | 'placeholder' +>; + // TODO: better styling const widgetStyles = tv({ extend: focusRing, diff --git a/packages/cmsui/components/Sidebar/Sidebar.tsx b/packages/cmsui/components/Sidebar/Sidebar.tsx index a98f087cc4f..60049f48f78 100644 --- a/packages/cmsui/components/Sidebar/Sidebar.tsx +++ b/packages/cmsui/components/Sidebar/Sidebar.tsx @@ -1,9 +1,9 @@ -import { Fragment } from 'react'; +import { useTranslation } from 'react-i18next'; import { atom, useAtom } from 'jotai'; import { tv } from 'tailwind-variants'; import { Pluggable } from '@plone/layout/components/Pluggable'; -export const sidebarAtom = atom(true); +export const sidebarAtom = atom(false); const sidebar = tv({ base: ` @@ -18,21 +18,22 @@ const sidebar = tv({ }); const Sidebar = () => { - const [collapsed] = useAtom(sidebarAtom); + const { t } = useTranslation(); + const [collapsed, setCollapsed] = useAtom(sidebarAtom); return ( - + {!collapsed && } + ); }; diff --git a/packages/cmsui/components/TextField/TextField.stories.tsx b/packages/cmsui/components/TextField/TextField.stories.tsx deleted file mode 100644 index 56273da96c1..00000000000 --- a/packages/cmsui/components/TextField/TextField.stories.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react-vite'; -import { Form } from 'react-aria-components'; -import { Button } from '@plone/components/quanta'; -import { TextField } from './TextField'; - -const meta = { - component: TextField, - parameters: { - layout: 'centered', - backgrounds: { disable: true }, - }, - tags: ['autodocs'], - args: { - label: 'Name', - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - args: { - name: 'fieldname', - label: 'Field label', - description: 'Optional help text', - placeholder: 'Type something…', - }, -}; - -export const Required: Story = { - args: { - ...Default.args, - name: 'required', - isRequired: true, - }, -}; - -export const Filled: Story = { - args: { - ...Default.args, - name: 'filled', - defaultValue: 'Filled with value A', - isRequired: true, - }, -}; - -export const Errored: Story = { - args: { - ...Default.args, - name: 'errored', - defaultValue: 'Filled with value A', - errorMessage: 'This is the error', - isInvalid: true, - isRequired: true, - }, -}; - -export const Disabled: Story = { - args: { - ...Default.args, - name: 'disabled', - label: 'Disabled field title', - isDisabled: true, - }, -}; - -export const ReadOnly: Story = { - args: { - ...Default.args, - name: 'readonly', - label: 'Readonly field title', - defaultValue: 'Filled with value A', - isReadOnly: true, - }, -}; - -export const Example = (args: any) => ; - -export const Validation = (args: any) => ( -
- - - -); - -Validation.args = { - isRequired: true, -}; diff --git a/packages/cmsui/components/TextField/TextField.tsx b/packages/cmsui/components/TextField/TextField.tsx deleted file mode 100644 index fdbfc5ba6c4..00000000000 --- a/packages/cmsui/components/TextField/TextField.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { - TextField as AriaTextField, - type TextFieldProps as AriaTextFieldProps, - type ValidationResult, -} from 'react-aria-components'; -import { tv } from 'tailwind-variants'; -import { - Description, - FieldError, - Input, - Label, - fieldBorderStyles, -} from '../Field/Field'; -import { composeTailwindRenderProps, focusRing } from '../utils'; - -const inputStyles = tv({ - extend: focusRing, - base: 'rounded-md', - variants: { - isFocused: fieldBorderStyles.variants.isFocusWithin, - isInvalid: fieldBorderStyles.variants.isInvalid, - isDisabled: fieldBorderStyles.variants.isDisabled, - }, -}); -export interface BaseFormFieldProps { - label?: string; - description?: string; - errorMessage?: string | ((validation: ValidationResult) => string); - placeholder?: string; -} -export interface TextFieldProps - extends AriaTextFieldProps, - BaseFormFieldProps {} - -export function TextField({ - label, - description, - errorMessage, - ...props -}: TextFieldProps) { - return ( - - {label && } - - {description && {description}} - {errorMessage} - - ); -} diff --git a/packages/cmsui/components/Toolbar/Toolbar.tsx b/packages/cmsui/components/Toolbar/Toolbar.tsx deleted file mode 100644 index db3451c9f48..00000000000 --- a/packages/cmsui/components/Toolbar/Toolbar.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { Button } from '@plone/components/quanta'; -import { Plug, Pluggable } from '@plone/layout/components/Pluggable'; -import Settings from '@plone/components/icons/settings.svg?react'; -import Close from '@plone/components/icons/close.svg?react'; -import { sidebarAtom } from '../Sidebar/Sidebar'; -import { useSetAtom } from 'jotai'; -import { useNavigate } from 'react-router'; - -const Toolbar = () => { - const setCollapsed = useSetAtom(sidebarAtom); - const navigate = useNavigate(); - - return ( - - ); -}; - -export default Toolbar; diff --git a/packages/cmsui/config/widgets.ts b/packages/cmsui/config/widgets.ts index 07150b5fec7..df49918545b 100644 --- a/packages/cmsui/config/widgets.ts +++ b/packages/cmsui/config/widgets.ts @@ -1,11 +1,11 @@ import type { ConfigType } from '@plone/registry'; -import { TextField } from '../components/TextField/TextField'; import { AlignWidget, Checkbox, DateTimePicker, SizeWidget, WidthWidget, + TextField, } from '@plone/components/quanta'; import { DateField } from '@plone/components'; import { ObjectBrowserWidget } from '../components/ObjectBrowserWidget/ObjectBrowserWidget'; diff --git a/packages/cmsui/index.ts b/packages/cmsui/index.ts index 4b7a3bf83ed..ec46f872559 100644 --- a/packages/cmsui/index.ts +++ b/packages/cmsui/index.ts @@ -33,13 +33,6 @@ export default function install(config: ConfigType) { type: 'prefix', path: 'login', children: [ - { - type: 'index', - file: '@plone/cmsui/routes/auth/login.tsx', - options: { - id: 'index-login', - }, - }, { type: 'route', path: '*', @@ -51,13 +44,6 @@ export default function install(config: ConfigType) { type: 'prefix', path: 'logout', children: [ - { - type: 'index', - file: '@plone/cmsui/routes/auth/logout.tsx', - options: { - id: 'index-logout', - }, - }, { type: 'route', path: '*', @@ -69,13 +55,6 @@ export default function install(config: ConfigType) { type: 'prefix', path: '@@edit', children: [ - { - type: 'index', - file: '@plone/cmsui/routes/edit.tsx', - options: { - id: 'index-edit', - }, - }, { type: 'route', path: '*', @@ -105,13 +84,6 @@ export default function install(config: ConfigType) { type: 'prefix', path: 'test-layout', children: [ - { - type: 'index', - file: '@plone/cmsui/routes/test.tsx', - options: { - id: 'index-test', - }, - }, { type: 'route', path: '*', diff --git a/packages/cmsui/locales/en/common.json b/packages/cmsui/locales/en/common.json index ce0ea163245..71fcae06efd 100644 --- a/packages/cmsui/locales/en/common.json +++ b/packages/cmsui/locales/en/common.json @@ -54,6 +54,13 @@ "users": "Users", "groupMembership": "Group Membership", "groups": "Groups" + }, + "blocksEditor": { + "blocksTab": "Blocks", + "contentTab": "Content" + }, + "sidebar": { + "label": "Sidebar" } } } diff --git a/packages/cmsui/locales/it/common.json b/packages/cmsui/locales/it/common.json index c603f2d6c9e..480b330317e 100644 --- a/packages/cmsui/locales/it/common.json +++ b/packages/cmsui/locales/it/common.json @@ -2,7 +2,7 @@ "cmsui": { "edit": "Modifica", "save": "Salva", - "controlpanel": "Control Panel", + "controlpanel": "Pannello di controllo", "objectbrowserwidget": { "openDialog": "Seleziona contenuti", "dialogTitle": "Seleziona Contenuti", @@ -23,6 +23,34 @@ "list": "elenco", "grid": "griglia" } + }, + "panelgroups": { + "general": "Generale", + "content": "Contenuto", + "security": "Sicurezza", + "users": "Utenti", + "site": "Sito", + "addons": "Configurazione prodotti aggiuntivi", + "maintenance": "Manutenzione" + }, + "paneltitles": { + "addons": "Prodotti aggiuntivi", + "database": "Database", + "contentRules": "Regole di contenuto", + "undo": "Annulla operazioni", + "urlmanagement": "Gestione URL", + "relations": "Relazioni", + "moderatecomments": "Moderazione dei commenti", + "users": "Utenti", + "groupMembership": "Appartenenza ai gruppi", + "groups": "Gruppi" + }, + "blocksEditor": { + "blocksTab": "Blocchi", + "contentTab": "Contenuto" + }, + "sidebar": { + "label": "Barra laterale destra" } } } diff --git a/packages/cmsui/news/6649.feature b/packages/cmsui/news/6649.feature new file mode 100644 index 00000000000..f37df625361 --- /dev/null +++ b/packages/cmsui/news/6649.feature @@ -0,0 +1 @@ +Added the left toolbar @pnicolli diff --git a/packages/cmsui/news/7355.feature b/packages/cmsui/news/7355.feature new file mode 100644 index 00000000000..bdbf4b5ede5 --- /dev/null +++ b/packages/cmsui/news/7355.feature @@ -0,0 +1 @@ +Added blocks editor layout with tabs @pnicolli \ No newline at end of file diff --git a/packages/cmsui/news/8015.breaking b/packages/cmsui/news/8015.breaking new file mode 100644 index 00000000000..9ee31725de8 --- /dev/null +++ b/packages/cmsui/news/8015.breaking @@ -0,0 +1 @@ +Remove resident TextField in CMSUI (former quanta one), use @plone/components one instead. @sneridagh diff --git a/packages/cmsui/routes/auth/login.tsx b/packages/cmsui/routes/auth/login.tsx index adb8e5bd57f..2c91780731c 100644 --- a/packages/cmsui/routes/auth/login.tsx +++ b/packages/cmsui/routes/auth/login.tsx @@ -9,8 +9,7 @@ import { redirectIfLoggedInLoader, setAuthOnResponse, } from '@plone/react-router'; -import { Button } from '@plone/components/quanta'; -import { TextField } from '../../components/TextField/TextField'; +import { Button, TextField } from '@plone/components/quanta'; import ploneSvg from '../../static/plone-white.svg'; import ArrowRightSVG from '@plone/components/icons/arrow-right.svg?react'; @@ -66,7 +65,7 @@ export default function Login() { | undefined; return ( -
+
- + ); } diff --git a/packages/cmsui/routes/controlpanel.tsx b/packages/cmsui/routes/controlpanel.tsx index 360420f8f62..cac78dd49bb 100644 --- a/packages/cmsui/routes/controlpanel.tsx +++ b/packages/cmsui/routes/controlpanel.tsx @@ -117,59 +117,60 @@ export default function SingleControlPanel() { - - -

- {controlpanel.title || 'a control panel'} -

-
- {schema.fieldsets.map((fieldset: ControlPanelFieldset) => ( - - - {fieldset.title} - - {(fieldset.fields as DeepKeys[]).map( - (schemaField, index) => ( - ( - - )} - /> - ), - )} - - - - ))} - - - -
-
+
+ +

+ {controlpanel.title || 'a control panel'} +

+
+ {schema.fieldsets.map((fieldset: ControlPanelFieldset) => ( + + + {fieldset.title} + + {(fieldset.fields as DeepKeys[]).map( + (schemaField, index) => ( + ( + + )} + /> + ), + )} + + + + ))} + + + +
+
+
); } diff --git a/packages/cmsui/routes/controlpanels.tsx b/packages/cmsui/routes/controlpanels.tsx index d9ceebe3b18..5efd050a6e7 100644 --- a/packages/cmsui/routes/controlpanels.tsx +++ b/packages/cmsui/routes/controlpanels.tsx @@ -35,7 +35,7 @@ export default function ControlPanels() { const navigate = useNavigate(); const { t } = useTranslation(); return ( - <> +
); } diff --git a/packages/cmsui/routes/edit.tsx b/packages/cmsui/routes/edit.tsx index dc080d39731..146cd470971 100644 --- a/packages/cmsui/routes/edit.tsx +++ b/packages/cmsui/routes/edit.tsx @@ -16,14 +16,16 @@ import { flattenToAppURL, InitAtoms } from '@plone/helpers'; import type { Content } from '@plone/types'; import { Plug } from '@plone/layout/components/Pluggable'; import Checkbox from '@plone/components/icons/checkbox.svg?react'; +import Close from '@plone/components/icons/close.svg?react'; import { useAppForm } from '../components/Form/Form'; +import { Link } from 'react-aria-components'; import { Accordion, AccordionItem, AccordionPanel, AccordionItemTrigger, - Button, + Tabs, } from '@plone/components/quanta'; import BlocksEditor from '../components/BlockEditor/BlocksEditor'; @@ -95,68 +97,90 @@ export default function Edit() { return ( -
-
- -
-
-

- {content.title} - {t('cmsui.edit')} -

-
- {schema.fieldsets.map((fieldset) => ( - - - - {fieldset.title} - - - {(fieldset.fields as DeepKeys[]).map( - (schemaField, index) => ( - ( - - )} - /> - ), - )} - - - - ))} - - - -
- {/*
- -
*/} -
+
+ , + }, + { + id: 'content', + title: t('cmsui.blocksEditor.contentTab'), + content: ( +
+

+ {content.title} - {t('cmsui.edit')} +

+
+ {schema.fieldsets.map((fieldset) => ( + + + + {fieldset.title} + + + {(fieldset.fields as DeepKeys[]).map( + (schemaField, index) => ( + ( + + )} + /> + ), + )} + + + + ))} +
+ {/*
+ +
*/} +
+ ), + }, + ]} + /> + + + + + + + +
diff --git a/packages/cmsui/routes/layout.tsx b/packages/cmsui/routes/layout.tsx index 249d3d8e641..40abcc791b5 100644 --- a/packages/cmsui/routes/layout.tsx +++ b/packages/cmsui/routes/layout.tsx @@ -4,22 +4,24 @@ import { Outlet, Scripts, ScrollRestoration, + useNavigate, useRouteLoaderData, type LinksFunction, type MetaFunction, } from 'react-router'; import { useTranslation } from 'react-i18next'; +import { RouterProvider as RACRouterProvider } from 'react-aria-components'; import type { RootLoader } from 'seven/app/root'; -import { PluggablesProvider } from '@plone/layout/components/Pluggable'; -import Toolbar from '../components/Toolbar/Toolbar'; +import { PluggablesProvider, Plug } from '@plone/layout/components/Pluggable'; +import Toolbar from '@plone/layout/components/Toolbar/Toolbar'; +import { shouldShowToolbar } from '@plone/layout/helpers'; import Sidebar, { sidebarAtom } from '../components/Sidebar/Sidebar'; -import TopNavBar from '../components/Layout/TopNavBar'; +import Settings from '@plone/components/icons/settings.svg?react'; import { useAtom } from 'jotai'; import { useLayoutEffect } from 'react'; import { clsx } from 'clsx'; import config from '@plone/registry'; -// eslint-disable-next-line import/no-unresolved import stylesheet from 'seven/.plone/cmsui.css?url'; export const meta: MetaFunction = ({ @@ -69,7 +71,8 @@ export async function loader() { export default function Index() { const rootData = useRouteLoaderData('root'); const { i18n } = useTranslation(); - const [collapsed] = useAtom(sidebarAtom); + const navigate = useNavigate(); + const [collapsed, setCollapsed] = useAtom(sidebarAtom); useLayoutEffect(() => { document @@ -96,24 +99,35 @@ export default function Index() { {/* We pre-define here the @layer before tailwind does, adding our own layers in a React 19 managed tag */} - -
+ + + + + -
- - +
+
+ +
+
- -
-
+ +
diff --git a/packages/cmsui/styles/cmsui.css b/packages/cmsui/styles/cmsui.css index ffc7cc982a7..d4349b44281 100644 --- a/packages/cmsui/styles/cmsui.css +++ b/packages/cmsui/styles/cmsui.css @@ -7,7 +7,11 @@ @import 'tailwindcss/preflight.css' layer(base); @import 'tailwindcss/utilities.css' layer(utilities); +@custom-variant dark (&:where(.dark, .dark *)); + @layer cmsui { + @import '@plone/components/src/styles/basic/theme.css'; + body.cmsui { --background: hsl(0 0% 100%); --foreground: hsl(222.2 84% 4.9%); @@ -69,6 +73,8 @@ --default-container-width: 940px; --narrow-container-width: 620px; + --plone-toolbar-width: 80px; + --color-quanta-air: #fff; --color-quanta-space: #000; --color-quanta-denim: #021322; diff --git a/packages/layout/components/Toolbar/Toolbar.css b/packages/layout/components/Toolbar/Toolbar.css new file mode 100644 index 00000000000..f0df80bc4c7 --- /dev/null +++ b/packages/layout/components/Toolbar/Toolbar.css @@ -0,0 +1,100 @@ +.toolbar { + position: fixed; + z-index: 10; + top: 0; + bottom: 0; + left: 0; + display: flex; + width: var(--plone-toolbar-width); + justify-content: center; + background-color: var(--quanta-smoke); + transition: + left 0.2s ease, + right 0.2s ease, + width 0.2s ease; +} + +.toolbar-buttons { + position: fixed; + z-index: 1; + top: 0; + bottom: 0; + left: 0; + display: flex; + width: var(--plone-toolbar-width); + flex-direction: column; + align-items: center; + justify-content: space-between; + gap: 0.75rem; + margin-block: 1rem; +} + +.toolbar-region { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.75rem; +} + +.toolbar-region > button, +.toolbar-region > a, +.toolbar-button { + display: inline-flex; + width: 44px; + height: 44px; + box-sizing: border-box; + align-items: center; + justify-content: center; + padding: 0; + border: none; + border-radius: 50%; + background-color: transparent; + color: var(--quanta-iron); + cursor: pointer; + /* Reset any inherited browser defaults */ + font-family: inherit; + font-size: 14px; + line-height: 1; + transition: background-color 0.15s ease; +} + +.toolbar-region > button:hover, +.toolbar-region > a:hover, +.toolbar-button:hover { + background-color: var(--quanta-snow); +} + +.toolbar-region > button:active, +.toolbar-region > a:active, +.toolbar-button:active { + background-color: var(--quanta-silver); +} + +.toolbar-region > button:focus-visible, +.toolbar-region > a:focus-visible, +.toolbar-button:focus-visible { + outline: 2px solid var(--quanta-royal); + outline-offset: 2px; +} + +.toolbar-region > button.primary, +.toolbar-region > a.primary, +.toolbar-button.primary { + background-color: var(--quanta-sapphire); + color: var(--quanta-air); +} + +.toolbar-region > button.primary:hover, +.toolbar-region > a.primary:hover, +.toolbar-button.primary:hover { + background-color: var(--quanta-royal); +} + +.toolbar-region > button svg, +.toolbar-region > a svg, +.toolbar-button svg { + display: block; + width: 24px; + height: 24px; + pointer-events: none; +} diff --git a/packages/layout/components/Toolbar/Toolbar.tsx b/packages/layout/components/Toolbar/Toolbar.tsx new file mode 100644 index 00000000000..2bfe290ba6c --- /dev/null +++ b/packages/layout/components/Toolbar/Toolbar.tsx @@ -0,0 +1,90 @@ +/** + * CMS Toolbar — rendered inside a Shadow DOM for full CSS isolation. + * + * Why Shadow DOM? + * Third-party Plone themes can ship any CSS they like. A theme's rules must + * never leak into the toolbar, and the toolbar's rules must never leak into + * the public page. Shadow DOM provides a hard boundary: styles declared + * inside the shadow root do not inherit from the host page, and the host + * page's selectors cannot pierce the boundary. + * + * The toolbar is client-side only (useEffect attaches the shadow root). + * On the server the host
is rendered as an inert empty element, which + * is acceptable because permission-gated UI requires an authenticated request + * anyway. + * + * React context (Jotai, Router, Pluggables…) flows through createPortal + * unchanged — portals preserve the React tree's context even when the DOM + * target is a shadow root. + */ + +import { createPortal } from 'react-dom'; +import { useEffect, useRef, useState } from 'react'; +import { useRouteLoaderData } from 'react-router'; +import type { RootLoader } from 'seven/app/root'; +import { Pluggable } from '../Pluggable'; +import { shouldShowToolbar } from '../../helpers'; +import toolbarStyles from './Toolbar.css?inline'; +import { useTranslation } from 'react-i18next'; + +function ToolbarInner() { + const { t } = useTranslation(); + + return ( + + ); +} + +/** + * Renders a fixed CMS toolbar on the left side of the viewport, isolated from + * the host-page stylesheet via Shadow DOM. + * + * Extensibility is handled by the Pluggable system: + * • `toolbar-top` — slot at the top of the toolbar + * • `toolbar-bottom` — slot at the bottom of the toolbar + * + * Register items with `` + * More info about Pluggables: https://6.docs.plone.org/volto/development/pluggables.html + */ +const Toolbar = () => { + const rootData = useRouteLoaderData('root'); + const [shadowRoot, setShadowRoot] = useState(null); + const hostRef = useRef(null); + + const showToolbar = !!rootData?.content + ? shouldShowToolbar(rootData.content) + : false; + + useEffect(() => { + if (!hostRef.current || hostRef.current.shadowRoot) return; + const root = hostRef.current.attachShadow({ mode: 'open' }); + setShadowRoot(root); + }, []); + + // The host element is always rendered so the ref is stable. No content is + // placed in the shadow root until we know the user can edit. + return ( +
+ {shadowRoot && + showToolbar && + createPortal( + <> + + + , + shadowRoot, + )} +
+ ); +}; + +export default Toolbar; diff --git a/packages/layout/helpers/index.ts b/packages/layout/helpers/index.ts index b6cd024a0d7..6bec2ba4f17 100644 --- a/packages/layout/helpers/index.ts +++ b/packages/layout/helpers/index.ts @@ -28,3 +28,12 @@ export function NotContentTypeCondition(contentType: string[]) { ); }; } + +export function shouldShowToolbar(content: Content) { + const actions = content['@components']?.actions; + const isVisible = + (actions?.object?.some((a) => a.id === 'edit') ?? false) || + (actions?.object_buttons?.some((a) => a.id === 'edit') ?? false); + + return isVisible; +} diff --git a/packages/layout/locales/en/common.json b/packages/layout/locales/en/common.json index 30047b61f2f..9e791c24e7f 100644 --- a/packages/layout/locales/en/common.json +++ b/packages/layout/locales/en/common.json @@ -13,6 +13,9 @@ "file": { "download": "Download file" } + }, + "toolbar": { + "label": "Toolbar" } } } diff --git a/packages/layout/locales/it/common.json b/packages/layout/locales/it/common.json index 8e4202ecf30..551ea16fd64 100644 --- a/packages/layout/locales/it/common.json +++ b/packages/layout/locales/it/common.json @@ -13,6 +13,9 @@ "file": { "download": "Clicca per scaricare il file" } + }, + "toolbar": { + "label": "Barra degli strumenti" } } } diff --git a/packages/layout/news/6649.feature b/packages/layout/news/6649.feature new file mode 100644 index 00000000000..f37df625361 --- /dev/null +++ b/packages/layout/news/6649.feature @@ -0,0 +1 @@ +Added the left toolbar @pnicolli diff --git a/packages/plate/components/editor/plugins/media-base-kit.tsx b/packages/plate/components/editor/plugins/media-base-kit.tsx index 04a95abeb50..9614dec7493 100644 --- a/packages/plate/components/editor/plugins/media-base-kit.tsx +++ b/packages/plate/components/editor/plugins/media-base-kit.tsx @@ -2,7 +2,7 @@ import { BaseCaptionPlugin } from '@platejs/caption'; import { BaseAudioPlugin, BaseFilePlugin, - BaseImagePlugin, + // BaseImagePlugin, BaseMediaEmbedPlugin, BasePlaceholderPlugin, BaseVideoPlugin, @@ -11,11 +11,11 @@ import { KEYS } from 'platejs'; import { AudioElementStatic } from '../../ui/media-audio-node-static'; import { FileElementStatic } from '../../ui/media-file-node-static'; -import { ImageElementStatic } from '../../ui/media-image-node-static'; +// import { ImageElementStatic } from '../../ui/media-image-node-static'; import { VideoElementStatic } from '../../ui/media-video-node-static'; export const BaseMediaKit = [ - BaseImagePlugin.withComponent(ImageElementStatic), + // BaseImagePlugin.withComponent(ImageElementStatic), BaseVideoPlugin.withComponent(VideoElementStatic), BaseAudioPlugin.withComponent(AudioElementStatic), BaseFilePlugin.withComponent(FileElementStatic), diff --git a/packages/plate/components/editor/plugins/media-kit.tsx b/packages/plate/components/editor/plugins/media-kit.tsx index 98582bb6f92..4171569bceb 100644 --- a/packages/plate/components/editor/plugins/media-kit.tsx +++ b/packages/plate/components/editor/plugins/media-kit.tsx @@ -2,7 +2,7 @@ import { CaptionPlugin } from '@platejs/caption/react'; import { AudioPlugin, FilePlugin, - ImagePlugin, + // ImagePlugin, MediaEmbedPlugin, PlaceholderPlugin, VideoPlugin, @@ -12,19 +12,19 @@ import { KEYS } from 'platejs'; import { AudioElement } from '../../ui/media-audio-node'; import { MediaEmbedElement } from '../../ui/media-embed-node'; import { FileElement } from '../../ui/media-file-node'; -import { ImageElement } from '../../ui/media-image-node'; +// import { ImageElement } from '../../ui/media-image-node'; import { PlaceholderElement } from '../../ui/media-placeholder-node'; -import { MediaPreviewDialog } from '../../ui/media-preview-dialog'; +// import { MediaPreviewDialog } from '../../ui/media-preview-dialog'; import { MediaUploadToast } from '../../ui/media-upload-toast'; import { VideoElement } from '../../ui/media-video-node'; export const MediaKit = [ - ImagePlugin.configure({ - // Image nodes are inserted empty and completed through the custom - // source dialog in `media-image-node.tsx`. - options: { disableUploadInsert: true }, - render: { afterEditable: MediaPreviewDialog, node: ImageElement }, - }), + // ImagePlugin.configure({ + // // Image nodes are inserted empty and completed through the custom + // // source dialog in `media-image-node.tsx`. + // options: { disableUploadInsert: true }, + // render: { afterEditable: MediaPreviewDialog, node: ImageElement }, + // }), MediaEmbedPlugin.withComponent(MediaEmbedElement), VideoPlugin.withComponent(VideoElement), AudioPlugin.withComponent(AudioElement), diff --git a/packages/plate/input.css b/packages/plate/input.css deleted file mode 100644 index be9482be7bb..00000000000 --- a/packages/plate/input.css +++ /dev/null @@ -1,17 +0,0 @@ -/* seven/packages/plate/input.css */ -@import 'tailwindcss'; - -/* Plate’s own code */ -@source './components/**/*.{ts,tsx,js,jsx}'; -@source './stories/**/*.{ts,tsx,js,jsx}'; -@source './lib/**/*.{ts,tsx,js,jsx}'; - -/* Dependencies that contain Tailwind classes */ -@source './node_modules/@platejs/**/*.{js,jsx,ts,tsx}'; -@source './node_modules/@radix-ui/**/*.{js,jsx,ts,tsx}'; -@source './node_modules/sonner/**/*.{js,jsx,ts,tsx}'; - -/* Optional: keep Tailwind from walking into nested deps */ -@source not './node_modules/**/node_modules/**'; - -@import '../theming/styles/colors.css'; diff --git a/packages/plate/news/8015.breaking b/packages/plate/news/8015.breaking new file mode 100644 index 00000000000..e7601793ede --- /dev/null +++ b/packages/plate/news/8015.breaking @@ -0,0 +1,2 @@ +Remove output.css from @plone/plate and generation command. @sneridagh +Remove Plate image plugin. @sneridagh diff --git a/packages/plate/output.css b/packages/plate/output.css deleted file mode 100644 index 30541df6c82..00000000000 --- a/packages/plate/output.css +++ /dev/null @@ -1,4305 +0,0 @@ -/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */ -@layer properties; -@layer theme, base, components, utilities; -@layer theme { - :root, :host { - --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", - "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", - "Courier New", monospace; - --color-red-100: oklch(93.6% 0.032 17.717); - --color-red-200: oklch(88.5% 0.062 18.334); - --color-red-700: oklch(50.5% 0.213 27.518); - --color-emerald-100: oklch(95% 0.052 163.051); - --color-emerald-200: oklch(90.5% 0.093 164.15); - --color-emerald-700: oklch(50.8% 0.118 165.612); - --color-purple-50: oklch(97.7% 0.014 308.299); - --color-purple-100: oklch(94.6% 0.033 307.174); - --color-purple-800: oklch(43.8% 0.218 303.724); - --color-slate-500: oklch(55.4% 0.046 257.417); - --color-gray-300: oklch(87.2% 0.01 258.338); - --color-gray-400: oklch(70.7% 0.022 261.325); - --color-gray-500: oklch(55.1% 0.027 264.364); - --color-black: #000; - --color-white: #fff; - --spacing: 0.25rem; - --container-lg: 32rem; - --text-xs: 0.75rem; - --text-xs--line-height: calc(1 / 0.75); - --text-sm: 0.875rem; - --text-sm--line-height: calc(1.25 / 0.875); - --text-base: 1rem; - --text-base--line-height: calc(1.5 / 1); - --text-lg: 1.125rem; - --text-lg--line-height: calc(1.75 / 1.125); - --text-xl: 1.25rem; - --text-xl--line-height: calc(1.75 / 1.25); - --text-2xl: 1.5rem; - --text-2xl--line-height: calc(2 / 1.5); - --text-4xl: 2.25rem; - --text-4xl--line-height: calc(2.5 / 2.25); - --font-weight-normal: 400; - --font-weight-medium: 500; - --font-weight-semibold: 600; - --font-weight-bold: 700; - --tracking-tight: -0.025em; - --tracking-widest: 0.1em; - --radius-xs: 0.125rem; - --radius-sm: 0.25rem; - --radius-md: 0.375rem; - --radius-lg: 0.5rem; - --radius-xl: 0.75rem; - --radius-2xl: 1rem; - --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); - --animate-spin: spin 1s linear infinite; - --blur-sm: 8px; - --aspect-video: 16 / 9; - --default-transition-duration: 150ms; - --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - --default-font-family: var(--font-sans); - --default-mono-font-family: var(--font-mono); - --color-quanta-azure: #7cc0f8; - --color-quanta-sapphire: #0b78d0; - } -} -@layer base { - *, ::after, ::before, ::backdrop, ::file-selector-button { - box-sizing: border-box; - margin: 0; - padding: 0; - border: 0 solid; - } - html, :host { - line-height: 1.5; - -webkit-text-size-adjust: 100%; - tab-size: 4; - font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); - font-feature-settings: var(--default-font-feature-settings, normal); - font-variation-settings: var(--default-font-variation-settings, normal); - -webkit-tap-highlight-color: transparent; - } - hr { - height: 0; - color: inherit; - border-top-width: 1px; - } - abbr:where([title]) { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; - } - h1, h2, h3, h4, h5, h6 { - font-size: inherit; - font-weight: inherit; - } - a { - color: inherit; - -webkit-text-decoration: inherit; - text-decoration: inherit; - } - b, strong { - font-weight: bolder; - } - code, kbd, samp, pre { - font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace); - font-feature-settings: var(--default-mono-font-feature-settings, normal); - font-variation-settings: var(--default-mono-font-variation-settings, normal); - font-size: 1em; - } - small { - font-size: 80%; - } - sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; - } - sub { - bottom: -0.25em; - } - sup { - top: -0.5em; - } - table { - text-indent: 0; - border-color: inherit; - border-collapse: collapse; - } - :-moz-focusring { - outline: auto; - } - progress { - vertical-align: baseline; - } - summary { - display: list-item; - } - ol, ul, menu { - list-style: none; - } - img, svg, video, canvas, audio, iframe, embed, object { - display: block; - vertical-align: middle; - } - img, video { - max-width: 100%; - height: auto; - } - button, input, select, optgroup, textarea, ::file-selector-button { - font: inherit; - font-feature-settings: inherit; - font-variation-settings: inherit; - letter-spacing: inherit; - color: inherit; - border-radius: 0; - background-color: transparent; - opacity: 1; - } - :where(select:is([multiple], [size])) optgroup { - font-weight: bolder; - } - :where(select:is([multiple], [size])) optgroup option { - padding-inline-start: 20px; - } - ::file-selector-button { - margin-inline-end: 4px; - } - ::placeholder { - opacity: 1; - } - @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) { - ::placeholder { - color: currentcolor; - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, currentcolor 50%, transparent); - } - } - } - textarea { - resize: vertical; - } - ::-webkit-search-decoration { - -webkit-appearance: none; - } - ::-webkit-date-and-time-value { - min-height: 1lh; - text-align: inherit; - } - ::-webkit-datetime-edit { - display: inline-flex; - } - ::-webkit-datetime-edit-fields-wrapper { - padding: 0; - } - ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field { - padding-block: 0; - } - ::-webkit-calendar-picker-indicator { - line-height: 1; - } - :-moz-ui-invalid { - box-shadow: none; - } - button, input:where([type="button"], [type="reset"], [type="submit"]), ::file-selector-button { - appearance: button; - } - ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { - height: auto; - } - [hidden]:where(:not([hidden="until-found"])) { - display: none !important; - } -} -@layer utilities { - .pointer-events-auto { - pointer-events: auto; - } - .pointer-events-none { - pointer-events: none; - } - .collapse { - visibility: collapse; - } - .invisible { - visibility: hidden; - } - .visible { - visibility: visible; - } - .sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip-path: inset(50%); - white-space: nowrap; - border-width: 0; - } - .absolute { - position: absolute; - } - .fixed { - position: fixed; - } - .relative { - position: relative; - } - .static { - position: static; - } - .sticky { - position: sticky; - } - .inset-0 { - inset: calc(var(--spacing) * 0); - } - .inset-x-0 { - inset-inline: calc(var(--spacing) * 0); - } - .inset-y-0 { - inset-block: calc(var(--spacing) * 0); - } - .-top-2 { - top: calc(var(--spacing) * -2); - } - .-top-px { - top: -1px; - } - .top-0 { - top: calc(var(--spacing) * 0); - } - .top-1 { - top: calc(var(--spacing) * 1); - } - .top-1\/2 { - top: calc(1/2 * 100%); - } - .top-2 { - top: calc(var(--spacing) * 2); - } - .top-4 { - top: calc(var(--spacing) * 4); - } - .top-\[-1px\] { - top: -1px; - } - .top-\[5px\] { - top: 5px; - } - .top-\[50\%\] { - top: 50%; - } - .-right-1 { - right: calc(var(--spacing) * -1); - } - .-right-3 { - right: calc(var(--spacing) * -3); - } - .right-0 { - right: calc(var(--spacing) * 0); - } - .right-0\.5 { - right: calc(var(--spacing) * 0.5); - } - .right-1 { - right: calc(var(--spacing) * 1); - } - .right-2 { - right: calc(var(--spacing) * 2); - } - .right-4 { - right: calc(var(--spacing) * 4); - } - .right-\[-1\.5px\] { - right: -1.5px; - } - .right-\[-11px\] { - right: -11px; - } - .-bottom-1 { - bottom: calc(var(--spacing) * -1); - } - .-bottom-px { - bottom: -1px; - } - .bottom-0 { - bottom: calc(var(--spacing) * 0); - } - .bottom-0\.5 { - bottom: calc(var(--spacing) * 0.5); - } - .bottom-1 { - bottom: calc(var(--spacing) * 1); - } - .bottom-2 { - bottom: calc(var(--spacing) * 2); - } - .bottom-4 { - bottom: calc(var(--spacing) * 4); - } - .bottom-\[-1px\] { - bottom: -1px; - } - .-left-0 { - left: calc(var(--spacing) * -0); - } - .-left-0\.5 { - left: calc(var(--spacing) * -0.5); - } - .-left-1 { - left: calc(var(--spacing) * -1); - } - .-left-3 { - left: calc(var(--spacing) * -3); - } - .-left-6 { - left: calc(var(--spacing) * -6); - } - .left-0 { - left: calc(var(--spacing) * 0); - } - .left-1\/2 { - left: calc(1/2 * 100%); - } - .left-2 { - left: calc(var(--spacing) * 2); - } - .left-3 { - left: calc(var(--spacing) * 3); - } - .left-\[-1\.5px\] { - left: -1.5px; - } - .left-\[-10\.5px\] { - left: -10.5px; - } - .left-\[50\%\] { - left: 50%; - } - .z-1 { - z-index: 1; - } - .z-10 { - z-index: 10; - } - .z-20 { - z-index: 20; - } - .z-30 { - z-index: 30; - } - .z-40 { - z-index: 40; - } - .z-50 { - z-index: 50; - } - .z-51 { - z-index: 51; - } - .z-100 { - z-index: 100; - } - .z-500 { - z-index: 500; - } - .col-span-1 { - grid-column: span 1 / span 1; - } - .container { - width: 100%; - @media (width >= 40rem) { - max-width: 40rem; - } - @media (width >= 48rem) { - max-width: 48rem; - } - @media (width >= 64rem) { - max-width: 64rem; - } - @media (width >= 80rem) { - max-width: 80rem; - } - @media (width >= 96rem) { - max-width: 96rem; - } - } - .m-0 { - margin: calc(var(--spacing) * 0); - } - .-mx-1 { - margin-inline: calc(var(--spacing) * -1); - } - .mx-1 { - margin-inline: calc(var(--spacing) * 1); - } - .mx-1\.5 { - margin-inline: calc(var(--spacing) * 1.5); - } - .mx-2 { - margin-inline: calc(var(--spacing) * 2); - } - .mx-auto { - margin-inline: auto; - } - .mx-px { - margin-inline: 1px; - } - .my-1 { - margin-block: calc(var(--spacing) * 1); - } - .my-1\.5 { - margin-block: calc(var(--spacing) * 1.5); - } - .my-px { - margin-block: 1px; - } - .mt-0\.5 { - margin-top: calc(var(--spacing) * 0.5); - } - .mt-1 { - margin-top: calc(var(--spacing) * 1); - } - .mt-1\.5 { - margin-top: calc(var(--spacing) * 1.5); - } - .mt-2 { - margin-top: calc(var(--spacing) * 2); - } - .mt-\[0\.75em\] { - margin-top: 0.75em; - } - .mt-\[1\.4em\] { - margin-top: 1.4em; - } - .mt-\[1\.6em\] { - margin-top: 1.6em; - } - .mt-\[1em\] { - margin-top: 1em; - } - .-mr-3 { - margin-right: calc(var(--spacing) * -3); - } - .mr-0 { - margin-right: calc(var(--spacing) * 0); - } - .mr-1 { - margin-right: calc(var(--spacing) * 1); - } - .mr-1\.5 { - margin-right: calc(var(--spacing) * 1.5); - } - .mr-2 { - margin-right: calc(var(--spacing) * 2); - } - .mr-3 { - margin-right: calc(var(--spacing) * 3); - } - .mr-auto { - margin-right: auto; - } - .mb-0 { - margin-bottom: calc(var(--spacing) * 0); - } - .mb-1 { - margin-bottom: calc(var(--spacing) * 1); - } - .mb-2 { - margin-bottom: calc(var(--spacing) * 2); - } - .mb-4 { - margin-bottom: calc(var(--spacing) * 4); - } - .-ml-2 { - margin-left: calc(var(--spacing) * -2); - } - .-ml-3 { - margin-left: calc(var(--spacing) * -3); - } - .ml-1 { - margin-left: calc(var(--spacing) * 1); - } - .ml-2 { - margin-left: calc(var(--spacing) * 2); - } - .ml-auto { - margin-left: auto; - } - .ml-px { - margin-left: 1px; - } - .box-border { - box-sizing: border-box; - } - .box-content { - box-sizing: content-box; - } - .block { - display: block; - } - .contents { - display: contents; - } - .flex { - display: flex; - } - .flex\! { - display: flex !important; - } - .flow-root { - display: flow-root; - } - .grid { - display: grid; - } - .hidden { - display: none; - } - .inline { - display: inline; - } - .inline-block { - display: inline-block; - } - .inline-flex { - display: inline-flex; - } - .table { - display: table; - } - .aspect-square { - aspect-ratio: 1 / 1; - } - .aspect-video { - aspect-ratio: var(--aspect-video); - } - .\!size-3 { - width: calc(var(--spacing) * 3) !important; - height: calc(var(--spacing) * 3) !important; - } - .\!size-3\.5 { - width: calc(var(--spacing) * 3.5) !important; - height: calc(var(--spacing) * 3.5) !important; - } - .size-0 { - width: calc(var(--spacing) * 0); - height: calc(var(--spacing) * 0); - } - .size-2 { - width: calc(var(--spacing) * 2); - height: calc(var(--spacing) * 2); - } - .size-2\.5 { - width: calc(var(--spacing) * 2.5); - height: calc(var(--spacing) * 2.5); - } - .size-3 { - width: calc(var(--spacing) * 3); - height: calc(var(--spacing) * 3); - } - .size-3\.5 { - width: calc(var(--spacing) * 3.5); - height: calc(var(--spacing) * 3.5); - } - .size-4 { - width: calc(var(--spacing) * 4); - height: calc(var(--spacing) * 4); - } - .size-5 { - width: calc(var(--spacing) * 5); - height: calc(var(--spacing) * 5); - } - .size-6 { - width: calc(var(--spacing) * 6); - height: calc(var(--spacing) * 6); - } - .size-8 { - width: calc(var(--spacing) * 8); - height: calc(var(--spacing) * 8); - } - .size-9 { - width: calc(var(--spacing) * 9); - height: calc(var(--spacing) * 9); - } - .size-\[28px\] { - width: 28px; - height: 28px; - } - .size-\[130px\] { - width: 130px; - height: 130px; - } - .size-full { - width: 100%; - height: 100%; - } - .h-0\.5 { - height: calc(var(--spacing) * 0.5); - } - .h-2 { - height: calc(var(--spacing) * 2); - } - .h-4 { - height: calc(var(--spacing) * 4); - } - .h-5 { - height: calc(var(--spacing) * 5); - } - .h-6 { - height: calc(var(--spacing) * 6); - } - .h-7 { - height: calc(var(--spacing) * 7); - } - .h-8 { - height: calc(var(--spacing) * 8); - } - .h-9 { - height: calc(var(--spacing) * 9); - } - .h-10 { - height: calc(var(--spacing) * 10); - } - .h-16 { - height: calc(var(--spacing) * 16); - } - .h-20 { - height: calc(var(--spacing) * 20); - } - .h-\[0\.1px\] { - height: 0.1px; - } - .h-\[1\.5em\] { - height: 1.5em; - } - .h-\[24px\] { - height: 24px; - } - .h-\[28px\] { - height: 28px; - } - .h-\[344px\] { - height: 344px; - } - .h-\[650px\] { - height: 650px; - } - .h-\[calc\(100\%_\+_8px\)\] { - height: calc(100% + 8px); - } - .h-auto { - height: auto; - } - .h-full { - height: 100%; - } - .h-px { - height: 1px; - } - .h-screen { - height: 100vh; - } - .max-h-\(--radix-context-menu-content-available-height\) { - max-height: var(--radix-context-menu-content-available-height); - } - .max-h-\(--radix-dropdown-menu-content-available-height\) { - max-height: var(--radix-dropdown-menu-content-available-height); - } - .max-h-\[288px\] { - max-height: 288px; - } - .max-h-\[300px\] { - max-height: 300px; - } - .max-h-\[500px\] { - max-height: 500px; - } - .max-h-\[calc\(100vh-4rem\)\] { - max-height: calc(100vh - 4rem); - } - .max-h-\[min\(50dvh\,calc\(-24px\+var\(--radix-popper-available-height\)\)\)\] { - max-height: min(50dvh, calc(-24px + var(--radix-popper-available-height))); - } - .max-h-\[min\(70vh\,320px\)\] { - max-height: min(70vh, 320px); - } - .max-h-screen { - max-height: 100vh; - } - .min-h-\[1lh\] { - min-height: 1lh; - } - .min-h-\[25px\] { - min-height: 25px; - } - .w-0\.5 { - width: calc(var(--spacing) * 0.5); - } - .w-1 { - width: calc(var(--spacing) * 1); - } - .w-2 { - width: calc(var(--spacing) * 2); - } - .w-4 { - width: calc(var(--spacing) * 4); - } - .w-4\.5 { - width: calc(var(--spacing) * 4.5); - } - .w-6 { - width: calc(var(--spacing) * 6); - } - .w-8 { - width: calc(var(--spacing) * 8); - } - .w-10 { - width: calc(var(--spacing) * 10); - } - .w-48 { - width: calc(var(--spacing) * 48); - } - .w-64 { - width: calc(var(--spacing) * 64); - } - .w-72 { - width: calc(var(--spacing) * 72); - } - .w-\[180px\] { - width: 180px; - } - .w-\[200px\] { - width: 200px; - } - .w-\[300px\] { - width: 300px; - } - .w-\[330px\] { - width: 330px; - } - .w-\[380px\] { - width: 380px; - } - .w-\[600px\] { - width: 600px; - } - .w-auto { - width: auto; - } - .w-fit { - width: fit-content; - } - .w-full { - width: 100%; - } - .w-px { - width: 1px; - } - .w-screen { - width: 100vw; - } - .max-w-\[80vw\] { - max-width: 80vw; - } - .max-w-\[700px\] { - max-width: 700px; - } - .max-w-\[calc\(100\%-2rem\)\] { - max-width: calc(100% - 2rem); - } - .max-w-\[calc\(100vw-24px\)\] { - max-width: calc(100vw - 24px); - } - .max-w-full { - max-width: 100%; - } - .min-w-0 { - min-width: calc(var(--spacing) * 0); - } - .min-w-8 { - min-width: calc(var(--spacing) * 8); - } - .min-w-9 { - min-width: calc(var(--spacing) * 9); - } - .min-w-10 { - min-width: calc(var(--spacing) * 10); - } - .min-w-\[8rem\] { - min-width: 8rem; - } - .min-w-\[92px\] { - min-width: 92px; - } - .min-w-\[125px\] { - min-width: 125px; - } - .min-w-\[130px\] { - min-width: 130px; - } - .min-w-\[180px\] { - min-width: 180px; - } - .min-w-\[220px\] { - min-width: 220px; - } - .min-w-full { - min-width: 100%; - } - .flex-1 { - flex: 1; - } - .shrink { - flex-shrink: 1; - } - .shrink-0 { - flex-shrink: 0; - } - .grow { - flex-grow: 1; - } - .table-fixed { - table-layout: fixed; - } - .border-collapse { - border-collapse: collapse; - } - .origin-\(--radix-context-menu-content-transform-origin\) { - transform-origin: var(--radix-context-menu-content-transform-origin); - } - .origin-\(--radix-dropdown-menu-content-transform-origin\) { - transform-origin: var(--radix-dropdown-menu-content-transform-origin); - } - .origin-\(--radix-popover-content-transform-origin\) { - transform-origin: var(--radix-popover-content-transform-origin); - } - .origin-\(--radix-tooltip-content-transform-origin\) { - transform-origin: var(--radix-tooltip-content-transform-origin); - } - .-translate-x-1\/2 { - --tw-translate-x: calc(calc(1/2 * 100%) * -1); - translate: var(--tw-translate-x) var(--tw-translate-y); - } - .-translate-x-full { - --tw-translate-x: -100%; - translate: var(--tw-translate-x) var(--tw-translate-y); - } - .translate-x-\[-50\%\] { - --tw-translate-x: -50%; - translate: var(--tw-translate-x) var(--tw-translate-y); - } - .-translate-y-1\/2 { - --tw-translate-y: calc(calc(1/2 * 100%) * -1); - translate: var(--tw-translate-x) var(--tw-translate-y); - } - .translate-y-\[-50\%\] { - --tw-translate-y: -50%; - translate: var(--tw-translate-x) var(--tw-translate-y); - } - .translate-y-\[calc\(-50\%_-_2px\)\] { - --tw-translate-y: calc(-50% - 2px); - translate: var(--tw-translate-x) var(--tw-translate-y); - } - .rotate-0 { - rotate: 0deg; - } - .rotate-45 { - rotate: 45deg; - } - .rotate-90 { - rotate: 90deg; - } - .transform { - transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,); - } - .animate-spin { - animation: var(--animate-spin); - } - .cursor-col-resize { - cursor: col-resize; - } - .cursor-default { - cursor: default; - } - .cursor-grab { - cursor: grab; - } - .cursor-not-allowed { - cursor: not-allowed; - } - .cursor-pointer { - cursor: pointer; - } - .cursor-row-resize { - cursor: row-resize; - } - .cursor-text { - cursor: text; - } - .resize { - resize: both; - } - .resize-none { - resize: none; - } - .scroll-py-1 { - scroll-padding-block: calc(var(--spacing) * 1); - } - .list-none { - list-style-type: none; - } - .grid-cols-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - .grid-cols-8 { - grid-template-columns: repeat(8, minmax(0, 1fr)); - } - .grid-cols-\[repeat\(10\,1fr\)\] { - grid-template-columns: repeat(10,1fr); - } - .flex-col { - flex-direction: column; - } - .flex-col-reverse { - flex-direction: column-reverse; - } - .flex-row { - flex-direction: row; - } - .flex-wrap { - flex-wrap: wrap; - } - .place-items-center { - place-items: center; - } - .items-center { - align-items: center; - } - .items-end { - align-items: flex-end; - } - .items-start { - align-items: flex-start; - } - .justify-between { - justify-content: space-between; - } - .justify-center { - justify-content: center; - } - .gap-0 { - gap: calc(var(--spacing) * 0); - } - .gap-0\.5 { - gap: calc(var(--spacing) * 0.5); - } - .gap-1 { - gap: calc(var(--spacing) * 1); - } - .gap-1\.5 { - gap: calc(var(--spacing) * 1.5); - } - .gap-2 { - gap: calc(var(--spacing) * 2); - } - .gap-3 { - gap: calc(var(--spacing) * 3); - } - .gap-4 { - gap: calc(var(--spacing) * 4); - } - .gap-5 { - gap: calc(var(--spacing) * 5); - } - .gap-6 { - gap: calc(var(--spacing) * 6); - } - .gap-x-1 { - column-gap: calc(var(--spacing) * 1); - } - .space-x-1 { - :where(& > :not(:last-child)) { - --tw-space-x-reverse: 0; - margin-inline-start: calc(calc(var(--spacing) * 1) * var(--tw-space-x-reverse)); - margin-inline-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-x-reverse))); - } - } - .space-x-2 { - :where(& > :not(:last-child)) { - --tw-space-x-reverse: 0; - margin-inline-start: calc(calc(var(--spacing) * 2) * var(--tw-space-x-reverse)); - margin-inline-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-x-reverse))); - } - } - .truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .overflow-hidden { - overflow: hidden; - } - .overflow-visible { - overflow: visible; - } - .overflow-x-auto { - overflow-x: auto; - } - .overflow-x-hidden { - overflow-x: hidden; - } - .overflow-y-auto { - overflow-y: auto; - } - .overflow-y-hidden { - overflow-y: hidden; - } - .rounded { - border-radius: 0.25rem; - } - .rounded-2xl { - border-radius: var(--radius-2xl); - } - .rounded-\[2px\] { - border-radius: 2px; - } - .rounded-\[4px\] { - border-radius: 4px; - } - .rounded-\[50\%\] { - border-radius: 50%; - } - .rounded-full { - border-radius: calc(infinity * 1px); - } - .rounded-lg { - border-radius: var(--radius-lg); - } - .rounded-md { - border-radius: var(--radius-md); - } - .rounded-none { - border-radius: 0; - } - .rounded-sm { - border-radius: var(--radius-sm); - } - .rounded-xl { - border-radius: var(--radius-xl); - } - .rounded-xs { - border-radius: var(--radius-xs); - } - .rounded-t-lg { - border-top-left-radius: var(--radius-lg); - border-top-right-radius: var(--radius-lg); - } - .rounded-r-md { - border-top-right-radius: var(--radius-md); - border-bottom-right-radius: var(--radius-md); - } - .rounded-r-none { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } - .border { - border-style: var(--tw-border-style); - border-width: 1px; - } - .border-0 { - border-style: var(--tw-border-style); - border-width: 0px; - } - .border-2 { - border-style: var(--tw-border-style); - border-width: 2px; - } - .border-\[1\.5px\] { - border-style: var(--tw-border-style); - border-width: 1.5px; - } - .border-b { - border-bottom-style: var(--tw-border-style); - border-bottom-width: 1px; - } - .border-b-2 { - border-bottom-style: var(--tw-border-style); - border-bottom-width: 2px; - } - .border-l-0 { - border-left-style: var(--tw-border-style); - border-left-width: 0px; - } - .border-l-2 { - border-left-style: var(--tw-border-style); - border-left-width: 2px; - } - .border-dashed { - --tw-border-style: dashed; - border-style: dashed; - } - .border-none { - --tw-border-style: none; - border-style: none; - } - .border-solid { - --tw-border-style: solid; - border-style: solid; - } - .border-border { - border-color: var(--border); - } - .border-border\/50 { - border-color: var(--border); - @supports (color: color-mix(in lab, red, red)) { - border-color: color-mix(in oklab, var(--border) 50%, transparent); - } - } - .border-brand\/\[0\.8\] { - border-color: color-mix(in srgb, #0b78d0 80%, transparent); - @supports (color: color-mix(in lab, red, red)) { - border-color: color-mix(in oklab, var(--color-quanta-sapphire) 80%, transparent); - } - } - .border-current { - border-color: currentcolor; - } - .border-gray-300 { - border-color: var(--color-gray-300); - } - .border-input { - border-color: var(--input); - } - .border-muted { - border-color: var(--muted); - } - .border-muted-foreground { - border-color: var(--muted-foreground); - } - .border-primary { - border-color: var(--primary); - } - .border-quanta-azure { - border-color: var(--color-quanta-azure); - } - .border-transparent { - border-color: transparent; - } - .border-t-transparent { - border-top-color: transparent; - } - .border-b-border { - border-bottom-color: var(--border); - } - .border-b-brand\/\[\.24\] { - border-bottom-color: color-mix(in srgb, #0b78d0 24%, transparent); - @supports (color: color-mix(in lab, red, red)) { - border-bottom-color: color-mix(in oklab, var(--color-quanta-sapphire) 24%, transparent); - } - } - .border-b-brand\/\[\.60\] { - border-bottom-color: color-mix(in srgb, #0b78d0 60%, transparent); - @supports (color: color-mix(in lab, red, red)) { - border-bottom-color: color-mix(in oklab, var(--color-quanta-sapphire) 60%, transparent); - } - } - .border-b-gray-300 { - border-bottom-color: var(--color-gray-300); - } - .border-b-gray-500 { - border-bottom-color: var(--color-gray-500); - } - .border-b-purple-100 { - border-bottom-color: var(--color-purple-100); - } - .bg-\(--cellBackground\) { - background-color: var(--cellBackground); - } - .bg-\[rgba\(0\,0\,0\,0\.5\)\] { - background-color: rgba(0,0,0,0.5); - } - .bg-background { - background-color: var(--background); - } - .bg-background\/95 { - background-color: var(--background); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--background) 95%, transparent); - } - } - .bg-black { - background-color: var(--color-black); - } - .bg-black\/50 { - background-color: color-mix(in srgb, #000 50%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-black) 50%, transparent); - } - } - .bg-border { - background-color: var(--border); - } - .bg-brand { - background-color: var(--color-quanta-sapphire); - } - .bg-brand\/25 { - background-color: color-mix(in srgb, #0b78d0 25%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-quanta-sapphire) 25%, transparent); - } - } - .bg-brand\/50 { - background-color: color-mix(in srgb, #0b78d0 50%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-quanta-sapphire) 50%, transparent); - } - } - .bg-brand\/\[\.08\] { - background-color: color-mix(in srgb, #0b78d0 8%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-quanta-sapphire) 8%, transparent); - } - } - .bg-brand\/\[\.13\] { - background-color: color-mix(in srgb, #0b78d0 13%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-quanta-sapphire) 13%, transparent); - } - } - .bg-current { - background-color: currentcolor; - } - .bg-destructive { - background-color: var(--destructive); - } - .bg-emerald-100 { - background-color: var(--color-emerald-100); - } - .bg-emerald-200\/80 { - background-color: color-mix(in srgb, oklch(90.5% 0.093 164.15) 80%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-emerald-200) 80%, transparent); - } - } - .bg-foreground { - background-color: var(--foreground); - } - .bg-gray-300\/25 { - background-color: color-mix(in srgb, oklch(87.2% 0.01 258.338) 25%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-gray-300) 25%, transparent); - } - } - .bg-gray-400\/25 { - background-color: color-mix(in srgb, oklch(70.7% 0.022 261.325) 25%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-gray-400) 25%, transparent); - } - } - .bg-inherit { - background-color: inherit; - } - .bg-muted { - background-color: var(--muted); - } - .bg-muted\/50 { - background-color: var(--muted); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--muted) 50%, transparent); - } - } - .bg-muted\/60 { - background-color: var(--muted); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--muted) 60%, transparent); - } - } - .bg-popover { - background-color: var(--popover); - } - .bg-primary { - background-color: var(--primary); - } - .bg-primary\/40 { - background-color: var(--primary); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--primary) 40%, transparent); - } - } - .bg-purple-50 { - background-color: var(--color-purple-50); - } - .bg-red-100 { - background-color: var(--color-red-100); - } - .bg-red-200\/80 { - background-color: color-mix(in srgb, oklch(88.5% 0.062 18.334) 80%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-red-200) 80%, transparent); - } - } - .bg-ring { - background-color: var(--ring); - } - .bg-secondary { - background-color: var(--secondary); - } - .bg-transparent { - background-color: transparent; - } - .bg-cover { - background-size: cover; - } - .bg-clip-content { - background-clip: content-box; - } - .bg-center { - background-position: center; - } - .fill-current { - fill: currentcolor; - } - .fill-foreground { - fill: var(--foreground); - } - .fill-primary { - fill: var(--primary); - } - .stroke-\[3px\] { - stroke-width: 3px; - } - .object-contain { - object-fit: contain; - } - .object-cover { - object-fit: cover; - } - .p-0 { - padding: calc(var(--spacing) * 0); - } - .p-1 { - padding: calc(var(--spacing) * 1); - } - .p-1\.5 { - padding: calc(var(--spacing) * 1.5); - } - .p-2 { - padding: calc(var(--spacing) * 2); - } - .p-3 { - padding: calc(var(--spacing) * 3); - } - .p-4 { - padding: calc(var(--spacing) * 4); - } - .p-6 { - padding: calc(var(--spacing) * 6); - } - .p-8 { - padding: calc(var(--spacing) * 8); - } - .p-px { - padding: 1px; - } - .\!px-1 { - padding-inline: calc(var(--spacing) * 1) !important; - } - .\!px-1\.5 { - padding-inline: calc(var(--spacing) * 1.5) !important; - } - .px-0 { - padding-inline: calc(var(--spacing) * 0); - } - .px-0\.5 { - padding-inline: calc(var(--spacing) * 0.5); - } - .px-1 { - padding-inline: calc(var(--spacing) * 1); - } - .px-1\.5 { - padding-inline: calc(var(--spacing) * 1.5); - } - .px-2 { - padding-inline: calc(var(--spacing) * 2); - } - .px-2\.5 { - padding-inline: calc(var(--spacing) * 2.5); - } - .px-3 { - padding-inline: calc(var(--spacing) * 3); - } - .px-4 { - padding-inline: calc(var(--spacing) * 4); - } - .px-5 { - padding-inline: calc(var(--spacing) * 5); - } - .px-6 { - padding-inline: calc(var(--spacing) * 6); - } - .px-16 { - padding-inline: calc(var(--spacing) * 16); - } - .px-\[0\.3em\] { - padding-inline: 0.3em; - } - .px-px { - padding-inline: 1px; - } - .py-0 { - padding-block: calc(var(--spacing) * 0); - } - .py-0\.5 { - padding-block: calc(var(--spacing) * 0.5); - } - .py-1 { - padding-block: calc(var(--spacing) * 1); - } - .py-1\.5 { - padding-block: calc(var(--spacing) * 1.5); - } - .py-2 { - padding-block: calc(var(--spacing) * 2); - } - .py-2\.5 { - padding-block: calc(var(--spacing) * 2.5); - } - .py-3 { - padding-block: calc(var(--spacing) * 3); - } - .py-5 { - padding-block: calc(var(--spacing) * 5); - } - .py-6 { - padding-block: calc(var(--spacing) * 6); - } - .py-\[0\.2em\] { - padding-block: 0.2em; - } - .py-\[3px\] { - padding-block: 3px; - } - .pt-0\.5 { - padding-top: calc(var(--spacing) * 0.5); - } - .pt-2 { - padding-top: calc(var(--spacing) * 2); - } - .pt-4 { - padding-top: calc(var(--spacing) * 4); - } - .pr-1 { - padding-right: calc(var(--spacing) * 1); - } - .pr-2 { - padding-right: calc(var(--spacing) * 2); - } - .pr-3 { - padding-right: calc(var(--spacing) * 3); - } - .pr-4 { - padding-right: calc(var(--spacing) * 4); - } - .pr-8 { - padding-right: calc(var(--spacing) * 8); - } - .pr-9 { - padding-right: calc(var(--spacing) * 9); - } - .pb-1 { - padding-bottom: calc(var(--spacing) * 1); - } - .pb-72 { - padding-bottom: calc(var(--spacing) * 72); - } - .pb-\[51\.25\%\] { - padding-bottom: 51.25%; - } - .pb-\[56\.25\%\] { - padding-bottom: 56.25%; - } - .pb-\[56\.0417\%\] { - padding-bottom: 56.0417%; - } - .pb-\[75\%\] { - padding-bottom: 75%; - } - .pb-px { - padding-bottom: 1px; - } - .pl-0\.5 { - padding-left: calc(var(--spacing) * 0.5); - } - .pl-2 { - padding-left: calc(var(--spacing) * 2); - } - .pl-3 { - padding-left: calc(var(--spacing) * 3); - } - .pl-6 { - padding-left: calc(var(--spacing) * 6); - } - .pl-8 { - padding-left: calc(var(--spacing) * 8); - } - .pl-\[26px\] { - padding-left: 26px; - } - .pl-\[32px\] { - padding-left: 32px; - } - .pl-\[50px\] { - padding-left: 50px; - } - .text-center { - text-align: center; - } - .text-end { - text-align: end; - } - .text-justify { - text-align: justify; - } - .text-left { - text-align: left; - } - .text-start { - text-align: start; - } - .align-baseline { - vertical-align: baseline; - } - .font-\[inherit\] { - font-family: inherit; - } - .font-mono { - font-family: var(--font-mono); - } - .text-2xl { - font-size: var(--text-2xl); - line-height: var(--tw-leading, var(--text-2xl--line-height)); - } - .text-4xl { - font-size: var(--text-4xl); - line-height: var(--tw-leading, var(--text-4xl--line-height)); - } - .text-base { - font-size: var(--text-base); - line-height: var(--tw-leading, var(--text-base--line-height)); - } - .text-lg { - font-size: var(--text-lg); - line-height: var(--tw-leading, var(--text-lg--line-height)); - } - .text-sm { - font-size: var(--text-sm); - line-height: var(--tw-leading, var(--text-sm--line-height)); - } - .text-xl { - font-size: var(--text-xl); - line-height: var(--tw-leading, var(--text-xl--line-height)); - } - .text-xs { - font-size: var(--text-xs); - line-height: var(--tw-leading, var(--text-xs--line-height)); - } - .text-\[10px\] { - font-size: 10px; - } - .text-\[18px\] { - font-size: 18px; - } - .leading-\[normal\] { - --tw-leading: normal; - line-height: normal; - } - .leading-none { - --tw-leading: 1; - line-height: 1; - } - .font-bold { - --tw-font-weight: var(--font-weight-bold); - font-weight: var(--font-weight-bold); - } - .font-medium { - --tw-font-weight: var(--font-weight-medium); - font-weight: var(--font-weight-medium); - } - .font-normal { - --tw-font-weight: var(--font-weight-normal); - font-weight: var(--font-weight-normal); - } - .font-semibold { - --tw-font-weight: var(--font-weight-semibold); - font-weight: var(--font-weight-semibold); - } - .tracking-tight { - --tw-tracking: var(--tracking-tight); - letter-spacing: var(--tracking-tight); - } - .tracking-widest { - --tw-tracking: var(--tracking-widest); - letter-spacing: var(--tracking-widest); - } - .text-balance { - text-wrap: balance; - } - .text-nowrap { - text-wrap: nowrap; - } - .break-words { - overflow-wrap: break-word; - } - .whitespace-nowrap { - white-space: nowrap; - } - .whitespace-pre-wrap { - white-space: pre-wrap; - } - .text-background { - color: var(--background); - } - .text-brand\/80 { - color: color-mix(in srgb, #0b78d0 80%, transparent); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--color-quanta-sapphire) 80%, transparent); - } - } - .text-current { - color: currentcolor; - } - .text-emerald-700 { - color: var(--color-emerald-700); - } - .text-foreground { - color: var(--foreground); - } - .text-gray-400 { - color: var(--color-gray-400); - } - .text-gray-500 { - color: var(--color-gray-500); - } - .text-inherit { - color: inherit; - } - .text-muted-foreground { - color: var(--muted-foreground); - } - .text-muted-foreground\/70 { - color: var(--muted-foreground); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--muted-foreground) 70%, transparent); - } - } - .text-muted-foreground\/80 { - color: var(--muted-foreground); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--muted-foreground) 80%, transparent); - } - } - .text-popover-foreground { - color: var(--popover-foreground); - } - .text-primary { - color: var(--primary); - } - .text-primary-foreground { - color: var(--primary-foreground); - } - .text-purple-800 { - color: var(--color-purple-800); - } - .text-red-700 { - color: var(--color-red-700); - } - .text-secondary-foreground { - color: var(--secondary-foreground); - } - .text-slate-500 { - color: var(--color-slate-500); - } - .text-white { - color: var(--color-white); - } - .capitalize { - text-transform: capitalize; - } - .italic { - font-style: italic; - } - .line-through { - text-decoration-line: line-through; - } - .no-underline { - text-decoration-line: none; - } - .underline { - text-decoration-line: underline; - } - .decoration-primary { - text-decoration-color: var(--primary); - } - .decoration-\[0\.5px\] { - text-decoration-thickness: 0.5px; - } - .underline-offset-4 { - text-underline-offset: 4px; - } - .caret-primary { - caret-color: var(--primary); - } - .opacity-0 { - opacity: 0%; - } - .opacity-30 { - opacity: 30%; - } - .opacity-50 { - opacity: 50%; - } - .opacity-70 { - opacity: 70%; - } - .opacity-100 { - opacity: 100%; - } - .shadow-lg { - --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - .shadow-md { - --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - .shadow-none { - --tw-shadow: 0 0 #0000; - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - .shadow-sm { - --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - .shadow-xl { - --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - .shadow-xs { - --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05)); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - .ring-2 { - --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - .shadow-\[rgba\(255\,_255\,_255\,_0\.1\)_0px_0\.5px_0px_0px_inset\,_rgb\(248\,_249\,_250\)_0px_1px_5px_0px_inset\,_rgb\(193\,_200\,_205\)_0px_0px_0px_0\.5px\,_rgb\(193\,_200\,_205\)_0px_2px_1px_-1px\,_rgb\(193\,_200\,_205\)_0px_1px_0px_0px\] { - --tw-shadow-color: rgba(255, 255, 255, 0.1); - @supports (color: color-mix(in lab, red, red)) { - --tw-shadow-color: color-mix(in oklab, rgba(255, 255, 255, 0.1) 0px 0.5px 0px 0px inset, rgb(248, 249, 250) 0px 1px 5px 0px inset, rgb(193, 200, 205) 0px 0px 0px 0.5px, rgb(193, 200, 205) 0px 2px 1px -1px, rgb(193, 200, 205) 0px 1px 0px 0px var(--tw-shadow-alpha), transparent); - } - } - .ring-ring { - --tw-ring-color: var(--ring); - } - .ring-offset-2 { - --tw-ring-offset-width: 2px; - --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - } - .ring-offset-background { - --tw-ring-offset-color: var(--background); - } - .outline-hidden { - --tw-outline-style: none; - outline-style: none; - @media (forced-colors: active) { - outline: 2px solid transparent; - outline-offset: 2px; - } - } - .outline { - outline-style: var(--tw-outline-style); - outline-width: 1px; - } - .blur { - --tw-blur: blur(8px); - filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); - } - .invert { - --tw-invert: invert(100%); - filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); - } - .\!filter { - filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,) !important; - } - .filter { - filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); - } - .backdrop-blur-sm { - --tw-backdrop-blur: blur(var(--blur-sm)); - -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,); - backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,); - } - .transition { - transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .transition-\[color\,box-shadow\] { - transition-property: color,box-shadow; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .transition-all { - transition-property: all; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .transition-colors { - transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .transition-opacity { - transition-property: opacity; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .transition-shadow { - transition-property: box-shadow; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .transition-transform { - transition-property: transform, translate, scale, rotate; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .transition-none { - transition-property: none; - } - .duration-75 { - --tw-duration: 75ms; - transition-duration: 75ms; - } - .duration-100 { - --tw-duration: 100ms; - transition-duration: 100ms; - } - .duration-200 { - --tw-duration: 200ms; - transition-duration: 200ms; - } - .duration-300 { - --tw-duration: 300ms; - transition-duration: 300ms; - } - .ease-in-out { - --tw-ease: var(--ease-in-out); - transition-timing-function: var(--ease-in-out); - } - .\[contain\:content\] { - contain: content; - } - .outline-none { - --tw-outline-style: none; - outline-style: none; - } - .select-none { - -webkit-user-select: none; - user-select: none; - } - .select-text { - -webkit-user-select: text; - user-select: text; - } - .\[tab-size\:2\] { - tab-size: 2; - } - .\*\:m-0 { - :is(& > *) { - margin: calc(var(--spacing) * 0); - } - } - .not-last\:border-b { - &:not(*:last-child) { - border-bottom-style: var(--tw-border-style); - border-bottom-width: 1px; - } - } - .group-first\/column\:-left-1 { - &:is(:where(.group\/column):first-child *) { - left: calc(var(--spacing) * -1); - } - } - .group-first\/column\:pl-0 { - &:is(:where(.group\/column):first-child *) { - padding-left: calc(var(--spacing) * 0); - } - } - .group-last\/column\:-right-1 { - &:is(:where(.group\/column):last-child *) { - right: calc(var(--spacing) * -1); - } - } - .group-last\/column\:pr-0 { - &:is(:where(.group\/column):last-child *) { - padding-right: calc(var(--spacing) * 0); - } - } - .group-last\/toolbar-group\:hidden\! { - &:is(:where(.group\/toolbar-group):last-child *) { - display: none !important; - } - } - .group-focus-within\:pointer-events-none { - &:is(:where(.group):focus-within *) { - pointer-events: none; - } - } - .group-focus-within\:top-0 { - &:is(:where(.group):focus-within *) { - top: calc(var(--spacing) * 0); - } - } - .group-focus-within\:cursor-default { - &:is(:where(.group):focus-within *) { - cursor: default; - } - } - .group-focus-within\:text-xs { - &:is(:where(.group):focus-within *) { - font-size: var(--text-xs); - line-height: var(--tw-leading, var(--text-xs--line-height)); - } - } - .group-focus-within\:font-medium { - &:is(:where(.group):focus-within *) { - --tw-font-weight: var(--font-weight-medium); - font-weight: var(--font-weight-medium); - } - } - .group-focus-within\:text-foreground { - &:is(:where(.group):focus-within *) { - color: var(--foreground); - } - } - .group-hover\:opacity-100 { - &:is(:where(.group):hover *) { - @media (hover: hover) { - opacity: 100%; - } - } - } - .group-hover\/column\:opacity-100 { - &:is(:where(.group\/column):hover *) { - @media (hover: hover) { - opacity: 100%; - } - } - } - .group-hover\/container\:opacity-100 { - &:is(:where(.group\/container):hover *) { - @media (hover: hover) { - opacity: 100%; - } - } - } - .group-hover\/row\:opacity-100 { - &:is(:where(.group\/row):hover *) { - @media (hover: hover) { - opacity: 100%; - } - } - } - .group-has-data-\[resizing\=\"true\"\]\/row\:opacity-0 { - &:is(:where(.group\/row):has(*[data-resizing="true"]) *) { - opacity: 0%; - } - } - .group-has-\[\[data-col\=\"0\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="0"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"0\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="0"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"1\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="1"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"1\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="1"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"10\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="10"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"10\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="10"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"2\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="2"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"2\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="2"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"3\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="3"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"3\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="3"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"4\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="4"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"4\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="4"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"5\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="5"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"5\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="5"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"6\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="6"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"6\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="6"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"7\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="7"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"7\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="7"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"8\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="8"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"8\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="8"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"9\"\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="9"]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-col\=\"9\"\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-col="9"][data-resizing="true"])) *) { - display: block; - } - } - .group-has-\[\[data-resizer-left\]\:hover\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-resizer-left]:hover)) *) { - display: block; - } - } - .group-has-\[\[data-resizer-left\]\[data-resizing\=\"true\"\]\]\/table\:block { - &:is(:where(.group\/table):has(*:is([data-resizer-left][data-resizing="true"])) *) { - display: block; - } - } - .group-data-\[pressed\=true\]\:bg-accent { - &:is(:where(.group)[data-pressed="true"] *) { - background-color: var(--accent); - } - } - .group-data-\[pressed\=true\]\:text-accent-foreground { - &:is(:where(.group)[data-pressed="true"] *) { - color: var(--accent-foreground); - } - } - .peer-has-\[\[role\=menuitem\]\]\/menu-group\:block { - &:is(:where(.peer\/menu-group):has(*:is([role=menuitem])) ~ *) { - display: block; - } - } - .peer-has-\[\[role\=menuitemradio\]\]\/menu-group\:block { - &:is(:where(.peer\/menu-group):has(*:is([role=menuitemradio])) ~ *) { - display: block; - } - } - .peer-has-\[\[role\=option\]\]\/menu-group\:block { - &:is(:where(.peer\/menu-group):has(*:is([role=option])) ~ *) { - display: block; - } - } - .selection\:bg-brand\/25 { - & *::selection { - background-color: color-mix(in srgb, #0b78d0 25%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-quanta-sapphire) 25%, transparent); - } - } - &::selection { - background-color: color-mix(in srgb, #0b78d0 25%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-quanta-sapphire) 25%, transparent); - } - } - } - .selection\:bg-primary { - & *::selection { - background-color: var(--primary); - } - &::selection { - background-color: var(--primary); - } - } - .selection\:bg-transparent { - & *::selection { - background-color: transparent; - } - &::selection { - background-color: transparent; - } - } - .selection\:text-primary-foreground { - & *::selection { - color: var(--primary-foreground); - } - &::selection { - color: var(--primary-foreground); - } - } - .file\:inline-flex { - &::file-selector-button { - display: inline-flex; - } - } - .file\:h-7 { - &::file-selector-button { - height: calc(var(--spacing) * 7); - } - } - .file\:border-0 { - &::file-selector-button { - border-style: var(--tw-border-style); - border-width: 0px; - } - } - .file\:bg-transparent { - &::file-selector-button { - background-color: transparent; - } - } - .file\:text-sm { - &::file-selector-button { - font-size: var(--text-sm); - line-height: var(--tw-leading, var(--text-sm--line-height)); - } - } - .file\:font-medium { - &::file-selector-button { - --tw-font-weight: var(--font-weight-medium); - font-weight: var(--font-weight-medium); - } - } - .file\:text-foreground { - &::file-selector-button { - color: var(--foreground); - } - } - .placeholder\:text-muted-foreground { - &::placeholder { - color: var(--muted-foreground); - } - } - .placeholder\:text-muted-foreground\/80 { - &::placeholder { - color: var(--muted-foreground); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--muted-foreground) 80%, transparent); - } - } - } - .before\:absolute { - &::before { - content: var(--tw-content); - position: absolute; - } - } - .before\:z-10 { - &::before { - content: var(--tw-content); - z-index: 10; - } - } - .before\:box-border { - &::before { - content: var(--tw-content); - box-sizing: border-box; - } - } - .before\:size-full { - &::before { - content: var(--tw-content); - width: 100%; - height: 100%; - } - } - .before\:cursor-text { - &::before { - content: var(--tw-content); - cursor: text; - } - } - .before\:border-t { - &::before { - content: var(--tw-content); - border-top-style: var(--tw-border-style); - border-top-width: 1px; - } - } - .before\:border-r { - &::before { - content: var(--tw-content); - border-right-style: var(--tw-border-style); - border-right-width: 1px; - } - } - .before\:border-b { - &::before { - content: var(--tw-content); - border-bottom-style: var(--tw-border-style); - border-bottom-width: 1px; - } - } - .before\:border-l { - &::before { - content: var(--tw-content); - border-left-style: var(--tw-border-style); - border-left-width: 1px; - } - } - .before\:border-t-border { - &::before { - content: var(--tw-content); - border-top-color: var(--border); - } - } - .before\:border-r-border { - &::before { - content: var(--tw-content); - border-right-color: var(--border); - } - } - .before\:border-b-border { - &::before { - content: var(--tw-content); - border-bottom-color: var(--border); - } - } - .before\:border-l-border { - &::before { - content: var(--tw-content); - border-left-color: var(--border); - } - } - .before\:bg-brand\/5 { - &::before { - content: var(--tw-content); - background-color: color-mix(in srgb, #0b78d0 5%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-quanta-sapphire) 5%, transparent); - } - } - } - .before\:text-muted-foreground\/80 { - &::before { - content: var(--tw-content); - color: var(--muted-foreground); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--muted-foreground) 80%, transparent); - } - } - } - .before\:content-\[\'\'\] { - &::before { - --tw-content: ''; - content: var(--tw-content); - } - } - .before\:content-\[attr\(placeholder\)\] { - &::before { - --tw-content: attr(placeholder); - content: var(--tw-content); - } - } - .before\:select-none { - &::before { - content: var(--tw-content); - -webkit-user-select: none; - user-select: none; - } - } - .after\:ml-1\.5 { - &::after { - content: var(--tw-content); - margin-left: calc(var(--spacing) * 1.5); - } - } - .after\:block { - &::after { - content: var(--tw-content); - display: block; - } - } - .after\:flex { - &::after { - content: var(--tw-content); - display: flex; - } - } - .after\:inline-block { - &::after { - content: var(--tw-content); - display: inline-block; - } - } - .after\:h-3 { - &::after { - content: var(--tw-content); - height: calc(var(--spacing) * 3); - } - } - .after\:h-16 { - &::after { - content: var(--tw-content); - height: calc(var(--spacing) * 16); - } - } - .after\:w-3 { - &::after { - content: var(--tw-content); - width: calc(var(--spacing) * 3); - } - } - .after\:w-\[3px\] { - &::after { - content: var(--tw-content); - width: 3px; - } - } - .after\:rounded-\[6px\] { - &::after { - content: var(--tw-content); - border-radius: 6px; - } - } - .after\:rounded-full { - &::after { - content: var(--tw-content); - border-radius: calc(infinity * 1px); - } - } - .after\:bg-primary { - &::after { - content: var(--tw-content); - background-color: var(--primary); - } - } - .after\:bg-ring { - &::after { - content: var(--tw-content); - background-color: var(--ring); - } - } - .after\:pb-\[var\(--aspect-ratio\)\] { - &::after { - content: var(--tw-content); - padding-bottom: var(--aspect-ratio); - } - } - .after\:align-middle { - &::after { - content: var(--tw-content); - vertical-align: middle; - } - } - .after\:opacity-0 { - &::after { - content: var(--tw-content); - opacity: 0%; - } - } - .after\:content-\[\"\"\] { - &::after { - --tw-content: ""; - content: var(--tw-content); - } - } - .after\:content-\[\'_\'\] { - &::after { - --tw-content: ' '; - content: var(--tw-content); - } - } - .group-hover\:after\:opacity-100 { - &:is(:where(.group):hover *) { - @media (hover: hover) { - &::after { - content: var(--tw-content); - opacity: 100%; - } - } - } - } - .focus-within\:ring-2 { - &:focus-within { - --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - } - .focus-within\:ring-ring { - &:focus-within { - --tw-ring-color: var(--ring); - } - } - .focus-within\:ring-offset-2 { - &:focus-within { - --tw-ring-offset-width: 2px; - --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - } - } - .hover\:scale-125 { - &:hover { - @media (hover: hover) { - --tw-scale-x: 125%; - --tw-scale-y: 125%; - --tw-scale-z: 125%; - scale: var(--tw-scale-x) var(--tw-scale-y); - } - } - } - .hover\:bg-accent { - &:hover { - @media (hover: hover) { - background-color: var(--accent); - } - } - } - .hover\:bg-destructive\/90 { - &:hover { - @media (hover: hover) { - background-color: var(--destructive); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--destructive) 90%, transparent); - } - } - } - } - .hover\:bg-muted { - &:hover { - @media (hover: hover) { - background-color: var(--muted); - } - } - } - .hover\:bg-muted-foreground\/15 { - &:hover { - @media (hover: hover) { - background-color: var(--muted-foreground); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--muted-foreground) 15%, transparent); - } - } - } - } - .hover\:bg-primary\/10 { - &:hover { - @media (hover: hover) { - background-color: var(--primary); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--primary) 10%, transparent); - } - } - } - } - .hover\:bg-primary\/90 { - &:hover { - @media (hover: hover) { - background-color: var(--primary); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--primary) 90%, transparent); - } - } - } - } - .hover\:bg-secondary\/80 { - &:hover { - @media (hover: hover) { - background-color: var(--secondary); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--secondary) 80%, transparent); - } - } - } - } - .hover\:bg-transparent { - &:hover { - @media (hover: hover) { - background-color: transparent; - } - } - } - .hover\:text-accent-foreground { - &:hover { - @media (hover: hover) { - color: var(--accent-foreground); - } - } - } - .hover\:text-brand\/80 { - &:hover { - @media (hover: hover) { - color: color-mix(in srgb, #0b78d0 80%, transparent); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--color-quanta-sapphire) 80%, transparent); - } - } - } - } - .hover\:text-muted-foreground { - &:hover { - @media (hover: hover) { - color: var(--muted-foreground); - } - } - } - .hover\:text-muted-foreground\/80 { - &:hover { - @media (hover: hover) { - color: var(--muted-foreground); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--muted-foreground) 80%, transparent); - } - } - } - } - .hover\:underline { - &:hover { - @media (hover: hover) { - text-decoration-line: underline; - } - } - } - .hover\:opacity-100 { - &:hover { - @media (hover: hover) { - opacity: 100%; - } - } - } - .focus\:bg-accent { - &:focus { - background-color: var(--accent); - } - } - .focus\:text-accent-foreground { - &:focus { - color: var(--accent-foreground); - } - } - .focus\:ring-2 { - &:focus { - --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - } - .focus\:ring-ring { - &:focus { - --tw-ring-color: var(--ring); - } - } - .focus\:ring-offset-2 { - &:focus { - --tw-ring-offset-width: 2px; - --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - } - } - .focus\:outline-hidden { - &:focus { - --tw-outline-style: none; - outline-style: none; - @media (forced-colors: active) { - outline: 2px solid transparent; - outline-offset: 2px; - } - } - } - .focus\:outline-none { - &:focus { - --tw-outline-style: none; - outline-style: none; - } - } - .focus-visible\:border-ring { - &:focus-visible { - border-color: var(--ring); - } - } - .focus-visible\:ring-0 { - &:focus-visible { - --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - } - .focus-visible\:ring-2 { - &:focus-visible { - --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - } - .focus-visible\:ring-\[3px\] { - &:focus-visible { - --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - } - .focus-visible\:ring-destructive\/20 { - &:focus-visible { - --tw-ring-color: var(--destructive); - @supports (color: color-mix(in lab, red, red)) { - --tw-ring-color: color-mix(in oklab, var(--destructive) 20%, transparent); - } - } - } - .focus-visible\:ring-ring { - &:focus-visible { - --tw-ring-color: var(--ring); - } - } - .focus-visible\:ring-ring\/50 { - &:focus-visible { - --tw-ring-color: var(--ring); - @supports (color: color-mix(in lab, red, red)) { - --tw-ring-color: color-mix(in oklab, var(--ring) 50%, transparent); - } - } - } - .focus-visible\:ring-transparent { - &:focus-visible { - --tw-ring-color: transparent; - } - } - .focus-visible\:ring-offset-0 { - &:focus-visible { - --tw-ring-offset-width: 0px; - --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - } - } - .focus-visible\:ring-offset-2 { - &:focus-visible { - --tw-ring-offset-width: 2px; - --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - } - } - .focus-visible\:outline-none { - &:focus-visible { - --tw-outline-style: none; - outline-style: none; - } - } - .active\:cursor-grabbing { - &:active { - cursor: grabbing; - } - } - .disabled\:pointer-events-none { - &:disabled { - pointer-events: none; - } - } - .disabled\:cursor-not-allowed { - &:disabled { - cursor: not-allowed; - } - } - .disabled\:opacity-50 { - &:disabled { - opacity: 50%; - } - } - .has-aria-disabled\:border-input { - &:has(*[aria-disabled="true"]) { - border-color: var(--input); - } - } - .has-aria-disabled\:bg-muted { - &:has(*[aria-disabled="true"]) { - background-color: var(--muted); - } - } - .has-data-readonly\:w-fit { - &:has(*[data-readonly]) { - width: fit-content; - } - } - .has-data-readonly\:cursor-default { - &:has(*[data-readonly]) { - cursor: default; - } - } - .has-data-readonly\:border-transparent { - &:has(*[data-readonly]) { - border-color: transparent; - } - } - .has-data-readonly\:focus-within\:\[box-shadow\:none\] { - &:has(*[data-readonly]) { - &:focus-within { - box-shadow: none; - } - } - } - .has-\[\[data-slate-editor\]\:focus\]\:border-brand\/50 { - &:has(*:is([data-slate-editor]:focus)) { - border-color: color-mix(in srgb, #0b78d0 50%, transparent); - @supports (color: color-mix(in lab, red, red)) { - border-color: color-mix(in oklab, var(--color-quanta-sapphire) 50%, transparent); - } - } - } - .has-\[\[data-slate-editor\]\:focus\]\:ring-2 { - &:has(*:is([data-slate-editor]:focus)) { - --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - } - .has-\[\[data-slate-editor\]\:focus\]\:ring-brand\/30 { - &:has(*:is([data-slate-editor]:focus)) { - --tw-ring-color: color-mix(in srgb, #0b78d0 30%, transparent); - @supports (color: color-mix(in lab, red, red)) { - --tw-ring-color: color-mix(in oklab, var(--color-quanta-sapphire) 30%, transparent); - } - } - } - .has-\[\[role\=menuitem\]\]\:block { - &:has(*:is([role=menuitem])) { - display: block; - } - } - .has-\[\[role\=menuitemradio\]\]\:block { - &:has(*:is([role=menuitemradio])) { - display: block; - } - } - .has-\[\[role\=option\]\]\:block { - &:has(*:is([role=option])) { - display: block; - } - } - .has-\[button\]\:flex { - &:has(*:is(button)) { - display: flex; - } - } - .has-\[\+input\:not\(\:placeholder-shown\)\]\:pointer-events-none { - &:has(+input:not(:placeholder-shown)) { - pointer-events: none; - } - } - .has-\[\+input\:not\(\:placeholder-shown\)\]\:top-0 { - &:has(+input:not(:placeholder-shown)) { - top: calc(var(--spacing) * 0); - } - } - .has-\[\+input\:not\(\:placeholder-shown\)\]\:cursor-default { - &:has(+input:not(:placeholder-shown)) { - cursor: default; - } - } - .has-\[\+input\:not\(\:placeholder-shown\)\]\:text-xs { - &:has(+input:not(:placeholder-shown)) { - font-size: var(--text-xs); - line-height: var(--tw-leading, var(--text-xs--line-height)); - } - } - .has-\[\+input\:not\(\:placeholder-shown\)\]\:font-medium { - &:has(+input:not(:placeholder-shown)) { - --tw-font-weight: var(--font-weight-medium); - font-weight: var(--font-weight-medium); - } - } - .has-\[\+input\:not\(\:placeholder-shown\)\]\:text-foreground { - &:has(+input:not(:placeholder-shown)) { - color: var(--foreground); - } - } - .has-\[\>svg\]\:px-2\.5 { - &:has(>svg) { - padding-inline: calc(var(--spacing) * 2.5); - } - } - .has-\[\>svg\]\:px-3 { - &:has(>svg) { - padding-inline: calc(var(--spacing) * 3); - } - } - .has-\[\>svg\]\:px-4 { - &:has(>svg) { - padding-inline: calc(var(--spacing) * 4); - } - } - .aria-checked\:bg-accent { - &[aria-checked="true"] { - background-color: var(--accent); - } - } - .aria-checked\:text-accent-foreground { - &[aria-checked="true"] { - color: var(--accent-foreground); - } - } - .aria-invalid\:border-destructive { - &[aria-invalid="true"] { - border-color: var(--destructive); - } - } - .aria-invalid\:ring-destructive\/20 { - &[aria-invalid="true"] { - --tw-ring-color: var(--destructive); - @supports (color: color-mix(in lab, red, red)) { - --tw-ring-color: color-mix(in oklab, var(--destructive) 20%, transparent); - } - } - } - .data-readonly\:w-fit { - &[data-readonly] { - width: fit-content; - } - } - .\*\*\:data-slate-placeholder\:\!top-1\/2 { - :is(& *) { - &[data-slate-placeholder] { - top: calc(1/2 * 100%) !important; - } - } - } - .\*\*\:data-slate-placeholder\:top-\[auto_\!important\] { - :is(& *) { - &[data-slate-placeholder] { - top: auto !important; - } - } - } - .\*\*\:data-slate-placeholder\:-translate-y-1\/2 { - :is(& *) { - &[data-slate-placeholder] { - --tw-translate-y: calc(calc(1/2 * 100%) * -1); - translate: var(--tw-translate-x) var(--tw-translate-y); - } - } - } - .\*\*\:data-slate-placeholder\:text-muted-foreground\/80 { - :is(& *) { - &[data-slate-placeholder] { - color: var(--muted-foreground); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--muted-foreground) 80%, transparent); - } - } - } - } - .\*\*\:data-slate-placeholder\:opacity-100\! { - :is(& *) { - &[data-slate-placeholder] { - opacity: 100% !important; - } - } - } - .data-\[active-item\=true\]\:bg-accent { - &[data-active-item="true"] { - background-color: var(--accent); - } - } - .data-\[active-item\=true\]\:text-accent-foreground { - &[data-active-item="true"] { - color: var(--accent-foreground); - } - } - .data-\[active\=true\]\:bg-muted { - &[data-active="true"] { - background-color: var(--muted); - } - } - .data-\[disabled\]\:pointer-events-none { - &[data-disabled] { - pointer-events: none; - } - } - .data-\[disabled\]\:opacity-50 { - &[data-disabled] { - opacity: 50%; - } - } - .data-\[disabled\=true\]\:pointer-events-none { - &[data-disabled="true"] { - pointer-events: none; - } - } - .data-\[disabled\=true\]\:opacity-50 { - &[data-disabled="true"] { - opacity: 50%; - } - } - .data-\[highlighted\=true\]\:bg-accent { - &[data-highlighted="true"] { - background-color: var(--accent); - } - } - .data-\[inset\]\:pl-8 { - &[data-inset] { - padding-left: calc(var(--spacing) * 8); - } - } - .data-\[orientation\=horizontal\]\:h-px { - &[data-orientation="horizontal"] { - height: 1px; - } - } - .data-\[orientation\=horizontal\]\:w-full { - &[data-orientation="horizontal"] { - width: 100%; - } - } - .data-\[orientation\=vertical\]\:h-full { - &[data-orientation="vertical"] { - height: 100%; - } - } - .data-\[orientation\=vertical\]\:w-px { - &[data-orientation="vertical"] { - width: 1px; - } - } - .data-\[selected\=true\]\:bg-accent { - &[data-selected="true"] { - background-color: var(--accent); - } - } - .data-\[selected\=true\]\:text-accent-foreground { - &[data-selected="true"] { - color: var(--accent-foreground); - } - } - .\*\:data-\[slot\=block-selection\]\:left-2 { - :is(& > *) { - &[data-slot="block-selection"] { - left: calc(var(--spacing) * 2); - } - } - } - .\*\*\:data-\[slot\=command-input-wrapper\]\:h-12 { - :is(& *) { - &[data-slot="command-input-wrapper"] { - height: calc(var(--spacing) * 12); - } - } - } - .data-\[state\=checked\]\:border-primary { - &[data-state="checked"] { - border-color: var(--primary); - } - } - .data-\[state\=checked\]\:bg-accent { - &[data-state="checked"] { - background-color: var(--accent); - } - } - .data-\[state\=checked\]\:bg-primary { - &[data-state="checked"] { - background-color: var(--primary); - } - } - .data-\[state\=checked\]\:text-primary-foreground { - &[data-state="checked"] { - color: var(--primary-foreground); - } - } - .data-\[state\=closed\]\:opacity-0 { - &[data-state="closed"] { - opacity: 0%; - } - } - .data-\[state\=on\]\:bg-accent { - &[data-state="on"] { - background-color: var(--accent); - } - } - .data-\[state\=on\]\:text-accent-foreground { - &[data-state="on"] { - color: var(--accent-foreground); - } - } - .data-\[state\=open\]\:bg-accent { - &[data-state="open"] { - background-color: var(--accent); - } - } - .data-\[state\=open\]\:text-accent-foreground { - &[data-state="open"] { - color: var(--accent-foreground); - } - } - .data-\[state\=open\]\:text-muted-foreground { - &[data-state="open"] { - color: var(--muted-foreground); - } - } - .data-\[variant\=destructive\]\:text-destructive { - &[data-variant="destructive"] { - color: var(--destructive); - } - } - .data-\[variant\=destructive\]\:focus\:bg-destructive\/10 { - &[data-variant="destructive"] { - &:focus { - background-color: var(--destructive); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--destructive) 10%, transparent); - } - } - } - } - .data-\[variant\=destructive\]\:focus\:text-destructive { - &[data-variant="destructive"] { - &:focus { - color: var(--destructive); - } - } - } - .supports-backdrop-blur\:bg-background\/60 { - @supports (backdrop-blur: var(--tw)) { - background-color: var(--background); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--background) 60%, transparent); - } - } - } - .sm\:max-w-lg { - @media (width >= 40rem) { - max-width: var(--container-lg); - } - } - .sm\:flex-row { - @media (width >= 40rem) { - flex-direction: row; - } - } - .sm\:justify-end { - @media (width >= 40rem) { - justify-content: flex-end; - } - } - .sm\:px-24 { - @media (width >= 40rem) { - padding-inline: calc(var(--spacing) * 24); - } - } - .sm\:px-\[max\(64px\,calc\(50\%-350px\)\)\] { - @media (width >= 40rem) { - padding-inline: max(64px, calc(50% - 350px)); - } - } - .sm\:text-left { - @media (width >= 40rem) { - text-align: left; - } - } - .sm\:opacity-0 { - @media (width >= 40rem) { - opacity: 0%; - } - } - .md\:text-sm { - @media (width >= 48rem) { - font-size: var(--text-sm); - line-height: var(--tw-leading, var(--text-sm--line-height)); - } - } - .lg\:inline { - @media (width >= 64rem) { - display: inline; - } - } - .dark\:border-input { - &:is(.dark *) { - border-color: var(--input); - } - } - .dark\:bg-destructive\/60 { - &:is(.dark *) { - background-color: var(--destructive); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--destructive) 60%, transparent); - } - } - } - .dark\:bg-input\/30 { - &:is(.dark *) { - background-color: var(--input); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--input) 30%, transparent); - } - } - } - .dark\:shadow-\[rgba\(255\,_255\,_255\,_0\.1\)_0px_0\.5px_0px_0px_inset\,_rgb\(26\,_29\,_30\)_0px_1px_5px_0px_inset\,_rgb\(76\,_81\,_85\)_0px_0px_0px_0\.5px\,_rgb\(76\,_81\,_85\)_0px_2px_1px_-1px\,_rgb\(76\,_81\,_85\)_0px_1px_0px_0px\] { - &:is(.dark *) { - --tw-shadow-color: rgba(255, 255, 255, 0.1); - @supports (color: color-mix(in lab, red, red)) { - --tw-shadow-color: color-mix(in oklab, rgba(255, 255, 255, 0.1) 0px 0.5px 0px 0px inset, rgb(26, 29, 30) 0px 1px 5px 0px inset, rgb(76, 81, 85) 0px 0px 0px 0.5px, rgb(76, 81, 85) 0px 2px 1px -1px, rgb(76, 81, 85) 0px 1px 0px 0px var(--tw-shadow-alpha), transparent); - } - } - } - .dark\:hover\:bg-accent\/50 { - &:is(.dark *) { - &:hover { - @media (hover: hover) { - background-color: var(--accent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--accent) 50%, transparent); - } - } - } - } - } - .dark\:hover\:bg-input\/50 { - &:is(.dark *) { - &:hover { - @media (hover: hover) { - background-color: var(--input); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--input) 50%, transparent); - } - } - } - } - } - .dark\:focus-visible\:ring-destructive\/40 { - &:is(.dark *) { - &:focus-visible { - --tw-ring-color: var(--destructive); - @supports (color: color-mix(in lab, red, red)) { - --tw-ring-color: color-mix(in oklab, var(--destructive) 40%, transparent); - } - } - } - } - .dark\:aria-invalid\:ring-destructive\/40 { - &:is(.dark *) { - &[aria-invalid="true"] { - --tw-ring-color: var(--destructive); - @supports (color: color-mix(in lab, red, red)) { - --tw-ring-color: color-mix(in oklab, var(--destructive) 40%, transparent); - } - } - } - } - .dark\:data-\[state\=checked\]\:bg-primary { - &:is(.dark *) { - &[data-state="checked"] { - background-color: var(--primary); - } - } - } - .dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20 { - &:is(.dark *) { - &[data-variant="destructive"] { - &:focus { - background-color: var(--destructive); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--destructive) 20%, transparent); - } - } - } - } - } - .print\:hidden { - @media print { - display: none; - } - } - .print\:break-inside-avoid { - @media print { - break-inside: avoid; - } - } - .print\:placeholder\:text-transparent { - @media print { - &::placeholder { - color: transparent; - } - } - } - .\[\&_\.slate-selection-area\]\:z-50 { - & .slate-selection-area { - z-index: 50; - } - } - .\[\&_\.slate-selection-area\]\:border { - & .slate-selection-area { - border-style: var(--tw-border-style); - border-width: 1px; - } - } - .\[\&_\.slate-selection-area\]\:border-brand\/25 { - & .slate-selection-area { - border-color: color-mix(in srgb, #0b78d0 25%, transparent); - @supports (color: color-mix(in lab, red, red)) { - border-color: color-mix(in oklab, var(--color-quanta-sapphire) 25%, transparent); - } - } - } - .\[\&_\.slate-selection-area\]\:bg-brand\/15 { - & .slate-selection-area { - background-color: color-mix(in srgb, #0b78d0 15%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-quanta-sapphire) 15%, transparent); - } - } - } - .\[\&_\>_\.lty-playbtn\]\:absolute { - & > .lty-playbtn { - position: absolute; - } - } - .\[\&_\>_\.lty-playbtn\]\:top-1\/2 { - & > .lty-playbtn { - top: calc(1/2 * 100%); - } - } - .\[\&_\>_\.lty-playbtn\]\:left-1\/2 { - & > .lty-playbtn { - left: calc(1/2 * 100%); - } - } - .\[\&_\>_\.lty-playbtn\]\:z-1 { - & > .lty-playbtn { - z-index: 1; - } - } - .\[\&_\>_\.lty-playbtn\]\:h-\[46px\] { - & > .lty-playbtn { - height: 46px; - } - } - .\[\&_\>_\.lty-playbtn\]\:w-\[70px\] { - & > .lty-playbtn { - width: 70px; - } - } - .\[\&_\>_\.lty-playbtn\]\:\[transform\:translate3d\(-50\%\,-50\%\,0\)\] { - & > .lty-playbtn { - transform: translate3d(-50%,-50%,0); - } - } - .\[\&_\>_\.lty-playbtn\]\:rounded-\[14\%\] { - & > .lty-playbtn { - border-radius: 14%; - } - } - .\[\&_\>_\.lty-playbtn\]\:bg-\[\#212121\] { - & > .lty-playbtn { - background-color: #212121; - } - } - .\[\&_\>_\.lty-playbtn\]\:opacity-80 { - & > .lty-playbtn { - opacity: 80%; - } - } - .\[\&_\>_\.lty-playbtn\]\:\[transition\:all_0\.2s_cubic-bezier\(0\,_0\,_0\.2\,_1\)\] { - & > .lty-playbtn { - transition: all 0.2s cubic-bezier(0, 0, 0.2, 1); - } - } - .\[\&_\>_\.lty-playbtn\]\:before\:absolute { - & > .lty-playbtn { - &::before { - content: var(--tw-content); - position: absolute; - } - } - } - .\[\&_\>_\.lty-playbtn\]\:before\:top-1\/2 { - & > .lty-playbtn { - &::before { - content: var(--tw-content); - top: calc(1/2 * 100%); - } - } - } - .\[\&_\>_\.lty-playbtn\]\:before\:left-1\/2 { - & > .lty-playbtn { - &::before { - content: var(--tw-content); - left: calc(1/2 * 100%); - } - } - } - .\[\&_\>_\.lty-playbtn\]\:before\:\[transform\:translate3d\(-50\%\,-50\%\,0\)\] { - & > .lty-playbtn { - &::before { - content: var(--tw-content); - transform: translate3d(-50%,-50%,0); - } - } - } - .\[\&_\>_\.lty-playbtn\]\:before\:border-y-\[11px\] { - & > .lty-playbtn { - &::before { - content: var(--tw-content); - border-block-style: var(--tw-border-style); - border-block-width: 11px; - } - } - } - .\[\&_\>_\.lty-playbtn\]\:before\:border-r-0 { - & > .lty-playbtn { - &::before { - content: var(--tw-content); - border-right-style: var(--tw-border-style); - border-right-width: 0px; - } - } - } - .\[\&_\>_\.lty-playbtn\]\:before\:border-l-\[19px\] { - & > .lty-playbtn { - &::before { - content: var(--tw-content); - border-left-style: var(--tw-border-style); - border-left-width: 19px; - } - } - } - .\[\&_\>_\.lty-playbtn\]\:before\:border-\[transparent_transparent_transparent_\#fff\] { - & > .lty-playbtn { - &::before { - content: var(--tw-content); - border-color: transparent transparent transparent #fff; - } - } - } - .\[\&_\>_\.lty-playbtn\]\:before\:content-\[\"\"\] { - & > .lty-playbtn { - &::before { - --tw-content: ""; - content: var(--tw-content); - } - } - } - .\[\&_\>_iframe\]\:absolute { - & > iframe { - position: absolute; - } - } - .\[\&_\>_iframe\]\:top-0 { - & > iframe { - top: calc(var(--spacing) * 0); - } - } - .\[\&_\>_iframe\]\:left-0 { - & > iframe { - left: calc(var(--spacing) * 0); - } - } - .\[\&_\>_iframe\]\:size-full { - & > iframe { - width: 100%; - height: 100%; - } - } - .\[\&_\[cmdk-group-heading\]\]\:px-2 { - & [cmdk-group-heading] { - padding-inline: calc(var(--spacing) * 2); - } - } - .\[\&_\[cmdk-group-heading\]\]\:py-1\.5 { - & [cmdk-group-heading] { - padding-block: calc(var(--spacing) * 1.5); - } - } - .\[\&_\[cmdk-group-heading\]\]\:text-xs { - & [cmdk-group-heading] { - font-size: var(--text-xs); - line-height: var(--tw-leading, var(--text-xs--line-height)); - } - } - .\[\&_\[cmdk-group-heading\]\]\:font-medium { - & [cmdk-group-heading] { - --tw-font-weight: var(--font-weight-medium); - font-weight: var(--font-weight-medium); - } - } - .\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground { - & [cmdk-group-heading] { - color: var(--muted-foreground); - } - } - .\[\&_\[cmdk-group\]\]\:px-2 { - & [cmdk-group] { - padding-inline: calc(var(--spacing) * 2); - } - } - .\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 { - & [cmdk-group]:not([hidden]) ~[cmdk-group] { - padding-top: calc(var(--spacing) * 0); - } - } - .\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 { - & [cmdk-input-wrapper] svg { - height: calc(var(--spacing) * 5); - } - } - .\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 { - & [cmdk-input-wrapper] svg { - width: calc(var(--spacing) * 5); - } - } - .\[\&_\[cmdk-input\]\]\:h-12 { - & [cmdk-input] { - height: calc(var(--spacing) * 12); - } - } - .\[\&_\[cmdk-item\]\]\:px-2 { - & [cmdk-item] { - padding-inline: calc(var(--spacing) * 2); - } - } - .\[\&_\[cmdk-item\]\]\:py-3 { - & [cmdk-item] { - padding-block: calc(var(--spacing) * 3); - } - } - .\[\&_\[cmdk-item\]_svg\]\:h-5 { - & [cmdk-item] svg { - height: calc(var(--spacing) * 5); - } - } - .\[\&_\[cmdk-item\]_svg\]\:w-5 { - & [cmdk-item] svg { - width: calc(var(--spacing) * 5); - } - } - .\[\&_strong\]\:font-bold { - & strong { - --tw-font-weight: var(--font-weight-bold); - font-weight: var(--font-weight-bold); - } - } - .\[\&_svg\]\:pointer-events-none { - & svg { - pointer-events: none; - } - } - .\[\&_svg\]\:size-4 { - & svg { - width: calc(var(--spacing) * 4); - height: calc(var(--spacing) * 4); - } - } - .\[\&_svg\]\:size-6 { - & svg { - width: calc(var(--spacing) * 6); - height: calc(var(--spacing) * 6); - } - } - .\[\&_svg\]\:shrink-0 { - & svg { - flex-shrink: 0; - } - } - .\[\&_svg\]\:text-muted-foreground { - & svg { - color: var(--muted-foreground); - } - } - .\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 { - & svg:not([class*='size-']) { - width: calc(var(--spacing) * 4); - height: calc(var(--spacing) * 4); - } - } - .\[\&_svg\:not\(\[class\*\=\'text-\'\]\)\]\:text-muted-foreground { - & svg:not([class*='text-']) { - color: var(--muted-foreground); - } - } - .\[\&\.lyt-activated\]\:cursor-\[unset\] { - &.lyt-activated { - cursor: unset; - } - } - .\[\&\.lyt-activated\]\:before\:pointer-events-none { - &.lyt-activated { - &::before { - content: var(--tw-content); - pointer-events: none; - } - } - } - .\[\&\.lyt-activated\]\:before\:absolute { - &.lyt-activated { - &::before { - content: var(--tw-content); - position: absolute; - } - } - } - .\[\&\.lyt-activated\]\:before\:top-0 { - &.lyt-activated { - &::before { - content: var(--tw-content); - top: calc(var(--spacing) * 0); - } - } - } - .\[\&\.lyt-activated\]\:before\:h-\[60px\] { - &.lyt-activated { - &::before { - content: var(--tw-content); - height: 60px; - } - } - } - .\[\&\.lyt-activated\]\:before\:w-full { - &.lyt-activated { - &::before { - content: var(--tw-content); - width: 100%; - } - } - } - .\[\&\.lyt-activated\]\:before\:bg-\[url\(data\:image\/png\;base64\,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT\+OqFAAAAdklEQVQoz42QQQ7AIAgEF\/T\/D\+kbq\/RWAlnQyyazA4aoAB4FsBSA\/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg\=\=\)\] { - &.lyt-activated { - &::before { - content: var(--tw-content); - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==); - } - } - } - .\[\&\.lyt-activated\]\:before\:bg-top { - &.lyt-activated { - &::before { - content: var(--tw-content); - background-position: top; - } - } - } - .\[\&\.lyt-activated\]\:before\:bg-repeat-x { - &.lyt-activated { - &::before { - content: var(--tw-content); - background-repeat: repeat-x; - } - } - } - .\[\&\.lyt-activated\]\:before\:pb-\[50px\] { - &.lyt-activated { - &::before { - content: var(--tw-content); - padding-bottom: 50px; - } - } - } - .\[\&\.lyt-activated\]\:before\:opacity-0 { - &.lyt-activated { - &::before { - content: var(--tw-content); - opacity: 0%; - } - } - } - .\[\&\.lyt-activated\]\:before\:\[transition\:all_0\.2s_cubic-bezier\(0\,_0\,_0\.2\,_1\)\] { - &.lyt-activated { - &::before { - content: var(--tw-content); - transition: all 0.2s cubic-bezier(0, 0, 0.2, 1); - } - } - } - .\[\&\.lyt-activated_\>_\.lty-playbtn\]\:pointer-events-none { - &.lyt-activated > .lty-playbtn { - pointer-events: none; - } - } - .\[\&\.lyt-activated_\>_\.lty-playbtn\]\:opacity-0\! { - &.lyt-activated > .lty-playbtn { - opacity: 0% !important; - } - } - .focus\:\[\&\:\:placeholder\]\:opacity-0 { - &:focus { - &::placeholder { - opacity: 0%; - } - } - } - .\[\&\:has\(\[role\=option\]\)\]\:block { - &:has([role=option]) { - display: block; - } - } - .\[\&\:hover_\>_\.lty-playbtn\]\:bg-\[red\] { - &:hover > .lty-playbtn { - background-color: red; - } - } - .\[\&\:hover_\>_\.lty-playbtn\]\:opacity-100 { - &:hover > .lty-playbtn { - opacity: 100%; - } - } - .\*\*\:\[\.hljs-addition\]\:bg-\[\#f0fff4\] { - :is(& *) { - &:is(.hljs-addition) { - background-color: #f0fff4; - } - } - } - .\*\*\:\[\.hljs-addition\]\:text-\[\#22863a\] { - :is(& *) { - &:is(.hljs-addition) { - color: #22863a; - } - } - } - .dark\:\*\*\:\[\.hljs-addition\]\:bg-\[\#3c5743\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-addition) { - background-color: #3c5743; - } - } - } - } - .dark\:\*\*\:\[\.hljs-addition\]\:text-\[\#ceead5\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-addition) { - color: #ceead5; - } - } - } - } - .\*\*\:\[\.hljs-attr\,\.hljs-attribute\,\.hljs-literal\,\.hljs-meta\,\.hljs-number\,\.hljs-operator\,\.hljs-selector-attr\,\.hljs-selector-class\,\.hljs-selector-id\,\.hljs-variable\]\:text-\[\#005cc5\] { - :is(& *) { - &:is(.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable) { - color: #005cc5; - } - } - } - .dark\:\*\*\:\[\.hljs-attr\,\.hljs-attribute\,\.hljs-literal\,\.hljs-meta\,\.hljs-number\,\.hljs-operator\,\.hljs-selector-attr\,\.hljs-selector-class\,\.hljs-selector-id\,\.hljs-variable\]\:text-\[\#6596cf\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable) { - color: #6596cf; - } - } - } - } - .\*\*\:\[\.hljs-built_in\,\.hljs-symbol\]\:text-\[\#e36209\] { - :is(& *) { - &:is(.hljs-built in,.hljs-symbol) { - color: #e36209; - } - } - } - .dark\:\*\*\:\[\.hljs-built_in\,\.hljs-symbol\]\:text-\[\#c3854e\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-built in,.hljs-symbol) { - color: #c3854e; - } - } - } - } - .\*\*\:\[\.hljs-bullet\]\:text-\[\#735c0f\] { - :is(& *) { - &:is(.hljs-bullet) { - color: #735c0f; - } - } - } - .\*\*\:\[\.hljs-comment\,\.hljs-code\,\.hljs-formula\]\:text-\[\#6a737d\] { - :is(& *) { - &:is(.hljs-comment,.hljs-code,.hljs-formula) { - color: #6a737d; - } - } - } - .dark\:\*\*\:\[\.hljs-comment\,\.hljs-code\,\.hljs-formula\]\:text-\[\#6a737d\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-comment,.hljs-code,.hljs-formula) { - color: #6a737d; - } - } - } - } - .\*\*\:\[\.hljs-deletion\]\:bg-\[\#ffeef0\] { - :is(& *) { - &:is(.hljs-deletion) { - background-color: #ffeef0; - } - } - } - .\*\*\:\[\.hljs-deletion\]\:text-\[\#b31d28\] { - :is(& *) { - &:is(.hljs-deletion) { - color: #b31d28; - } - } - } - .dark\:\*\*\:\[\.hljs-deletion\]\:bg-\[\#473235\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-deletion) { - background-color: #473235; - } - } - } - } - .dark\:\*\*\:\[\.hljs-deletion\]\:text-\[\#e7c7cb\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-deletion) { - color: #e7c7cb; - } - } - } - } - .\*\*\:\[\.hljs-emphasis\]\:italic { - :is(& *) { - &:is(.hljs-emphasis) { - font-style: italic; - } - } - } - .\*\*\:\[\.hljs-keyword\,\.hljs-doctag\,\.hljs-template-tag\,\.hljs-template-variable\,\.hljs-type\,\.hljs-variable\.language_\]\:text-\[\#d73a49\] { - :is(& *) { - &:is(.hljs-keyword,.hljs-doctag,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language ) { - color: #d73a49; - } - } - } - .dark\:\*\*\:\[\.hljs-keyword\,\.hljs-doctag\,\.hljs-template-tag\,\.hljs-template-variable\,\.hljs-type\,\.hljs-variable\.language_\]\:text-\[\#ee6960\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-keyword,.hljs-doctag,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language ) { - color: #ee6960; - } - } - } - } - .\*\*\:\[\.hljs-name\,\.hljs-quote\,\.hljs-selector-tag\,\.hljs-selector-pseudo\]\:text-\[\#22863a\] { - :is(& *) { - &:is(.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo) { - color: #22863a; - } - } - } - .dark\:\*\*\:\[\.hljs-name\,\.hljs-quote\,\.hljs-selector-tag\,\.hljs-selector-pseudo\]\:text-\[\#36a84f\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo) { - color: #36a84f; - } - } - } - } - .\*\*\:\[\.hljs-regexp\,\.hljs-string\,\.hljs-meta_\.hljs-string\]\:text-\[\#032f62\] { - :is(& *) { - &:is(.hljs-regexp,.hljs-string,.hljs-meta .hljs-string) { - color: #032f62; - } - } - } - .dark\:\*\*\:\[\.hljs-regexp\,\.hljs-string\,\.hljs-meta_\.hljs-string\]\:text-\[\#3593ff\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-regexp,.hljs-string,.hljs-meta .hljs-string) { - color: #3593ff; - } - } - } - } - .\*\*\:\[\.hljs-section\]\:font-bold { - :is(& *) { - &:is(.hljs-section) { - --tw-font-weight: var(--font-weight-bold); - font-weight: var(--font-weight-bold); - } - } - } - .\*\*\:\[\.hljs-section\]\:text-\[\#005cc5\] { - :is(& *) { - &:is(.hljs-section) { - color: #005cc5; - } - } - } - .dark\:\*\*\:\[\.hljs-section\]\:text-\[\#61a5f2\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-section) { - color: #61a5f2; - } - } - } - } - .\*\*\:\[\.hljs-strong\]\:font-bold { - :is(& *) { - &:is(.hljs-strong) { - --tw-font-weight: var(--font-weight-bold); - font-weight: var(--font-weight-bold); - } - } - } - .\*\*\:\[\.hljs-title\,\.hljs-title\.class_\,\.hljs-title\.class_\.inherited__\,\.hljs-title\.function_\]\:text-\[\#6f42c1\] { - :is(& *) { - &:is(.hljs-title,.hljs-title.class ,.hljs-title.class .inherited ,.hljs-title.function ) { - color: #6f42c1; - } - } - } - .dark\:\*\*\:\[\.hljs-title\,\.hljs-title\.class_\,\.hljs-title\.class_\.inherited__\,\.hljs-title\.function_\]\:text-\[\#a77bfa\] { - &:is(.dark *) { - :is(& *) { - &:is(.hljs-title,.hljs-title.class ,.hljs-title.class .inherited ,.hljs-title.function ) { - color: #a77bfa; - } - } - } - } - .\*\:first\:\[span\]\:hidden { - :is(& > *) { - &:first-child { - &:is(span) { - display: none; - } - } - } - } - .\*\:\[svg\]\:text-muted-foreground { - :is(& > *) { - &:is(svg) { - color: var(--muted-foreground); - } - } - } - .data-\[variant\=destructive\]\:\*\:\[svg\]\:\!text-destructive { - &[data-variant="destructive"] { - :is(& > *) { - &:is(svg) { - color: var(--destructive) !important; - } - } - } - } -} -:root { - --background: hsl(0 0% 100%); - --foreground: hsl(222.2 84% 4.9%); - --card: hsl(0 0% 100%); - --card-foreground: hsl(222.2 84% 4.9%); - --popover: hsl(0 0% 100%); - --popover-foreground: hsl(222.2 84% 4.9%); - --primary: hsl(222.2 47.4% 11.2%); - --primary-foreground: hsl(210 40% 98%); - --secondary: hsl(210 40% 96.1%); - --secondary-foreground: hsl(222.2 47.4% 11.2%); - --muted: hsl(210 40% 96.1%); - --muted-foreground: hsl(215.4 16.3% 46.9%); - --accent: hsl(210 40% 96.1%); - --accent-foreground: hsl(222.2 47.4% 11.2%); - --destructive: hsl(0 84.2% 60.2%); - --destructive-foreground: hsl(210 40% 98%); - --border: hsl(214.3 31.8% 91.4%); - --input: hsl(214.3 31.8% 91.4%); - --ring: hsl(222.2 84% 4.9%); - --chart-1: hsl(12 76% 61%); - --chart-2: hsl(173 58% 39%); - --chart-3: hsl(197 37% 24%); - --chart-4: hsl(43 74% 66%); - --chart-5: hsl(27 87% 67%); -} -.dark { - --background: hsl(222.2 84% 4.9%); - --foreground: hsl(210 40% 98%); - --card: hsl(222.2 84% 4.9%); - --card-foreground: hsl(210 40% 98%); - --popover: hsl(222.2 84% 4.9%); - --popover-foreground: hsl(210 40% 98%); - --primary: hsl(210 40% 98%); - --primary-foreground: hsl(222.2 47.4% 11.2%); - --secondary: hsl(217.2 32.6% 17.5%); - --secondary-foreground: hsl(210 40% 98%); - --muted: hsl(217.2 32.6% 17.5%); - --muted-foreground: hsl(215 20.2% 65.1%); - --accent: hsl(217.2 32.6% 17.5%); - --accent-foreground: hsl(210 40% 98%); - --destructive: hsl(0 62.8% 30.6%); - --destructive-foreground: hsl(210 40% 98%); - --border: hsl(217.2 32.6% 17.5%); - --input: hsl(217.2 32.6% 17.5%); - --ring: hsl(212.7 26.8% 83.9%); - --chart-1: hsl(220 70% 50%); - --chart-2: hsl(160 60% 45%); - --chart-3: hsl(30 80% 55%); - --chart-4: hsl(280 65% 60%); - --chart-5: hsl(340 75% 55%); -} -@property --tw-translate-x { - syntax: "*"; - inherits: false; - initial-value: 0; -} -@property --tw-translate-y { - syntax: "*"; - inherits: false; - initial-value: 0; -} -@property --tw-translate-z { - syntax: "*"; - inherits: false; - initial-value: 0; -} -@property --tw-rotate-x { - syntax: "*"; - inherits: false; -} -@property --tw-rotate-y { - syntax: "*"; - inherits: false; -} -@property --tw-rotate-z { - syntax: "*"; - inherits: false; -} -@property --tw-skew-x { - syntax: "*"; - inherits: false; -} -@property --tw-skew-y { - syntax: "*"; - inherits: false; -} -@property --tw-space-x-reverse { - syntax: "*"; - inherits: false; - initial-value: 0; -} -@property --tw-border-style { - syntax: "*"; - inherits: false; - initial-value: solid; -} -@property --tw-leading { - syntax: "*"; - inherits: false; -} -@property --tw-font-weight { - syntax: "*"; - inherits: false; -} -@property --tw-tracking { - syntax: "*"; - inherits: false; -} -@property --tw-shadow { - syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; -} -@property --tw-shadow-color { - syntax: "*"; - inherits: false; -} -@property --tw-shadow-alpha { - syntax: ""; - inherits: false; - initial-value: 100%; -} -@property --tw-inset-shadow { - syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; -} -@property --tw-inset-shadow-color { - syntax: "*"; - inherits: false; -} -@property --tw-inset-shadow-alpha { - syntax: ""; - inherits: false; - initial-value: 100%; -} -@property --tw-ring-color { - syntax: "*"; - inherits: false; -} -@property --tw-ring-shadow { - syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; -} -@property --tw-inset-ring-color { - syntax: "*"; - inherits: false; -} -@property --tw-inset-ring-shadow { - syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; -} -@property --tw-ring-inset { - syntax: "*"; - inherits: false; -} -@property --tw-ring-offset-width { - syntax: ""; - inherits: false; - initial-value: 0px; -} -@property --tw-ring-offset-color { - syntax: "*"; - inherits: false; - initial-value: #fff; -} -@property --tw-ring-offset-shadow { - syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; -} -@property --tw-outline-style { - syntax: "*"; - inherits: false; - initial-value: solid; -} -@property --tw-blur { - syntax: "*"; - inherits: false; -} -@property --tw-brightness { - syntax: "*"; - inherits: false; -} -@property --tw-contrast { - syntax: "*"; - inherits: false; -} -@property --tw-grayscale { - syntax: "*"; - inherits: false; -} -@property --tw-hue-rotate { - syntax: "*"; - inherits: false; -} -@property --tw-invert { - syntax: "*"; - inherits: false; -} -@property --tw-opacity { - syntax: "*"; - inherits: false; -} -@property --tw-saturate { - syntax: "*"; - inherits: false; -} -@property --tw-sepia { - syntax: "*"; - inherits: false; -} -@property --tw-drop-shadow { - syntax: "*"; - inherits: false; -} -@property --tw-drop-shadow-color { - syntax: "*"; - inherits: false; -} -@property --tw-drop-shadow-alpha { - syntax: ""; - inherits: false; - initial-value: 100%; -} -@property --tw-drop-shadow-size { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-blur { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-brightness { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-contrast { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-grayscale { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-hue-rotate { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-invert { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-opacity { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-saturate { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-sepia { - syntax: "*"; - inherits: false; -} -@property --tw-duration { - syntax: "*"; - inherits: false; -} -@property --tw-ease { - syntax: "*"; - inherits: false; -} -@property --tw-content { - syntax: "*"; - initial-value: ""; - inherits: false; -} -@property --tw-scale-x { - syntax: "*"; - inherits: false; - initial-value: 1; -} -@property --tw-scale-y { - syntax: "*"; - inherits: false; - initial-value: 1; -} -@property --tw-scale-z { - syntax: "*"; - inherits: false; - initial-value: 1; -} -@keyframes spin { - to { - transform: rotate(360deg); - } -} -@layer properties { - @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) { - *, ::before, ::after, ::backdrop { - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-translate-z: 0; - --tw-rotate-x: initial; - --tw-rotate-y: initial; - --tw-rotate-z: initial; - --tw-skew-x: initial; - --tw-skew-y: initial; - --tw-space-x-reverse: 0; - --tw-border-style: solid; - --tw-leading: initial; - --tw-font-weight: initial; - --tw-tracking: initial; - --tw-shadow: 0 0 #0000; - --tw-shadow-color: initial; - --tw-shadow-alpha: 100%; - --tw-inset-shadow: 0 0 #0000; - --tw-inset-shadow-color: initial; - --tw-inset-shadow-alpha: 100%; - --tw-ring-color: initial; - --tw-ring-shadow: 0 0 #0000; - --tw-inset-ring-color: initial; - --tw-inset-ring-shadow: 0 0 #0000; - --tw-ring-inset: initial; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-offset-shadow: 0 0 #0000; - --tw-outline-style: solid; - --tw-blur: initial; - --tw-brightness: initial; - --tw-contrast: initial; - --tw-grayscale: initial; - --tw-hue-rotate: initial; - --tw-invert: initial; - --tw-opacity: initial; - --tw-saturate: initial; - --tw-sepia: initial; - --tw-drop-shadow: initial; - --tw-drop-shadow-color: initial; - --tw-drop-shadow-alpha: 100%; - --tw-drop-shadow-size: initial; - --tw-backdrop-blur: initial; - --tw-backdrop-brightness: initial; - --tw-backdrop-contrast: initial; - --tw-backdrop-grayscale: initial; - --tw-backdrop-hue-rotate: initial; - --tw-backdrop-invert: initial; - --tw-backdrop-opacity: initial; - --tw-backdrop-saturate: initial; - --tw-backdrop-sepia: initial; - --tw-duration: initial; - --tw-ease: initial; - --tw-content: ""; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-scale-z: 1; - } - } -} diff --git a/packages/plate/package.json b/packages/plate/package.json index 1b5793cf50b..7674ee076da 100644 --- a/packages/plate/package.json +++ b/packages/plate/package.json @@ -33,7 +33,6 @@ "type": "module", "main": "index.ts", "scripts": { - "generate:styles": "pnpm dlx @tailwindcss/cli -i ./input.css -o ./output.css", "test": "vitest", "test:debug": "vitest --inspect-brk --watch", "check-ts": "tsc --project tsconfig.json", diff --git a/packages/publicui/news/6649.feature b/packages/publicui/news/6649.feature new file mode 100644 index 00000000000..f37df625361 --- /dev/null +++ b/packages/publicui/news/6649.feature @@ -0,0 +1 @@ +Added the left toolbar @pnicolli diff --git a/packages/publicui/routes/index.tsx b/packages/publicui/routes/index.tsx index 2da0b2f4f1c..f1e9cc3fcc5 100644 --- a/packages/publicui/routes/index.tsx +++ b/packages/publicui/routes/index.tsx @@ -17,15 +17,20 @@ import { } from 'react-router'; import { useLayoutEffect } from 'react'; import { useTranslation } from 'react-i18next'; -import { RouterProvider as RACRouterProvider } from 'react-aria-components'; +import { + Link, + RouterProvider as RACRouterProvider, +} from 'react-aria-components'; import type { RootLoader } from 'seven/app/root'; +import Pencil from '@plone/components/icons/pencil.svg?react'; import SlotRenderer from '@plone/layout/slots/SlotRenderer'; +import Toolbar from '@plone/layout/components/Toolbar/Toolbar'; +import { shouldShowToolbar } from '@plone/layout/helpers'; +import { Plug, PluggablesProvider } from '@plone/layout/components/Pluggable'; import clsx from 'clsx'; import config from '@plone/registry'; import styles from '@plone/layout/slots/App/App.module.css'; - -// eslint-disable-next-line import/no-unresolved import stylesheet from 'seven/.plone/publicui.css?url'; export const meta: MetaFunction = ({ @@ -102,33 +107,48 @@ export default function Index() { - + {/* We pre-define here the @layer before tailwind does, adding our own layers in a React 19 managed tag */} -