Files
chat/frontend/src/index.css
T
2026-09-22 08:04:10 +02:00

199 lines
5.4 KiB
CSS

@tailwind base;
@tailwind components;
@tailwind utilities;
/* Accent palette defaults (emerald). Overridden at runtime by lib/accent.ts
from the user's saved accent color / custom pick. Values are RGB triplets. */
:root {
--ka-accent-50: 236 253 245;
--ka-accent-100: 209 250 229;
--ka-accent-200: 167 243 208;
--ka-accent-300: 110 231 183;
--ka-accent-400: 52 211 153;
--ka-accent-500: 16 185 129;
--ka-accent-600: 5 150 105;
--ka-accent-700: 4 120 87;
--ka-accent-800: 6 95 70;
--ka-accent-900: 6 78 59;
--ka-accent-950: 2 44 34;
}
html, body, #root {
height: 100%;
}
/* Mobile browser chrome (URL bar) shrinks the visible area — dynamic
viewport units keep the app glued to the real screen height. */
@supports (height: 100dvh) {
html, body, #root {
height: 100dvh;
}
}
body {
@apply bg-stone-100 text-stone-900 antialiased dark:bg-zinc-950 dark:text-zinc-100;
/* Kill the 300ms tap delay, keep gestures app-like. */
touch-action: manipulation;
overscroll-behavior-y: none;
}
/* slim scrollbars */
* {
scrollbar-width: thin;
scrollbar-color: rgb(0 0 0 / 0.2) transparent;
}
*::-webkit-scrollbar {
width: 6px;
height: 6px;
}
*::-webkit-scrollbar-thumb {
background: rgb(0 0 0 / 0.2);
border-radius: 999px;
}
/* markdown content */
.md p:first-child { margin-top: 0; }
.md p:last-child { margin-bottom: 0; }
/* Long unbroken strings (URLs, file paths, hashes, tokens) must wrap
anywhere — otherwise they overflow the bubble, which then grows past its
row and glues itself to the screen edge. `pre` keeps its own horizontal
scroll (white-space:pre ignores wrapping). */
.md {
overflow-wrap: anywhere;
}
.md pre {
@apply relative overflow-x-auto rounded-2xl border border-stone-200 bg-stone-900 p-4 text-[13.5px] leading-relaxed text-stone-100 dark:border-zinc-700;
}
.md pre code {
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
background: none !important;
padding: 0 !important;
}
.md :not(pre) > code {
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
@apply rounded-md bg-stone-200/70 px-1.5 py-0.5 text-[13px] dark:bg-zinc-800;
}
.md table {
@apply w-full border-collapse overflow-hidden rounded-xl text-sm;
}
.md th, .md td {
@apply border border-stone-200 px-3 py-1.5 dark:border-zinc-700;
}
.md th {
@apply bg-stone-200/50 dark:bg-zinc-800;
}
.md a {
@apply text-accent-600 underline dark:text-accent-400;
}
.md ul { @apply list-disc pl-5; }
.md ol { @apply list-decimal pl-5; }
.md blockquote {
@apply border-l-4 border-accent-500/50 pl-3 italic opacity-80;
}
.typing-cursor::after {
content: "▍";
animation: blink 1s steps(1) infinite;
}
@keyframes blink {
50% { opacity: 0; }
}
/* Loading flower: outer petals bloom in turn, inner petals follow softer,
core breathes with an amber glow. */
.flower-petal, .flower-petal-inner, .flower-core {
transform-box: fill-box;
transform-origin: center;
}
.flower-petal {
animation: bloom 2.4s ease-in-out infinite;
}
.flower-petal-inner {
animation: bloom-inner 2.4s ease-in-out infinite;
}
@keyframes bloom {
0%, 100% { transform: scale(0.62); opacity: 0.35; }
50% { transform: scale(1); opacity: 1; }
}
@keyframes bloom-inner {
0%, 100% { transform: scale(0.55); opacity: 0.2; }
50% { transform: scale(1); opacity: 0.95; }
}
.flower-core {
animation: core-breathe 2.4s ease-in-out infinite;
}
@keyframes core-breathe {
0%, 100% { transform: scale(0.9); }
50% { transform: scale(1.1); }
}
/* Smooth entrance for full-screen loaders. */
@keyframes loading-in {
from { opacity: 0; transform: scale(0.94); }
to { opacity: 1; transform: scale(1); }
}
.loading-enter {
animation: loading-in 0.45s ease-out both;
}
/* Loader title: soft accent glow pulse. */
.loader-title {
animation: title-glow 2.6s ease-in-out infinite;
}
@keyframes title-glow {
0%, 100% { opacity: 0.92; }
50% { opacity: 1; text-shadow: 0 0 18px rgb(var(--ka-accent-500) / 0.35); }
}
.loading-dots::after {
content: "";
animation: dots 1.4s steps(4) infinite;
}
@keyframes dots {
0% { content: ""; }
25% { content: "."; }
50% { content: ".."; }
75% { content: "..."; }
}
/* Bottom pills: springy rise on appear, soft sink on dismiss. */
@keyframes toast-in {
from { opacity: 0; transform: translateY(18px) scale(0.94); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
.toast-enter {
animation: toast-in 0.38s cubic-bezier(0.21, 1.02, 0.73, 1) both;
}
@keyframes toast-out {
from { opacity: 1; transform: translateY(0) scale(1); }
to { opacity: 0; transform: translateY(12px) scale(0.95); }
}
.toast-exit {
animation: toast-out 0.26s ease-in both;
}
@media (prefers-reduced-motion: reduce) {
/* Brand flower intentionally exempt: it always animates, even when the
browser requests reduced motion (battery saver / eco mode). */
.typing-cursor::after,
.loading-dots::after {
animation: none;
}
}
/* Kill Chrome's yellow autofill background (login / password fields) */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 60px rgb(245 245 244) inset; /* stone-100, matches soft fields */
-webkit-text-fill-color: #1c1917; /* stone-900 */
caret-color: #1c1917;
}
.dark input:-webkit-autofill,
.dark input:-webkit-autofill:hover,
.dark input:-webkit-autofill:focus,
.dark input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 60px #27272a inset; /* zinc-800 */
-webkit-text-fill-color: #f4f4f5; /* zinc-100 */
caret-color: #f4f4f5;
}