# daw v0.5.0 — Upgrade Plan (working doc) Living plan for migrating the `daw` theme from a 22-year-old classic PHP theme to a modern FSE block theme. Update freely as we go. Companion: [[dependencies]]. ## Goal Bring `daw` in line with how I build themes now (the `srh` theme is the reference), shedding accumulated cruft along the way — without losing the bespoke, hand-crafted character of the site. ## Locked decisions (2026-06-15) 1. **Full block / FSE theme** — `theme.json` + `templates/` + `parts/` + `patterns/` + `blocks/`, Site-Editor driven (like `srh`). 2. **Build:** `@wordpress/scripts` + webpack — replaces the gulp pipeline. 3. **Homepage stays bespoke** — keep the hand-rolled `front-page.php` (centered card, davo-bot, inline critical CSS); a classic PHP front-page coexists fine inside a block theme. ## Target conventions (from the `srh` theme) - **Loader:** thin `functions.php` → `require_once` of `inc//loader.php`; each subdir's loader requires its peers. Consistent `dw_` function prefix. - **`inc/` by concern:** e.g. `seo/`, `analytics/`, `perf/`, `a11y/`, `integrations/` — each procedural, hooked to `wp_head`/`wp_footer`/`wp_enqueue_scripts`. - **`theme.json` v3:** `settings` (layout contentSize/wideSize, color palette, typography fontFamilies/fontSizes, spacing) + `styles` (elements). Design tokens live here, not in CSS. - **`templates/` + `parts/`:** block-markup `*.html` (`index/single/archive/page/home/search/404/category`); parts for `header`/`footer`. - **`patterns/`:** auto-discovered from `/patterns/` via PHP file headers (Title/Slug/Categories/Block Types). Categories registered in `functions.php`. - **`blocks/`:** per-block `block.json` (apiVersion 3) + `render.php`; `autoRegister:true` for render-only blocks (WP 7.0+), manual `register_block_type` + editor script for interactive ones. - **Build:** `wp-scripts build`/`start`, custom `webpack.config.js` for extra entries + BrowserSync, `.babelrc` with `wp.element.createElement` pragma. --- ## Phases ### Phase 0 — Get a handle on it (done) - [x] Document existing dependencies → [[dependencies]] - [~] **Refactor `functions.php` → modular `inc/`** — **deferred** (2026-06-15): it's only ~200 lines and readable enough; not worth chopping yet. The `inc/` modularization will happen naturally as the FSE build grows. Map kept below for when we do. **Proposed `functions.php` → `inc/` map (deferred — reference)** (current responsibilities → modules): | Current (in functions.php) | New home | |---|---| | `dw_setup()` — theme supports, image sizes | `inc/setup.php` | | `dw_scripts()` — the per-page enqueue ladder | `inc/assets.php` (the big readability win) | | `dw_editor()` — editor styles | `inc/assets.php` | | `dw_analytics()` — Matomo footer | `inc/analytics/matomo.php` | | `dw_login_session()` — auth cookie filter | `inc/auth.php` | | `dw_ask_widget()` — davo-bot loader | `inc/integrations/davo-bot.php` | | `dw_plugs()` → smtp | `inc/integrations/smtp.php` (wraps existing `inc/smtp.php`) | | existing `inc/{utils,template,tweaks,form,analytics}.php` | keep; fold into loader | `functions.php` ends up a thin bootstrap: define constants → `require inc/loader.php`. **Behavior must be byte-for-byte identical** at this stage (pure reorg, no feature change). ### Phase 1 — Build toolchain (in progress) - [x] Stand up `@wordpress/scripts` + webpack: `package.json` (build/start scripts + deps), `.babelrc`, `webpack.config.js` (browser-sync proxying `daw.stu:3030`), `src/` → `build/` seed - [x] `npm install` + `npm run build` verified (compiles `src/` → `build/index.js`). `npm start` wired (browser-sync `daw.stu:3030`), not yet run. - [x] **CSS build → webpack** (2026-06-15): `v4-style.min.css` is now built by webpack — `src/legacy-style.js` imports the 5 sources in gulp's order → MiniCssExtractPlugin → theme root, `css-loader { url:false }` (keeps `fonts/…` paths), cssnano `discardComments.removeAll` (matches old clean-css). Faithful 1:1: 444 KB vs gulp 451 KB, fonts/sources/order intact, serves 200. **`style-min` enqueue unchanged.** The `cssf` → `v4-front.min.css` output was dead (nothing enqueues it) — skipped. ⚠️ **Don't run `gulp build`** now — it would overwrite `v4-style.min.css` with the (equivalent) clean-css version; webpack owns it. JS bundles still on gulp (`js`/`jsf`). - [ ] Port front-end JS into webpack incrementally as behaviors modernize (Phases 2–4) **Decision (2026-06-15):** new toolchain runs **alongside** the existing gulp build, not replacing it yet. **Gulp is still the active build** — it pulls vendor packages out of `node_modules` (bootstrap, jquery, fullcalendar, svg-morpheus, animate, …) and concats/minifies them with `style.css`/`styles.css` into the `v4-*.min.*` files the live theme enqueues (`gulp copy`/`mixin`/`build`/`js`/`jsf`/`cssf`). It keeps running normally; wp-scripts just adds a second, block-aware pipeline. **Retiring gulp + the `v4-*` outputs happens in Phase 5**, once block templates + `theme.json` supersede those assets. New source is isolated in `src/` → `build/` so it never collides with the legacy files in `js/`. **JS bundle audit (2026-06-15, corrected).** ⚠️ My first two broad greps were unreliable — **zsh doesn't word-split an unquoted file-list variable**, so the multi-file searches erred into false "unused." Re-audited with literal file args + context + DB content scan. Corrected result: **`scripts.js` is the plugin *library* the per-page scripts call into — mostly load-bearing, not dead.** - **KEEPERS (verified in use):** - jQuery + bootstrap/Carousel — site-wide (jQuery via webpack `ProvidePlugin`) - **WOW** — about, studio, art, desk - **DrawFillSVG** — about, studio (animates the inline SVGs `#sv`, `#brain`, `#svg-device`…) - **backstretch** — studio (`#studio-caro` hero background) - **lazyload** — desk - **js-cookie** (`Cookies`) — single - **jQuery Validation** (`.validate()`) — WP comment form (`#commentform`) on single + about - **Rainbow.js** — `code.js` defines the grammars; 20 posts use `data-language` (candidate to replace with a modern highlighter in Phase 4) - **SVGMorpheus** — front-page only (icon morph) - page scripts `about/studio/music/art/desk/contact/single/analytics/code.js` + `front-page.js` - **DROP (verified unused — 0 in page scripts, templates, content):** Typed.js, Formstone Wallpaper, smoothState, jQuery Waypoints, jquery.appear, **jquery-scrollto** (the `scrollTo` hits were native `$(window).scrollTop()`), Modernizr, **ghembedder** (post 1341 cleaned; only a 2023 revision still references `.github-widget`). [**fullcalendar is NOT droppable** — used on the About page calendar; my earlier "0 usage" was a case-sensitivity miss (`FullCalendar.Calendar`).] - **Implication → revised build rec:** most legacy plugins are in use *and* are exactly the ones slated for native/modern replacement in Phases 3–4 (WOW→IntersectionObserver/CSS, lazyload→`loading=lazy`, backstretch→CSS bg, Rainbow→Prism, comment validation→native). Porting them to webpack **now** is throwaway work. So: **port CSS to webpack now; leave JS on gulp** and migrate it to webpack incrementally as each behavior is modernized — don't reproduce the fragile jQuery-plugin bundle just to delete it. - **Reversibility:** nothing deleted — `scripts.js`/gulp/`v4-*` stay on disk + in git; enqueues switch only after page verification. ### Phase 2 — theme.json foundation - [ ] `theme.json` v3: layout, color palette, typography, spacing, element styles - [ ] Port design tokens out of `style.css`/`styles.scss` ### Phase 3 — Block templates + parts - [ ] `templates/`: index, single, archive, page, home, search, 404, category, tag - [ ] `parts/`: header, footer (retire `header-*.php` / `footer-*.php` variants) - [ ] Keep `front-page.php` bespoke (coexists) - [ ] Decide each legacy `page-*.php`: → block template, → pattern, → retire (see open questions) ### Phase 4 — Patterns + custom blocks - [ ] `patterns/` for reusable sections - [ ] `blocks/` for dynamic bits (music/last.fm, desk loop → Query Loop, etc.) ### Phase 5 — Cleanup (the "additional cleanup") - [ ] Drop confirmed-dead deps per [[dependencies]] (terminal.js, messenger, modernizr, jasny, animate.css…) - [ ] Resolve audits: Twilio call/SMS/chat, fullcalendar, simple_html_dom, Stripe v2, icon fonts - [ ] Remove legacy build outputs + `style.min.css` ### Phase 6 — New features - [ ] _TBD — to be specified_ --- ## Open questions / decisions to make - Sign-off on the Phase 0 `inc/` module map above. - **Page audit:** which legacy pages survive vs retire? Candidates to confirm: `bio`, `cv`, `shop`, `archive`, `chat`. - **Feature audits:** is the Twilio phone/SMS/chat feature still live? Is `fullcalendar` still rendered anywhere? Is `simple_html_dom` still used? - New features list (Phase 6). ## Changelog - **2026-06-16** — **CSS pipeline fully on webpack.** Wired `sass-loader` (`implementation: require('sass')`, `quietDeps`) so webpack compiles `styles.scss` directly (Bootstrap + bootstrap-icons from `node_modules`) instead of importing the gulp-compiled `styles.css`. gulp's `mixin` / CSS `copy` / `build` / `cssf` are now **fully superseded** — `styles.css` is an orphaned artifact (source of truth = `styles.scss`). Then **upgraded Bootstrap 5.2.3 → 5.3.8** (flows straight through the webpack sass compile; bundle 440→470 KB from 5.3's color-mode vars). Removed `jasny-bootstrap` (unused). **Visual verification pending.** Next dep upgrades (bootstrap-icons, animate.css) flow the same way. gulp still owns JS bundles until the JS migration; once that's done, gulp goes entirely. - **2026-06-15** — Fixed intermittent **stuck loader** (reported on Studio). Cause: `#loader` was hidden only by per-page `$(window).bind('load', …fadeOut)` with no fallback — if a resource hung (Studio backstretches `camera.mp4`) or `load` already fired, it stuck forever. Fix: `loader.php` now hides the preloader itself in vanilla JS (runs in the header, before `load`), with a `setTimeout` fail-safe (6s) + `readyState` check. The per-page `fadeOut` bindings in `studio/about/art/desk.js` are now redundant (harmless; clean up when those scripts are modernized in Phases 3–4). Not caused by the CSS build change — pre-existing. - **2026-06-15** — Plan created; dependencies documented; decisions locked (FSE / wp-scripts / bespoke homepage).