Frontend revamp: Animal Crossing × Claude design with shadcn components

- New palette: deep nook green sidebar, sage user bubbles, warm cream answer cards
- shadcn-style UI primitives: Button (CVA variants), Textarea, Input, Badge, Table
- cn() utility (clsx + tailwind-merge)
- lucide-react icons throughout (no more text-only buttons)
- Simba mode: custom CSS toggle switch
- Send button: circular amber button with arrow icon
- AnswerBubble: amber gradient accent bar, loading dots animation
- QuestionBubble: sage green pill with rounded-3xl
- ToolBubble: centered leaf-green badge pill
- ConversationList: active item highlighting, proper selectedId prop
- Sidebar: collapsible with PanelLeftClose/Open icons, icon-only collapsed state
- LoginScreen: decorative background blobs, refined rounded card
- AdminPanel: proper icon buttons, leaf-green save confirmation
- Fonts: Playfair Display (brand) + Nunito 800 weight added

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ryan
2026-03-11 09:22:34 -04:00
parent 53b2b3b366
commit d1cb55ff1a
17 changed files with 2439 additions and 3327 deletions

View File

@@ -1,26 +1,44 @@
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700;800&family=Playfair+Display:ital,wght@0,600;0,700;1,600&display=swap');
@import "tailwindcss";
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700&family=Playfair+Display:ital,wght@0,600;0,700;1,600&display=swap');
@theme {
--color-cream: #FBF7F0;
--color-cream-dark: #F3EDE2;
/* === Animal Crossing × Claude Palette === */
/* Backgrounds */
--color-cream: #FAF8F2;
--color-cream-dark: #F0EBDF;
--color-warm-white: #FFFDF9;
/* Forest / Nook Green system */
--color-forest: #2A4D38;
--color-forest-mid: #345E46;
--color-forest-light: #4D7A5E;
--color-leaf: #5E9E70;
--color-leaf-dark: #3D7A52;
--color-leaf-light: #B8DEC4;
--color-leaf-pale: #EBF7EE;
/* Amber / warm accents */
--color-amber-glow: #E8943A;
--color-amber-dark: #C97828;
--color-amber-soft: #F5C882;
--color-amber-pale: #FFF0D6;
--color-forest: #2D5A3D;
--color-forest-light: #3D763A;
--color-forest-pale: #E8F5E4;
--color-amber-pale: #FFF4E0;
/* Neutrals */
--color-charcoal: #2C2420;
--color-warm-gray: #8A7E74;
--color-sand: #D4C5B0;
--color-sand-light: #E8DED0;
--color-warm-gray: #7A7268;
--color-sand: #DECFB8;
--color-sand-light: #EDE3D4;
--color-blush: #F2D1B3;
--color-sidebar-bg: #2C2420;
--color-sidebar-hover: #3D352F;
--color-sidebar-active: #4A3F38;
/* Sidebar */
--color-sidebar-bg: #2A4D38;
--color-sidebar-hover: #345E46;
--color-sidebar-active: #3D6E52;
/* Fonts */
--font-display: 'Playfair Display', Georgia, serif;
--font-body: 'Nunito', -apple-system, BlinkMacSystemFont, sans-serif;
--font-body: 'Nunito', 'Nunito Sans', system-ui, sans-serif;
}
* {
@@ -36,97 +54,92 @@ body {
-moz-osx-font-smoothing: grayscale;
}
/* Scrollbar styling */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: var(--color-sand);
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--color-warm-gray);
}
/* ── Scrollbar ─────────────────────────────────────── */
::-webkit-scrollbar { width: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--color-sand); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: var(--color-warm-gray); }
/* ── Markdown in answer bubbles ─────────────────────── */
.markdown-content p { margin: 0.5em 0; line-height: 1.7; }
.markdown-content p:first-child { margin-top: 0; }
.markdown-content p:last-child { margin-bottom: 0; }
/* Markdown content styling in answer bubbles */
.markdown-content h1,
.markdown-content h2,
.markdown-content h3 {
font-family: var(--font-display);
font-weight: 600;
margin-top: 1em;
margin-bottom: 0.5em;
margin: 1em 0 0.4em;
line-height: 1.3;
color: var(--color-charcoal);
}
.markdown-content h1 { font-size: 1.25rem; }
.markdown-content h2 { font-size: 1.1rem; }
.markdown-content h3 { font-size: 1rem; }
.markdown-content p {
margin: 0.5em 0;
line-height: 1.65;
}
.markdown-content h1 { font-size: 1.2rem; }
.markdown-content h2 { font-size: 1.05rem; }
.markdown-content h3 { font-size: 0.95rem; }
.markdown-content ul,
.markdown-content ol {
padding-left: 1.5em;
margin: 0.5em 0;
}
.markdown-content li {
margin: 0.25em 0;
line-height: 1.6;
}
.markdown-content ol { padding-left: 1.4em; margin: 0.5em 0; }
.markdown-content li { margin: 0.3em 0; line-height: 1.6; }
.markdown-content code {
background: rgba(0, 0, 0, 0.06);
background: rgba(0,0,0,0.06);
padding: 0.15em 0.4em;
border-radius: 4px;
font-size: 0.88em;
font-family: 'SF Mono', 'Fira Code', monospace;
border-radius: 5px;
font-size: 0.85em;
font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
}
.markdown-content pre {
background: var(--color-charcoal);
color: #F3EDE2;
padding: 1em;
border-radius: 8px;
color: #F0EBDF;
padding: 1em 1.1em;
border-radius: 12px;
overflow-x: auto;
margin: 0.75em 0;
}
.markdown-content pre code {
background: none;
padding: 0;
color: inherit;
margin: 0.8em 0;
}
.markdown-content pre code { background: none; padding: 0; color: inherit; }
.markdown-content a {
color: var(--color-forest);
color: var(--color-leaf-dark);
text-decoration: underline;
text-underline-offset: 2px;
}
.markdown-content blockquote {
border-left: 3px solid var(--color-amber-glow);
border-left: 3px solid var(--color-amber-soft);
padding-left: 1em;
margin: 0.75em 0;
color: var(--color-warm-gray);
font-style: italic;
}
/* Loading skeleton animation */
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
.markdown-content strong { font-weight: 700; }
.markdown-content em { font-style: italic; }
/* ── Animations ─────────────────────────────────────── */
@keyframes fadeSlideUp {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.message-enter {
animation: fadeSlideUp 0.3s ease-out forwards;
}
@keyframes catPulse {
0%, 80%, 100% { opacity: 0.25; transform: scale(0.75); }
40% { opacity: 1; transform: scale(1); }
}
.loading-dot { animation: catPulse 1.4s ease-in-out infinite; }
.loading-dot:nth-child(2) { animation-delay: 0.2s; }
.loading-dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.skeleton-shimmer {
background: linear-gradient(
90deg,
background: linear-gradient(90deg,
var(--color-sand-light) 25%,
var(--color-cream) 50%,
var(--color-sand-light) 75%
@@ -135,36 +148,26 @@ body {
animation: shimmer 1.8s ease-in-out infinite;
}
/* Fade-in animation for messages */
@keyframes fadeSlideUp {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
/* ── Toggle switch ──────────────────────────────────── */
.toggle-track {
width: 36px;
height: 20px;
border-radius: 99px;
background: var(--color-sand);
position: relative;
transition: background 0.2s;
cursor: pointer;
}
.message-enter {
animation: fadeSlideUp 0.35s ease-out forwards;
}
/* Subtle pulse for loading dots */
@keyframes catPulse {
0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
40% { opacity: 1; transform: scale(1); }
}
.loading-dot {
animation: catPulse 1.4s ease-in-out infinite;
}
.loading-dot:nth-child(2) { animation-delay: 0.2s; }
.loading-dot:nth-child(3) { animation-delay: 0.4s; }
/* Textarea focus glow */
textarea:focus {
outline: none;
box-shadow: 0 0 0 2px var(--color-amber-soft);
.toggle-track.checked { background: var(--color-leaf); }
.toggle-thumb {
width: 14px;
height: 14px;
background: white;
border-radius: 99px;
position: absolute;
top: 3px;
left: 3px;
transition: transform 0.2s;
box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}
.toggle-track.checked .toggle-thumb { transform: translateX(16px); }