File
Blob: src/client/components/canvas/styles/canvas-theme.css
| 1 | /* Scope Excalidraw's customizable CSS variables to bland's canvas surface. |
| 2 | * Upstream API: https://docs.excalidraw.com/docs/@excalidraw/excalidraw/customizing-styles |
| 3 | * Stable selectors: .excalidraw and .excalidraw.theme--dark. |
| 4 | * |
| 5 | * The outer `.bland-canvas` wrapper keeps our overrides scoped so we never |
| 6 | * leak into any other Excalidraw instance a page might embed later. */ |
| 7 | |
| 8 | /* Hide the entire top-right chrome. |
| 9 | * Excalidraw renders three things there: |
| 10 | * 1. DefaultSidebar.Trigger (the "Library" button — we don't use its |
| 11 | * stock-shape library; pages are the unit of content in bland) |
| 12 | * 2. Collaborator UserList (bland already renders its own AvatarStack |
| 13 | * in the page chrome — duplicating it here is noise) |
| 14 | * 3. whatever `renderTopRightUI` returns (we return null) |
| 15 | * `renderTopRightUI` does not replace the other two, it only appends, so |
| 16 | * CSS is the cleanest way to drop the whole cluster. */ |
| 17 | .bland-canvas .excalidraw .layer-ui__wrapper__top-right { |
| 18 | display: none; |
| 19 | } |
| 20 | |
| 21 | /* UI chrome font — keep Excalidraw's own Excalifont/Cascadia on canvas |
| 22 | * content (part of the hand-drawn character), but make floating islands, |
| 23 | * menus, and dialogs read as bland surfaces. Excalidraw sets `Assistant` on |
| 24 | * several widget elements directly (burger button, help icon, zoom label, |
| 25 | * zen toggle), so a single rule on `.excalidraw` gets overridden by their |
| 26 | * own specificity. Descendant selector covers the whole subtree — the |
| 27 | * inline `<canvas>` element renders its own text, unaffected by this. */ |
| 28 | .bland-canvas .excalidraw, |
| 29 | .bland-canvas .excalidraw * { |
| 30 | font-family: var(--font-sans); |
| 31 | } |
| 32 | |
| 33 | /* Font-size / weight consistency across menus. |
| 34 | * Excalidraw's right-click context menu defaults to 16px / weight 450 |
| 35 | * while its dropdown MainMenu defaults to 14px / weight 400 — visibly |
| 36 | * different sizes. Normalize both to 14px / 450 (matches bland's sidebar |
| 37 | * menu language and the astigmatism-comfort "heavier weights" guidance |
| 38 | * in PRODUCT.md). */ |
| 39 | .bland-canvas .excalidraw .context-menu-item, |
| 40 | .bland-canvas .excalidraw .dropdown-menu-item-base { |
| 41 | font-size: 14px; |
| 42 | font-weight: 450; |
| 43 | } |
| 44 | |
| 45 | .bland-canvas .excalidraw, |
| 46 | .bland-canvas .excalidraw.theme--dark { |
| 47 | /* Brand accent — warm amethyst ramp. Drives selection handles, active |
| 48 | * tool state, and focus rings. */ |
| 49 | --color-primary: var(--color-accent-500); |
| 50 | --color-primary-darker: var(--color-accent-600); |
| 51 | --color-primary-darkest: var(--color-accent-700); |
| 52 | --color-primary-light: color-mix(in oklab, var(--color-accent-500) 22%, transparent); |
| 53 | --color-primary-light-darker: color-mix(in oklab, var(--color-accent-500) 32%, transparent); |
| 54 | --color-primary-hover: var(--color-accent-400); |
| 55 | --color-primary-contrast-offset: var(--color-accent-400); |
| 56 | |
| 57 | /* Link color inside dialogs + hints. */ |
| 58 | --link-color: var(--color-accent-400); |
| 59 | --link-color-hover: var(--color-accent-300); |
| 60 | } |
| 61 | |
| 62 | .bland-canvas .excalidraw.theme--dark { |
| 63 | /* Inset surface — slightly darker than the page body (#221f21) so the |
| 64 | * canvas reads as a recessed panel. Uses bland's warmed zinc-950. */ |
| 65 | --default-bg-color: var(--color-zinc-950); |
| 66 | |
| 67 | /* Floating tool islands (top toolbar, properties panel) — one step up |
| 68 | * from the canvas so they lift off the surface. */ |
| 69 | --island-bg-color: var(--color-zinc-800); |
| 70 | --island-bg-color-alt: var(--color-zinc-900); |
| 71 | --overlay-bg-color: color-mix(in oklab, var(--color-zinc-950) 80%, transparent); |
| 72 | |
| 73 | /* Popups (color picker, context menu, dropdowns) — match bland's |
| 74 | * overlay-surface token. */ |
| 75 | --popup-bg-color: var(--color-zinc-800); |
| 76 | --popup-secondary-bg-color: var(--color-zinc-700); |
| 77 | --popup-text-color: var(--color-zinc-100); |
| 78 | |
| 79 | /* Sidebar (we hide Library, but dialogs + sheets still use this). */ |
| 80 | --sidebar-bg-color: var(--color-zinc-900); |
| 81 | --sidebar-border-color: var(--color-zinc-800); |
| 82 | |
| 83 | /* Borders — subtle, avoid hairline contrast against the lifted dark. */ |
| 84 | --default-border-color: var(--color-zinc-700); |
| 85 | --dialog-border-color: var(--color-zinc-700); |
| 86 | |
| 87 | /* Shadows — match the soft-lift feel of bland's own popovers. */ |
| 88 | --shadow-island: 0 1px 2px rgba(0, 0, 0, 0.28), 0 8px 24px rgba(0, 0, 0, 0.32); |
| 89 | --shadow-island-stronger: 0 2px 4px rgba(0, 0, 0, 0.36), 0 12px 32px rgba(0, 0, 0, 0.4); |
| 90 | --modal-shadow: 0 4px 8px rgba(0, 0, 0, 0.4), 0 24px 48px rgba(0, 0, 0, 0.5); |
| 91 | --sidebar-shadow: 0 0 0 1px var(--color-zinc-800); |
| 92 | |
| 93 | /* Text — lifted off pure white per the astigmatism guidance in |
| 94 | * PRODUCT.md. Keep the contrast comfortable, not maximal. */ |
| 95 | --text-primary-color: var(--color-zinc-100); |
| 96 | |
| 97 | /* Icons on chrome — same lifted tone as text. */ |
| 98 | --icon-fill-color: var(--color-zinc-300); |
| 99 | |
| 100 | /* Buttons — bland's quiet-hover pattern. */ |
| 101 | --button-hover-bg: color-mix(in srgb, var(--color-zinc-700) 60%, transparent); |
| 102 | --button-active-bg: color-mix(in srgb, var(--color-accent-500) 20%, transparent); |
| 103 | --button-active-border: var(--color-accent-500); |
| 104 | --button-gray-1: var(--color-zinc-800); |
| 105 | --button-gray-2: var(--color-zinc-700); |
| 106 | --button-gray-3: var(--color-zinc-600); |
| 107 | |
| 108 | /* Inputs inside dialogs. */ |
| 109 | --input-bg-color: var(--color-zinc-900); |
| 110 | --input-border-color: var(--color-zinc-700); |
| 111 | --input-hover-bg-color: var(--color-zinc-800); |
| 112 | --input-label-color: var(--color-zinc-400); |
| 113 | |
| 114 | /* Selection highlight on canvas handles. */ |
| 115 | --color-selection: var(--color-accent-500); |
| 116 | --focus-highlight-color: color-mix(in oklab, var(--color-accent-500) 50%, transparent); |
| 117 | } |