Custom CSS

Customize the appearance of your chat interface with custom CSS

Overview

Custom CSS allows you to customize the appearance of your Junet chat application beyond the standard theme settings. Your CSS is injected after the theme styles, allowing you to override any default styling.

Accessing Custom CSS

  1. Navigate to SettingsBranding
  2. Select the Custom CSS tab
  3. Enter your CSS in the text field
  4. Click Save

Your CSS is applied immediately to all users.


Available CSS Variables

Use these CSS variables to stay consistent with the selected theme:

Main Colors

VariableDescription
--backgroundPage background color
--foregroundDefault text color
--primaryPrimary color (buttons, links)
--primary-foregroundText on primary background
--secondarySecondary color
--secondary-foregroundText on secondary background
--accentAccent color for hover effects
--accent-foregroundText on accent color
--mutedMuted background color
--muted-foregroundMuted text color
--destructiveColor for delete/error actions
--destructive-foregroundText on destructive color

UI Elements

VariableDescription
--cardCard background color
--card-foregroundText color in cards
--popoverPopover/dropdown background
--popover-foregroundText in popovers
--borderDefault border color
--inputInput field border color
--ringFocus ring color
--radiusDefault border radius
VariableDescription
--sidebar-backgroundSidebar background
--sidebar-foregroundText in sidebar
--sidebar-accentHover/active background
--sidebar-accent-foregroundText on accent background
--sidebar-borderSidebar border color
--sidebar-primaryPrimary color in sidebar
--sidebar-primary-foregroundText on primary color

Fonts

VariableDescription
--font-sansSans-serif font family
--font-serifSerif font family
--font-monoMonospace font family

Charts

VariableDescription
--chart-1 to --chart-5Colors for charts

Using CSS Variables

CSS variables are stored in HSL format. Use them with hsl():

/* Correct: With hsl() wrapper */
.my-element {
  background-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  border: 1px solid hsl(var(--border));
}
 
/* With transparency */
.my-element-transparent {
  background-color: hsl(var(--primary) / 0.5); /* 50% transparency */
}

CSS Selectors

Messages

/* Individual message container */
[id^="message-"] {
  /* Your styles */
}
 
/* User messages */
[id^="message-"] .ml-auto.rounded-xl {
  /* Your styles */
}
 
/* Assistant messages */
.assistant-message-bubble-card {
  /* Your styles */
}
 
/* Artifact buttons in messages */
.artifact-buttons-container {
  /* Your styles */
}
/* Entire sidebar */
[data-sidebar] {
  /* Your styles */
}
 
/* Sidebar header */
[data-sidebar="header"] {
  /* Your styles */
}
 
/* Sidebar menu buttons */
[data-sidebar="menu-button"] {
  /* Your styles */
}
 
/* Active sidebar item */
[data-sidebar="menu-button"][data-active="true"] {
  /* Your styles */
}
 
/* Hide sidebar on mobile */
@media (max-width: 768px) {
  [data-sidebar] {
    display: none;
  }
}

Chat Input

/* Input container */
.pb-12.pt-1.rounded-md.border {
  /* Your styles */
}
 
/* Send button */
button.bg-primary.rounded-lg.h-9.min-w-9 {
  /* Your styles */
}

Examples

Custom Scrollbar

::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
 
::-webkit-scrollbar-track {
  background: transparent;
}
 
::-webkit-scrollbar-thumb {
  background: hsl(var(--muted-foreground) / 0.3);
  border-radius: 3px;
}
 
::-webkit-scrollbar-thumb:hover {
  background: hsl(var(--muted-foreground) / 0.5);
}
 
/* Firefox */
* {
  scrollbar-width: thin;
  scrollbar-color: hsl(var(--muted-foreground) / 0.3) transparent;
}

Animated Messages

[id^="message-"] {
  animation: messageAppear 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}
 
@keyframes messageAppear {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

User Message Gradient

[id^="message-"] .ml-auto.rounded-xl {
  background: linear-gradient(
    135deg,
    hsl(var(--primary) / 0.12) 0%,
    hsl(var(--primary) / 0.06) 100%
  ) !important;
  border: 1px solid hsl(var(--primary) / 0.15);
  box-shadow: 0 2px 8px hsl(var(--primary) / 0.08);
}

Send Button Glow

button.bg-primary.rounded-lg.h-9.min-w-9 {
  transition: box-shadow 0.25s ease;
}
 
button.bg-primary.rounded-lg.h-9.min-w-9:hover {
  box-shadow: 
    0 0 20px hsl(var(--primary) / 0.5),
    0 0 40px hsl(var(--primary) / 0.25);
}

Code Block Rainbow Border

pre {
  position: relative;
  border: 1px solid hsl(var(--border) / 0.8);
  overflow: hidden;
}
 
pre::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(
    90deg,
    hsl(var(--chart-1, 220 70% 50%)) 0%,
    hsl(var(--chart-2, 160 60% 45%)) 25%,
    hsl(var(--chart-3, 30 80% 55%)) 50%,
    hsl(var(--chart-4, 280 65% 60%)) 75%,
    hsl(var(--chart-5, 340 75% 55%)) 100%
  );
}

Dark Mode Specific Styles

/* Only in dark mode */
.dark .my-element {
  box-shadow: 0 0 20px hsl(var(--primary) / 0.2);
}
 
/* Only in light mode */
:root:not(.dark) .my-element {
  box-shadow: 0 2px 10px hsl(var(--foreground) / 0.1);
}

Hide Sidebar Completely

[data-sidebar] {
  display: none !important;
}
 
main {
  margin-left: 0 !important;
  width: 100% !important;
}

Import Custom Font

@import url('https://fonts.googleapis.com/css2?family=Fira+Code&display=swap');
 
pre, code {
  font-family: 'Fira Code', monospace !important;
}

Best Practices

1. Use CSS Variables

Always use theme variables instead of fixed color values so your CSS works with light/dark mode:

/* ❌ Bad - fixed color */
.my-button {
  background: #7c3aed;
}
 
/* ✅ Good - theme variable */
.my-button {
  background: hsl(var(--primary));
}

2. Avoid !important When Possible

!important should only be used as a last resort:

/* ❌ Avoid */
.element {
  color: red !important;
}
 
/* ✅ Better - more specific selector */
body .element {
  color: hsl(var(--destructive));
}

3. Avoid Transform on Sidebar Items

Using transform on sidebar items can cause layout issues with absolute positioned elements:

/* ❌ Avoid - causes layout shifts */
[data-sidebar] button:hover {
  transform: translateX(3px);
}
 
/* ✅ Better - use background/color changes */
[data-sidebar] button:hover {
  background: hsl(var(--sidebar-accent));
}

4. Consider Responsive Design

Test your CSS on different screen sizes:

@media (max-width: 768px) {
  /* Mobile styles */
}

Limits

  • Maximum length: 50,000 characters
  • Syntax validation: None - invalid CSS is silently ignored
  • Scope: Global - applies to the entire application

Debugging

Use browser DevTools (F12) to:

  1. Inspect CSS variables: Under Computed → Filter by --
  2. Test styles: Make live changes in the Elements panel
  3. Find errors: Console shows CSS parsing errors

Security Notes

  • Custom CSS can only change styles, not execute JavaScript
  • External resources (fonts, images) must be loaded via HTTPS
  • CSS code is stored server-side and injected on every app load
Custom CSS | Junet.io Documentation