Skip to content

Commit 843da2d

Browse files
committed
v2.521 - Experimental Theme 2
1 parent 0d45ee5 commit 843da2d

18 files changed

Lines changed: 822 additions & 243 deletions

frontend/src/app/globals.css

Lines changed: 341 additions & 49 deletions
Large diffs are not rendered by default.

frontend/src/components/app/AgentThinkingStatus.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { useEffect, useState } from "react"
44
import type { CSSProperties } from "react"
55
import { FONTS } from "@/lib/constants"
6-
import { useIsDark, useThemeColors } from "@/context/ThemeContext"
6+
import { useIsDark, useThemeColors, useExp1 } from "@/context/ThemeContext"
77

88
export type AgentThinkingStatusPhase = "analyzing" | "planning" | "drafting" | "generating"
99

@@ -99,6 +99,7 @@ export function AgentThinkingStatus({
9999
}: AgentThinkingStatusProps) {
100100
const COLORS = useThemeColors()
101101
const isDark = useIsDark()
102+
const exp1 = useExp1()
102103

103104
return (
104105
<div
@@ -108,14 +109,20 @@ export function AgentThinkingStatus({
108109
aria-busy="true"
109110
className={className}
110111
style={{
111-
border: `1px solid ${COLORS.border}`,
112-
borderRadius: compact ? "10px" : "12px",
113-
background: isDark ? "rgba(255,255,255,0.02)" : "rgba(0,0,0,0.02)",
112+
border: `1px solid ${exp1.active ? "rgba(212,168,83,0.08)" : COLORS.border}`,
113+
borderRadius: exp1.active ? "16px" : (compact ? "10px" : "12px"),
114+
background: exp1.active ? "rgba(212,168,83,0.03)" : (isDark ? "rgba(255,255,255,0.02)" : "rgba(0,0,0,0.02)"),
114115
padding: compact ? "10px 12px" : "12px 14px",
115116
display: "flex",
116117
flexDirection: "column",
117118
gap: compact ? "6px" : "8px",
118-
transition: "opacity 0.2s ease",
119+
transition: exp1.active ? `all 0.5s ${exp1.ease}` : "opacity 0.2s ease",
120+
...(exp1.active ? {
121+
backdropFilter: exp1.glass,
122+
WebkitBackdropFilter: exp1.glass,
123+
animation: "exp1FadeIn 0.5s cubic-bezier(0.22,1,0.36,1) both",
124+
boxShadow: "0 0 24px rgba(212,168,83,0.04)",
125+
} : {}),
119126
...style,
120127
}}
121128
>

frontend/src/components/app/ChatInput.tsx

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ const ChatInput = memo(function ChatInput() {
243243
: exp1.shadow,
244244
} : {}),
245245
}}
246+
data-exp1-input={exp1.active ? "" : undefined}
247+
data-exp1-glow={exp1.active ? "" : undefined}
246248
onMouseEnter={(e) => {
247249
if (!inputFocused) {
248250
e.currentTarget.style.borderColor = borderHover
@@ -405,6 +407,7 @@ const ChatInput = memo(function ChatInput() {
405407
onClick={handleAttachClick}
406408
onMouseEnter={() => setAttachHover(true)}
407409
onMouseLeave={() => setAttachHover(false)}
410+
data-exp1-icon-btn={exp1.active ? "" : undefined}
408411
style={{ background: "none", border: "none", padding: 0, cursor: "pointer", display: "flex" }}
409412
aria-label="Attach file"
410413
>
@@ -427,18 +430,23 @@ const ChatInput = memo(function ChatInput() {
427430
onClick={() => setInputFeatures({ webSearch: !inputFeatures.webSearch })}
428431
onMouseEnter={() => setGlobeHover(true)}
429432
onMouseLeave={() => setGlobeHover(false)}
433+
data-exp1-icon-btn={exp1.active ? "" : undefined}
430434
style={{
431435
width: "30px",
432436
height: "30px",
433437
borderRadius: "25px",
434-
background: inputFeatures.webSearch ? (isDark ? "rgba(255,255,255,0.7)" : "rgba(0,0,0,0.75)") : "transparent",
435-
border: inputFeatures.webSearch ? `1px solid ${COLORS.textPrimary}` : "1px solid transparent",
438+
background: inputFeatures.webSearch
439+
? (exp1.active ? "rgba(212,168,83,0.7)" : isDark ? "rgba(255,255,255,0.7)" : "rgba(0,0,0,0.75)")
440+
: "transparent",
441+
border: inputFeatures.webSearch
442+
? `1px solid ${exp1.active ? "rgba(212,168,83,0.5)" : COLORS.textPrimary}`
443+
: "1px solid transparent",
436444
padding: 0,
437445
cursor: "pointer",
438446
display: "flex",
439447
alignItems: "center",
440448
justifyContent: "center",
441-
transition: "background 0.2s, border 0.2s",
449+
transition: exp1.active ? `all 0.5s ${exp1.ease}` : "background 0.2s, border 0.2s",
442450
}}
443451
aria-label="Toggle web search"
444452
aria-pressed={inputFeatures.webSearch}
@@ -462,14 +470,17 @@ const ChatInput = memo(function ChatInput() {
462470
onClick={mic.toggle}
463471
onMouseEnter={() => setMicHover(true)}
464472
onMouseLeave={() => setMicHover(false)}
473+
data-exp1-icon-btn={exp1.active ? "" : undefined}
465474
style={{
466475
background: "none",
467476
border: "none",
468477
padding: 0,
469478
cursor: "pointer",
470479
display: "flex",
471-
filter: mic.active ? `drop-shadow(0 0 6px ${COLORS.accent})` : "none",
472-
transition: "filter 0.2s",
480+
filter: mic.active
481+
? `drop-shadow(0 0 6px ${exp1.active ? "rgba(212,168,83,0.7)" : COLORS.accent})`
482+
: "none",
483+
transition: exp1.active ? `all 0.5s ${exp1.ease}` : "filter 0.2s",
473484
}}
474485
aria-label={mic.active ? "Stop recording" : "Start voice input"}
475486
>
@@ -487,11 +498,14 @@ const ChatInput = memo(function ChatInput() {
487498
onMouseEnter={() => setSendHover(true)}
488499
onMouseLeave={() => setSendHover(false)}
489500
disabled={!hasInput || isSending || !canSend}
501+
data-exp1-send={exp1.active ? "" : undefined}
490502
style={{
491503
width: "32px",
492504
height: "32px",
493505
borderRadius: "50%",
494-
background: isDark ? "rgba(255,255,255,0.7)" : "rgba(0,0,0,0.75)",
506+
background: exp1.active
507+
? (hasInput && !isSending && canSend ? "rgba(212,168,83,0.85)" : "rgba(255,255,255,0.15)")
508+
: (isDark ? "rgba(255,255,255,0.7)" : "rgba(0,0,0,0.75)"),
495509
border: "none",
496510
outline: "none",
497511
padding: 0,
@@ -500,16 +514,20 @@ const ChatInput = memo(function ChatInput() {
500514
justifyContent: "center",
501515
cursor: hasInput && !isSending && canSend ? "pointer" : "default",
502516
opacity: hasInput && !isSending && canSend ? 1 : 0.25,
503-
boxShadow: lit
504-
? isDark
505-
? "0px 0px 0px 4px rgba(255,255,255,0.5), inset 0px 0px 2px 4px #FFFFFF"
506-
: "0px 0px 0px 4px rgba(0,0,0,0.3), inset 0px 0px 2px 4px rgba(0,0,0,0.6)"
507-
: hasInput
517+
boxShadow: exp1.active
518+
? (hasInput && !isSending && canSend
519+
? "0 0 20px rgba(212,168,83,0.3), 0 0 40px rgba(212,168,83,0.1)"
520+
: "none")
521+
: (lit
508522
? isDark
509-
? "0px 0px 0px 4px rgba(255,255,255,0.25), inset 0px 0px 2px 3px rgba(255,255,255,0.8)"
510-
: "0px 0px 0px 4px rgba(0,0,0,0.15), inset 0px 0px 2px 3px rgba(0,0,0,0.4)"
511-
: "none",
512-
transition: "opacity 0.2s, box-shadow 0.2s",
523+
? "0px 0px 0px 4px rgba(255,255,255,0.5), inset 0px 0px 2px 4px #FFFFFF"
524+
: "0px 0px 0px 4px rgba(0,0,0,0.3), inset 0px 0px 2px 4px rgba(0,0,0,0.6)"
525+
: hasInput
526+
? isDark
527+
? "0px 0px 0px 4px rgba(255,255,255,0.25), inset 0px 0px 2px 3px rgba(255,255,255,0.8)"
528+
: "0px 0px 0px 4px rgba(0,0,0,0.15), inset 0px 0px 2px 3px rgba(0,0,0,0.4)"
529+
: "none"),
530+
transition: exp1.active ? `all 0.4s ${exp1.ease}` : "opacity 0.2s, box-shadow 0.2s",
513531
}}
514532
aria-label={isSending ? "Sending message" : "Send message"}
515533
>

frontend/src/components/app/DeleteConfirmModal.tsx

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import { createPortal } from "react-dom"
55
import { useChat } from "@/context/ChatContext"
66
import { useEscapeKey } from "@/hooks/useEscapeKey"
77
import { FONTS } from "@/lib/constants"
8+
import { useExp1 } from "@/context/ThemeContext"
89
import type { ThemeColors } from "@/context/ThemeContext"
910

1011
const DeleteConfirmModal = memo(function DeleteConfirmModal({ COLORS }: { COLORS: ThemeColors }) {
1112
const { deleteConfirmTarget, closeDeleteConfirm, deleteConversation } = useChat()
13+
const exp1 = useExp1()
1214

1315
useEscapeKey(closeDeleteConfirm)
1416

@@ -44,6 +46,7 @@ const DeleteConfirmModal = memo(function DeleteConfirmModal({ COLORS }: { COLORS
4446
aria-modal="true"
4547
aria-labelledby="fp-delete-title"
4648
aria-describedby="fp-delete-desc"
49+
{...(exp1.active ? { "data-exp1-popup": "" } : {})}
4750
style={{
4851
position: "fixed",
4952
top: "50%",
@@ -52,11 +55,16 @@ const DeleteConfirmModal = memo(function DeleteConfirmModal({ COLORS }: { COLORS
5255
width: "400px",
5356
maxWidth: "90vw",
5457
background: COLORS.modalBg,
55-
border: `1px solid ${COLORS.borderLight}`,
56-
borderRadius: "16px",
58+
border: `1px solid ${exp1.active ? "rgba(255,255,255,0.06)" : COLORS.borderLight}`,
59+
borderRadius: exp1.active ? "20px" : "16px",
5760
padding: "24px",
5861
zIndex: 201,
59-
boxShadow: "0 24px 48px rgba(0,0,0,0.3)",
62+
backdropFilter: exp1.active ? exp1.glass : undefined,
63+
WebkitBackdropFilter: exp1.active ? exp1.glass : undefined,
64+
boxShadow: exp1.active
65+
? "0 8px 40px rgba(0,0,0,0.4)"
66+
: "0 24px 48px rgba(0,0,0,0.3)",
67+
transition: exp1.active ? "all 0.5s cubic-bezier(0.22,1,0.36,1)" : undefined,
6068
animation: "fpDeleteDialogIn 0.25s cubic-bezier(0.34, 1.56, 0.64, 1) forwards",
6169
}}
6270
>
@@ -92,20 +100,33 @@ const DeleteConfirmModal = memo(function DeleteConfirmModal({ COLORS }: { COLORS
92100
fontSize: "14px",
93101
fontWeight: 500,
94102
color: COLORS.textSecondary,
95-
background: COLORS.hover,
96-
border: "none",
97-
borderRadius: "8px",
103+
background: exp1.active ? "rgba(255,255,255,0.06)" : COLORS.hover,
104+
border: exp1.active ? "1px solid rgba(255,255,255,0.08)" : "none",
105+
borderRadius: exp1.active ? exp1.radiusSm : "8px",
98106
padding: "10px 20px",
99107
cursor: "pointer",
100-
transition: "background 0.15s, color 0.15s",
108+
transition: exp1.active ? exp1.transition : "background 0.15s, color 0.15s",
109+
backdropFilter: exp1.active ? "blur(12px)" : undefined,
101110
}}
102111
onMouseEnter={(e) => {
103-
e.currentTarget.style.background = COLORS.borderLight
104-
e.currentTarget.style.color = COLORS.textPrimary
112+
if (exp1.active) {
113+
e.currentTarget.style.background = "rgba(212,175,55,0.10)"
114+
e.currentTarget.style.borderColor = "rgba(212,175,55,0.25)"
115+
e.currentTarget.style.color = COLORS.textPrimary
116+
} else {
117+
e.currentTarget.style.background = COLORS.borderLight
118+
e.currentTarget.style.color = COLORS.textPrimary
119+
}
105120
}}
106121
onMouseLeave={(e) => {
107-
e.currentTarget.style.background = COLORS.hover
108-
e.currentTarget.style.color = COLORS.textSecondary
122+
if (exp1.active) {
123+
e.currentTarget.style.background = "rgba(255,255,255,0.06)"
124+
e.currentTarget.style.borderColor = "rgba(255,255,255,0.08)"
125+
e.currentTarget.style.color = COLORS.textSecondary
126+
} else {
127+
e.currentTarget.style.background = COLORS.hover
128+
e.currentTarget.style.color = COLORS.textSecondary
129+
}
109130
}}
110131
>
111132
Cancel
@@ -118,16 +139,27 @@ const DeleteConfirmModal = memo(function DeleteConfirmModal({ COLORS }: { COLORS
118139
fontWeight: 500,
119140
color: "#fff",
120141
background: COLORS.danger,
121-
border: "none",
122-
borderRadius: "8px",
142+
border: exp1.active ? "1px solid rgba(212,175,55,0.15)" : "none",
143+
borderRadius: exp1.active ? exp1.radiusSm : "8px",
123144
padding: "10px 20px",
124145
cursor: "pointer",
125-
transition: "opacity 0.15s, transform 0.1s",
146+
transition: exp1.active ? exp1.transition : "opacity 0.15s, transform 0.1s",
147+
boxShadow: exp1.active
148+
? "0 0 12px rgba(212,175,55,0.12), 0 2px 8px rgba(0,0,0,0.3)"
149+
: undefined,
126150
}}
127151
onMouseEnter={(e) => {
152+
if (exp1.active) {
153+
e.currentTarget.style.boxShadow = "0 0 20px rgba(212,175,55,0.22), 0 4px 12px rgba(0,0,0,0.35)"
154+
e.currentTarget.style.borderColor = "rgba(212,175,55,0.3)"
155+
}
128156
e.currentTarget.style.opacity = "0.9"
129157
}}
130158
onMouseLeave={(e) => {
159+
if (exp1.active) {
160+
e.currentTarget.style.boxShadow = "0 0 12px rgba(212,175,55,0.12), 0 2px 8px rgba(0,0,0,0.3)"
161+
e.currentTarget.style.borderColor = "rgba(212,175,55,0.15)"
162+
}
131163
e.currentTarget.style.opacity = "1"
132164
}}
133165
>

frontend/src/components/app/GoldenGuideModal.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useChat } from "@/context/ChatContext"
66
import { useEscapeKey } from "@/hooks/useEscapeKey"
77
import { CloseIcon } from "./Icons"
88
import { FONTS } from "@/lib/constants"
9+
import { useExp1 } from "@/context/ThemeContext"
910
import type { ThemeColors } from "@/context/ThemeContext"
1011

1112
/* ——— Guide step data (static, never re-creates) ——— */
@@ -52,6 +53,7 @@ function StepIcon({ step, accent }: { step: (typeof STEPS)[number]; accent: stri
5253
const GoldenGuideModal = memo(function GoldenGuideModal({ COLORS }: { COLORS: ThemeColors }) {
5354
const { closeGuide } = useChat()
5455
useEscapeKey(closeGuide)
56+
const exp1 = useExp1()
5557

5658
const isDark = COLORS.textPrimary === "#FFFFFF"
5759
const backdropBg = isDark ? "rgba(0,0,0,0.6)" : "rgba(0,0,0,0.4)"
@@ -67,14 +69,15 @@ const GoldenGuideModal = memo(function GoldenGuideModal({ COLORS }: { COLORS: Th
6769
inset: 0,
6870
background: backdropBg,
6971
zIndex: 200,
70-
backdropFilter: "blur(4px)",
72+
backdropFilter: exp1.active ? (exp1.glass || "blur(40px) saturate(1.6)") : "blur(4px)",
7173
}}
7274
/>
7375
{/* Dialog */}
7476
<div
7577
role="dialog"
7678
aria-modal="true"
7779
aria-label="Golden Guide"
80+
{...(exp1.active ? { "data-exp1-popup": "" } : {})}
7881
style={{
7982
position: "fixed",
8083
top: "50%",
@@ -85,10 +88,16 @@ const GoldenGuideModal = memo(function GoldenGuideModal({ COLORS }: { COLORS: Th
8588
maxHeight: "85vh",
8689
overflowY: "auto",
8790
background: COLORS.modalBg,
88-
border: `1px solid ${COLORS.borderLight}`,
89-
borderRadius: "16px",
91+
border: `1px solid ${exp1.active ? "rgba(255,255,255,0.06)" : COLORS.borderLight}`,
92+
borderRadius: exp1.active ? "20px" : "16px",
9093
padding: "36px 32px 32px",
9194
zIndex: 201,
95+
...(exp1.active ? {
96+
backdropFilter: exp1.glass || "blur(40px) saturate(1.6)",
97+
transition: "all 0.5s cubic-bezier(0.22,1,0.36,1)",
98+
boxShadow: "0 8px 40px rgba(0,0,0,0.4), 0 0 1px rgba(212,168,83,0.1)",
99+
animation: "exp1FadeIn 0.5s cubic-bezier(0.22,1,0.36,1) both",
100+
} : {}),
92101
}}
93102
>
94103
{/* Close */}
@@ -106,7 +115,7 @@ const GoldenGuideModal = memo(function GoldenGuideModal({ COLORS }: { COLORS: Th
106115
display: "flex",
107116
transition: "color 0.2s",
108117
}}
109-
onMouseEnter={(e) => (e.currentTarget.style.color = COLORS.textPrimary)}
118+
onMouseEnter={(e) => (e.currentTarget.style.color = exp1.active ? "rgba(212,168,83,0.9)" : COLORS.textPrimary)}
110119
onMouseLeave={(e) => (e.currentTarget.style.color = COLORS.textTertiary)}
111120
aria-label="Close guide"
112121
>
@@ -149,9 +158,10 @@ const GoldenGuideModal = memo(function GoldenGuideModal({ COLORS }: { COLORS: Th
149158
display: "flex",
150159
gap: "16px",
151160
padding: "16px",
152-
borderRadius: "12px",
161+
borderRadius: exp1.active ? "14px" : "12px",
153162
background: COLORS.hover,
154-
border: `1px solid ${COLORS.border}`,
163+
border: `1px solid ${exp1.active ? "rgba(255,255,255,0.06)" : COLORS.border}`,
164+
...(exp1.active ? { transition: "all 0.5s cubic-bezier(0.22,1,0.36,1)" } : {}),
155165
}}
156166
>
157167
<div

frontend/src/components/app/MessageList.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,14 @@ const MessageBubble = memo(
4242

4343
return (
4444
<div
45+
data-exp1-message={exp1.active ? "" : undefined}
4546
style={{
4647
display: "flex",
4748
gap: "12px",
4849
opacity: message.streamStatus === "idle" && !message.content ? 0.5 : 1,
49-
transition: exp1.active ? `opacity 0.5s ${exp1.ease}` : "opacity 0.2s",
50+
transition: exp1.active ? `all 0.5s ${exp1.ease}` : "opacity 0.2s",
5051
...(exp1.active ? {
51-
animation: "exp1FadeIn 0.6s cubic-bezier(0.22,1,0.36,1) both",
52+
animation: "exp1FadeInUp 0.7s cubic-bezier(0.22,1,0.36,1) both",
5253
} : {}),
5354
}}
5455
role="article"
@@ -58,16 +59,23 @@ const MessageBubble = memo(
5859
{isUser && <div style={{ flex: 1, minWidth: 0 }} />}
5960
{/* Avatar */}
6061
<div
62+
data-exp1-avatar={exp1.active ? "" : undefined}
6163
style={{
6264
width: "32px",
6365
height: "32px",
6466
borderRadius: "50%",
65-
background: isUser ? (isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.06)") : COLORS.accentDim,
67+
background: exp1.active
68+
? (isUser ? "rgba(212,168,83,0.12)" : "rgba(212,168,83,0.08)")
69+
: (isUser ? (isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.06)") : COLORS.accentDim),
6670
display: "flex",
6771
alignItems: "center",
6872
justifyContent: "center",
6973
flexShrink: 0,
7074
marginTop: "2px",
75+
transition: exp1.active ? `all 0.4s ${exp1.ease}` : undefined,
76+
...(exp1.active ? {
77+
border: "1px solid rgba(212,168,83,0.1)",
78+
} : {}),
7179
}}
7280
>
7381
{isUser ? (
@@ -123,12 +131,15 @@ const MessageBubble = memo(
123131
<span
124132
style={{
125133
display: "inline-block",
126-
width: "2px",
134+
width: exp1.active ? "3px" : "2px",
127135
height: "16px",
128136
background: COLORS.accent,
129137
marginLeft: "2px",
130138
verticalAlign: "text-bottom",
131-
animation: "cursorBlink 0.8s step-end infinite",
139+
borderRadius: exp1.active ? "2px" : undefined,
140+
animation: exp1.active
141+
? "exp1CursorGlow 1.2s ease-in-out infinite"
142+
: "cursorBlink 0.8s step-end infinite",
132143
}}
133144
/>
134145
)}

0 commit comments

Comments
 (0)