webmuppet Claude Sonnet 4.6 commited on
Commit
ac3c645
·
1 Parent(s): c812b81

chat: bottom input matches hero — floating card, text-xl, Send label

Browse files

Replaces the compact dark footer bar with a floating rounded card
(same rgba glass style as the hero input) centred at max-w-3xl.
Textarea grows to rows=2, text-xl with transparent background.
Stop/Send buttons gain a text label to match the hero variant.
A gradient fade from #0F0027 to transparent behind the card
prevents content bleeding through.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (1) hide show
  1. frontend/src/components/ChatInput.tsx +52 -46
frontend/src/components/ChatInput.tsx CHANGED
@@ -101,63 +101,69 @@ export function ChatInput({
101
  );
102
  }
103
 
104
- // "bottom" variant — sticky footer bar once a conversation is in progress
105
  return (
106
- <div className="sticky bottom-0 w-full" style={{ backgroundColor: "#0F0027" }}>
107
- <form
108
- onSubmit={handleSubmit}
109
- className="mx-auto max-w-3xl flex items-center gap-3 px-4 py-3"
110
  >
111
- {/* Download conversation button */}
112
- {hasMessages && (
113
- <button
114
- type="button"
115
- onClick={onExportConversation}
116
- className="shrink-0 p-2 rounded-lg text-white/70 hover:text-white hover:bg-white/10 transition-colors"
117
- title="Download conversation"
118
- aria-label="Download conversation"
119
- >
120
- <DownloadIcon />
121
- </button>
122
- )}
123
-
124
- {/* Text input */}
125
- <div className="flex-1">
126
  <textarea
127
  value={query}
128
  onChange={(e) => setQuery(e.target.value)}
129
  onKeyDown={handleKeyDown}
130
  disabled={isStreaming}
131
  placeholder={isStreaming ? "Waiting for response..." : "Ask a compliance question..."}
132
- rows={1}
133
- className="w-full resize-none rounded-lg border-0 bg-white/15 px-4 py-2.5 text-sm text-white placeholder-white/50 outline-none focus:bg-white/20 focus:ring-0 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
134
  aria-label="Chat input"
135
  />
136
- </div>
137
 
138
- {/* Stop button while streaming, send button otherwise */}
139
- {isStreaming ? (
140
- <button
141
- type="button"
142
- onClick={onStop}
143
- className="shrink-0 p-2 rounded-lg text-white/80 hover:text-white hover:bg-white/10 transition-colors"
144
- title="Stop generating"
145
- aria-label="Stop generating"
146
- >
147
- <StopIcon />
148
- </button>
149
- ) : (
150
- <button
151
- type="submit"
152
- disabled={!canSubmit}
153
- className="shrink-0 p-2 rounded-lg text-white/80 hover:text-white hover:bg-white/10 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
154
- title="Send message"
155
- aria-label="Send message"
156
- >
157
- <SendIcon />
158
- </button>
159
- )}
160
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  </div>
162
  );
163
  }
 
101
  );
102
  }
103
 
104
+ // "bottom" variant — floating card anchored to bottom, matching hero style
105
  return (
106
+ <div className="sticky bottom-0 w-full px-4 pb-4 pt-2" style={{ background: "linear-gradient(to top, #0F0027 60%, transparent)" }}>
107
+ <div
108
+ className="mx-auto max-w-3xl rounded-2xl border border-white/10"
109
+ style={{ backgroundColor: "rgba(255,255,255,0.08)" }}
110
  >
111
+ <form onSubmit={handleSubmit} className="flex flex-col gap-0 px-5 pt-4 pb-3">
112
+ {/* Large textarea — same scale as hero input */}
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  <textarea
114
  value={query}
115
  onChange={(e) => setQuery(e.target.value)}
116
  onKeyDown={handleKeyDown}
117
  disabled={isStreaming}
118
  placeholder={isStreaming ? "Waiting for response..." : "Ask a compliance question..."}
119
+ rows={2}
120
+ className="w-full resize-none border-0 bg-transparent text-xl text-white placeholder-white/40 outline-none focus:ring-0 disabled:opacity-50 disabled:cursor-not-allowed leading-relaxed"
121
  aria-label="Chat input"
122
  />
 
123
 
124
+ {/* Action row */}
125
+ <div className="flex items-center justify-between pt-2">
126
+ {/* Download conversation button */}
127
+ {hasMessages && (
128
+ <button
129
+ type="button"
130
+ onClick={onExportConversation}
131
+ className="p-2 rounded-lg text-white/50 hover:text-white hover:bg-white/10 transition-colors"
132
+ title="Download conversation"
133
+ aria-label="Download conversation"
134
+ >
135
+ <DownloadIcon />
136
+ </button>
137
+ )}
138
+ {!hasMessages && <div />}
139
+
140
+ {/* Stop / Send */}
141
+ {isStreaming ? (
142
+ <button
143
+ type="button"
144
+ onClick={onStop}
145
+ className="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-medium text-white/90 hover:text-white bg-white/10 hover:bg-white/20 transition-colors"
146
+ title="Stop generating"
147
+ aria-label="Stop generating"
148
+ >
149
+ <StopIcon />
150
+ <span>Stop</span>
151
+ </button>
152
+ ) : (
153
+ <button
154
+ type="submit"
155
+ disabled={!canSubmit}
156
+ className="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-medium text-white/90 hover:text-white bg-white/10 hover:bg-white/20 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
157
+ title="Send message"
158
+ aria-label="Send message"
159
+ >
160
+ <SendIcon />
161
+ <span>Send</span>
162
+ </button>
163
+ )}
164
+ </div>
165
+ </form>
166
+ </div>
167
  </div>
168
  );
169
  }