Files
smoothschedule/frontend/src/index.css
poduck 725a3c5d84 Add dynamic sidebar text color with brand color contrast
- Add sidebar text color picker to Branding Settings page
- Implement auto-calculated complementary text colors based on brand color luminance
- Dark themes get light tinted text, light themes get dark tinted text
- Add navigation preview showing text on gradient background
- Support 10 new lighter color palettes (Soft Mint, Lavender, Peach, etc.)
- Add CSS utility classes for brand-text with opacity support
- Update sidebar and navigation components to use dynamic text colors
- Add sidebar_text_color field to Tenant model with migration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 22:16:25 -05:00

300 lines
7.0 KiB
CSS

@import "tailwindcss";
@variant dark (&:where(.dark, .dark *));
@theme {
--font-sans: Inter, sans-serif;
--color-brand-50: #eff6ff;
--color-brand-100: #dbeafe;
--color-brand-200: #bfdbfe;
--color-brand-300: #93c5fd;
--color-brand-400: #60a5fa;
--color-brand-500: #3b82f6;
--color-brand-600: #2563eb;
--color-brand-700: #1d4ed8;
--color-brand-800: #1e40af;
--color-brand-900: #1e3a8a;
/* Dynamic brand text color - uses RGB for opacity support */
/* Format: rgb(R G B / alpha) where R G B come from --color-brand-text-rgb */
--color-brand-text: rgb(var(--color-brand-text-rgb) / 1);
}
:root {
font-family: 'Inter', system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
/* Default brand text color (light blue-white for dark backgrounds) */
/* This is dynamically updated by applyBrandColors() based on brand color luminance */
--color-brand-text-rgb: 233 239 255;
}
/* Custom text-brand-text utility classes with opacity support */
.text-brand-text {
color: rgb(var(--color-brand-text-rgb));
}
.text-brand-text\/5 {
color: rgb(var(--color-brand-text-rgb) / 0.05);
}
.text-brand-text\/10 {
color: rgb(var(--color-brand-text-rgb) / 0.1);
}
.text-brand-text\/20 {
color: rgb(var(--color-brand-text-rgb) / 0.2);
}
.text-brand-text\/30 {
color: rgb(var(--color-brand-text-rgb) / 0.3);
}
.text-brand-text\/40 {
color: rgb(var(--color-brand-text-rgb) / 0.4);
}
.text-brand-text\/50 {
color: rgb(var(--color-brand-text-rgb) / 0.5);
}
.text-brand-text\/60 {
color: rgb(var(--color-brand-text-rgb) / 0.6);
}
.text-brand-text\/70 {
color: rgb(var(--color-brand-text-rgb) / 0.7);
}
.text-brand-text\/80 {
color: rgb(var(--color-brand-text-rgb) / 0.8);
}
.text-brand-text\/90 {
color: rgb(var(--color-brand-text-rgb) / 0.9);
}
/* Hover variants */
.hover\:text-brand-text:hover {
color: rgb(var(--color-brand-text-rgb));
}
.hover\:text-brand-text\/60:hover {
color: rgb(var(--color-brand-text-rgb) / 0.6);
}
.hover\:text-brand-text\/80:hover {
color: rgb(var(--color-brand-text-rgb) / 0.8);
}
/* Background variants using brand-text color */
.bg-brand-text\/5 {
background-color: rgb(var(--color-brand-text-rgb) / 0.05);
}
.bg-brand-text\/10 {
background-color: rgb(var(--color-brand-text-rgb) / 0.1);
}
.hover\:bg-brand-text\/5:hover {
background-color: rgb(var(--color-brand-text-rgb) / 0.05);
}
/* Border variants */
.border-brand-text\/10 {
border-color: rgb(var(--color-brand-text-rgb) / 0.1);
}
.border-brand-text\/20 {
border-color: rgb(var(--color-brand-text-rgb) / 0.2);
}
html, body {
margin: 0;
min-width: 320px;
height: 100%;
}
#root {
width: 100%;
height: 100%;
}
/* React Grid Layout Dashboard Styling */
.layout {
position: relative;
}
.widget-container {
height: 100%;
}
.widget-container > div {
height: 100%;
}
/* Drag handle styling */
.drag-handle {
cursor: grab;
}
.drag-handle:active {
cursor: grabbing;
}
/* React Grid Layout overrides */
.react-grid-item {
transition: all 200ms ease;
transition-property: left, top;
}
.react-grid-item.cssTransforms {
transition-property: transform;
}
.react-grid-item.resizing {
z-index: 1;
will-change: width, height;
}
.react-grid-item.react-draggable-dragging {
transition: none;
z-index: 3;
will-change: transform;
}
.react-grid-item.dropping {
visibility: hidden;
}
.react-grid-item > .react-resizable-handle {
position: absolute;
width: 20px;
height: 20px;
}
.react-grid-item > .react-resizable-handle::after {
content: "";
position: absolute;
right: 3px;
bottom: 3px;
width: 6px;
height: 6px;
border-right: 2px solid rgba(0, 0, 0, 0.3);
border-bottom: 2px solid rgba(0, 0, 0, 0.3);
}
.dark .react-grid-item > .react-resizable-handle::after {
border-right-color: rgba(255, 255, 255, 0.3);
border-bottom-color: rgba(255, 255, 255, 0.3);
}
.react-resizable-handle-se {
bottom: 0;
right: 0;
cursor: se-resize;
}
.react-resizable-handle-sw {
bottom: 0;
left: 0;
cursor: sw-resize;
}
.react-resizable-handle-nw {
top: 0;
left: 0;
cursor: nw-resize;
}
.react-resizable-handle-ne {
top: 0;
right: 0;
cursor: ne-resize;
}
/* =============================================================================
Email Template Editor - Force Light Mode
Puck editor for emails should always use light theme for accurate preview
============================================================================= */
.email-editor-light-mode {
color-scheme: light !important;
background-color: #ffffff !important;
}
/* Override all Puck dark mode styles within email editor */
.email-editor-light-mode,
.email-editor-light-mode * {
--puck-color-bg: #ffffff !important;
--puck-color-text: #1f2937 !important;
}
/* Puck sidebar and component list */
.email-editor-light-mode [class*="Puck-"] {
background-color: #f9fafb !important;
color: #1f2937 !important;
}
/* Puck frame/canvas area */
.email-editor-light-mode [class*="Frame"],
.email-editor-light-mode [class*="canvas"],
.email-editor-light-mode [class*="preview"] {
background-color: #f3f4f6 !important;
}
/* Puck component panels */
.email-editor-light-mode [class*="ComponentList"],
.email-editor-light-mode [class*="Fields"],
.email-editor-light-mode [class*="Outline"] {
background-color: #ffffff !important;
border-color: #e5e7eb !important;
}
/* Puck inputs and form elements */
.email-editor-light-mode input,
.email-editor-light-mode select,
.email-editor-light-mode textarea {
background-color: #ffffff !important;
border-color: #d1d5db !important;
color: #1f2937 !important;
}
/* Puck buttons */
.email-editor-light-mode button {
color: #374151 !important;
}
/* Puck labels and text */
.email-editor-light-mode label,
.email-editor-light-mode [class*="label"] {
color: #374151 !important;
}
/* Puck header bar */
.email-editor-light-mode [class*="header"] {
background-color: #ffffff !important;
border-color: #e5e7eb !important;
}
/* =============================================================================
Puck Editor Height Fix
Force Puck to fill container and enable sidebar scrolling
============================================================================= */
/* Container must be positioned for absolute child */
.email-editor-light-mode {
position: relative !important;
}
/* Force Puck root to fill container absolutely */
.email-editor-light-mode > [id^="_r_"] {
position: absolute !important;
inset: 0 !important;
}
/* Target Puck's main layout - all direct children need height constraints */
.email-editor-light-mode > [id^="_r_"] > div {
height: 100% !important;
}
.email-editor-light-mode > [id^="_r_"] > div > div {
height: 100% !important;
}
/* Force the left sidebar to be constrained and scrollable */
/* Use calc to account for the header areas above the editor */
.email-editor-light-mode [class*="_Sidebar_"][class*="--left"],
.email-editor-light-mode [class*="_Sidebar_"][class*="--right"] {
max-height: calc(100vh - 280px) !important;
overflow-y: auto !important;
border: 3px solid red !important; /* TEST - remove after confirming selector works */
}