feat(plugins): hero widget slot + Koffi reference plugin

Widget plugins can now declare capabilities.widget.slot 'hero' to render as a
transparent, click-through overlay sitting on the boarding-pass bar's top edge
(migration 157 persists capabilities; manifest validation server+SDK, feed
exposes the slot, dashboard mounts hero frames above the pass). Sidebar stays
the default slot.

Replaces the trip-countdown example with Koffi, the TREK mascot: an animated
suitcase with a 14-state behavior engine driven by real trip data — walking,
waving, napping, trolley rolls, passport-stamp stickers, a split-flap luggage-
tag countdown under 7 days, and sunglasses while the trip runs. Validated by
the SDK suite like any author plugin; published as mauriceboe/trek-plugin-koffi
in the registry.

Migrations 156/157 follow the idempotent ALTER pattern (the reconciliation
test re-runs everything from v135, so duplicate-column must stay non-fatal).
This commit is contained in:
mauriceboe
2026-07-03 21:02:28 +02:00
committed by Maurice
parent 8c9476e487
commit 17f3c86967
22 changed files with 1196 additions and 188 deletions
+13
View File
@@ -262,6 +262,19 @@
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none;
}
/* Hero-slot plugin overlay: a transparent strip whose bottom edge sits on the
pass's top edge, so a plugin (e.g. the mascot) appears to stand ON the bar.
pointer-events none — it must never block the pass or hero interactions. */
.trek-dash .hero-pass-wrap { position: relative; }
.trek-dash .hero-pass-overlay {
position: absolute; left: 16px; right: 16px; bottom: 100%; height: 110px;
pointer-events: none; z-index: 3; overflow: hidden;
}
.trek-dash .hero-overlay-frame {
position: absolute; inset: 0; width: 100%; height: 100% !important;
border: 0; background: transparent; color-scheme: light;
}
.trek-dash .pass-cell {
padding: 4px 18px; position: relative; display: flex; flex-direction: column;
justify-content: center; align-items: center; text-align: center; gap: 6px; flex: 1; min-width: 0;