Files
textbee/web/styles/main.css
isra el 50d0902535 refactor: make transitions and entrance animations subtle
The entrance motion added in the previous rounds was too loud. Softened at
the token level and removed at the call sites where it replayed repeatedly.

Tokens (styles/main.css):
- fade-in 0.3s -> 0.15s
- fade-in-up 0.4s / 8px rise -> 0.2s / 3px rise
- check-pop 0.35s / 0.6-1.15-1 overshoot -> 0.2s / 0.92-1.02-1

Call sites, which mattered more than the token tuning:
- message-card: dropped animate-fade-in. Message history refetches on filter
  change, pagination and auto-refresh, so every row replayed its fade on
  every tick.
- get-started: dropped the per-index animationDelay stagger. The card polls
  every 10s, so any remount replayed a cascading six-row stagger.
- empty-state: dropped animate-fade-in from a static block.
- community-links: hover:scale-105 -> border and shadow change.
- onboarding progress bars: duration-500 -> duration-300.

Radix enter/exit animations on dialogs, dropdowns, selects, toasts and the
accordion are unchanged: they are short, conventional and expected. The
prefers-reduced-motion guard is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 19:52:29 +03:00

220 lines
5.6 KiB
CSS

@import 'tailwindcss';
@import 'tw-animate-css';
/* Tailwind v4 dark mode driven by a `.dark` class (set by next-themes). */
@custom-variant dark (&:is(.dark *));
/*
* Map the shadcn HSL design tokens (defined in :root / .dark below) to Tailwind
* v4 theme colors so utilities like bg-background, text-muted-foreground,
* border-border, bg-primary and the brand-* ramp keep working.
*
* Rebrand: the primary accent is now a warm modern orange (#EA580C,
* hsl(21 90% 48%)) and the brand-* ramp is the matching orange scale.
*/
@theme inline {
--color-background: hsl(var(--background));
--color-foreground: hsl(var(--foreground));
--color-card: hsl(var(--card));
--color-card-foreground: hsl(var(--card-foreground));
--color-popover: hsl(var(--popover));
--color-popover-foreground: hsl(var(--popover-foreground));
--color-primary: hsl(var(--primary));
--color-primary-foreground: hsl(var(--brand-foreground));
--color-secondary: hsl(var(--secondary));
--color-secondary-foreground: hsl(var(--secondary-foreground));
--color-muted: hsl(var(--muted));
--color-muted-foreground: hsl(var(--muted-foreground));
--color-accent: hsl(var(--accent));
--color-accent-foreground: hsl(var(--accent-foreground));
--color-destructive: hsl(var(--destructive));
--color-destructive-foreground: hsl(var(--destructive-foreground));
--color-border: hsl(var(--border));
--color-input: hsl(var(--input));
--color-ring: hsl(var(--ring));
--color-brand-foreground: hsl(var(--brand-foreground));
--color-chart-1: hsl(var(--chart-1));
--color-chart-2: hsl(var(--chart-2));
--color-chart-3: hsl(var(--chart-3));
--color-chart-4: hsl(var(--chart-4));
--color-chart-5: hsl(var(--chart-5));
/* Warm modern orange ramp (Tailwind orange), 600 is the primary accent. */
--color-brand-50: #fff7ed;
--color-brand-100: #ffedd5;
--color-brand-200: #fed7aa;
--color-brand-300: #fdba74;
--color-brand-400: #fb923c;
--color-brand-500: #f97316;
--color-brand-600: #ea580c;
--color-brand-700: #c2410c;
--color-brand-800: #9a3412;
--color-brand-900: #7c2d12;
--color-brand-950: #431407;
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
--font-sans: var(--font-inter), ui-sans-serif, system-ui, -apple-system,
'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
--animate-accordion-down: accordion-down 0.2s ease-out;
--animate-accordion-up: accordion-up 0.2s ease-out;
/* Entrance motion is deliberately barely perceptible: it should soften a
state change, never announce itself. */
--animate-fade-in: fade-in 0.15s ease-out both;
--animate-fade-in-up: fade-in-up 0.2s ease-out both;
--animate-check-pop: check-pop 0.2s ease-out both;
}
@keyframes check-pop {
0% {
transform: scale(0.92);
opacity: 0.6;
}
60% {
transform: scale(1.02);
}
100% {
transform: scale(1);
opacity: 1;
}
}
@keyframes accordion-down {
from {
height: 0;
}
to {
height: var(--radix-accordion-content-height);
}
}
@keyframes accordion-up {
from {
height: var(--radix-accordion-content-height);
}
to {
height: 0;
}
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fade-in-up {
from {
opacity: 0;
transform: translateY(3px);
}
to {
opacity: 1;
transform: none;
}
}
:root {
--background: 0 0% 100%;
--foreground: 222 47% 11%;
--card: 0 0% 100%;
--card-foreground: 222 47% 11%;
--popover: 0 0% 100%;
--popover-foreground: 222 47% 11%;
/* #EA580C */
--primary: 21 90% 48%;
--brand-foreground: 0 0% 100%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
--muted: 220 14.3% 95.9%;
--muted-foreground: 220 8.9% 46.1%;
--accent: 24 100% 97%;
--accent-foreground: 21 90% 40%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 20% 98%;
--border: 220 13% 91%;
--input: 220 13% 91%;
--ring: 21 90% 48%;
--chart-1: 21 90% 48%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 262 52% 55%;
--radius: 0.625rem;
}
.dark {
/* Layered neutrals: background sits below cards for depth. */
--background: 0 0% 9%;
--foreground: 0 0% 98%;
--card: 0 0% 12%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 12%;
--popover-foreground: 0 0% 98%;
/* #EA580C */
--primary: 21 90% 48%;
--brand-foreground: 0 0% 100%;
--secondary: 0 0% 16%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 16%;
--muted-foreground: 0 0% 64%;
--accent: 22 60% 16%;
--accent-foreground: 24 95% 80%;
--destructive: 0 62.8% 45%;
--destructive-foreground: 210 20% 98%;
--border: 0 0% 20%;
--input: 0 0% 22%;
--ring: 21 90% 52%;
--chart-1: 21 90% 52%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
/*
* v4 no longer applies a default border color, and defaults many borders to
* currentColor. Keep the app's existing behavior of using the border token.
*/
@layer base {
* {
border-color: hsl(var(--border));
}
body {
background-color: hsl(var(--background));
color: hsl(var(--foreground));
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
/* Safety net: an oversized element must never widen the page sideways. */
overflow-x: clip;
}
}
/* Respect users who prefer reduced 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;
}
}