Campaign surfaces
Scarecrow for the on-platform marketing campaign system (.docs/specs/onplatform-marketing-campaigns.md). Covers: the rotating promo strip with crunchy transitions, per-placement content creatives, the hero→bar collapse, the three overlay presets, and zany ad-content skins. Transitions honor prefers-reduced-motion (falls back to crossfade).
The promo strip — rotation between campaigns
One user, several eligible campaigns → the strip cycles instead of one silently losing. The chunky transition announces "different message now". Strip sits above the navbar — chrome stays chrome, the strip is the stage. Pick a transition:
Spec deltas this implies: delivery returns N eligible bar campaigns (not ≤1), priority becomes rotation order/weight, and an impression = one flap-view (affects marketingEvents + frequency caps). Dismiss suppresses the whole strip, not one campaign — or per-campaign? Open call.
Strip variants
Same slot, three different personalities: the literal Solari board, a split duo for two simultaneous campaigns, and a countdown sale bar.
Strongest identity, loudest render cost — reserve for moments, not always-on. Copy is hard-capped by cell count (38 here).
Answers "two eligible campaigns" with simultaneity instead of rotation — both always visible, zero motion. Only works with ≤2 campaigns and ultra-short copy; kills the flap identity.
Countdown = schedule.endAt rendered live. House rule worth writing down: only real deadlines — fake-resetting timers are the one dark pattern the dev audience never forgives.
In-navbar placements — logo moves left
No extra strip: the nav row's center becomes the stage. Costs the centered TANGIBLE logo; buys back 44px of vertical space.
The tasteful one: single message, quiet frame, flap on rotation. Degrades fine on mobile (capsule hides, nothing breaks).
Two simultaneous messages, zero motion — but this is the crowding tradeoff made visible: copy is squeezed to fragments and it's the first thing that breaks under ~1100px. Honest verdict: works only with ruthless copy discipline.
Quietest of all — reads as ambient status, not advertising. Weakness is the same as its strength: nobody clicks a whisper. Continuous motion also needs the reduced-motion kill switch.
Same campaign, per-placement content
The spec has one content blob per campaign. Real placements need different copy lengths and art direction — content.base plus optional per-placement overrides (content.bar, content.inline_card).
Lightning-Fast WordPress Platform Hosting
Designed by WordPress specialists for high-volume online learning, e-commerce, and membership platforms.
* See tangiblexp.com/pricing for faster-or-it's-free guarantee terms
Host it on TangibleXP
Purpose-built for LMS & membership sites. Free migration included.
Hero collapses into the strip on scroll
Scroll the frame: when the hero leaves the viewport, its bar rendition drops in at the top (same campaignId → attribution stays coherent). Scroll back up and it retreats.
Lightning-Fast WordPress Platform Hosting
Designed by WordPress specialists for high-volume platforms.
Modal · Slide-in · Welcome mat
The three overlay presets, contained in a demo stage. Spec rules: ≤1 overlay interruption per session, dismiss = 14-day suppression, policy-acceptance gate always wins, never on admin/auth/policy surfaces.
Same strip frame, zany creative
The crunch lives in the content, the frame stays disciplined. Three skins — sticker/stamp (already the TXP banner's language), Web 1.0, and a sale marquee.
OFF
- Bar delivery returns N campaigns + rotation, not ≤1; impression = per flap-view.
- Per-placement content overrides (content.base / content.bar / content.inline_card).
- Hero→bar morph = one campaign, two renditions, scroll-linked.
- All animated transitions degrade to crossfade under prefers-reduced-motion; auto-rotation always has pause + dismiss.
- §3 vs §7 slot-name drift: product-detail.sidebar vs product-detail.below-header — pick one.