Add Day-Part Clock Animator and multiple animation options for various displays

- Implemented a new Day-Part Clock Animator in `solutions-animator.js` that updates a clock and badge based on simulated time.
- Updated `index.php` to include new animation options for lobby, conference, day-part, wayfinding, storefront, announcement, campus wayfinding, emergency, enclosure, brightness, cellular, designer, media library, publish, screen groups, monitoring, patient wayfinding, waiting room, multi-zone, and membership displays.
- Each animation option includes HTML structure for respective displays.
This commit is contained in:
Matt Batchelder
2026-03-16 22:32:57 -04:00
parent fa6dce039b
commit ff5f392236
11 changed files with 1621 additions and 25 deletions

View File

@@ -11,8 +11,8 @@
<!-- wp:oribi/platform-section {"label":"Capabilities","heading":"Signage Built for the Modern Office","lead":"Keep employees informed, visitors impressed, and operations visible - without email overload."} -->
<!-- wp:oribi/platform-row {"heading":"Meeting Room Displays","description":"Show live room availability, upcoming bookings, and organiser details on screens outside every meeting room. Native integration with Microsoft Teams and calendar systems means your room displays are always accurate - no double-bookings, no manual updates, no confusion.","btnText":"See Features","btnUrl":"/features","isDashboard":true} /-->
<!-- wp:oribi/platform-row {"heading":"Company-Wide Announcements","description":"Push critical updates, HR notices, safety alerts, and celebrations to screens across every floor and building. Reach employees in common areas, break rooms, and reception - the people who miss emails but never miss a screen. Schedule recurring content or publish instantly when it matters.","btnText":"See Pricing","btnUrl":"/pricing","reversed":true} /-->
<!-- wp:oribi/platform-row {"heading":"Live KPI Dashboards","description":"Stream your existing web dashboards, BI tools, and real-time operational data to large-format screens in common areas, operations centres, and management floors. Make critical business metrics visible to the teams who need them - without everyone logging into separate tools.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
<!-- wp:oribi/platform-row {"heading":"Company-Wide Announcements","description":"Push critical updates, HR notices, safety alerts, and celebrations to screens across every floor and building. Reach employees in common areas, break rooms, and reception - the people who miss emails but never miss a screen. Schedule recurring content or publish instantly when it matters.","btnText":"See Pricing","btnUrl":"/pricing","reversed":true,"announcementAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Live KPI Dashboards","description":"Stream your existing web dashboards, BI tools, and real-time operational data to large-format screens in common areas, operations centres, and management floors. Make critical business metrics visible to the teams who need them - without everyone logging into separate tools.","btnText":"Get a Quote","btnUrl":"/contact","liveDataAnim":true} /-->
<!-- /wp:oribi/platform-section -->
<!-- wp:oribi/feature-section {"variant":"alt","label":"Use Cases","heading":"Screens Across the Workplace","lead":"From single offices to multi-site enterprises, corporate signage solves communication challenges at every scale.","columns":3} -->

View File

@@ -10,9 +10,9 @@
<!-- wp:oribi/page-hero-animated {"label":"Education Signage","title":"Keep Your Campus Connected","description":"Timetable displays, campus wayfinding, emergency alerts, and event boards - all managed centrally across every building on campus."} /-->
<!-- wp:oribi/platform-section {"label":"Capabilities","heading":"Signage Built for Education","lead":"Universities, colleges, and schools use digital signage to inform, navigate, and protect - without the admin overhead of managing individual screens."} -->
<!-- wp:oribi/platform-row {"heading":"Timetable &amp; Schedule Displays","description":"Show live class schedules, room assignments, and last-minute changes on screens outside lecture halls, libraries, and common areas. Connect to your timetabling system so displays update automatically when rooms are swapped or sessions rescheduled - no manual edits needed.","btnText":"See Features","btnUrl":"/features"} /-->
<!-- wp:oribi/platform-row {"heading":"Campus Wayfinding","description":"Help students, staff, and visitors navigate sprawling campuses with interactive directory screens and building maps. Touchscreen kiosks let users search for departments, lecture theatres, and facilities by name - ideal for open days, freshers' week, and multi-building institutions.","btnText":"See Kiosks","btnUrl":"/kiosks","reversed":true} /-->
<!-- wp:oribi/platform-row {"heading":"Emergency Override Alerts","description":"Push critical safety notifications to every screen on campus instantly. Lockdown alerts, fire evacuation instructions, and severe weather warnings override scheduled content within seconds - ensuring life-safety messaging reaches everyone, everywhere, immediately.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
<!-- wp:oribi/platform-row {"heading":"Timetable &amp; Schedule Displays","description":"Show live class schedules, room assignments, and last-minute changes on screens outside lecture halls, libraries, and common areas. Connect to your timetabling system so displays update automatically when rooms are swapped or sessions rescheduled - no manual edits needed.","btnText":"See Features","btnUrl":"/features","educationAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Campus Wayfinding","description":"Help students, staff, and visitors navigate sprawling campuses with interactive directory screens and building maps. Touchscreen kiosks let users search for departments, lecture theatres, and facilities by name - ideal for open days, freshers' week, and multi-building institutions.","btnText":"See Kiosks","btnUrl":"/kiosks","reversed":true,"campusWayfindAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Emergency Override Alerts","description":"Push critical safety notifications to every screen on campus instantly. Lockdown alerts, fire evacuation instructions, and severe weather warnings override scheduled content within seconds - ensuring life-safety messaging reaches everyone, everywhere, immediately.","btnText":"Get a Quote","btnUrl":"/contact","emergencyAnim":true} /-->
<!-- /wp:oribi/platform-section -->
<!-- wp:oribi/feature-section {"variant":"alt","label":"Use Cases","heading":"Screens Across Campus","lead":"Digital signage supports communication, safety, and engagement across every type of educational institution.","columns":3} -->

View File

@@ -9,11 +9,11 @@ return <<<'ORIBI_SYNC_CONTENT'
<!-- wp:oribi/page-hero-animated {"label":"Platform Features","title":"Create It. Schedule It. Forget It.","description":"Design content in minutes, automate your schedule, and let your screens run themselves. One cloud dashboard for every display in your network - with live data, real-time analytics, and the tools your whole team can use from day one."} /-->
<!-- wp:oribi/platform-section {"label":"Create \u0026amp; Publish","heading":"From Idea to Screen in Minutes","lead":"A drag-and-drop layout designer, a built-in media library, and instant publishing - so your content goes live the moment it's ready."} -->
<!-- wp:oribi/platform-row {"heading":"Design for Any Screen","description":"Build layouts visually with a drag-and-drop editor that works in any browser. Use ready-made stencils or start from scratch. Layer text, images, video, tickers, and data widgets across multiple zones - then preview exactly how it will look on screen before you publish. Save any layout as a reusable template for your team.","btnText":"Request Demo","btnUrl":"/demo"} /-->
<!-- wp:oribi/platform-row {"heading":"Design for Any Screen","description":"Build layouts visually with a drag-and-drop editor that works in any browser. Use ready-made stencils or start from scratch. Layer text, images, video, tickers, and data widgets across multiple zones - then preview exactly how it will look on screen before you publish. Save any layout as a reusable template for your team.","btnText":"Request Demo","btnUrl":"/demo","designerAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Every Media Type, One Library","description":"Upload images, video (including H.265 and HLS streams), PDFs, PowerPoint files, and audio to a centralised media library. Tag, organise, and reuse assets across layouts and playlists. Set expiration dates on media so outdated content removes itself automatically. Need polished creative? Our in-house team handles photography, video production, and graphic design.","btnText":"Creative Services","btnUrl":"/design","reversed":true} /-->
<!-- wp:oribi/platform-row {"heading":"Every Media Type, One Library","description":"Upload images, video (including H.265 and HLS streams), PDFs, PowerPoint files, and audio to a centralised media library. Tag, organise, and reuse assets across layouts and playlists. Set expiration dates on media so outdated content removes itself automatically. Need polished creative? Our in-house team handles photography, video production, and graphic design.","btnText":"Creative Services","btnUrl":"/design","reversed":true,"mediaLibraryAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Publish Without the Wait","description":"Content goes live the moment you hit publish. A draft/publish workflow lets you edit layouts safely without affecting what's already on screen - then push updates across your entire network in one click. Schedule a layout to auto-publish at a specific date and time, or push it immediately. No queues, no approval chains, no delays.","btnUrl":"/pricing"} /-->
<!-- wp:oribi/platform-row {"heading":"Publish Without the Wait","description":"Content goes live the moment you hit publish. A draft/publish workflow lets you edit layouts safely without affecting what's already on screen - then push updates across your entire network in one click. Schedule a layout to auto-publish at a specific date and time, or push it immediately. No queues, no approval chains, no delays.","btnUrl":"/pricing","publishAnim":true} /-->
<!-- /wp:oribi/platform-section -->
<!-- wp:oribi/feature-section {"variant":"alt","label":"Smart Scheduling","heading":"Automate Your Entire Schedule","lead":"Set it once and let the platform handle the rest. Day-parting, recurring events, location-based triggers, and weather-driven rules keep the right content on the right screen at the right time."} -->
@@ -27,11 +27,11 @@ return <<<'ORIBI_SYNC_CONTENT'
<!-- /wp:oribi/feature-section -->
<!-- wp:oribi/platform-section {"label":"Display Management","heading":"One Dashboard for Every Screen","lead":"Group, monitor, and control your entire display network - whether that's three screens in one venue or three hundred across the country."} -->
<!-- wp:oribi/platform-row {"heading":"Group, Target, Update","description":"Organise displays into groups by location, department, or purpose. Use dynamic groups that auto-populate based on tags or criteria. Push a content update to one screen, a group, or your whole network - all from one place. Nested groups let you build multi-level hierarchies that mirror your real-world structure.","btnText":"View Devices","btnUrl":"/devices"} /-->
<!-- wp:oribi/platform-row {"heading":"Group, Target, Update","description":"Organise displays into groups by location, department, or purpose. Use dynamic groups that auto-populate based on tags or criteria. Push a content update to one screen, a group, or your whole network - all from one place. Nested groups let you build multi-level hierarchies that mirror your real-world structure.","btnText":"View Devices","btnUrl":"/devices","screenGroupsAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Monitor \u0026amp; Control Remotely","description":"See which screens are online at a glance. Take on-demand or periodic screenshots to verify content is playing correctly. Control screen power, volume, and brightness remotely. Get email alerts the moment a player goes offline. Map view shows every display's location so you always know what's where.","btnUrl":"/contact","reversed":true} /-->
<!-- wp:oribi/platform-row {"heading":"Monitor \u0026amp; Control Remotely","description":"See which screens are online at a glance. Take on-demand or periodic screenshots to verify content is playing correctly. Control screen power, volume, and brightness remotely. Get email alerts the moment a player goes offline. Map view shows every display's location so you always know what's where.","btnUrl":"/contact","reversed":true,"monitoringAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Runs on Your Hardware","description":"Our player software runs on Android, Windows, Samsung Tizen, LG webOS, ChromeOS, and Amazon Fire. Portrait or landscape. Single screen or synchronised video wall. Content is cached locally, so your displays keep running seamlessly even when the internet drops. Already have compatible hardware? Use our BYO option at the same per-screen rate — set it up yourself or let our team handle it for a one-time $99 setup fee.","btnText":"See Devices &amp; BYO","btnUrl":"/devices"} /-->
<!-- wp:oribi/platform-row {"heading":"Runs on Your Hardware","description":"Our player software runs on Android, Windows, Samsung Tizen, LG webOS, ChromeOS, and Amazon Fire. Portrait or landscape. Single screen or synchronised video wall. Content is cached locally, so your displays keep running seamlessly even when the internet drops. Already have compatible hardware? Use our BYO option at the same per-screen rate — set it up yourself or let our team handle it for a one-time $99 setup fee.","btnText":"See Devices &amp; BYO","btnUrl":"/devices","deviceAnim":true} /-->
<!-- /wp:oribi/platform-section -->
<!-- wp:oribi/feature-section {"variant":"alt","label":"Content Toolkit","heading":"Connect Your World to Screen","lead":"Pull in live data, social feeds, menus, dashboards, and third-party content. Everything updates automatically - no manual refreshing, no extra steps.","columns":3} -->

View File

@@ -10,9 +10,9 @@
<!-- wp:oribi/page-hero-animated {"label":"Fitness &amp; Leisure Signage","title":"Energise Your Facility with Digital Screens","description":"Class timetables, motivational content, live performance metrics, and promotional offers - on screens throughout gyms, leisure centres, and sports facilities."} /-->
<!-- wp:oribi/platform-section {"label":"Capabilities","heading":"Signage That Moves with Your Members","lead":"Keep members informed, motivated, and engaged from the moment they walk through the door."} -->
<!-- wp:oribi/platform-row {"heading":"Class Timetables &amp; Schedules","description":"Display live class schedules, instructor details, and room assignments on screens at reception, in corridors, and near studios. When classes change or get cancelled, the timetable updates instantly - no reprinting, no crossed-out posters, no confusion at the front desk.","btnText":"See Features","btnUrl":"/features"} /-->
<!-- wp:oribi/platform-row {"heading":"Motivational &amp; Ambient Content","description":"Energise workout areas with high-impact visuals, training tips, member achievements, and challenge leaderboards. Multi-zone layouts let you show live TV alongside class schedules and branded content simultaneously - keeping the energy high without sacrificing information.","btnText":"See Pricing","btnUrl":"/pricing","reversed":true} /-->
<!-- wp:oribi/platform-row {"heading":"Membership &amp; Promotional Offers","description":"Promote new memberships, personal training packages, retail products, and upcoming events on screens at reception and in changing areas. Schedule promotional content around peak sign-up periods - January campaigns, summer offers, and back-to-school deals run automatically.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
<!-- wp:oribi/platform-row {"heading":"Class Timetables &amp; Schedules","description":"Display live class schedules, instructor details, and room assignments on screens at reception, in corridors, and near studios. When classes change or get cancelled, the timetable updates instantly - no reprinting, no crossed-out posters, no confusion at the front desk.","btnText":"See Features","btnUrl":"/features","fitnessAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Motivational &amp; Ambient Content","description":"Energise workout areas with high-impact visuals, training tips, member achievements, and challenge leaderboards. Multi-zone layouts let you show live TV alongside class schedules and branded content simultaneously - keeping the energy high without sacrificing information.","btnText":"See Pricing","btnUrl":"/pricing","reversed":true,"multiZoneAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Membership &amp; Promotional Offers","description":"Promote new memberships, personal training packages, retail products, and upcoming events on screens at reception and in changing areas. Schedule promotional content around peak sign-up periods - January campaigns, summer offers, and back-to-school deals run automatically.","btnText":"Get a Quote","btnUrl":"/contact","membershipAnim":true} /-->
<!-- /wp:oribi/platform-section -->
<!-- wp:oribi/feature-section {"variant":"alt","label":"Use Cases","heading":"Screens for Every Facility","lead":"From boutique studios to multi-site leisure chains, digital signage works across every fitness environment.","columns":3} -->

View File

@@ -10,9 +10,9 @@
<!-- wp:oribi/page-hero-animated {"label":"Healthcare Signage","title":"Better Communication, Better Patient Experience","description":"Queue management, patient wayfinding, waiting room displays, and public health messaging - centrally managed across clinics, hospitals, and multi-site health networks."} /-->
<!-- wp:oribi/platform-section {"label":"Capabilities","heading":"Signage Designed for Healthcare Environments","lead":"Reduce anxiety, improve navigation, and streamline patient flow with screens in every area of your facility."} -->
<!-- wp:oribi/platform-row {"heading":"Queue Management Displays","description":"Show real-time queue positions, estimated wait times, and 'now serving' notifications on waiting room screens. Patients know exactly where they stand - reducing anxiety, reception desk enquiries, and perceived wait times. Integrate with your appointment or ticket system for fully automated updates.","btnText":"See Features","btnUrl":"/features"} /-->
<!-- wp:oribi/platform-row {"heading":"Patient Wayfinding","description":"Guide patients, visitors, and staff through complex hospital layouts with interactive directory kiosks and static wayfinding screens. Touchscreen search lets users find departments, wards, consultants, and facilities by name - essential for large hospitals and multi-building campuses.","btnText":"See Kiosks","btnUrl":"/kiosks","reversed":true} /-->
<!-- wp:oribi/platform-row {"heading":"Waiting Room Information","description":"Keep patients informed and engaged with health education content, appointment reminders, facility information, and real-time wait updates. Replace outdated poster racks and leaflet stands with screens that always show current, relevant information - managed centrally and updated instantly.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
<!-- wp:oribi/platform-row {"heading":"Queue Management Displays","description":"Show real-time queue positions, estimated wait times, and 'now serving' notifications on waiting room screens. Patients know exactly where they stand - reducing anxiety, reception desk enquiries, and perceived wait times. Integrate with your appointment or ticket system for fully automated updates.","btnText":"See Features","btnUrl":"/features","healthcareAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Patient Wayfinding","description":"Guide patients, visitors, and staff through complex hospital layouts with interactive directory kiosks and static wayfinding screens. Touchscreen search lets users find departments, wards, consultants, and facilities by name - essential for large hospitals and multi-building campuses.","btnText":"See Kiosks","btnUrl":"/kiosks","reversed":true,"patientWayfindAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Waiting Room Information","description":"Keep patients informed and engaged with health education content, appointment reminders, facility information, and real-time wait updates. Replace outdated poster racks and leaflet stands with screens that always show current, relevant information - managed centrally and updated instantly.","btnText":"Get a Quote","btnUrl":"/contact","waitingRoomAnim":true} /-->
<!-- /wp:oribi/platform-section -->
<!-- wp:oribi/feature-section {"variant":"alt","label":"Use Cases","heading":"Screens Across Healthcare","lead":"From GP surgeries to major hospitals, digital signage improves communication at every patient touchpoint.","columns":3} -->

View File

@@ -11,8 +11,8 @@
<!-- wp:oribi/platform-section {"label":"Capabilities","heading":"Signage Designed for Guest-Facing Environments","lead":"From the front desk to the restaurant floor, digital signage keeps guests informed, engaged, and spending."} -->
<!-- wp:oribi/platform-row {"heading":"Digital Menu Boards","description":"Sync with your POS system so prices, items, and availability update automatically. Schedule breakfast, lunch, and dinner menus with day-parting. Highlight daily specials, allergen information, and seasonal promotions - all without reprinting a single card. Multi-language support lets you switch menus for international guests automatically.","btnText":"See Features","btnUrl":"/features","galleryIds":[418,417]} /-->
<!-- wp:oribi/platform-row {"heading":"Lobby &amp; Reception Displays","description":"Welcome guests by name, showcase local attractions, promote on-site amenities, and display live event schedules. First impressions matter - and a polished digital lobby creates a modern, professional atmosphere that sets the tone for the entire stay.","btnText":"See Pricing","btnUrl":"/pricing","reversed":true} /-->
<!-- wp:oribi/platform-row {"heading":"Conference &amp; Event Signage","description":"Display meeting room schedules, event agendas, and directional wayfinding for conference centres and function rooms. Update in real time when sessions change or rooms are reassigned - no more handwritten signs or outdated printed schedules outside meeting rooms.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
<!-- wp:oribi/platform-row {"heading":"Lobby &amp; Reception Displays","description":"Welcome guests by name, showcase local attractions, promote on-site amenities, and display live event schedules. First impressions matter - and a polished digital lobby creates a modern, professional atmosphere that sets the tone for the entire stay.","btnText":"See Pricing","btnUrl":"/pricing","reversed":true,"lobbyAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Conference &amp; Event Signage","description":"Display meeting room schedules, event agendas, and directional wayfinding for conference centres and function rooms. Update in real time when sessions change or rooms are reassigned - no more handwritten signs or outdated printed schedules outside meeting rooms.","btnText":"Get a Quote","btnUrl":"/contact","conferenceAnim":true} /-->
<!-- /wp:oribi/platform-section -->
<!-- wp:oribi/feature-section {"variant":"alt","label":"Use Cases","heading":"Screens in Every Space","lead":"Hotels, restaurants, bars, and venues use digital signage differently. Here's how hospitality businesses put screens to work.","columns":3} -->

View File

@@ -10,9 +10,9 @@
<!-- wp:oribi/page-hero-animated {"label":"Outdoor Signage","title":"Digital Displays Built for the Elements","description":"Weather-resistant hardware, high-brightness panels, and cellular connectivity \u2014 professional outdoor signage that performs rain or shine, day or night."} /-->
<!-- wp:oribi/platform-section {"label":"Outdoor Solutions","heading":"Reliable Signage in Any Environment","lead":"From forecourts and market squares to transport stops and building exteriors \u2014 our outdoor hardware is engineered for year-round operation."} -->
<!-- wp:oribi/platform-row {"heading":"Weather-Resistant Enclosures","description":"IP-rated enclosures protect player hardware from rain, dust, humidity, and temperature extremes. Designed for permanent outdoor deployment with ventilation, heating, and cooling systems that keep the electronics running in conditions from -20\u00b0C to 50\u00b0C. Available for a range of display sizes from 32 to 75 inches.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
<!-- wp:oribi/platform-row {"heading":"High-Brightness Displays","description":"Standard indoor screens wash out in daylight. Our outdoor panels deliver 2,500+ nit brightness \u2014 ensuring content remains vivid and readable even in direct sunlight. Anti-glare and anti-reflective coatings further enhance visibility for drive-by and pedestrian audiences.","btnText":"View Devices","btnUrl":"/devices","reversed":true} /-->
<!-- wp:oribi/platform-row {"heading":"Connectivity Anywhere","description":"No Wi-Fi? No problem. An optional 4G/5G cellular module gives your outdoor displays a dedicated connection independent of on-site infrastructure. Combined with offline playback and local content caching, your screens stay live even in the most remote locations.","btnText":"See Features","btnUrl":"/features"} /-->
<!-- wp:oribi/platform-row {"heading":"Weather-Resistant Enclosures","description":"IP-rated enclosures protect player hardware from rain, dust, humidity, and temperature extremes. Designed for permanent outdoor deployment with ventilation, heating, and cooling systems that keep the electronics running in conditions from -20\u00b0C to 50\u00b0C. Available for a range of display sizes from 32 to 75 inches.","btnText":"Get a Quote","btnUrl":"/contact","enclosureAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"High-Brightness Displays","description":"Standard indoor screens wash out in daylight. Our outdoor panels deliver 2,500+ nit brightness \u2014 ensuring content remains vivid and readable even in direct sunlight. Anti-glare and anti-reflective coatings further enhance visibility for drive-by and pedestrian audiences.","btnText":"View Devices","btnUrl":"/devices","reversed":true,"brightnessAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Connectivity Anywhere","description":"No Wi-Fi? No problem. An optional 4G/5G cellular module gives your outdoor displays a dedicated connection independent of on-site infrastructure. Combined with offline playback and local content caching, your screens stay live even in the most remote locations.","btnText":"See Features","btnUrl":"/features","cellularAnim":true} /-->
<!-- /wp:oribi/platform-section -->
<!-- wp:oribi/feature-section {"variant":"alt","label":"Smart Content","heading":"Content That Responds to the Weather","lead":"Outdoor signage works best when it reacts to real-world conditions. Our Pro plan includes intelligent scheduling features designed for outdoor environments.","columns":3} -->

View File

@@ -10,9 +10,9 @@
<!-- wp:oribi/page-hero-animated {"label":"Retail Signage","title":"Turn Footfall into Revenue","description":"Promotional displays, in-store wayfinding, and digital price tags - all managed centrally across every location from one platform."} /-->
<!-- wp:oribi/platform-section {"label":"Capabilities","heading":"Signage That Sells","lead":"Digital signage gives retailers the tools to influence purchasing decisions at the point of sale - instantly and at scale."} -->
<!-- wp:oribi/platform-row {"heading":"Promotional Displays","description":"Launch flash sales, seasonal campaigns, and product spotlights across every store simultaneously. Schedule promotions in advance and let them go live automatically. Day-parting lets you show breakfast offers in the morning and evening deals after 5 pm - matching your messaging to customer behaviour throughout the day.","btnText":"See Features","btnUrl":"/features"} /-->
<!-- wp:oribi/platform-row {"heading":"In-Store Wayfinding","description":"Guide customers through large-format stores, shopping centres, and department stores with interactive directories and aisle-level navigation. Reduce 'where is it?' questions for staff and help shoppers find what they need faster - increasing basket size and reducing frustration.","btnText":"See Kiosks","btnUrl":"/kiosks","reversed":true} /-->
<!-- wp:oribi/platform-row {"heading":"Window &amp; Storefront Displays","description":"High-brightness screens in shop windows attract passing foot traffic with dynamic, attention-grabbing content. Rotate promotions automatically, display opening hours, and showcase new arrivals - replacing static window posters that go stale within days.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
<!-- wp:oribi/platform-row {"heading":"Promotional Displays","description":"Launch flash sales, seasonal campaigns, and product spotlights across every store simultaneously. Schedule promotions in advance and let them go live automatically. Day-parting lets you show breakfast offers in the morning and evening deals after 5 pm - matching your messaging to customer behaviour throughout the day.","btnText":"See Features","btnUrl":"/features","dayPartAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"In-Store Wayfinding","description":"Guide customers through large-format stores, shopping centres, and department stores with interactive directories and aisle-level navigation. Reduce 'where is it?' questions for staff and help shoppers find what they need faster - increasing basket size and reducing frustration.","btnText":"See Kiosks","btnUrl":"/kiosks","reversed":true,"wayfindAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Window &amp; Storefront Displays","description":"High-brightness screens in shop windows attract passing foot traffic with dynamic, attention-grabbing content. Rotate promotions automatically, display opening hours, and showcase new arrivals - replacing static window posters that go stale within days.","btnText":"Get a Quote","btnUrl":"/contact","storefrontAnim":true} /-->
<!-- /wp:oribi/platform-section -->
<!-- wp:oribi/feature-section {"variant":"alt","label":"Use Cases","heading":"Screens That Drive Sales","lead":"From boutiques to big-box stores, digital signage works in every retail format.","columns":3} -->

File diff suppressed because it is too large Load Diff

View File

@@ -289,3 +289,66 @@
boot();
}
})();
/* ── 3. Day-Part Clock Animator ────────────────────────────────────────── */
(function () {
'use strict';
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
function initDaypart(stage) {
var clockEl = stage.querySelector('[data-daypart-clock]');
var badgeEl = stage.querySelector('[data-daypart-badge]');
if (!clockEl || !badgeEl) return;
var visible = true;
var observer = new IntersectionObserver(function (entries) {
visible = entries[0].isIntersecting;
}, { threshold: 0.1 });
observer.observe(stage);
var simHour = 7;
var simMin = 0;
var parts = ['Morning', 'Afternoon', 'Evening'];
function pad(n) { return n < 10 ? '0' + n : '' + n; }
function tick() {
if (!visible) { requestAnimationFrame(tick); return; }
simMin += 1;
if (simMin >= 60) { simMin = 0; simHour = (simHour + 1) % 24; }
var displayHour = simHour % 12 || 12;
var ampm = simHour < 12 ? 'AM' : 'PM';
clockEl.textContent = displayHour + ':' + pad(simMin) + ' ' + ampm;
if (simHour >= 5 && simHour < 12) {
badgeEl.textContent = parts[0];
} else if (simHour >= 12 && simHour < 17) {
badgeEl.textContent = parts[1];
} else {
badgeEl.textContent = parts[2];
}
requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
}
function boot() {
var stages = document.querySelectorAll('.daypart-stage');
for (var i = 0; i < stages.length; i++) {
if (stages[i]._daypartAnim) continue;
stages[i]._daypartAnim = true;
initDaypart(stages[i]);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
})();

View File

@@ -585,6 +585,26 @@ add_action('init', function () {
'healthcareAnim' => ['type' => 'boolean', 'default' => false],
'transitAnim' => ['type' => 'boolean', 'default' => false],
'fitnessAnim' => ['type' => 'boolean', 'default' => false],
'lobbyAnim' => ['type' => 'boolean', 'default' => false],
'conferenceAnim' => ['type' => 'boolean', 'default' => false],
'dayPartAnim' => ['type' => 'boolean', 'default' => false],
'wayfindAnim' => ['type' => 'boolean', 'default' => false],
'storefrontAnim' => ['type' => 'boolean', 'default' => false],
'announcementAnim' => ['type' => 'boolean', 'default' => false],
'campusWayfindAnim' => ['type' => 'boolean', 'default' => false],
'emergencyAnim' => ['type' => 'boolean', 'default' => false],
'enclosureAnim' => ['type' => 'boolean', 'default' => false],
'brightnessAnim' => ['type' => 'boolean', 'default' => false],
'cellularAnim' => ['type' => 'boolean', 'default' => false],
'designerAnim' => ['type' => 'boolean', 'default' => false],
'mediaLibraryAnim' => ['type' => 'boolean', 'default' => false],
'publishAnim' => ['type' => 'boolean', 'default' => false],
'screenGroupsAnim' => ['type' => 'boolean', 'default' => false],
'monitoringAnim' => ['type' => 'boolean', 'default' => false],
'patientWayfindAnim' => ['type' => 'boolean', 'default' => false],
'waitingRoomAnim' => ['type' => 'boolean', 'default' => false],
'multiZoneAnim' => ['type' => 'boolean', 'default' => false],
'membershipAnim' => ['type' => 'boolean', 'default' => false],
'galleryIds' => ['type' => 'array', 'default' => [], 'items' => ['type' => 'number']],
],
'supports' => $block_supports,
@@ -2420,6 +2440,354 @@ function oribi_render_platform_row($a)
$visual_html = $fa;
$visual_cls = 'platform-visual has-fitness';
}
elseif (!empty($a['lobbyAnim'])) {
/* ── Hotel Lobby Welcome Display ── */
$lb = '<div class="lobby-stage" aria-hidden="true">';
$lb .= '<div class="lobby-screen">';
$lb .= '<div class="lobby-hdr"><span class="lobby-hdr__logo">&#9670; Grand Hotel</span><span class="lobby-hdr__time">3:42 PM</span></div>';
$lb .= '<div class="lobby-slides">';
$lb .= '<div class="lobby-slide lobby-slide--welcome"><div class="lobby-welcome__msg">Welcome</div><div class="lobby-welcome__sub">We hope you enjoy your stay</div></div>';
$lb .= '<div class="lobby-slide lobby-slide--amenities"><div class="lobby-amen__title">Hotel Amenities</div><div class="lobby-amen__grid"><div class="lobby-amen__item">&#9737; Pool</div><div class="lobby-amen__item">&#9883; Spa</div><div class="lobby-amen__item">&#9832; Restaurant</div><div class="lobby-amen__item">&#8982; Gym</div></div></div>';
$lb .= '<div class="lobby-slide lobby-slide--events"><div class="lobby-events__title">Today\'s Events</div><div class="lobby-events__list"><div class="lobby-events__item"><span class="lobby-events__time">10:00</span><span class="lobby-events__name">Yoga on the Terrace</span></div><div class="lobby-events__item"><span class="lobby-events__time">14:00</span><span class="lobby-events__name">Wine Tasting</span></div><div class="lobby-events__item"><span class="lobby-events__time">19:00</span><span class="lobby-events__name">Live Jazz — Lobby Bar</span></div></div></div>';
$lb .= '</div>';
$lb .= '<div class="lobby-wifi">Wi-Fi: <strong>GrandGuest</strong></div>';
$lb .= '</div>';
$lb .= '</div>';
$visual_html = $lb;
$visual_cls = 'platform-visual has-lobby';
}
elseif (!empty($a['conferenceAnim'])) {
/* ── Conference Room Door Panel ── */
$cf = '<div class="conf-stage" aria-hidden="true">';
$cf .= '<div class="conf-panel">';
$cf .= '<div class="conf-panel__room">Boardroom A</div>';
$cf .= '<div class="conf-panel__status"><span class="conf-status__dot"></span>In Use</div>';
$cf .= '<div class="conf-panel__current"><div class="conf-current__label">Current Session</div><div class="conf-current__title">Q1 Strategy Review</div><div class="conf-current__meta">09:00 10:30 &nbsp;·&nbsp; Sarah Mitchell</div></div>';
$cf .= '<div class="conf-panel__timeline">';
$cf .= '<div class="conf-tl__bar"><div class="conf-tl__fill"></div></div>';
$cf .= '</div>';
$cf .= '<div class="conf-panel__next"><span class="conf-next__label">Next:</span> <span class="conf-next__title">Design Sprint Kickoff</span> <span class="conf-next__time">11:00</span></div>';
$cf .= '</div>';
$cf .= '</div>';
$visual_html = $cf;
$visual_cls = 'platform-visual has-conference';
}
elseif (!empty($a['dayPartAnim'])) {
/* ── Day-Part Retail Promo Display (JS-driven clock) ── */
$dp = '<div class="daypart-stage" aria-hidden="true">';
$dp .= '<div class="daypart-screen">';
$dp .= '<div class="daypart-hdr"><span class="daypart-hdr__clock" data-daypart-clock>12:00</span><span class="daypart-hdr__badge" data-daypart-badge>Afternoon</span></div>';
$dp .= '<div class="daypart-slides">';
$dp .= '<div class="daypart-slide daypart-slide--morning"><div class="daypart-promo__tag">Morning</div><div class="daypart-promo__title">Breakfast Deals</div><div class="daypart-promo__sub">Fresh pastries &amp; coffee combos from $4.99</div></div>';
$dp .= '<div class="daypart-slide daypart-slide--afternoon"><div class="daypart-promo__tag">Afternoon</div><div class="daypart-promo__title">Lunch Specials</div><div class="daypart-promo__sub">Meal deals &amp; combo offers until 4 PM</div></div>';
$dp .= '<div class="daypart-slide daypart-slide--evening"><div class="daypart-promo__tag">Evening</div><div class="daypart-promo__title">Happy Hour</div><div class="daypart-promo__sub">2-for-1 drinks &amp; 20% off appetisers</div></div>';
$dp .= '</div>';
$dp .= '</div>';
$dp .= '</div>';
$visual_html = $dp;
$visual_cls = 'platform-visual has-daypart';
}
elseif (!empty($a['wayfindAnim'])) {
/* ── In-Store Wayfinding Kiosk ── */
$wf = '<div class="wayfind-stage" aria-hidden="true">';
$wf .= '<div class="wayfind-kiosk">';
$wf .= '<div class="wayfind-kiosk__search"><span class="wayfind-search__icon">&#128269;</span><span class="wayfind-search__text">Search departments...</span></div>';
$wf .= '<div class="wayfind-kiosk__map">';
$wf .= '<div class="wayfind-zone wayfind-zone--a">Fashion</div>';
$wf .= '<div class="wayfind-zone wayfind-zone--b">Electronics</div>';
$wf .= '<div class="wayfind-zone wayfind-zone--c">Home</div>';
$wf .= '<div class="wayfind-zone wayfind-zone--d">Food Hall</div>';
$wf .= '<div class="wayfind-pin"><span class="wayfind-pin__dot"></span><span class="wayfind-pin__label">You are here</span></div>';
$wf .= '</div>';
$wf .= '<div class="wayfind-kiosk__dir">';
$wf .= '<div class="wayfind-dir__item"><span class="wayfind-dir__arrow">&#8593;</span> Fashion — Level 1</div>';
$wf .= '<div class="wayfind-dir__item"><span class="wayfind-dir__arrow">&#8594;</span> Electronics — Level 2</div>';
$wf .= '<div class="wayfind-dir__item"><span class="wayfind-dir__arrow">&#8595;</span> Food Hall — Ground</div>';
$wf .= '</div>';
$wf .= '</div>';
$wf .= '</div>';
$visual_html = $wf;
$visual_cls = 'platform-visual has-wayfind';
}
elseif (!empty($a['storefrontAnim'])) {
/* ── Window / Storefront Display ── */
$sf = '<div class="store-stage" aria-hidden="true">';
$sf .= '<div class="store-window">';
$sf .= '<div class="store-window__sun"></div>';
$sf .= '<div class="store-window__screen">';
$sf .= '<div class="store-slides">';
$sf .= '<div class="store-slide store-slide--new"><div class="store-slide__tag">New Arrivals</div><div class="store-slide__title">Spring Collection</div><div class="store-slide__cta">Shop Now &#8594;</div></div>';
$sf .= '<div class="store-slide store-slide--sale"><div class="store-slide__tag">Limited Time</div><div class="store-slide__title">Up to 50% Off</div><div class="store-slide__cta">View Offers &#8594;</div></div>';
$sf .= '<div class="store-slide store-slide--hours"><div class="store-slide__tag">Opening Hours</div><div class="store-slide__title">MonSat 9am9pm</div><div class="store-slide__sub">Sunday 10am6pm</div></div>';
$sf .= '</div>';
$sf .= '</div>';
$sf .= '<div class="store-window__glare"></div>';
$sf .= '</div>';
$sf .= '</div>';
$visual_html = $sf;
$visual_cls = 'platform-visual has-storefront';
}
elseif (!empty($a['announcementAnim'])) {
/* ── Corporate Announcement Board ── */
$an = '<div class="announce-stage" aria-hidden="true">';
$an .= '<div class="announce-board">';
$an .= '<div class="announce-hdr"><span class="announce-hdr__title">Company Updates</span><span class="announce-hdr__live">&#9679; Live</span></div>';
$an .= '<div class="announce-cards">';
$an .= '<div class="announce-card announce-card--urgent"><div class="announce-card__badge">Urgent</div><div class="announce-card__title">Fire Drill — 2 PM Today</div><div class="announce-card__body">All staff evacuate via nearest exit. Assembly point: Car Park B.</div></div>';
$an .= '<div class="announce-card announce-card--celebration"><div class="announce-card__badge">Celebration</div><div class="announce-card__title">Welcome New Starters!</div><div class="announce-card__body">Say hello to 5 new team members joining Engineering &amp; Design.</div></div>';
$an .= '<div class="announce-card announce-card--hr"><div class="announce-card__badge">HR Notice</div><div class="announce-card__title">Benefits Enrolment Open</div><div class="announce-card__body">Deadline: March 31. Visit the HR portal to review your options.</div></div>';
$an .= '</div>';
$an .= '</div>';
$an .= '</div>';
$visual_html = $an;
$visual_cls = 'platform-visual has-announcement';
}
elseif (!empty($a['campusWayfindAnim'])) {
/* ── Campus Wayfinding Kiosk ── */
$cw = '<div class="campus-stage" aria-hidden="true">';
$cw .= '<div class="campus-kiosk">';
$cw .= '<div class="campus-kiosk__hdr">Campus Directory</div>';
$cw .= '<div class="campus-kiosk__search"><span class="campus-search__icon">&#128269;</span><span class="campus-search__text">Find a building...</span></div>';
$cw .= '<div class="campus-kiosk__map">';
$cw .= '<div class="campus-bldg campus-bldg--lib">Library</div>';
$cw .= '<div class="campus-bldg campus-bldg--sci">Science</div>';
$cw .= '<div class="campus-bldg campus-bldg--arts">Arts</div>';
$cw .= '<div class="campus-bldg campus-bldg--sports">Sports</div>';
$cw .= '<div class="campus-pin"><span class="campus-pin__dot"></span></div>';
$cw .= '</div>';
$cw .= '<div class="campus-kiosk__legend"><span class="campus-legend__dot campus-legend__dot--you"></span> You are here</div>';
$cw .= '</div>';
$cw .= '</div>';
$visual_html = $cw;
$visual_cls = 'platform-visual has-campus-wayfind';
}
elseif (!empty($a['emergencyAnim'])) {
/* ── Emergency Override Alert ── */
$em = '<div class="emerg-stage" aria-hidden="true">';
$em .= '<div class="emerg-screen">';
$em .= '<div class="emerg-screen__normal">';
$em .= '<div class="emerg-normal__hdr">Campus Notices</div>';
$em .= '<div class="emerg-normal__item">Library open until 10 PM</div>';
$em .= '<div class="emerg-normal__item">Café special: Flat white $3</div>';
$em .= '</div>';
$em .= '<div class="emerg-screen__alert">';
$em .= '<div class="emerg-alert__icon">&#9888;</div>';
$em .= '<div class="emerg-alert__title">EMERGENCY ALERT</div>';
$em .= '<div class="emerg-alert__msg">Building lockdown in effect. Remain indoors. Follow staff instructions.</div>';
$em .= '<div class="emerg-alert__pulse"></div>';
$em .= '</div>';
$em .= '</div>';
$em .= '</div>';
$visual_html = $em;
$visual_cls = 'platform-visual has-emergency';
}
elseif (!empty($a['enclosureAnim'])) {
/* ── Outdoor Weather-Resistant Enclosure ── */
$en = '<div class="encl-stage" aria-hidden="true">';
$en .= '<div class="encl-rain">';
for ($i = 0; $i < 12; $i++) {
$en .= '<div class="encl-rain__drop"></div>';
}
$en .= '</div>';
$en .= '<div class="encl-unit">';
$en .= '<div class="encl-unit__body">';
$en .= '<div class="encl-unit__screen"><div class="encl-screen__content">Your Content Here</div></div>';
$en .= '</div>';
$en .= '<div class="encl-unit__badge">IP65</div>';
$en .= '<div class="encl-unit__temp"><span class="encl-temp__icon">&#127777;</span> <span class="encl-temp__range">-20°C to 50°C</span></div>';
$en .= '</div>';
$en .= '</div>';
$visual_html = $en;
$visual_cls = 'platform-visual has-enclosure';
}
elseif (!empty($a['brightnessAnim'])) {
/* ── High-Brightness Comparison ── */
$br = '<div class="bright-stage" aria-hidden="true">';
$br .= '<div class="bright-sun"></div>';
$br .= '<div class="bright-compare">';
$br .= '<div class="bright-panel bright-panel--indoor"><div class="bright-panel__screen bright-panel__screen--dim"><span class="bright-panel__text">Hello World</span></div><div class="bright-panel__label">Indoor 350 nits</div></div>';
$br .= '<div class="bright-vs">vs</div>';
$br .= '<div class="bright-panel bright-panel--outdoor"><div class="bright-panel__screen bright-panel__screen--vivid"><span class="bright-panel__text">Hello World</span></div><div class="bright-panel__label">Outdoor 2,500+ nits</div></div>';
$br .= '</div>';
$br .= '</div>';
$visual_html = $br;
$visual_cls = 'platform-visual has-brightness';
}
elseif (!empty($a['cellularAnim'])) {
/* ── Cellular Connectivity Tower ── */
$cl = '<div class="cell-stage" aria-hidden="true">';
$cl .= '<div class="cell-tower">';
$cl .= '<div class="cell-tower__mast"></div>';
$cl .= '<div class="cell-tower__base"></div>';
$cl .= '<div class="cell-wave cell-wave--1"></div>';
$cl .= '<div class="cell-wave cell-wave--2"></div>';
$cl .= '<div class="cell-wave cell-wave--3"></div>';
$cl .= '</div>';
$cl .= '<div class="cell-badge">4G / 5G</div>';
$cl .= '<div class="cell-signal"><div class="cell-signal__bar cell-signal__bar--1"></div><div class="cell-signal__bar cell-signal__bar--2"></div><div class="cell-signal__bar cell-signal__bar--3"></div><div class="cell-signal__bar cell-signal__bar--4"></div></div>';
$cl .= '<div class="cell-status">Connected &nbsp;&#9679;</div>';
$cl .= '</div>';
$visual_html = $cl;
$visual_cls = 'platform-visual has-cellular';
}
elseif (!empty($a['designerAnim'])) {
/* ── Drag-and-Drop Editor Canvas ── */
$ds = '<div class="designer-stage" aria-hidden="true">';
$ds .= '<div class="designer-editor">';
$ds .= '<div class="designer-toolbar"><span class="designer-tool">T</span><span class="designer-tool">&#9633;</span><span class="designer-tool">&#9654;</span><span class="designer-tool">&#8943;</span></div>';
$ds .= '<div class="designer-canvas">';
$ds .= '<div class="designer-widget designer-widget--text"><span class="designer-widget__label">Heading</span></div>';
$ds .= '<div class="designer-widget designer-widget--img"><span class="designer-widget__label">Image</span></div>';
$ds .= '<div class="designer-widget designer-widget--ticker"><span class="designer-widget__label">Ticker</span></div>';
$ds .= '<div class="designer-widget designer-widget--video"><span class="designer-widget__label">Video</span></div>';
$ds .= '</div>';
$ds .= '<div class="designer-layers"><div class="designer-layers__title">Layers</div><div class="designer-layer">Heading</div><div class="designer-layer">Image</div><div class="designer-layer">Ticker</div><div class="designer-layer">Video</div></div>';
$ds .= '</div>';
$ds .= '</div>';
$visual_html = $ds;
$visual_cls = 'platform-visual has-designer';
}
elseif (!empty($a['mediaLibraryAnim'])) {
/* ── Media Library Grid ── */
$ml = '<div class="medialib-stage" aria-hidden="true">';
$ml .= '<div class="medialib-panel">';
$ml .= '<div class="medialib-hdr"><span class="medialib-hdr__title">Media Library</span><span class="medialib-hdr__count">24 assets</span></div>';
$ml .= '<div class="medialib-grid">';
$ml .= '<div class="medialib-thumb medialib-thumb--img"><span class="medialib-thumb__icon">&#128247;</span></div>';
$ml .= '<div class="medialib-thumb medialib-thumb--vid"><span class="medialib-thumb__icon">&#9654;</span></div>';
$ml .= '<div class="medialib-thumb medialib-thumb--pdf"><span class="medialib-thumb__icon">PDF</span></div>';
$ml .= '<div class="medialib-thumb medialib-thumb--ppt"><span class="medialib-thumb__icon">PPT</span></div>';
$ml .= '<div class="medialib-thumb medialib-thumb--img2"><span class="medialib-thumb__icon">&#128247;</span></div>';
$ml .= '<div class="medialib-thumb medialib-thumb--audio"><span class="medialib-thumb__icon">&#9835;</span></div>';
$ml .= '</div>';
$ml .= '<div class="medialib-upload"><div class="medialib-upload__bar"></div><span class="medialib-upload__text">Uploading...</span></div>';
$ml .= '</div>';
$ml .= '</div>';
$visual_html = $ml;
$visual_cls = 'platform-visual has-media-library';
}
elseif (!empty($a['publishAnim'])) {
/* ── Draft → Publish Workflow ── */
$pb = '<div class="publish-stage" aria-hidden="true">';
$pb .= '<div class="publish-flow">';
$pb .= '<div class="publish-step publish-step--draft"><span class="publish-step__badge">Draft</span><span class="publish-step__label">Edit safely</span></div>';
$pb .= '<div class="publish-arrow">&#8594;</div>';
$pb .= '<div class="publish-step publish-step--review"><span class="publish-step__badge">Review</span><span class="publish-step__label">Preview on screen</span></div>';
$pb .= '<div class="publish-arrow">&#8594;</div>';
$pb .= '<div class="publish-step publish-step--live"><span class="publish-step__badge">Live</span><span class="publish-step__label">Instant publish</span></div>';
$pb .= '</div>';
$pb .= '<div class="publish-bar"><div class="publish-bar__fill"></div></div>';
$pb .= '<div class="publish-status">Publishing to 48 screens...</div>';
$pb .= '</div>';
$visual_html = $pb;
$visual_cls = 'platform-visual has-publish';
}
elseif (!empty($a['screenGroupsAnim'])) {
/* ── Screen Group Hierarchy Tree ── */
$sg = '<div class="groups-stage" aria-hidden="true">';
$sg .= '<div class="groups-tree">';
$sg .= '<div class="groups-node groups-node--root"><span class="groups-node__icon">&#9679;</span><span class="groups-node__name">HQ</span><span class="groups-node__count">48</span></div>';
$sg .= '<div class="groups-branch">';
$sg .= '<div class="groups-node groups-node--region"><span class="groups-node__icon">&#9679;</span><span class="groups-node__name">London</span><span class="groups-node__count">24</span></div>';
$sg .= '<div class="groups-branch groups-branch--deep">';
$sg .= '<div class="groups-node groups-node--site"><span class="groups-node__icon">&#9679;</span><span class="groups-node__name">Oxford St</span><span class="groups-node__count">12</span></div>';
$sg .= '<div class="groups-node groups-node--site"><span class="groups-node__icon">&#9679;</span><span class="groups-node__name">Canary Wharf</span><span class="groups-node__count">12</span></div>';
$sg .= '</div>';
$sg .= '<div class="groups-node groups-node--region"><span class="groups-node__icon">&#9679;</span><span class="groups-node__name">Manchester</span><span class="groups-node__count">24</span></div>';
$sg .= '</div>';
$sg .= '</div>';
$sg .= '<div class="groups-push"><div class="groups-push__ripple"></div><span class="groups-push__label">Push Update</span></div>';
$sg .= '</div>';
$visual_html = $sg;
$visual_cls = 'platform-visual has-screen-groups';
}
elseif (!empty($a['monitoringAnim'])) {
/* ── Remote Monitoring Dashboard ── */
$mo = '<div class="monitor-stage" aria-hidden="true">';
$mo .= '<div class="monitor-dash">';
$mo .= '<div class="monitor-hdr"><span class="monitor-hdr__title">Display Status</span><span class="monitor-hdr__count">48/48 Online</span></div>';
$mo .= '<div class="monitor-grid">';
$mo .= '<div class="monitor-tile monitor-tile--ok"><span class="monitor-tile__dot"></span><span class="monitor-tile__name">Lobby-01</span></div>';
$mo .= '<div class="monitor-tile monitor-tile--ok"><span class="monitor-tile__dot"></span><span class="monitor-tile__name">Lobby-02</span></div>';
$mo .= '<div class="monitor-tile monitor-tile--warn"><span class="monitor-tile__dot"></span><span class="monitor-tile__name">Floor3-01</span></div>';
$mo .= '<div class="monitor-tile monitor-tile--ok"><span class="monitor-tile__dot"></span><span class="monitor-tile__name">Café-01</span></div>';
$mo .= '<div class="monitor-tile monitor-tile--ok"><span class="monitor-tile__dot"></span><span class="monitor-tile__name">Conf-A</span></div>';
$mo .= '<div class="monitor-tile monitor-tile--ok"><span class="monitor-tile__dot"></span><span class="monitor-tile__name">Conf-B</span></div>';
$mo .= '</div>';
$mo .= '<div class="monitor-screenshot"><div class="monitor-screenshot__img"></div><span class="monitor-screenshot__label">Live Screenshot — Lobby-01</span></div>';
$mo .= '</div>';
$mo .= '</div>';
$visual_html = $mo;
$visual_cls = 'platform-visual has-monitoring';
}
elseif (!empty($a['patientWayfindAnim'])) {
/* ── Hospital Patient Wayfinding Kiosk ── */
$pw = '<div class="pwayfind-stage" aria-hidden="true">';
$pw .= '<div class="pwayfind-kiosk">';
$pw .= '<div class="pwayfind-hdr"><span class="pwayfind-hdr__title">Find Department</span><span class="pwayfind-hdr__a11y">&#9855;</span></div>';
$pw .= '<div class="pwayfind-search"><span class="pwayfind-search__icon">&#128269;</span><span class="pwayfind-search__text">Cardiology...</span></div>';
$pw .= '<div class="pwayfind-result">';
$pw .= '<div class="pwayfind-result__dept">Cardiology — Level 3, Wing B</div>';
$pw .= '<div class="pwayfind-result__route"><div class="pwayfind-route__line"></div><div class="pwayfind-route__start">You are here</div><div class="pwayfind-route__end">Cardiology</div></div>';
$pw .= '</div>';
$pw .= '<div class="pwayfind-quick"><span class="pwayfind-quick__item">A&amp;E</span><span class="pwayfind-quick__item">Pharmacy</span><span class="pwayfind-quick__item">Radiology</span></div>';
$pw .= '</div>';
$pw .= '</div>';
$visual_html = $pw;
$visual_cls = 'platform-visual has-patient-wayfind';
}
elseif (!empty($a['waitingRoomAnim'])) {
/* ── Waiting Room Information Display ── */
$wr = '<div class="waitroom-stage" aria-hidden="true">';
$wr .= '<div class="waitroom-tv">';
$wr .= '<div class="waitroom-tv__body">';
$wr .= '<div class="waitroom-tv__screen">';
$wr .= '<div class="waitroom-slides">';
$wr .= '<div class="waitroom-slide waitroom-slide--tips"><div class="waitroom-tips__title">Health Tip</div><div class="waitroom-tips__text">Regular hand washing reduces infection spread by up to 50%</div></div>';
$wr .= '<div class="waitroom-slide waitroom-slide--wait"><div class="waitroom-wait__title">Estimated Wait</div><div class="waitroom-wait__value">~15 min</div><div class="waitroom-wait__queue">Position: 4 of 12</div></div>';
$wr .= '<div class="waitroom-slide waitroom-slide--info"><div class="waitroom-info__title">Facility Hours</div><div class="waitroom-info__text">MonFri: 8am 8pm<br>Sat: 9am 1pm</div></div>';
$wr .= '</div>';
$wr .= '</div>';
$wr .= '</div>';
$wr .= '<div class="waitroom-tv__feet"><div class="waitroom-tv__foot"></div><div class="waitroom-tv__foot"></div></div>';
$wr .= '</div>';
$wr .= '</div>';
$visual_html = $wr;
$visual_cls = 'platform-visual has-waiting-room';
}
elseif (!empty($a['multiZoneAnim'])) {
/* ── Multi-Zone Layout Display ── */
$mz = '<div class="mzone-stage" aria-hidden="true">';
$mz .= '<div class="mzone-tv">';
$mz .= '<div class="mzone-tv__body">';
$mz .= '<div class="mzone-tv__screen">';
$mz .= '<div class="mzone-layout">';
$mz .= '<div class="mzone-main"><div class="mzone-main__label">&#9654; Live TV</div></div>';
$mz .= '<div class="mzone-side"><div class="mzone-side__title">Class Schedule</div><div class="mzone-side__item">10:00 Spin</div><div class="mzone-side__item">11:15 Yoga</div><div class="mzone-side__item">12:30 HIIT</div></div>';
$mz .= '<div class="mzone-ticker">&#9733; Member of the Month: Alex R &nbsp;&nbsp;|&nbsp;&nbsp; Gym closes 10 PM tonight &nbsp;&nbsp;|&nbsp;&nbsp; New PT packages available</div>';
$mz .= '</div>';
$mz .= '</div>';
$mz .= '</div>';
$mz .= '<div class="mzone-tv__feet"><div class="mzone-tv__foot"></div><div class="mzone-tv__foot"></div></div>';
$mz .= '</div>';
$mz .= '</div>';
$visual_html = $mz;
$visual_cls = 'platform-visual has-multi-zone';
}
elseif (!empty($a['membershipAnim'])) {
/* ── Seasonal Membership Promo Cycling ── */
$mb = '<div class="member-stage" aria-hidden="true">';
$mb .= '<div class="member-screen">';
$mb .= '<div class="member-slides">';
$mb .= '<div class="member-slide member-slide--jan"><div class="member-slide__tag">January Offer</div><div class="member-slide__title">New Year, New You</div><div class="member-slide__price">Join from $29/mo</div><div class="member-slide__cta">Sign Up Today &#8594;</div></div>';
$mb .= '<div class="member-slide member-slide--summer"><div class="member-slide__tag">Summer Special</div><div class="member-slide__title">Get Beach Ready</div><div class="member-slide__price">3 months for $79</div><div class="member-slide__cta">Claim Offer &#8594;</div></div>';
$mb .= '<div class="member-slide member-slide--sept"><div class="member-slide__tag">Back to Fitness</div><div class="member-slide__title">Bring a Friend Free</div><div class="member-slide__price">This week only</div><div class="member-slide__cta">Book Now &#8594;</div></div>';
$mb .= '</div>';
$mb .= '</div>';
$mb .= '</div>';
$visual_html = $mb;
$visual_cls = 'platform-visual has-membership';
}
elseif (!empty($a['hospitalityAnim'])) {
/* ── Hospitality Sign: Rotating Menu (Breakfast, Lunch, Dinner) ── */
$ha = '<div class="hosp-stage" aria-hidden="true">';