feat(carbon): init - #2286
Conversation
|
Hi, sorry to bother you. I just wanted to ask if there is any estimated timeline for the review. Thank you! |
|
Hi, we are unfortunately unable to review this pull request until it meets our contributing guidelines, which require you to use our pull request template https://github.com/catppuccin/userstyles/blob/main/.github/PULL_REQUEST_TEMPLATE/userstyle-creation.md. |
|
Thanks for letting me know! I’ve updated the pull request description to use the required template. |
- Revert @Version to the template default (2000.01.01); CI bumps it. - Drop the unused #lib.css-variables() call since nothing here reads --ctp-* custom properties. - Replace the `* { scrollbar-color: ... }` wildcard with a plain root-level declaration. - Remove all !important flags, instead tripling the :root selector at the mixin call site so every rule inherits enough specificity to win without it.
|
Thanks for the feedback, I think I fixed everything ([9e539ccd](DurianBurger561@9e539ccd)): version back to 2000.01.01 (my bad, forgot CI bumps that), removed the unneeded css-variables() call, moved the scrollbar rule off the |
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
Carbon has its own palette feature for the code editor's colours (Blackboard, Dracula, etc.). Overriding CodeMirror/token colours here fights that and leaves users unable to pick another editor theme, per scarcekoi's review. This userstyle now only themes the surrounding site chrome.
|
Made all the requested changes Should be good to go now; would appreciate a re-review when you get a chance |
Carbon's outer "editor" div (which wraps the toolbar and code card) kept its own near-black background since our Editor/Preview/Container selectors only set color/border-color, not background-color. That left a visible black seam around the toolbar and language dropdown, which is what scarcekoi's screenshot was showing. Verified live on carbon.now.sh by patching the site's actual CSS in devtools before and after. Also updated the lib import to the new versioned path (lib/std/v1.less) to match the rest of the repo after the standard library migration.
The `html, body, #__next, main` rule sits inside `:root:root:root`, which LESS expands as a descendant combinator (`:root:root:root html`). <html> has no ancestor element, so that compiled selector can never match — the background/color on <html> itself was silently dead code, letting Carbon's own near-black background show through at the page edges. Verified live on carbon.now.sh: before this fix, elementFromPoint(10, 10) resolved to <html> with its original rgb(18,18,18) background even with the rest of the page themed. Fixed by using `html&` so LESS compiles it to the compound selector `html:root:root:root` (same element, not a descendant), confirmed the background now applies correctly.
Carbon draws a 1px/2px white inset box-shadow around a dropdown trigger (e.g. the language selector) while it's open, as its own "active" indicator — unrelated to background-color. Left uncolored, that white ring made the trigger look like a different, lighter shade than the rest of the dropdown, which is what the report about "light/dark mismatch" in the open dropdown was actually showing. Recolored it to the configured accent instead of leaving Carbon's white. Verified live via devtools: before, computed box-shadow on the expanded trigger was `rgb(255,255,255) ... inset`; after, it's the accent color.
Carbon's dropdown triggers (theme selector, searchable language picker) are a <span class="...dropdown-display"> wrapping an <input>. Both matched two of our rules with EQUAL specificity — "Shared surfaces" via [class*="dropdown"] (mantle) and "Controls" via the bare `input`/`button` element selector (surface0) — so the tie broke on source order per element: the [role="button"] wrapper span also matches an attribute selector in Controls and won there, but the plain <input> only matched Controls via the low-specificity bare tag and lost to Shared surfaces instead. Result: the wrapper rendered surface0 while the input inside it rendered mantle, a visible two-tone seam within what should be one control. Fixed by adding `:not(:disabled)` (a functional no-op) to the plain button/input/select/textarea selectors in Controls, bumping them to attribute-selector specificity so they reliably win. Verified live via devtools: before, span bg was #313244 and the input inside it was #181825; after, both are #313244.
The previous fix only addressed the resting-state background mismatch between a dropdown trigger's wrapper span and its nested search <input>. The hover/active rules had the same gap: they only listed button/[role="button"]/[class*="button"], never input/select/textarea, so on hover the wrapper (matching [role="button"]:hover) would shift to surface1 while the input inside it stayed unaffected — reintroducing the two-tone mismatch, just in the hover state instead of the resting one. Added input/select/textarea to both the :hover and :active rule groups so the whole control changes shade together.
Carbon's dropdown triggers (theme selector, language picker) contain a small caret svg, so they also matched the "icon buttons" rule (button/[role="button"]:has(svg)), which hovers to lavender — a different color than the plain accent hover the trigger's nested <input> gets from Controls. Excluded dropdown triggers from the icon-button rule with :not([class*="Dropdown"]):not([class*="dropdown"]), since that rule is meant for icon-only buttons (settings, copy), not text+caret comboboxes. Also pinned border-color: transparent on the trigger (matched via its own "...dropdown-display" class) so hover/active border-color changes never show as a visible border there — the accent box-shadow ring added earlier is the only "active" indicator now, avoiding a doubled ring/border look.
The border-color: transparent rule for dropdown triggers tied in specificity with the button/input :hover and :active rules, which come later in source order and therefore won on hover — so the trigger's border flashed to the accent color on hover again despite the earlier fix. Raised the rule's specificity (doubled [class] attribute selector plus explicit :hover/:active variants) so it always beats those, in every interaction state. Verified resting-state border stays transparent; specificity now (0,7,0) vs the hover rules' (0,5,0).
Root cause of the recurring dropdown color mismatch: Carbon's trigger is a wrapper span (...dropdown-display) with a search input (...dropdown-display-text) layered inside, and both carried their own background from the broad Controls/Shared rules. Because :hover only applies to the element actually under the cursor, the wrapper and the input could sit in different hover states and render as two shades — which is why fixing one interaction state kept surfacing the seam in another. Fix it structurally instead of per-state: make the inner input's background fully transparent so it always reveals the wrapper's color, regardless of which element is hovered. The wrapper alone now owns the visible surface. Kept the border-transparent pin on the pair. Verified the -text selector matches only the input, not the wrapper.
The real "inner box" users saw was Carbon's own white inset box-shadow ring on the dropdown trigger (1px when closed, 2px .is-open). The earlier accent recolor only targeted the aria-expanded="true" open state, so the closed-state white ring survived — and even recolored it still looked like a mismatched inner rectangle. Its specificity (.dropdown-display.is-open, 0,3,0) also beat the recolor in some states. Flatten the trigger into a single surface instead: box-shadow: none in all states (specificity raised above Carbon's ring), border-color transparent, and the inner input's background transparent so it always reveals the wrapper. No inner ring, no two-tone, in resting/hover/ active/open. Verified live: computed box-shadow is now none.
Even after removing the inset ring, the open dropdown still looked two-tone: the trigger bar matched the Controls rule (surface0, lighter) while its own popup list and items are mantle (darker), so the trigger read as a lighter "outer" bar over a darker list. Pinned the trigger wrapper's background to mantle in all states so the whole dropdown — trigger, container, list, and items — is one consistent surface. The inner input stays transparent and reveals the wrapper, so no seam appears in any state. Verified live: trigger and list items now both render mantle.
The two-tone seam also affected the open list: each row is a li[role="option"] wrapping a span...dropdown-list-item-text. On hover the row went surface0 but the inner text span kept its own mantle background, so hovered rows showed a lighter bar with a darker inner strip. Generalized the transparent-text rule from just the trigger input (dropdown-display-text) to every dropdown text child ([class*="dropdown"][class*="-text"]) — which matches the trigger input and the list-row labels but never the wrappers/rows — so the label always reveals its row's background in every state. Verified live: the list-item text span computes to transparent.
The export popout had two background problems: the popout container itself matched none of our surface selectors (only "popover", not "popout") so it kept Carbon's default near-black, and its `export-row` containers matched the broad [class*="export"] accent rule, painting each File name / Size / Open / Download row with an accent tint and accent text — a lighter/tinted inner block over the darker popout. Added Popout/popout to the Shared surfaces group so the container is mantle like other menus, and excluded row containers from the Export accent rule with :not([class*="row"]) so the rows read as part of the popout surface while the toolbar's export-container keeps its accent highlight. Verified live: popout is mantle, export-row transparent with normal text, and the toolbar Export button stays accented.
After theming the popout mantle, its filename input still took the Controls surface0 and read as a lighter box floating on the darker panel. Gave inputs inside the popout the mantle surface so the field blends into the panel; the surface1 border it already gets from Controls keeps it legible as an editable input. Verified live: the filename field now computes to mantle and the popout reads as one cohesive surface.
Extended the popout-blend fix from just the filename input to the popout's buttons — the 1x/2x/4x size options, Open, and Download PNG/SVG — which were still surface0 boxes on the mantle panel. They now take the mantle surface and get a surface0 accent hover for feedback, so the whole export popout reads as one cohesive surface with no lighter control boxes. Verified live: all six popout buttons compute to mantle.
The window title input (aria-label "Image title") at the top of the code preview card took the Controls surface0 and showed as a lighter box in the card's title bar, whose backdrop is the user's export background, not one of our surfaces. Made that input transparent (background and border) so it reveals the card behind it instead of painting a box over it. Verified live: the title field now computes to transparent and the title bar reads cleanly.
The card's title bar (window-controls) matched the Controls rule via [class*="control"] and took surface0, showing as a lighter strip over the card's own background — the card is the user's artwork, themed by their chosen export background, not one of our surfaces. Made window-controls transparent (merged with the existing Image-title input rule) so the title bar reveals the card behind it, matching stock Carbon where the title bar is the card background. Verified live: window-controls computes to transparent.
The real cause of the lighter title bar: the Preview/export mantle rule included [class*="Window"]/[class*="window"], and it came after (and at equal specificity to) the window-controls transparent rule, so it won and repainted the card's title bar mantle. Those selectors only ever match the code card's own window-controls (title bar) and window-theme (code container) — the user's artwork — so removed them from the rule. Combined with the existing transparent window-controls rule, the title bar now reveals the card background like stock Carbon. Verified live: window-controls is transparent and the title bar matches the card.
Carbon hard-codes `background-color: #1f1f1f !important` on the hover (and :focus) of several action buttons — Tweet, Export, the copy and background-select buttons — so on hover they flipped to near-black. That reads fine against the dark flavors but is a jarring, high- contrast slab in the light flavors. Our regular hover rules lost to Carbon's !important, so added !important to the hover/active background-color of the control and icon-button rules — overriding an upstream !important, the one sanctioned use. Verified live: the Export button now hovers to surface1 (rgb(188,192,204) in Latte) instead of rgb(31,31,31).
The previous commit added `background-color: @Surface1 !important` to the control hover rule (to beat Carbon's black hover). That !important also hit the code card's title field on hover, repainting it as a grey box in the title bar. Made the window-controls / Image-title transparent rule !important too so it wins over the hover rule and the title bar stays part of the card in every state.
|
hi, please review it, all the theme background issues fixed |
scarcekoi noted the dropdown/box outlines were unthemed and missing on two boxes and the GitHub link. Root cause: Carbon draws button outlines with `box-shadow: #fff 0 0 0 1px inset` (a white inset ring), which our border-color theming never touched, and the dropdown rule had zeroed its ring entirely (so the two dropdowns lost their outline). Recolored the ring to a themed surface1 on the dropdown triggers and the icon buttons, and added an explicit rule for the GitHub sign-in button (its icon is a CSS background, not an <svg>, so it missed the icon-button rule). Verified live: dropdowns, icon buttons, and the GitHub button now show a subtle surface1 outline instead of white.
The themed ring added for the unthemed-border fix matched both the dropdown wrapper (...dropdown-display) and its inner search input (...dropdown-display-text, whose class also contains "dropdown-display"), so both drew the inset ring and it read as a doubled inner/outer border. Excluded the -text input from the ring rule (:not([class*="-text"])) and pinned box-shadow:none on the dropdown text elements, so only the outer wrapper carries the single themed outline. Verified live: wrapper box-shadow is surface1, the inner input's is none.
Tweet and Export are split buttons (text half + dropdown-arrow half). Carbon rings both halves the same colour, but the arrow half has an svg so the icon-button rule recolored only it to surface1, leaving the text half on Carbon's colour — each split button showed a two-tone, broken- looking outline. Recolored both halves per container to one themed ring (Tweet blue via share-menu-container, Export accent via export-menu-container), !important to beat the icon-button rule. Verified live: both halves of Tweet are blue, both halves of Export are accent.
A full audit of the toolbar rings turned up one box still on Carbon's white inset ring: the background-colour picker swatch (bg-select-display), a button with no svg that missed the icon-button rule. Recolored just its ring to surface1 (its background stays the colour preview). Re-audited all ten toolbar boxes: no white rings and none missing.
The bright border still visible on the dropdowns was the leading icon cell (dropdown-icon — the palette/globe box), a separate element from dropdown-display that kept Carbon's white inset ring, so each dropdown showed a themed border on one half and a white one on the icon half. Recolored dropdown-icon's ring to surface1. A full-page scan now finds zero white box-shadow rings anywhere.
|
Hi, I made a change. if there are still any problem, can you give me a specific details about it, thank you |




Website: Carbon
URL: https://carbon.now.sh
Description:
Carbon is a web app for creating and sharing images of source code. This userstyle applies Catppuccin colors to Carbon's UI, editor/export preview, syntax highlighting, controls, menus, and export-related surfaces.
🗒 Checklist 🗒
I have read and followed Catppuccin's userstyle contributing guidelines.
I used AI (or AI-assistance) for this change.
/styles/<name-of-website>.catppuccin.user.lesswithin the new directory.userstyles.ymlfile with information about the new userstyle.💬 Comments 💬
Tested all four flavours (Latte, Frappé, Macchiato, Mocha), accent switching, and Carbon PNG/SVG export with Stylus enabled.