# BW Agenda Table — Session Log

Append-only, newest first. Format: see §11 of PLUGIN.md.

---

## 2026-05-14 — actually centre the empty-state icon → 0.1.6

**Goal:** 0.1.5's `display: grid; place-items: center;` still rendered the calendar glyph visually top-of-pill in the browser. Find the real root cause and fix it.
**Done:**
- Diagnosed two stacked issues:
  1. **Specificity/source-order collision.** Google Fonts' Material Symbols stylesheet defines `.material-symbols-outlined { display: inline-block; ... }`. Both my `.bw-agenda-table__empty-icon` rule and Google's `.material-symbols-outlined` rule are single-class selectors (specificity `(0,1,0)`), so the later-loaded stylesheet wins. Google's enqueue (`bw-agenda-table-material-symbols`, registered in `class-bw-agenda-table-block.php`) and the block's `style.css` (registered via `block.json`) don't have a declared dependency order, so on some pages Google's CSS loaded after ours and overrode `display: grid` with `display: inline-block` — falling the glyph back to baseline alignment and pushing it to the top of the pill.
  2. **Glyph ascent gap.** Even with grid centering enforced, Material Symbols glyphs carry typographic ascent inside their `line-height: 1` line-box that pushes the visible glyph above the line-box's geometric centre. The grid centres the line-box, not the glyph.
- Fix in `style.css`:
  - Scoped the rule under `.bw-agenda-table .bw-agenda-table__empty-icon` — bumps specificity to `(0,2,0)` so our `display: inline-grid` always wins regardless of load order.
  - Switched to `display: inline-grid` + both `place-content: center` and `place-items: center` (belt-and-suspenders against any future child-element changes).
  - **`line-height: 0`** is the key fix — collapses the line-box so only the glyph's em-square gets centred. This removes the ascent gap that was offsetting the visible glyph upward.
  - Pinned `'opsz' 24` (the max in the variable-axis range loaded — `opsz,wght,FILL,GRAD@20..24,400,0,0`) so the variation setting actually applies.
- Bumped plugin header `Version:` + `BW_AGENDA_TABLE_VERSION` to `0.1.6`, `index.asset.php` `version` to `0.1.6`, `CLAUDE.md` header to `0.1.6`. Added `[0.1.6]` Fixed entry to `CHANGELOG.md`.
**Left off at:** 0.1.6 ready. Hard-refresh to bust the `style.css?ver=0.1.5` cache; the glyph should now be visually dead-centre in the gradient pill in both Chrome/Edge (Blink), Firefox (Gecko), and Safari (WebKit). Note that `line-height: 0` may need confirmation across browsers — if any browser clips the glyph, swap to `line-height: 1` and add `transform: translateY(-1px)` as a per-renderer nudge.
**Notes:** The same `line-height: 0` + scoped-specificity pattern should be applied to any future circular icon badge in this block. The inline icons in `.pv-day-session__icon` (18px size) don't show the offset visibly because the glyph is so small relative to its inline context, but they have the same underlying typographic geometry.

## 2026-05-14 — vertically centre the empty-state icon → 0.1.5

**Goal:** The 64×64 gradient pill on the empty-state card was rendering its Material Symbols glyph (`event_upcoming`) too high — visually top-of-pill instead of dead-centre — because `display: inline-flex; align-items: center;` only centres the glyph's *line box*, and Material Symbols' default ascent/descent metrics make that line box much taller than the glyph itself.
**Done:**
- Switched `.bw-agenda-table__empty-icon` to `display: grid; place-items: center;` — grid centres the content box independent of typographic baseline, which lands the glyph optically centred.
- Added `font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 32` directly on the pill so the optical-size axis matches the 32px font-size; the default `opsz` produces extra ascent padding above the glyph.
- Inlined `font-family: 'Material Symbols Outlined'`, `font-feature-settings: 'liga'`, and `user-select: none` on the pill rule too. The `.material-symbols-outlined` class on the span provides these globally, but specifying them locally guards against host themes that override the global rule (the existing `.pv-day-session__icon` rule follows the same pattern).
- Bumped plugin header `Version:` + `BW_AGENDA_TABLE_VERSION` to `0.1.5`, `index.asset.php` `version` to `0.1.5`, `CLAUDE.md` header to `0.1.5`. Added `[0.1.5]` Fixed entry to `CHANGELOG.md`.
**Left off at:** 0.1.5 ready. Hard-refresh the front-end / editor preview to bust the previous `0.1.4` style.css cache; the icon should now sit centred on both axes inside the pill.
**Notes:** The same `place-items: center` + `opsz`-matches-font-size pattern is the right fix for the inline icons in `.pv-day-session__icon` if those ever get bumped to a larger size — currently they're 18px which is small enough that the baseline offset isn't noticeable.

## 2026-05-14 — style the "Coming soon" empty state → 0.1.4

**Goal:** Replace the single-line "Coming soon" placeholder (added in 0.1.3) with a properly styled empty state that matches the rest of the block's visual language.
**Done:**
- `render.php`: expanded the empty branch to emit a `bw-agenda-table__empty-state` flex container holding a `material-symbols-outlined` icon badge (`event_upcoming`), the existing `bw-agenda-table__coming-soon` heading (capitalised to `Coming Soon`), and a new `bw-agenda-table__empty-hint` helper line ("The agenda is being finalised — check back soon for the full lineup."). Wrapped in `role="status"` for screen readers.
- `style.css`: added a card-style block for `.bw-agenda-table--empty` (white bg, `--pv-line` border, `--pv-r-lg` radius, `--pv-shadow-sm`) so the placeholder visually matches `.pv-day-view`. The 64×64 icon pill and the heading both use the navy→teal→green gradient (`linear-gradient(135deg, --pv-navy, --pv-teal 55%, --pv-green)`), with the heading clipped via `-webkit-background-clip: text`. Heading is Space Grotesk (`--pv-font-display`) at `--pv-fs-xl` mobile / 1.75rem ≥720px. Hint copy uses `--pv-slate` at `--pv-fs-sm`, capped at `36ch` for readability.
- Bumped plugin header `Version:` + `BW_AGENDA_TABLE_VERSION` to `0.1.4`, `blocks/bw-agenda-table/index.asset.php` `version` to `0.1.4`, and `CLAUDE.md` header to `0.1.4`. Added `[0.1.4]` entry to `CHANGELOG.md`.
**Left off at:** 0.1.4 ready. Frontend + editor preview both render the styled card; verified the rendered HTML via `do_blocks( '<!-- wp:bw/agenda-table /-->' )`.
**Notes:** Heading capitalisation went from "Coming soon" → "Coming Soon" for visual weight in the gradient — the text-domain string `Coming Soon` is the canonical form going forward. Material Symbols was already enqueued by `BW_Agenda_Table_Block::enqueue_material_symbols()` whenever the block is on the page, so no new enqueue paths needed.

## 2026-05-14 — drop demo fallback, add "Coming soon" empty state → 0.1.3

**Goal:** Block should render purely from the `session` CPT (and its ACF/post-meta + `track` taxonomy). When no Sessions are published — or the CPT isn't registered — show a "Coming soon" message instead of the ten-row demo dataset.
**Done:**
- Deleted `bw_agenda_table_demo_rows()` from `blocks/bw-agenda-table/render.php` (lines 332–444 in 0.1.2) and removed the demo-only track-filter shim that mirrored the WP_Query OR-NOT-EXISTS rule against those sample rows.
- Replaced sections 3–4 of `render.php` with an early-return path: `$bw_has_rows = is_array( $bw_rows ) && ! empty( $bw_rows )`; when false, emit `<div class="bw-agenda-table bw-agenda-table--empty"><p class="bw-agenda-table__coming-soon">Coming soon</p></div>` and `return;`. Sort / day-grouping / header-label resolution only runs in the populated branch.
- Removed the trailing `bw-agenda-table__demo-note` admin notice and the `bw-agenda-table--demo` wrapper class from the populated branch.
- `style.css`: replaced the `.bw-agenda-table__demo-note` rule (gold-on-amber dashed banner) with `.bw-agenda-table__coming-soon` (centred, `--pv-fs-lg`, `--pv-graphite`, 32px vertical padding via `--pv-s-6`).
- Bumped plugin header `Version:` + `BW_AGENDA_TABLE_VERSION` to `0.1.3`, `blocks/bw-agenda-table/index.asset.php` `version` to `0.1.3`, `CLAUDE.md` header date to `2026-05-14`, and the CLAUDE.md "What this plugin does" line so it describes the empty state instead of the demo fallback.
- Added `[0.1.3]` entry to `CHANGELOG.md` covering Changed / Added / Removed.
**Left off at:** 0.1.3 ready. promptvictoria currently has 0 published `session` posts, so frontend + editor preview now both render "Coming soon"; the moment the first Session is published the block flips to live data with no further work.
**Notes:** The Inspector's static `Track 1 / 2 / 3` track-options fallback in `index.js` (used when `useSelect`'s `getEntityRecords('taxonomy','track',…)` hasn't returned yet) is **not** demo-data — it's an editor-UX guard for the SelectControl and is kept intact. The comment there still mentions "demo / pre-CPT phase"; left as-is because the guard's purpose hasn't changed.

## 2026-05-01 — auto-derive single-day header label → 0.1.1

**Goal:** Remove the manual "Date label (single-day)" Inspector field and have the single-day header label derive automatically from the first session's event date.
**Done:**
- Dropped the `dateLabel` attribute from `blocks/bw-agenda-table/block.json`.
- Removed the corresponding `TextControl` from the Layout panel in `blocks/bw-agenda-table/index.js`. The `Limit` control still uses `TextControl`, so the import stays.
- Removed `$bw_date_label` resolution and the hard-coded `"Thursday, November 5, 2026"` fallback from `blocks/bw-agenda-table/render.php`.
- Rewrote the header-label block: when `$bw_days` is non-empty, multi-day uses `bw_agenda_table_format_date_range()` (with `format_day_heading()` as a parser-failure fallback) and single-day uses `bw_agenda_table_format_day_heading( $bw_days[0]['date'] )`. Empty data → empty label.
- Bumped plugin header `Version:` + `BW_AGENDA_TABLE_VERSION` to `0.1.1`, `index.asset.php` `version` to `0.1.1`, `CLAUDE.md` header date.
- Added `[0.1.1]` entry to `CHANGELOG.md`.
**Left off at:** 0.1.1 ready. Single-day header label is now identical to what a user would have typed manually for any normally-formatted `event_date` (Y-m-d). Existing posts that stored a `dateLabel` attribute keep the markup but the value is silently ignored.
**Notes:** Header label still keys off `$bw_is_multi_day` (data shape), not `$bw_date_nav_resolved` (UI mode). So if an author forces `single` mode on multi-day data, the picker collapses to a static button but the label still shows the full data range — same behaviour as 0.1.0, just without the editable string.

## 2026-04-28 — scaffold

**Goal:** Extract the `bw/agenda-table` block from the `kadence-child` theme into a portable, standalone plugin so it can be reused across other WordPress projects.
**Done:**
- Created `wp-content/plugins/bw-agenda-table/` per PLUGIN.md §3 layout.
- Main file `bw-agenda-table.php` with canonical header, constants, and `plugins_loaded` bootstrap.
- `includes/class-bw-agenda-table-block.php` with `register_block_type` and conditional Material Symbols enqueue.
- Block files copied into `blocks/bw-agenda-table/` with two changes:
  1. Helper functions renamed `bw_agenda_*` → `bw_agenda_table_*` (PLUGIN.md §2 prefix rule).
  2. Text domain `kadence-child` → `bw-agenda-table`.
- `uninstall.php` scrubs plugin options.
- `README.md` documents the host-site contract (CPT + taxonomy + field aliases).
- Doc stubs in place: `SPEC.md`, `ARCHITECTURE.md`, `TESTING.md`, `ROADMAP.md`, `KNOWN-ISSUES.md`, `HANDOFF-NOTES.md`, `SESSION-LOG.md`.
- `CHANGELOG.md` seeded with `[0.1.0] - 2026-04-28`.
**Left off at:** Plugin ready to activate. Original in-theme copy at `wp-content/themes/kadence-child/blocks/bw-agenda-table/` left untouched — must decide whether to remove it before activating the plugin (block name collision risk).
**Notes:** Versioned at 0.1.0 — pre-1.0, anything can break. The CSS/markup uses `pv-*` class names from the originating theme; scoped under `.bw-agenda-table` so it can't leak. Rename tracked in `KNOWN-ISSUES.md` for a future major release.
