techfreakworm commited on
Commit
14c6f28
unverified
1 Parent(s): 1d7b5cd

feat(web): responsive layout for phone and tablet (header stack, padding scale, seed-row wrap)

Browse files
web/src/components/LoadingBanner.tsx CHANGED
@@ -3,7 +3,7 @@ type Props = { visible: boolean; message: string };
3
  export default function LoadingBanner({ visible, message }: Props) {
4
  if (!visible) return null;
5
  return (
6
- <div className="border-b border-[hsl(var(--ember))]/30 bg-[hsl(var(--ember))]/10 px-8 py-2.5">
7
  <div className="flex items-center gap-3">
8
  <span className="size-1.5 rounded-full bg-[hsl(var(--ember))] animate-pulse-dot" />
9
  <span className="label-mono text-[hsl(var(--ember))]">{message}</span>
 
3
  export default function LoadingBanner({ visible, message }: Props) {
4
  if (!visible) return null;
5
  return (
6
+ <div className="border-b border-[hsl(var(--ember))]/30 bg-[hsl(var(--ember))]/10 px-4 sm:px-8 py-2.5">
7
  <div className="flex items-center gap-3">
8
  <span className="size-1.5 rounded-full bg-[hsl(var(--ember))] animate-pulse-dot" />
9
  <span className="label-mono text-[hsl(var(--ember))]">{message}</span>
web/src/components/ParamsPanel.tsx CHANGED
@@ -18,7 +18,7 @@ function renderControl(
18
  return (
19
  <div key={s.name} className="space-y-1.5">
20
  <label htmlFor={id} className="label-mono">{s.label}</label>
21
- <div className="flex items-center gap-3">
22
  <input
23
  id={id}
24
  aria-label={s.label}
@@ -27,7 +27,7 @@ function renderControl(
27
  step={s.step ?? 1}
28
  value={v}
29
  onChange={(e) => set(s.name, Number(e.target.value))}
30
- className="field-input !w-44 font-mono text-[12px] py-1"
31
  />
32
  <button
33
  type="button"
 
18
  return (
19
  <div key={s.name} className="space-y-1.5">
20
  <label htmlFor={id} className="label-mono">{s.label}</label>
21
+ <div className="flex flex-wrap items-center gap-x-3 gap-y-2">
22
  <input
23
  id={id}
24
  aria-label={s.label}
 
27
  step={s.step ?? 1}
28
  value={v}
29
  onChange={(e) => set(s.name, Number(e.target.value))}
30
+ className="field-input !w-40 sm:!w-44 font-mono text-[12px] py-1"
31
  />
32
  <button
33
  type="button"
web/src/components/ProgressBar.tsx CHANGED
@@ -12,9 +12,9 @@ export default function ProgressBar() {
12
 
13
  if (state.phase === "error") {
14
  return (
15
- <div className="sticky top-0 z-40 border-b border-red-900/40 bg-red-950/80 backdrop-blur-md px-8 py-2.5">
16
  <span className="label-mono text-red-400">progress error</span>
17
- <span className="ml-3 text-sm text-red-300/90">{state.message}</span>
18
  </div>
19
  );
20
  }
@@ -37,12 +37,12 @@ export default function ProgressBar() {
37
  : `Generating 路 ${fmt(elapsedS)}`;
38
 
39
  return (
40
- <div className="sticky top-0 z-40 border-b border-[hsl(var(--ember))]/30 bg-[hsl(var(--ember))]/15 backdrop-blur-md px-8 py-2">
41
- <div className="flex items-center gap-4">
42
- <span className="label-mono text-[hsl(var(--ember))] whitespace-nowrap">
43
  {label}
44
  </span>
45
- <div className="flex-1 h-1 bg-[hsl(var(--ember))]/20 rounded-sm overflow-hidden">
46
  {fill === null ? (
47
  <div className="h-full w-1/3 bg-[hsl(var(--ember))] animate-progress-stripe" />
48
  ) : (
 
12
 
13
  if (state.phase === "error") {
14
  return (
15
+ <div className="sticky top-0 z-40 border-b border-red-900/40 bg-red-950/80 backdrop-blur-md px-4 sm:px-8 py-2.5">
16
  <span className="label-mono text-red-400">progress error</span>
17
+ <span className="ml-3 text-sm text-red-300/90 break-words">{state.message}</span>
18
  </div>
19
  );
20
  }
 
37
  : `Generating 路 ${fmt(elapsedS)}`;
38
 
39
  return (
40
+ <div className="sticky top-0 z-40 border-b border-[hsl(var(--ember))]/30 bg-[hsl(var(--ember))]/15 backdrop-blur-md px-4 sm:px-8 py-2">
41
+ <div className="flex items-center gap-3 sm:gap-4">
42
+ <span className="label-mono text-[hsl(var(--ember))] whitespace-nowrap text-[10px] sm:text-[10.5px]">
43
  {label}
44
  </span>
45
+ <div className="flex-1 min-w-0 h-1 bg-[hsl(var(--ember))]/20 rounded-sm overflow-hidden">
46
  {fill === null ? (
47
  <div className="h-full w-1/3 bg-[hsl(var(--ember))] animate-progress-stripe" />
48
  ) : (
web/src/pages/Studio.tsx CHANGED
@@ -28,7 +28,7 @@ function SectionHeader({ num, title, hint }: { num: string; title: string; hint?
28
  <div className="space-y-1">
29
  <div className="flex items-baseline gap-3">
30
  <span className="marker-num">{num}</span>
31
- <h2 className="display-serif text-[22px] leading-tight">{title}</h2>
32
  </div>
33
  {hint && <p className="label-mono">{hint}</p>}
34
  <div className="rule-dotted mt-2" />
@@ -181,12 +181,12 @@ export default function Studio() {
181
  return (
182
  <div className="min-h-screen relative-z animate-fade-up">
183
  <header className="border-b border-border">
184
- <div className="mx-auto max-w-[1280px] px-8 py-5 flex items-end justify-between">
185
- <div className="flex items-end gap-4">
186
- <span className="display-serif text-[34px] leading-none">Chatterbox</span>
187
- <span className="label-mono pb-1">voice studio 路 v0.2</span>
188
  </div>
189
- <div className="flex items-center gap-6">
190
  <ModeToggle mode={mode} onChange={setMode} />
191
  {mode === "single" && (
192
  <ModelPicker
@@ -207,13 +207,13 @@ export default function Studio() {
207
  />
208
  <ProgressBar />
209
  {err && (
210
- <div className="border-b border-red-900/40 bg-red-950/30 px-8 py-2.5">
211
  <span className="label-mono text-red-400">error</span>
212
- <span className="ml-3 text-sm text-red-300/90">{err}</span>
213
  </div>
214
  )}
215
 
216
- <main className="mx-auto max-w-[1280px] px-8 py-10 grid lg:grid-cols-[minmax(0,1fr)_400px] gap-12">
217
  <section className="space-y-12">
218
  {mode === "single" ? (
219
  <>
@@ -355,10 +355,10 @@ export default function Studio() {
355
  </aside>
356
  </main>
357
 
358
- <footer className="border-t border-border mt-16">
359
  <MadeBy />
360
- <div className="rule-dotted mx-8" />
361
- <div className="mx-auto max-w-[1280px] px-8 py-6 flex items-center justify-between">
362
  <span className="label-mono">chatterbox 路 resemble ai</span>
363
  <span className="label-mono">stateless 路 browser-persisted</span>
364
  </div>
 
28
  <div className="space-y-1">
29
  <div className="flex items-baseline gap-3">
30
  <span className="marker-num">{num}</span>
31
+ <h2 className="display-serif text-[19px] sm:text-[22px] leading-tight">{title}</h2>
32
  </div>
33
  {hint && <p className="label-mono">{hint}</p>}
34
  <div className="rule-dotted mt-2" />
 
181
  return (
182
  <div className="min-h-screen relative-z animate-fade-up">
183
  <header className="border-b border-border">
184
+ <div className="mx-auto max-w-[1280px] px-4 sm:px-8 py-4 sm:py-5 flex flex-col lg:flex-row lg:items-end lg:justify-between gap-3 lg:gap-6">
185
+ <div className="flex items-end gap-3 sm:gap-4">
186
+ <span className="display-serif text-[26px] sm:text-[34px] leading-none">Chatterbox</span>
187
+ <span className="label-mono pb-0.5 sm:pb-1 whitespace-nowrap">voice studio 路 v0.2</span>
188
  </div>
189
+ <div className="flex flex-wrap items-center gap-3 sm:gap-6">
190
  <ModeToggle mode={mode} onChange={setMode} />
191
  {mode === "single" && (
192
  <ModelPicker
 
207
  />
208
  <ProgressBar />
209
  {err && (
210
+ <div className="border-b border-red-900/40 bg-red-950/30 px-4 sm:px-8 py-2.5">
211
  <span className="label-mono text-red-400">error</span>
212
+ <span className="ml-3 text-sm text-red-300/90 break-words">{err}</span>
213
  </div>
214
  )}
215
 
216
+ <main className="mx-auto max-w-[1280px] px-4 sm:px-8 py-6 sm:py-10 grid lg:grid-cols-[minmax(0,1fr)_400px] gap-8 lg:gap-12">
217
  <section className="space-y-12">
218
  {mode === "single" ? (
219
  <>
 
355
  </aside>
356
  </main>
357
 
358
+ <footer className="border-t border-border mt-10 sm:mt-16">
359
  <MadeBy />
360
+ <div className="rule-dotted mx-4 sm:mx-8" />
361
+ <div className="mx-auto max-w-[1280px] px-4 sm:px-8 py-5 sm:py-6 flex flex-col sm:flex-row items-center sm:justify-between gap-2 sm:gap-0">
362
  <span className="label-mono">chatterbox 路 resemble ai</span>
363
  <span className="label-mono">stateless 路 browser-persisted</span>
364
  </div>