Skip to content

feat(ui): convert more DubTab CSS to Tailwind (wave 2, live-screenshot-verified) - #794

Merged
debpalash merged 1 commit into
mainfrom
feat/tw-dubtab-wave2
Jun 30, 2026
Merged

feat(ui): convert more DubTab CSS to Tailwind (wave 2, live-screenshot-verified)#794
debpalash merged 1 commit into
mainfrom
feat/tw-dubtab-wave2

Conversation

@debpalash

@debpalash debpalash commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Summary

Second-wave CSS→Tailwind conversion of DubTab, building on wave 1 (#788). Removes 119 more lines from DubTab.css (919 → 800) by moving the stateless / standalone idle-skeleton rules into utilities in IdleSkeleton.jsx.

Net diff: 2 files changed, 79 insertions(+), 178 deletions(-).

How it was verified (the whole point)

Every conversion was proven pixel-identical against the LIVE app — the real Dub screen rendered by a Vite dev server, not the isolated component harness. A throwaway Playwright (chromium) spec:

  1. captured baseline screenshots of the reachable Dub states (before any CSS change),
  2. the rules were converted,
  3. the same states were re-shot and pixel-diffed with maxDiffPixels: 0 (exact, animations disabled).

The dev origin's cross-origin /setup/status is CORS-blocked, which would pin the app on the setup wizard, so the only thing faked was that one backend gate (page.routemodels_ready:true); everything visual is the real app. The shared backend on :3900 was never touched.

States verified (3/3 identical):

  • idle drop-zone — drop-zone text leaves, URL ingest row, landing options
  • idle + Advanced expanded — landing-adv field row
  • file-loaded skeleton — reached via setInputFiles on the hidden file input (no backend upload): skel settings, skel table cells/headers/hint, cast strip, pipeline stepper, ghost footer

Converted (base/standalone rules → utilities)

dub-idle-drop__lines/__title/__sub, dub-ingest-row + __input, dub-idle-upload-label, dub-hidden-file, dub-landing-opts + __label, dub-landing-opts__lang (base), dub-landing-adv + __field (base), dub-cast (base) + __row + __kicker/__label (base) + --muted__chip, dub-skel-settings, dub-skel-field/--sm, dub-skel-translate-btn, dub-skel-transcript-toggle, dub-inline-icon, dub-skel-cell-*/-header-* cells, dub-skel-hint, dub-skel-gen-row.

Deliberately left as CSS (honest ROI)

The rest of DubTab.css is genuinely irreducible for this milestone — converting it would regress (the pixel-diff oracle confirms) or is unreachable without a live transcription backend:

  • @Keyframes / animation: dub-skel-bar shimmer, dub-idle-drop pulse, stepper spin
  • :hover / state interplay: dub-ingest-row__cta.is-ready, dub-landing-opts__adv, dub-cast__pair
  • cross-file unlayered overrides a layered utility would lose to (no preflight; DubTab.css is unlayered, Tailwind utilities are in layer(utilities)): dub-skel-table.segment-table, dub-skel-row.segment-row, dub-skel-gen-btn/dub-change-row__cta.btn-primary, dub-skel-transcript-toggle__inner.override-toggle, dub-skel-cell-acts__icon.segment-del (opacity), dub-speakers-input.input-base, dub-ghost-footer.studio-panel
  • post-transcription components (settings-bar, footer-btn, preview-toggle, bulk/tracks/outputs rows, gen-overlay, prep/trans overlays, lang-switch, glossary, stepper done/active states) — only render after a real ASR run, so not screenshot-verifiable here

Class hooks were kept on elements whose .dub-cast--muted / --grow / descendant select rules still need them.

Gates

  • npx oxlint → exit 0 (only pre-existing warnings)
  • npx oxfmt --write src && npx oxfmt --check . → clean
  • npx vite build → success (also caught & fixed a */-in-comment lightningcss minify error that would have broken the Docker build)
  • npx vitest run → 641 passed
  • bun install --frozen-lockfile → no changes
  • bun run test:visual → 42 passed
  • live screenshot pixel-diff → 3/3 identical (maxDiffPixels: 0)

🤖 Generated with Claude Code

Summary:

  • Continued the DubTab Tailwind migration by moving more idle/skeleton layout styling out of DubTab.css and into IdleSkeleton.jsx utility classes.
  • Reworked the idle drop zone, ingest row, landing language/advanced controls, cast/speaker strip, skeleton settings, transcript toggle, table rows, and footer ghost-generation layout.
  • Removed a large set of now-redundant CSS rules, while keeping a few override/opacity-specific selectors that still need CSS.

UI sketch:

Before
+------------------------------------------------------+
| SRT import label / change file |
| [ idle drop-zone lines ] |
| [ ingest row + input ] |
| [ landing opts / adv fields ] |
| [ cast strip ] |
| [ skeleton settings ] |
| [ transcript toggle + table skeleton ] |
| [ footer ghost gen ] |
+------------------------------------------------------+

After
+------------------------------------------------------+
| SRT import label / change file (Tailwind utilities) |
| idle drop-zone text |
| [ centered ingest row ] |
| [ landing chrome-flex controls ] |
| [ cast muted chrome strip ] |
| [ skeleton settings chrome row ] |
| [ transcript toggle + table rows ] |
| [ footer ghost gen flex gap ] |
+------------------------------------------------------+

…t-verified)

Second-wave CSS->Tailwind conversion of DubTab, building on wave 1 (#788).
Removes 119 more lines from DubTab.css (919 -> 800) by moving the
stateless/standalone idle-skeleton rules into utilities in IdleSkeleton.jsx.

Every conversion was proven pixel-identical against the LIVE app (real Dub
screen on a dev server, not the isolated component harness). A throwaway
Playwright spec captured baselines of three reachable Dub states, the rules
were converted, and the same states were re-shot and pixel-diffed with
maxDiffPixels:0 (exact). States verified:
  - idle drop-zone (drop-zone leaves, URL ingest row, landing options)
  - idle + Advanced expanded (landing-adv field row)
  - file-loaded skeleton via setInputFiles, no backend upload (skel settings,
    skel table cells/headers/hint, cast strip, stepper)

Converted (base/standalone rules -> utilities): dub-idle-drop__lines/__title/
__sub, dub-ingest-row + __input, dub-idle-upload-label, dub-hidden-file,
dub-landing-opts + __label, dub-landing-opts__lang base, dub-landing-adv +
__field base, dub-cast base + __row + __kicker/__label base + --muted__chip,
dub-skel-settings, dub-skel-field/--sm, dub-skel-translate-btn,
dub-skel-transcript-toggle, dub-inline-icon, dub-skel-cell-*/header-* cells,
dub-skel-hint, dub-skel-gen-row.

Deliberately LEFT as CSS (would regress, per the diff oracle / wave-1 doctrine):
anything with @keyframes/animation (dub-skel-bar shimmer, dub-idle-drop pulse),
:hover/state interplay (dub-ingest-row__cta.is-ready, dub-landing-opts__adv,
dub-cast__pair), and cross-file unlayered overrides that a layered utility
would lose to (dub-skel-table on .segment-table, dub-skel-row on .segment-row,
dub-skel-gen-btn / dub-change-row__cta on .btn-primary,
dub-skel-transcript-toggle__inner on .override-toggle,
dub-skel-cell-acts__icon on .segment-del, dub-speakers-input on .input-base,
dub-ghost-footer on .studio-panel). Class hooks were kept on elements whose
.dub-cast--muted / --grow / select descendant rules still need them.

Gates: oxlint (0), oxfmt --check (clean), vite build, vitest (641 pass),
bun install --frozen-lockfile (no change), bun run test:visual (42 pass).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

IdleSkeleton.jsx replaces BEM-scoped class names with utility classes across the drop-zone, upload labels, ingest URL input, language/advanced selectors, cast strip, right-panel ghost settings, segment-table skeleton rows, and footer wrapper. DubTab.css removes the corresponding explicit CSS blocks, leaving only descendant/modifier overrides that cannot be expressed as utilities.

Changes

IdleSkeleton utility migration

Layer / File(s) Summary
Left-panel drop-zone, upload labels, and cast strip
frontend/src/components/dub/IdleSkeleton.jsx, frontend/src/pages/DubTab.css
SRT import labels switch from dub-idle-upload-label to utility flex/padding/border classes; drop-zone inner content restructured from dub-idle-drop__lines into a centered text block + chrome-styled ingest row; hidden file input changes to hidden; cast block rebuilt as dub-cast dub-cast--muted with kicker/label/chip spans. CSS removes .dub-idle-drop__lines, .dub-ingest-row, .dub-idle-upload-label, .dub-hidden-file, and cast container rules.
Language selector and advanced options
frontend/src/components/dub/IdleSkeleton.jsx, frontend/src/pages/DubTab.css
Target-language row and advanced container rewritten with flexbox/chrome-themed wrappers; style-field gains dub-landing-adv__field--grow. CSS removes base .dub-landing-opts and .dub-landing-adv blocks, retaining only descendant/modifier rules.
Right-panel ghost settings, table, and footer
frontend/src/components/dub/IdleSkeleton.jsx, frontend/src/pages/DubTab.css
Ghost settings rebuilt with label-row wrappers for language/ISO placeholders; translate-all replaced by a disabled button; segment-table rows switch to dub-skel-bar spans with width utilities; footer wrapper becomes flex gap-[4px]. CSS removes .dub-skel-settings, .dub-skel-gen-row, .dub-skel-field, table cell sizing, and .dub-skel-hint, retaining only .dub-skel-cell-acts__icon opacity.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • debpalash/OmniVoice-Studio#788: Directly precedes this PR — same files (IdleSkeleton.jsx, DubTab.css), same pattern of migrating BEM class names to Tailwind utilities.
  • debpalash/OmniVoice-Studio#759: Introduced components/dub/IdleSkeleton.jsx as part of DubTab modularization, establishing the component this PR further refactors.
  • debpalash/OmniVoice-Studio#374: Earlier rework of the same skeleton drop-zone and bar/table styling in the same two files.
🚥 Pre-merge checks | ✅ 8 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Cross-Platform Default Parity ⚠️ Warning FAIL: AudioMethodPanel.jsx:38-47 still uses dub-hidden-file, but DubTab.css:263 removes the only selector, exposing a native file input whose chooser varies by OS. Restore .dub-hidden-file until that consumer is migrated, or change the input to hidden in AudioMethodPanel.jsx in the same PR.
✅ Passed checks (8 passed)
Check name Status Explanation
Title check ✅ Passed Conventional-commit style and relevant scope; the PR body carries the issue reference (#788).
Description check ✅ Passed It covers summary, implementation details, verification, and test gates, but lacks the template's explicit Changes/Type/Checklist structure.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
I18n Completeness (21 Locales) ✅ Passed Patch only moved existing t() calls; the 11-key set is unchanged and all keys exist in all 21 locale files, with no new user-facing literals added.
Local-First Guarantee ✅ Passed PASS: IdleSkeleton.jsx is markup-only; lines 132-149, 191-209, 324-350, 363-418 use existing local inputs/toggles, and DubTab.css only swaps utility classes—no new fetch/auth/telemetry code.
Backward Compatibility ✅ Passed Only UI files changed (IdleSkeleton.jsx:130-247, DubTab.css:209-340); no DB/schema, omnivoice_data, or engine/model install/download logic is touched.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/tw-dubtab-wave2

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Wave-2 CSS→Tailwind conversion for DubTab/IdleSkeleton: 119 lines removed from DubTab.css and expressed as inline Tailwind utilities in IdleSkeleton.jsx. The pixel-diff harness (pre-transcription states only) passes, but one deletion escapes its coverage window.

  • Cast-strip regression — The four CSS base rules deleted for .dub-cast, .dub-cast__row, .dub-cast__kicker, and .dub-cast__label were migrated to Tailwind utilities only inside IdleSkeleton.jsx, but DubLeftColumn.jsx (lines 180–190) uses those exact class names for the live post-transcription cast strip. After an ASR run the real cast strip will render with no container chrome, stacked (not flex-row) layout, and browser-default fonts.

ASCII before/after (live cast strip after transcription):

Before                             After (this PR)
─────────────────────────────────  ─────────────────────────────────────
╭─ CAST  SPK1: [Voice ▼]  ────╮   CAST SPK1: [Voice ▼]
╰─ (pill bg, mono, flex-wrap) ╯   (browser defaults, block stacked)
  • Dropped CSS-variable fallbackbg-[var(--chrome-hover-bg)] on the landing-opts row omits the rgba(255,255,255,0.03) fallback that the original CSS declared; transparent instead of a subtle glass tint if the variable is ever absent.

Confidence Score: 3/5

Safe to merge for the pre-transcription idle UI; the live post-transcription cast strip in DubLeftColumn.jsx will be visually broken once a real ASR run completes.

The deleted base rules for .dub-cast, .dub-cast__row, .dub-cast__kicker, and .dub-cast__label are still consumed by DubLeftColumn.jsx for the live cast strip shown after transcription. That render path was outside the pixel-diff oracle's reach, so the regression was not caught by the stated verification. The layout and typographic styling of the live cast strip will fall back to browser defaults once that component mounts.

frontend/src/pages/DubTab.css — the four deleted base rules for the cast strip need to be restored or moved into DubLeftColumn.jsx as Tailwind utilities before this can merge safely.

Important Files Changed

Filename Overview
frontend/src/components/dub/IdleSkeleton.jsx CSS→Tailwind conversion of idle/skeleton UI rules; drops the fallback on --chrome-hover-bg and more critically provides Tailwind-only replacements for dub-cast/dub-cast__row/dub-cast__kicker/dub-cast__label that DubLeftColumn.jsx still needs as real CSS classes.
frontend/src/pages/DubTab.css Removes 119 lines of standalone idle/skeleton CSS rules migrated to Tailwind utilities; correctly preserves hover/modifier/keyframe rules, but incorrectly deletes base rules for .dub-cast, .dub-cast__row, .dub-cast__kicker, and .dub-cast__label that the live post-transcription cast strip in DubLeftColumn.jsx still depends on.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[DubTab.css] -->|base rules deleted| B{Who used them?}
    B -->|IdleSkeleton.jsx ✅| C[Skeleton cast strip\nreplaced by Tailwind utilities]
    B -->|DubLeftColumn.jsx ❌| D[Live cast strip\ndub-cast / __row / __kicker / __label\nNow unstyled!]
    D --> E[No pill container\nNo flex row layout\nBrowser-default fonts]

    style D fill:#d32f2f,color:#fff
    style E fill:#b71c1c,color:#fff
    style C fill:#388e3c,color:#fff
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[DubTab.css] -->|base rules deleted| B{Who used them?}
    B -->|IdleSkeleton.jsx ✅| C[Skeleton cast strip\nreplaced by Tailwind utilities]
    B -->|DubLeftColumn.jsx ❌| D[Live cast strip\ndub-cast / __row / __kicker / __label\nNow unstyled!]
    D --> E[No pill container\nNo flex row layout\nBrowser-default fonts]

    style D fill:#d32f2f,color:#fff
    style E fill:#b71c1c,color:#fff
    style C fill:#388e3c,color:#fff
Loading

Fix All in Claude Code

Reviews (1): Last reviewed commit: "feat(ui): convert more DubTab CSS to Tai..." | Re-trigger Greptile

Comment on lines 449 to 463
{dubVideoFile && (
<div className="dub-cast dub-cast--muted">
<div className="dub-cast__row">
<span className="dub-cast__kicker">{t('dub.cast')}</span>
<span className="dub-cast__label">{t('dub.speaker', { n: 1 })}</span>
<span className="dub-cast--muted__chip">{t('dub.default')}</span>
<div className="dub-cast dub-cast--muted mt-[2px] px-[var(--space-3)] py-[3px] bg-[var(--chrome-bg)] rounded-[var(--chrome-radius-pill)] [border:1px_solid_var(--chrome-border)]">
<div className="flex gap-[var(--space-2)] items-center flex-wrap">
<span className="dub-cast__kicker font-[family-name:var(--chrome-font-mono)] text-[length:var(--chrome-label-size)] text-[var(--chrome-fg-muted)] tracking-[var(--chrome-label-track)] uppercase font-semibold">
{t('dub.cast')}
</span>
<span className="dub-cast__label font-[family-name:var(--chrome-font-mono)] text-[0.62rem] text-[var(--chrome-fg)]">
{t('dub.speaker', { n: 1 })}
</span>
<span className="font-[family-name:var(--chrome-font-mono)] text-[0.62rem] text-[var(--chrome-fg-dim)] px-[6px] py-[1px] bg-transparent [border:1px_solid_var(--chrome-border)] rounded-[var(--chrome-radius-pill)]">
{t('dub.default')}
</span>
</div>
</div>
)}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Live cast strip loses all base styles after transcription

DubLeftColumn.jsx (line 180–190) renders the real post-transcription cast strip using dub-cast, dub-cast__row, dub-cast__kicker, and dub-cast__label as bare CSS class names. This PR deletes exactly those four rules from DubTab.css and re-expresses them as Tailwind utilities only here in IdleSkeleton.jsx. Once a real ASR run completes and DubLeftColumn mounts the live cast strip, it will have no styling for its container chrome (background, pill border, padding, margin-top), no flex-row layout, and plain browser-default fonts instead of the monospace chrome. The .dub-cast--muted modifier and descendant override rules that remain in CSS also become meaningless without the base declarations they are intended to override.

The pixel-diff oracle couldn't catch this because it was explicitly limited to pre-transcription states; the defect only surfaces after a real ASR run.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code

flow, OmniVoice chrome. The pick pre-seeds the editor. */}
<div className="dub-landing-opts">
<label className="dub-landing-opts__lang">
<div className="flex items-center justify-between gap-[10px] mt-[10px] px-[10px] py-[8px] [border:1px_solid_var(--chrome-border)] rounded-[10px] bg-[var(--chrome-hover-bg)]">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The original .dub-landing-opts CSS rule specified background: var(--chrome-hover-bg, rgba(255, 255, 255, 0.03)) with an explicit fallback. The Tailwind conversion drops that fallback, so if --chrome-hover-bg is ever undefined (e.g., a future theme or a test harness that doesn't inject the full design-token stylesheet) the background collapses to fully transparent. Encoding the fallback in the arbitrary-value bracket keeps the intent intact.

Suggested change
<div className="flex items-center justify-between gap-[10px] mt-[10px] px-[10px] py-[8px] [border:1px_solid_var(--chrome-border)] rounded-[10px] bg-[var(--chrome-hover-bg)]">
<div className="flex items-center justify-between gap-[10px] mt-[10px] px-[10px] py-[8px] [border:1px_solid_var(--chrome-border)] rounded-[10px] bg-[var(--chrome-hover-bg,rgba(255,255,255,0.03))]">

Fix in Claude Code

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/pages/DubTab.css`:
- Around line 708-719: The cast strip base styling is incomplete because
`DubTab.css` only keeps the muted overrides and
`dub-cast__pair`/`dub-cast__select`, while `DubLeftColumn.jsx` still renders
`dub-cast`, `dub-cast__row`, `dub-cast__kicker`, and `dub-cast__label`. Restore
the missing base layout/spacing/label rules in `DubTab.css` for those class
names, or update `DubLeftColumn.jsx` to use the shared utility classes
consistently so the real cast strip keeps its intended flex and typography
styling.
- Line 263: The clone upload input used by AudioMethodPanel still relies on the
dub-hidden-file class, but DubTab.css no longer applies the hidden-file styling,
so the native file picker becomes visible. Restore the styling for the
dub-hidden-file selector in DubTab.css until AudioMethodPanel is migrated, or
update the input in AudioMethodPanel to use hidden in the same change. Use the
AudioMethodPanel and dub-hidden-file identifiers to verify the affected upload
field stays visually hidden.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 65d02d32-d992-4942-b22e-f13caba9fa66

📥 Commits

Reviewing files that changed from the base of the PR and between ab87ef7 and 0d67660.

📒 Files selected for processing (2)
  • frontend/src/components/dub/IdleSkeleton.jsx
  • frontend/src/pages/DubTab.css

}

.dub-hidden-file { display: none; }
/* .dub-idle-upload-label + .dub-hidden-file → utilities (IdleSkeleton.jsx). */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# All remaining consumers of dub-hidden-file (should be empty if safe to delete the rule)
rg -nP --type=jsx --type=js --type=tsx -g '!**/IdleSkeleton.jsx' "dub-hidden-file" frontend/src
# Confirm the CSS rule is actually gone
rg -nP "\.dub-hidden-file\b" frontend/src/pages/DubTab.css

Repository: debpalash/OmniVoice-Studio

Length of output: 276


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== consumers ==\n'
rg -n "dub-hidden-file" frontend/src || true

printf '\n== AudioMethodPanel ==\n'
file=$(git ls-files 'frontend/src/**/AudioMethodPanel.jsx' | head -n 1)
echo "FILE=$file"
if [ -n "$file" ]; then
  sed -n '1,140p' "$file" | cat -n
fi

printf '\n== DubTab.css around line 263 ==\n'
sed -n '245,275p' frontend/src/pages/DubTab.css | cat -n

Repository: debpalash/OmniVoice-Studio

Length of output: 7479


Restore the hidden-file styling before deleting the selector

frontend/src/components/clone/AudioMethodPanel.jsx:38-47 still renders the clone upload input with className="dub-hidden-file", but frontend/src/pages/DubTab.css:263 now only leaves a comment there. That exposes the raw file picker in the clone tab next to the custom drop zone. Keep the selector until this consumer is migrated, or switch this input to hidden in the same change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/pages/DubTab.css` at line 263, The clone upload input used by
AudioMethodPanel still relies on the dub-hidden-file class, but DubTab.css no
longer applies the hidden-file styling, so the native file picker becomes
visible. Restore the styling for the dub-hidden-file selector in DubTab.css
until AudioMethodPanel is migrated, or update the input in AudioMethodPanel to
use hidden in the same change. Use the AudioMethodPanel and dub-hidden-file
identifiers to verify the affected upload field stays visually hidden.

Comment on lines +708 to 719
/* .dub-cast base + __row + __kicker/__label base + --muted__chip → utilities
(IdleSkeleton.jsx). .dub-cast / __kicker / __label keep their classes so the
.dub-cast--muted (and its descendant) overrides below still apply; __pair
(:hover) and __select (real cast, not the skeleton) stay. */
.dub-cast__pair { display: flex; align-items: center; gap: 3px; padding: 1px 5px; border-radius: var(--radius-sm); transition: background 0.2s ease; }
.dub-cast__pair:hover { background: rgba(255, 255, 255, 0.03); }
.dub-cast__label { font-family: var(--chrome-font-mono); font-size: 0.62rem; color: var(--chrome-fg); }
.dub-cast__select { width: 95px; padding: 1px 3px; font-size: 0.60rem; }

/* Muted placeholder cast strip shown in the idle skeleton */
.dub-cast--muted { background: transparent; border-color: var(--chrome-border); }
.dub-cast--muted .dub-cast__label,
.dub-cast--muted .dub-cast__kicker { color: var(--chrome-fg-dim); }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Non-skeleton consumers of the removed cast base classes
rg -nP "dub-cast(__row|__kicker|__label)?\b" frontend/src -g '!**/IdleSkeleton.jsx'
# Confirm base rules removed (only --muted override + __pair/__select should remain)
rg -nP "\.dub-cast(__row|__kicker|__label)?\s*\{" frontend/src/pages/DubTab.css

Repository: debpalash/OmniVoice-Studio

Length of output: 1286


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== DubTab.css around removed rules =="
sed -n '660,735p' frontend/src/pages/DubTab.css

echo
echo "== DubLeftColumn.jsx around cast markup =="
sed -n '160,210p' frontend/src/components/dub/DubLeftColumn.jsx

echo
echo "== IdleSkeleton.jsx utility usage =="
rg -n "dub-cast|__row|__kicker|__label|__pair|__select|utilities" frontend/src/components frontend/src/pages -g '!*node_modules*'

Repository: debpalash/OmniVoice-Studio

Length of output: 32370


Keep the cast base styles in DubTab.css

frontend/src/pages/DubTab.css:708-719 now only preserves the muted color overrides plus __pair/__select, but frontend/src/components/dub/DubLeftColumn.jsx:180-190 still renders dub-cast, dub-cast__row, dub-cast__kicker, and dub-cast__label without matching utilities. That removes the real cast strip’s base flex/spacing/label styling; the --muted selector only covers color. Restore the base rules here or move DubLeftColumn.jsx onto the same utility classes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/pages/DubTab.css` around lines 708 - 719, The cast strip base
styling is incomplete because `DubTab.css` only keeps the muted overrides and
`dub-cast__pair`/`dub-cast__select`, while `DubLeftColumn.jsx` still renders
`dub-cast`, `dub-cast__row`, `dub-cast__kicker`, and `dub-cast__label`. Restore
the missing base layout/spacing/label rules in `DubTab.css` for those class
names, or update `DubLeftColumn.jsx` to use the shared utility classes
consistently so the real cast strip keeps its intended flex and typography
styling.

@debpalash
debpalash merged commit 9d79bb8 into main Jun 30, 2026
15 checks passed
@debpalash
debpalash deleted the feat/tw-dubtab-wave2 branch June 30, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant