Goal
Reduce the vertical space each event occupies on low-density day groups (1–2 events) in the events calendar, with a clean compact list-row layout — without breaking the carousel on busy nights or the design system.
This replaces an existing CSS hack with intentional markup. It is count-driven and automatic, NOT a new user-facing display mode (decision: a displayMode=list toggle was rejected because density varies within a single calendar — Friday can have 6 acts wanting the carousel while Sunday has 1 wanting a list row; a page-level mode can't express that).
Current state (verified)
The data-machine-events/calendar block (data-machine-events, inc/Blocks/Calendar/) has two modes in block.json: date-groups (default) and month-grid. There is no real list mode.
In date-groups mode, events within a day are laid out as a horizontal carousel of fixed-size cards (built for "multiple acts per night"):
templates/date-group.php — emits .data-machine-date-group with data-event-count="N" (line 29).
templates/event-item.php — the event card markup (.data-machine-event-item → .data-machine-event-link → title/meta/More-Info).
src/modules/carousel.ts — carousel JS; early-returns when eventCount <= 1 (lines 26–30), so single-event days already skip carousel JS.
The existing low-density treatment is a CSS-only hack: style.css lines 931–1025. It uses [data-event-count="1"] / [data-event-count="2"] attribute selectors to undo the carousel's fixed-size card model — drops fixed height, re-flexes .data-machine-event-link from column to a single row, makes 2-event days two columns (stacked on mobile <=600px), hides the carousel overflow ::after, zeroes badge margins. It works but is ~90 lines of selector-warfare fighting markup designed for a different purpose. This is the "ad-hoc instead of clean API" smell.
What to build (hybrid: count-driven list-row partial)
- Renderer decision: In the date-groups render path (find where
date-group.php + the event loop run — likely render.php and/or src/modules/date-group-renderer.ts for the client-side append/load-more path), when a day group has ≤2 events, render a dedicated list-row partial (new templates/event-list-row.php + matching TS in date-group-renderer.ts/event-renderer.ts) instead of the carousel event-item.php card. 3+ events → unchanged carousel.
- The list-row partial should be a clean, compact single-row layout: title, time, performer, badges, More-Info — intrinsic height, no fixed-card dead space. Reuse the same data/fields
event-item.php uses; this is a layout change, not a data change.
- Delete the CSS hack (
style.css ~931–1025) once the partial replaces it. Add lean, intentional styles for the new .data-machine-event-list-row (or similar) class instead.
- Both render paths must match: initial PHP render (
render.php / templates/) AND the client-side append path used by load-more / day-loader (src/modules/date-group-renderer.ts, event-renderer.ts, day-loader.ts, load-more.ts). If only the PHP path gets the list row, load-more-appended low-density days will diverge. Verify parity.
- Mobile: keep the responsive behavior (2-event days stack on narrow screens) but via the new partial's own clean styles.
Design system constraints
- data-machine-events uses
--data-machine-* / --datamachine-* generic tokens. Reuse existing tokens (day-of-week background rgba vars at style.css ~1027–1034, grid gap --data-machine-grid-gap, etc.). Do NOT hardcode colors or introduce EC-specific tokens — this is the generic layer.
- Keep day-of-week background + hover-border treatment working on the list rows (they're keyed on
.data-machine-day-* ancestor classes).
- LAYER PURITY: this is data-machine-events (generic). No EC/my-shows/extrachill identifiers.
Files
inc/Blocks/Calendar/templates/date-group.php, event-item.php (+ new event-list-row.php)
inc/Blocks/Calendar/render.php (server render decision)
inc/Blocks/Calendar/src/modules/date-group-renderer.ts, event-renderer.ts, carousel.ts, day-loader.ts, load-more.ts (client parity)
inc/Blocks/Calendar/style.css (delete ~931–1025 hack, add list-row styles)
Acceptance
Context
Reporter: founder (Chris Huber), relayed design feedback from Chris Gardner. The complaint: "we re-shape our list into smaller cards when there are low numbers of events" and it leaves too much vertical space / feels off — want a simple, clean, easy-to-read compact list without breaking the vibe/design system.
Goal
Reduce the vertical space each event occupies on low-density day groups (1–2 events) in the events calendar, with a clean compact list-row layout — without breaking the carousel on busy nights or the design system.
This replaces an existing CSS hack with intentional markup. It is count-driven and automatic, NOT a new user-facing display mode (decision: a
displayMode=listtoggle was rejected because density varies within a single calendar — Friday can have 6 acts wanting the carousel while Sunday has 1 wanting a list row; a page-level mode can't express that).Current state (verified)
The
data-machine-events/calendarblock (data-machine-events,inc/Blocks/Calendar/) has two modes inblock.json:date-groups(default) andmonth-grid. There is no real list mode.In
date-groupsmode, events within a day are laid out as a horizontal carousel of fixed-size cards (built for "multiple acts per night"):templates/date-group.php— emits.data-machine-date-groupwithdata-event-count="N"(line 29).templates/event-item.php— the event card markup (.data-machine-event-item→.data-machine-event-link→ title/meta/More-Info).src/modules/carousel.ts— carousel JS; early-returns wheneventCount <= 1(lines 26–30), so single-event days already skip carousel JS.The existing low-density treatment is a CSS-only hack:
style.csslines 931–1025. It uses[data-event-count="1"]/[data-event-count="2"]attribute selectors to undo the carousel's fixed-size card model — drops fixed height, re-flexes.data-machine-event-linkfrom column to a single row, makes 2-event days two columns (stacked on mobile <=600px), hides the carousel overflow::after, zeroes badge margins. It works but is ~90 lines of selector-warfare fighting markup designed for a different purpose. This is the "ad-hoc instead of clean API" smell.What to build (hybrid: count-driven list-row partial)
date-group.php+ the event loop run — likelyrender.phpand/orsrc/modules/date-group-renderer.tsfor the client-side append/load-more path), when a day group has ≤2 events, render a dedicated list-row partial (newtemplates/event-list-row.php+ matching TS indate-group-renderer.ts/event-renderer.ts) instead of the carouselevent-item.phpcard. 3+ events → unchanged carousel.event-item.phpuses; this is a layout change, not a data change.style.css~931–1025) once the partial replaces it. Add lean, intentional styles for the new.data-machine-event-list-row(or similar) class instead.render.php/templates/) AND the client-side append path used by load-more / day-loader (src/modules/date-group-renderer.ts,event-renderer.ts,day-loader.ts,load-more.ts). If only the PHP path gets the list row, load-more-appended low-density days will diverge. Verify parity.Design system constraints
--data-machine-*/--datamachine-*generic tokens. Reuse existing tokens (day-of-week background rgba vars at style.css ~1027–1034, grid gap--data-machine-grid-gap, etc.). Do NOT hardcode colors or introduce EC-specific tokens — this is the generic layer..data-machine-day-*ancestor classes).Files
inc/Blocks/Calendar/templates/date-group.php,event-item.php(+ newevent-list-row.php)inc/Blocks/Calendar/render.php(server render decision)inc/Blocks/Calendar/src/modules/date-group-renderer.ts,event-renderer.ts,carousel.ts,day-loader.ts,load-more.ts(client parity)inc/Blocks/Calendar/style.css(delete ~931–1025 hack, add list-row styles)Acceptance
[data-event-count="1"/"2"]CSS override is removed and replaced by intentional partial markup + lean styles.--data-machine-*tokens reused (grep clean).Context
Reporter: founder (Chris Huber), relayed design feedback from Chris Gardner. The complaint: "we re-shape our list into smaller cards when there are low numbers of events" and it leaves too much vertical space / feels off — want a simple, clean, easy-to-read compact list without breaking the vibe/design system.