| # App.css reduction plan |
|
|
| This document tracks the work to retire the legacy `frontend/src/App.css` |
| in favour of the redesign's design tokens (`styles/design.css`), |
| shared utilities (`styles/page-shared.css`, `styles/clip-grid.css`), |
| and per-page CSS files (`styles/persons-page.css`, |
| `styles/download-page.css`). |
|
|
| ## Where we are now |
|
|
| | Snapshot | Lines | Notes | |
| |---|---|---| |
| | Pre-redesign baseline (main) | 6,401 | Single mega-file with mixed concerns. | |
| | After first orphan sweep (`09c416c`) | 5,892 | Removed 78 classes tied to deleted UI (.tab-bar-*, .results-*, .grid-*, etc.). | |
| | After deeper sweep (`1c47412`) | 4,695 | 145 more classes (details-panel cluster, frame thumbnails, batch forms, etc.). | |
| | After persons extraction (`be7f4cd`) | 3,828 | 144 rule blocks moved to `styles/persons-page.css`. | |
| | After download extraction (`3ef5161`) | 2,183 | 303 rule blocks moved to `styles/download-page.css`. | |
| | After iterative orphan scrub (`497e72c`) | **2,161** | **Current.** Eight passes of comma-orphan removal until stable. | |
| |
| Net reduction so far: **6,401 β 2,161 lines (β66 %)**. |
| |
| Other CSS files at the same date: |
| |
| | File | Lines | Purpose | |
| |---|---|---| |
| | `App.css` | 2,161 | Mostly legacy, see breakdown below. | |
| | `styles/design.css` | 342 | Tokens, topbar, layout, buttons, status pills, frame gradients. | |
| | `styles/clip-grid.css` | 421 | Search clip grid + inline player + Open Subtitles modal. | |
| | `styles/page-shared.css` | 109 | page-shell, page-head, card-section, settings rows, error banner. | |
| | `styles/persons-page.css` | 878 | All PersonsPage-only chrome. | |
| | `styles/download-page.css` | 1,625 | All DownloadPage-only chrome. | |
| |
| ## What's left in App.css |
| |
| Roughly 83 unique base classes remain, falling into four buckets: |
| |
| ### 1. Legacy SearchPage controls (~28 classes, ~580 lines) |
| Used only by `SearchPage.jsx`'s in-page Search Mode / Sort By / |
| Filters strip. The redesign already lifted the search input, |
| language picker, and method toggle into the topbar; the page-local |
| controls below it still ride on these legacy class names: |
| |
| `.search-controls`, `.controls-row`, `.control-group`, `.control-label`, |
| `.control-select`, `.search-input`, `.filter-toggle-button`, |
| `.filter-panel`, `.filter-row`, `.filter-group`, `.filter-group-wide`, |
| `.filter-label`, `.filter-date-inputs`, `.filter-duration-inputs`, |
| `.filter-input`, `.filter-separator`, `.filter-select`, `.filter-hint`, |
| `.filter-actions`, `.filter-clear-button`, `.image-drop-overlay`, |
| `.smart-search-info` (+ children), `.scripture-input` (+ children). |
| |
| ### 2. Legacy SearchPage face / image / scripture / save-person panels (~18 classes, ~350 lines) |
| Used by the empty-state panels rendered when the corresponding |
| search method is selected. Most of these moved into |
| `components/FaceSearchPanel`, `ImageUploadPanel`, |
| `ScriptureSearchPanel`, `SavePersonBanner` during the panel |
| extraction, but their CSS still lives in `App.css`: |
| |
| `.face-drop-zone`, `.face-drop-hint`, `.face-search-controls`, |
| `.face-search-divider`, `.face-search-hint`, `.face-quick-actions`, |
| `.drop-indicator`, `.upload-image-button`, `.scripture-search-form`, |
| `.scripture-search-button`, `.scripture-hint`, `.scripture-colon`, |
| `.scripture-inputs`, `.save-person-banner`, `.save-person-form`, |
| `.save-person-input`, `.save-person-confirm`, `.save-person-cancel`, |
| `.save-person-text`, `.save-person-button`, `.person-select`, |
| `.empty-state.face-drop-zone.dragging`. |
| |
| ### 3. Truly shared utilities (~5 classes, ~60 lines) |
| Consumed by more than one page or component: |
| |
| `.empty-state` (Search/Download/Persons + 3 panel components), |
| `.error-message` (Search/Download/Persons), `.toast` and `.toast-message` |
| (DownloadPage Toast + PersonsPage toast renderer). `.app` and |
| `.main-content` are wrappers used by the mockup-viewer branch in |
| `App.jsx`. |
| |
| (`.face-crop-container` was previously listed here but already lives |
| in `styles/persons-page.css` β only PersonsPage references it.) |
| |
| ### 4. Genuinely orphan / dead (~30 classes, ~350 lines) |
| Rules with no current consumer; survived prior sweeps because their |
| last selector was paired with a still-active class via comma list. |
| Includes `.add-person-button`, `.assign-button` and several |
| `.appearance-thumbnail*` modifiers that were superseded by |
| persons-page.css equivalents. |
|
|
| ## Sweep order for the rest |
|
|
| Each step is its own atomic commit, each verified with a 3-agent QC |
| panel (completeness + cross-page safety + runtime regression). |
|
|
| ### Step 1 β Move SearchPage in-page controls into a new `styles/search-page.css` |
| Bucket #1 above. The SearchPage component is finally under the |
| 600-line cap and its inner JSX is stable, so an extraction now is |
| low-risk. Expected impact: App.css β **β320 lines** β ~1,840 (the |
| controls cluster spans App.css:22β283 plus the scripture sub-cluster |
| near 1011β1037 plus the small drag-overlay rule near 1484). |
|
|
| ### Step 2 β Move SearchPage panel-specific styles into the panel components |
| Bucket #2 above. Each empty-state panel component |
| (FaceSearchPanel.jsx, ImageUploadPanel.jsx, ScriptureSearchPanel.jsx, |
| SavePersonBanner.jsx) gains its own `.css` sibling and CSS module |
| import. Expected impact: β **β200 lines** β ~1,640 (the face-drop / |
| save-person / image-upload clusters span roughly App.css:858β1037). |
|
|
| ### Step 3 β Promote the `.toast`, `.error-message`, `.empty-state` rules into `styles/page-shared.css` |
| Bucket #3. These are the truly shared utilities. Once they're in |
| the shared file, App.css can drop them. Expected impact: β **β60 |
| lines** β ~1,580. |
|
|
| ### Step 4 β Sweep the remaining orphans |
| Bucket #4. Confirm with a per-class JSX grep that every selector in |
| the file has a current consumer before deleting. Expected impact: |
| β **β350 lines** β ~1,230. |
|
|
| ### Step 5 β Audit what remains |
| Whatever survives Step 4 is genuinely shared between the redesign |
| and a legacy page that hasn't been refactored yet. Decide for each |
| remaining rule whether it (a) graduates into design tokens, (b) |
| stays in App.css as a temporary holding area, or (c) is dead and |
| removable. |
|
|
| ## Ground rules during the sweep |
|
|
| - **Never delete the last selector of a multi-selector list without |
| also moving its rule body somewhere.** The bug pattern that |
| reviewer #1 caught on 3ef5161 (orphan trailing-comma silently |
| extending into the next rule) is real β every extraction that |
| touches a comma-list must move both the relevant selectors AND the |
| rule body in one operation. |
| - **Run the iterative orphan-comma sweep after every extraction.** |
| Sweeping once isn't always enough β removing a trailing-comma |
| orphan can leave the line above it freshly orphaned. |
| - **Each commit must pass a three-reviewer QC panel** (completeness |
| + cross-page safety + runtime regression check) before the next |
| step starts. |
|
|
| ## Final target |
|
|
| `App.css` removed entirely; everything lives in: |
|
|
| - `styles/design.css` β tokens + global resets + topbar + buttons |
| - `styles/clip-grid.css` β search results layout |
| - `styles/page-shared.css` β page-head, card-section, error-banner, |
| toast, empty-state |
| - `styles/persons-page.css` β PersonsPage chrome |
| - `styles/download-page.css` β DownloadPage chrome |
| - `styles/search-page.css` β SearchPage chrome (created in Step 1) |
| - `components/<Panel>.css` β panel-specific styles (created in Step 2) |
|
|
| Estimated final state: **App.css = 0 lines (file deleted)**. |
| Cumulative deltas across Steps 1-4: β β930 lines, leaving ~1,230 |
| lines that need a Step 5 audit before the file can be removed |
| entirely. |
|
|