Files
resolutionflow/frontend/src/index.css
chihlasm ff985fb755 refactor: replace cyan accent with ember orange across entire frontend
Swap accent color from cyan (#22d3ee) to ember orange (#f97316) site-wide.
Cyan caused contrast issues and felt generic — orange brings warmth and
urgency fitting for a troubleshooting tool.

Changes:
- CSS variables: accent, accent-hover, accent-dim, accent-text, primary, ring
- Warning color shifted from amber (#fbbf24) to yellow (#eab308) for
  semantic separation from orange accent
- Brand SVGs: logo gradient updated to orange
- 50+ component files: all hardcoded cyan hex values, Tailwind cyan-*
  classes, and rgba(34,211,238,...) glow values replaced
- landing.css: all 45+ cyan references + 5 old border color fixes
- DESIGN-SYSTEM.md bumped to v5 with decisions log
- CLAUDE.md: all color references synced to charcoal palette + orange accent
- PWA theme-color meta tag updated to match sidebar (#10121a)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 07:37:44 +00:00

441 lines
14 KiB
CSS

@import 'tailwindcss';
@custom-variant dark (&:where(.dark, .dark *));
/* React Flow — imported here (not in component JS) so @tailwindcss/vite
doesn't wrap it in a cascade layer, which would lower its specificity
below Tailwind's own styles and hide nodes/edges. */
@import '@xyflow/react/dist/style.css';
@theme {
/* ── Surface colors (Charcoal — sidebar darkest) ─ */
--color-bg-page: #1a1c23;
--color-bg-sidebar: #10121a;
--color-bg-card: #22252e;
--color-bg-card-hover: #282b35;
--color-bg-input: #282b35;
--color-bg-code: #14161e;
--color-bg-elevated: #2e3140;
/* ── Text colors ───────────────────────────────── */
--color-text-heading: #f0f2f5;
--color-text-primary: #e2e5eb;
--color-text-secondary: #848b9b;
--color-text-muted: #4f5666;
--color-text-rail-label: #e2e5eb;
/* ── Border colors ─────────────────────────────── */
--color-border-default: #2e3240;
--color-border-hover: #3d4252;
/* ── Accent (ember orange) ─────────────────────── */
--color-accent: #f97316;
--color-accent-hover: #ea580c;
--color-accent-dim: rgba(249,115,22,0.10);
--color-accent-text: #fdba74;
/* ── Semantic colors ───────────────────────────── */
--color-success: #34d399;
--color-success-dim: rgba(52,211,153,0.10);
--color-warning: #eab308;
--color-warning-dim: rgba(234,179,8,0.10);
--color-danger: #f87171;
--color-danger-dim: rgba(248,113,113,0.10);
/* ── Tailwind semantic mappings ─────────────────── */
--color-background: #1a1c23;
--color-foreground: #e2e5eb;
--color-card: #22252e;
--color-card-foreground: #e2e5eb;
--color-popover: #22252e;
--color-popover-foreground: #e2e5eb;
--color-primary: #f97316;
--color-primary-foreground: #ffffff;
--color-secondary: #2e3140;
--color-secondary-foreground: #e2e5eb;
--color-muted: #2e3140;
--color-muted-foreground: #848b9b;
--color-accent-tw: #2e3140;
--color-accent-foreground: #e2e5eb;
--color-destructive: #f87171;
--color-destructive-foreground: #ffffff;
--color-border: #2e3240;
--color-input: #282b35;
--color-ring: #f97316;
/* ── Radii ─────────────────────────────────────── */
--radius-sm: 5px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
/* ── Fonts ─────────────────────────────────────── */
--font-sans: 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
--font-heading: 'Bricolage Grotesque', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', monospace;
/* font-label removed — migrated to font-mono or font-sans */
/* ── Animations ────────────────────────────────── */
--animate-fade-in: fade-in 200ms ease-out;
--animate-fade-in-up: fade-in-up 200ms ease-out;
--animate-slide-in-left: slide-in-from-left 200ms ease-out;
--animate-slide-in-bottom: slide-in-from-bottom 200ms ease-out;
--animate-scale-in: scale-in 150ms ease-out;
--animate-fade: fadeIn 300ms ease forwards;
@keyframes fade-in {
from { opacity: 0; } to { opacity: 1; }
}
@keyframes fade-in-up {
from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); }
}
@keyframes slide-in-from-left {
from { transform: translateX(-100%); } to { transform: translateX(0); }
}
@keyframes slide-in-from-bottom {
from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); }
}
@keyframes scale-in {
from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); }
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); }
}
}
:root {
--sidebar-w: 72px;
--sidebar-w-pinned: 260px;
--topbar-h: 44px;
--ease-out-smooth: cubic-bezier(0.4, 0, 0.2, 1);
}
/* ── Base styles ─────────────────────────────────────── */
@layer base {
* {
@apply border-border;
scrollbar-width: thin;
scrollbar-color: var(--color-border) transparent;
}
*::-webkit-scrollbar {
width: 6px;
height: 6px;
}
*::-webkit-scrollbar-track {
background: transparent;
}
*::-webkit-scrollbar-thumb {
background-color: var(--color-border);
border-radius: 9999px;
}
*::-webkit-scrollbar-thumb:hover {
background-color: var(--color-muted-foreground);
}
body {
@apply bg-background text-foreground font-sans;
}
button, [role="button"] {
cursor: pointer;
}
h1, h2, h3, h4, h5, h6 {
font-family: var(--font-heading);
font-weight: 700;
letter-spacing: -0.02em;
}
}
/* ── Glass/gradient shims removed — Design System v4 migration complete ── */
@utility stagger-item {
opacity: 0;
animation: fade-in-only 350ms var(--ease-out-smooth) forwards;
animation-delay: calc(var(--stagger-index, 0) * 50ms);
}
@utility btn-press {
@apply active:scale-[0.98] transition-transform;
}
/* ── New component classes (Design System v4) ───── */
@utility card-flat {
background: var(--color-bg-card);
border: 1px solid var(--color-border-default);
border-radius: 8px;
}
@utility card-interactive {
background: var(--color-bg-card);
border: 1px solid var(--color-border-default);
border-radius: 8px;
cursor: pointer;
transition: transform 350ms cubic-bezier(0.34, 1.56, 0.64, 1),
border-color 200ms ease,
box-shadow 200ms ease;
&:hover {
transform: translateY(-4px);
border-color: var(--color-border-hover);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}
}
@utility btn-primary-v4 {
background: var(--color-accent);
color: #ffffff;
font-weight: 550;
border-radius: 5px;
padding: 9px 16px;
font-size: 13px;
transition: filter 150ms ease, box-shadow 150ms ease, transform 150ms ease;
&:hover {
filter: brightness(1.1);
box-shadow: 0 2px 10px rgba(249, 115, 22, 0.2);
transform: translateY(-1px);
}
&:active {
box-shadow: 0 0 4px rgba(249, 115, 22, 0.1);
transform: translateY(0);
}
}
@utility btn-ghost-v4 {
background: transparent;
color: var(--color-text-secondary);
border: 1px solid var(--color-border-default);
border-radius: 5px;
padding: 9px 16px;
font-size: 13px;
transition: background 150ms ease, color 150ms ease, border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;
&:hover {
background: var(--color-bg-elevated);
color: var(--color-text-primary);
border-color: var(--color-border-hover);
transform: translateY(-1px);
}
&:active {
transform: translateY(0);
}
}
/* ── Interactive shadow patterns (dark-mode aware) ── */
/* On dark backgrounds, use brighter surfaces + faint accent glow
instead of black shadows (which are invisible on #1a1c23) */
/* Tab/toggle group: active item gets elevated surface + faint accent glow */
@utility tab-active-shadow {
background: var(--color-bg-elevated);
box-shadow: 0 1px 4px rgba(249, 115, 22, 0.08);
}
/* Card hover lift — brighter border + subtle accent glow */
@utility card-lift {
transition: box-shadow 200ms ease, transform 200ms ease, border-color 200ms ease;
&:hover {
border-color: var(--color-border-hover);
box-shadow: 0 2px 8px rgba(249, 115, 22, 0.06);
transform: translateY(-2px);
}
&:active {
box-shadow: none;
transform: translateY(0);
}
}
@utility rdp-custom {
@apply text-foreground;
& .rdp-month { @apply w-full; }
& .rdp-caption { @apply flex justify-center items-center mb-4; }
& .rdp-caption_label { @apply text-sm font-medium; }
& .rdp-nav { @apply flex gap-1; }
& .rdp-nav_button { @apply h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100; }
& .rdp-table { @apply w-full border-collapse; }
& .rdp-head_cell { @apply text-muted-foreground font-normal text-xs; }
& .rdp-cell { @apply text-center text-sm p-0; }
& .rdp-day { @apply h-9 w-9 p-0 font-normal hover:bg-accent rounded-md transition-colors; }
& .rdp-day_selected { @apply bg-primary text-primary-foreground hover:bg-primary/90; }
& .rdp-day_today { @apply bg-accent text-accent-foreground; }
& .rdp-day_outside { @apply text-muted-foreground opacity-50; }
& .rdp-day_disabled { @apply text-muted-foreground opacity-50; }
& .rdp-day_range_middle { @apply bg-accent text-accent-foreground; }
& .rdp-day_hidden { @apply invisible; }
}
/* ── Layout utilities ────────────────────────────────── */
@layer utilities {
.app-shell {
display: grid;
grid-template-columns: var(--sidebar-w) 1fr;
grid-template-rows: auto 1fr;
height: 100vh;
overflow: hidden;
transition: grid-template-columns 200ms ease;
}
.app-shell--pinned {
--sidebar-w: 260px;
}
/* Legacy collapsed class — kept as alias for pinned inverse */
.app-shell--collapsed {
grid-template-columns: 56px 1fr;
}
.topbar {
grid-column: 1 / -1;
height: var(--topbar-h);
}
.sidebar {
min-height: 0;
height: 100%;
overflow-y: auto;
}
.main-content {
min-height: 0;
min-width: 0;
/* Each page handles its own scrolling — full-height pages use
overflow-hidden, scrollable pages use overflow-y-auto */
}
@media (max-width: 767px) {
.app-shell {
grid-template-columns: 1fr;
}
}
/* Staggered fade-in helper — uses opacity-only animation
so it doesn't block hover transforms via fill-mode */
.fade-in {
animation: fade-in-only 0.3s ease forwards;
}
@keyframes fade-in-only {
from { opacity: 0; }
to { opacity: 1; }
}
}
/* ── Sonner toast overrides ──────────────────────────── */
[data-sonner-toast] {
background-color: var(--color-card) !important;
color: var(--color-card-foreground) !important;
border: 1px solid var(--color-border) !important;
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.3) !important;
border-radius: 0.75rem;
font-family: var(--font-sans);
}
[data-sonner-toast] [data-title] {
font-family: var(--font-sans);
font-weight: 600;
}
[data-sonner-toast][data-type='success'] {
border-color: oklch(0.76 0.15 163 / 0.3) !important;
}
[data-sonner-toast][data-type='success'] [data-icon] {
color: oklch(0.76 0.15 163);
}
[data-sonner-toast][data-type='error'] {
border-color: oklch(0.7 0.16 22 / 0.3) !important;
}
[data-sonner-toast][data-type='error'] [data-icon] {
color: oklch(0.7 0.16 22);
}
[data-sonner-toast][data-type='info'] {
border-color: var(--color-border) !important;
}
[data-sonner-toast][data-type='info'] [data-icon] {
color: var(--color-muted-foreground);
}
[data-sonner-toast][data-type='warning'] {
border-color: oklch(0.82 0.16 85 / 0.3) !important;
}
[data-sonner-toast][data-type='warning'] [data-icon] {
color: oklch(0.82 0.16 85);
}
[data-sonner-toast] [data-close-button] {
color: var(--color-muted-foreground);
border-radius: 0.375rem;
transition: color 150ms, background-color 150ms;
}
[data-sonner-toast] [data-close-button]:hover {
background-color: var(--color-accent);
color: var(--color-accent-foreground);
}
/* ── React Flow dark theme overrides ─────────────────── */
/* React Flow v12 uses --xy-* CSS custom properties for theming.
Override the defaults to match our design system. */
.react-flow.dark {
--xy-background-color-default: transparent;
--xy-edge-stroke-default: var(--color-border);
--xy-edge-stroke-selected-default: var(--color-primary);
--xy-edge-label-color-default: var(--color-muted-foreground);
--xy-edge-label-background-color-default: var(--color-card);
--xy-node-background-color-default: var(--color-card);
--xy-node-color-default: var(--color-foreground);
--xy-node-border-default: 1px solid var(--color-border);
--xy-handle-background-color-default: var(--color-border);
--xy-handle-border-color-default: var(--color-card);
--xy-minimap-background-color-default: var(--color-card);
--xy-minimap-mask-background-color-default: rgba(28, 31, 42, 0.6);
--xy-controls-button-background-color-default: var(--color-card);
--xy-controls-button-background-color-hover-default: var(--color-accent);
--xy-controls-button-color-default: var(--color-muted-foreground);
--xy-controls-button-color-hover-default: var(--color-foreground);
--xy-controls-button-border-color-default: var(--color-border);
}
.react-flow__controls {
border-radius: 0.75rem !important;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3) !important;
overflow: hidden;
}
.react-flow__minimap {
border-radius: 0.75rem !important;
}
.react-flow__attribution {
display: none;
}
/* ── Glow edge animations ────────────────────────────── */
@keyframes glow-flow-downstream {
from { stroke-dashoffset: 40; }
to { stroke-dashoffset: 0; }
}
@keyframes glow-flow-upstream {
from { stroke-dashoffset: 0; }
to { stroke-dashoffset: 40; }
}
.glow-edge-flow-downstream {
animation: glow-flow-downstream 1s linear infinite;
}
.glow-edge-flow-upstream {
animation: glow-flow-upstream 1s linear infinite;
}
/* ── Accessibility: Reduce motion ────────────────────── */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}