Enhance Solutions Page and Add Touchscreen Animation

- Updated descriptions for various industry sections on the solutions page to improve clarity and engagement.
- Introduced a new touchscreen display animation in the CSS, enhancing the visual appeal of the kiosks page.
- Modified JavaScript to update train departure data with local destinations, improving relevance for users.
- Added a new toggle for touchscreen display animations in the block editor, allowing for customizable visual effects.
- Updated the rendering logic to include touchscreen animations in the intro section, providing a more interactive experience.
- Made minor text adjustments across various sections for improved readability and consistency.
This commit is contained in:
Matt Batchelder
2026-04-16 22:28:07 -04:00
parent a274a13e94
commit 757c1eb05b
25 changed files with 362 additions and 193 deletions

View File

@@ -12115,6 +12115,196 @@ p:last-child { margin-bottom: 0; }
}
}
/* ═══════════════════════════════════════════════════════════
COMPATIBLE TOUCHSCREEN DISPLAYS ANIMATION
intro-section touchscreenAnim kiosks page
═══════════════════════════════════════════════════════════ */
.about-intro-visual.has-touchscreen-anim {
background: none;
box-shadow: none;
aspect-ratio: unset;
font-size: inherit;
color: inherit;
}
.ts-stage {
width: 100%;
max-width: 380px;
margin: 0 auto;
display: flex;
align-items: flex-end;
justify-content: center;
gap: 1.75rem;
padding: 1.5rem 0;
}
/* ── Panel shell ───────────────────────────────────────────── */
.ts-panel {
display: flex;
flex-direction: column;
align-items: center;
}
/* ── Bezel ─────────────────────────────────────────────────── */
.ts-bezel {
background: #141418;
border-radius: 8px;
padding: 4px;
box-shadow: 0 12px 40px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.04);
position: relative;
}
.ts-bezel--large { width: 152px; height: 210px; }
.ts-bezel--small { width: 96px; height: 126px; }
/* ── Screen ────────────────────────────────────────────────── */
.ts-screen {
width: 100%;
height: 100%;
border-radius: 5px;
background: linear-gradient(160deg, #0c1016 0%, #111827 100%);
position: relative;
overflow: hidden;
padding: 8px;
box-sizing: border-box;
}
/* Subtle scan line */
.ts-screen::after {
content: '';
position: absolute;
left: 0; top: 0; width: 100%; height: 2px;
background: linear-gradient(90deg, transparent, rgba(var(--color-primary-rgb), 0.2), transparent);
animation: ts-scan 5s linear infinite;
pointer-events: none;
}
@keyframes ts-scan {
0% { top: 0; opacity: 0; }
5% { opacity: 1; }
95% { opacity: 1; }
100% { top: 100%; opacity: 0; }
}
/* ── UI chrome ─────────────────────────────────────────────── */
.ts-ui-header {
height: 22px;
background: rgba(var(--color-primary-rgb), 0.25);
border-radius: 4px;
margin-bottom: 8px;
position: relative;
}
.ts-ui-header::before {
content: '';
position: absolute;
left: 6px; top: 7px;
width: 40px; height: 5px;
background: rgba(255,255,255,0.35);
border-radius: 3px;
}
.ts-ui-header--sm { height: 16px; margin-bottom: 6px; }
.ts-ui-header--sm::before { width: 28px; height: 4px; top: 4px; }
.ts-ui-row {
height: 15px;
background: rgba(255,255,255,0.07);
border-radius: 3px;
margin-bottom: 5px;
}
/* rows pulse in sync with the touch ripples */
.ts-ui-row--1 { animation: ts-row-pulse 6s ease-in-out infinite; animation-delay: 0.8s; }
.ts-ui-row--2 { animation: ts-row-pulse 6s ease-in-out infinite; animation-delay: 2.4s; }
.ts-ui-row--3 { animation: ts-row-pulse 6s ease-in-out infinite; animation-delay: 4.0s; }
.ts-ui-row--4 { animation: ts-row-pulse 6s ease-in-out infinite; animation-delay: 5.2s; }
.ts-ui-row--s1 { animation: ts-row-pulse 5s ease-in-out infinite; animation-delay: 1.2s; }
.ts-ui-row--s2 { animation: ts-row-pulse 5s ease-in-out infinite; animation-delay: 2.8s; }
.ts-ui-row--s3 { animation: ts-row-pulse 5s ease-in-out infinite; animation-delay: 4.2s; }
@keyframes ts-row-pulse {
0%, 100% { background: rgba(255,255,255,0.07); }
15%, 28% { background: rgba(var(--color-primary-rgb), 0.28);
box-shadow: 0 0 8px rgba(var(--color-primary-rgb), 0.15); }
}
.ts-ui-btn {
height: 18px;
background: rgba(var(--color-primary-rgb), 0.35);
border-radius: 4px;
margin-top: 8px;
animation: ts-btn-glow 4s ease-in-out infinite;
}
@keyframes ts-btn-glow {
0%, 100% { background: rgba(var(--color-primary-rgb), 0.35); }
50% { background: rgba(var(--color-primary-rgb), 0.6); }
}
/* ── Touch ripples ─────────────────────────────────────────── */
.ts-ripple {
position: absolute;
width: 0; height: 0;
border-radius: 50%;
border: 2px solid rgba(255,255,255,0.55);
transform: translate(-50%, -50%);
pointer-events: none;
opacity: 0;
}
.ts-ripple--a { left: 50%; top: 40%; animation: ts-ripple-expand 6s ease-out infinite; animation-delay: 1.0s; }
.ts-ripple--b { left: 25%; top: 57%; animation: ts-ripple-expand 6s ease-out infinite; animation-delay: 2.6s; }
.ts-ripple--c { left: 68%; top: 72%; animation: ts-ripple-expand 6s ease-out infinite; animation-delay: 4.2s; }
.ts-ripple--d { left: 55%; top: 55%; animation: ts-ripple-expand 5s ease-out infinite; animation-delay: 1.5s; }
@keyframes ts-ripple-expand {
0% { width: 0; height: 0; opacity: 0.9; }
30% { opacity: 0.5; }
100% { width: 52px; height: 52px; opacity: 0; }
}
/* ── Stand (large floor panel) ─────────────────────────────── */
.ts-stand { display: flex; flex-direction: column; align-items: center; }
.ts-stem {
width: 10px; height: 28px;
background: #141418;
border-radius: 0 0 3px 3px;
}
.ts-base {
width: 64px; height: 7px;
background: #141418;
border-radius: 4px;
}
/* ── Feet (small countertop unit) ───────────────────────────── */
.ts-feet { display: flex; justify-content: space-between; width: 56px; }
.ts-foot {
width: 12px; height: 5px;
background: #141418;
border-radius: 0 0 3px 3px;
}
@media (prefers-reduced-motion: reduce) {
.ts-screen::after,
.ts-ripple,
.ts-ui-btn { animation: none; opacity: 1; }
.ts-ui-row { animation: none; background: rgba(255,255,255,0.1) !important; }
.ts-ui-row--1, .ts-ui-row--3, .ts-ui-row--s2 {
background: rgba(var(--color-primary-rgb), 0.22) !important;
}
}
@media (max-width: 480px) {
.ts-stage { gap: 1.25rem; }
.ts-bezel--large { width: 120px; height: 168px; }
.ts-bezel--small { width: 76px; height: 100px; }
}
/* ═══════════════════════════════════════════════════════════
SELF CHECK-IN KIOSK ANIMATION
Used on the kiosks page platform-row selfCheckInAnim

View File

@@ -134,25 +134,25 @@
var DATA_SETS = [
[
{ time: '10:14', dest: 'London Victoria', plat: '2', status: 'On Time', cls: 'on-time' },
{ time: '10:22', dest: 'Brighton', plat: '4', status: 'On Time', cls: 'on-time' },
{ time: '10:31', dest: 'Gatwick Airport', plat: '1', status: 'Delayed', cls: 'delayed' },
{ time: '10:45', dest: 'London Bridge', plat: '3', status: 'On Time', cls: 'on-time' },
{ time: '11:02', dest: 'East Croydon', plat: '2', status: 'On Time', cls: 'on-time' },
{ time: '10:14', dest: 'Saratoga Springs', plat: '2', status: 'On Time', cls: 'on-time' },
{ time: '10:22', dest: 'Schenectady', plat: '4', status: 'On Time', cls: 'on-time' },
{ time: '10:31', dest: 'Albany Airport', plat: '1', status: 'Delayed', cls: 'delayed' },
{ time: '10:45', dest: 'Albany-Rensselaer', plat: '3', status: 'On Time', cls: 'on-time' },
{ time: '11:02', dest: 'Hudson', plat: '2', status: 'On Time', cls: 'on-time' },
],
[
{ time: '10:22', dest: 'Brighton', plat: '4', status: 'On Time', cls: 'on-time' },
{ time: '10:31', dest: 'Gatwick Airport', plat: '1', status: 'Delayed', cls: 'delayed' },
{ time: '10:45', dest: 'London Bridge', plat: '3', status: 'On Time', cls: 'on-time' },
{ time: '11:02', dest: 'East Croydon', plat: '2', status: 'On Time', cls: 'on-time' },
{ time: '11:14', dest: 'London Victoria', plat: '2', status: 'On Time', cls: 'on-time' },
{ time: '10:22', dest: 'Schenectady', plat: '4', status: 'On Time', cls: 'on-time' },
{ time: '10:31', dest: 'Albany Airport', plat: '1', status: 'Delayed', cls: 'delayed' },
{ time: '10:45', dest: 'Albany-Rensselaer', plat: '3', status: 'On Time', cls: 'on-time' },
{ time: '11:02', dest: 'Hudson', plat: '2', status: 'On Time', cls: 'on-time' },
{ time: '11:14', dest: 'Saratoga Springs', plat: '2', status: 'On Time', cls: 'on-time' },
],
[
{ time: '10:31', dest: 'Gatwick Airport', plat: '1', status: 'Delayed', cls: 'delayed' },
{ time: '10:45', dest: 'London Bridge', plat: '3', status: 'On Time', cls: 'on-time' },
{ time: '11:02', dest: 'East Croydon', plat: '2', status: 'On Time', cls: 'on-time' },
{ time: '11:14', dest: 'London Victoria', plat: '2', status: 'On Time', cls: 'on-time' },
{ time: '11:28', dest: 'Three Bridges', plat: '4', status: 'Cancelled', cls: 'cancelled'},
{ time: '10:31', dest: 'Albany Airport', plat: '1', status: 'Delayed', cls: 'delayed' },
{ time: '10:45', dest: 'Albany-Rensselaer', plat: '3', status: 'On Time', cls: 'on-time' },
{ time: '11:02', dest: 'Hudson', plat: '2', status: 'On Time', cls: 'on-time' },
{ time: '11:14', dest: 'Saratoga Springs', plat: '2', status: 'On Time', cls: 'on-time' },
{ time: '11:28', dest: 'Utica', plat: '4', status: 'Cancelled', cls: 'cancelled'},
],
];

View File

@@ -609,6 +609,7 @@
bundleAnim: { type: 'boolean', default: false },
demoAnim: { type: 'boolean', default: false },
featuresAnim: { type: 'boolean', default: false },
touchscreenAnim: { type: 'boolean', default: false },
imgId: { type: 'number', default: 0 },
imgUrl: { type: 'string', default: '' },
imgAlt: { type: 'string', default: '' },
@@ -653,7 +654,8 @@
el(TG, { label: 'Cloud Server Animation', checked: a.cloudAnim, onChange: function (v) { s({ cloudAnim: v }); } }),
el(TG, { label: 'Player + Display Bundle Animation', checked: !!a.bundleAnim, onChange: function (v) { s({ bundleAnim: v }); } }),
el(TG, { label: 'Command Center Demo Animation', checked: !!a.demoAnim, onChange: function (v) { s({ demoAnim: v }); } }),
el(TG, { label: 'Feature Ticker Animation', checked: !!a.featuresAnim, onChange: function (v) { s({ featuresAnim: v }); } })
el(TG, { label: 'Feature Ticker Animation', checked: !!a.featuresAnim, onChange: function (v) { s({ featuresAnim: v }); } }),
el(TG, { label: 'Touchscreen Displays Animation', checked: !!a.touchscreenAnim, onChange: function (v) { s({ touchscreenAnim: v }); } })
),
el(PB, { title: 'Visual Image', initialOpen: false },
el(MUC, null,
@@ -687,7 +689,7 @@
el(RT, { tagName: 'h2', style: { marginBottom: '1.5rem' }, value: a.heading, onChange: function (v) { s({ heading: v }); }, placeholder: 'Heading...' }),
el(RT, { tagName: 'p', className: 'lead', value: a.description, onChange: function (v) { s({ description: v }); }, placeholder: 'Description...' })
),
el('div', { className: 'about-intro-visual' + (a.cloudAnim ? ' has-cloud-anim' : (a.bundleAnim ? ' has-pkg-anim' : (a.demoAnim ? ' has-demo-anim' : (a.featuresAnim ? ' has-features-anim' : (a.imgUrl ? ' has-img' : ''))))), style: a.reversed ? { direction: 'ltr' } : {} }, visualContent)
el('div', { className: 'about-intro-visual' + (a.cloudAnim ? ' has-cloud-anim' : (a.bundleAnim ? ' has-pkg-anim' : (a.demoAnim ? ' has-demo-anim' : (a.featuresAnim ? ' has-features-anim' : (a.touchscreenAnim ? ' has-touchscreen-anim' : (a.imgUrl ? ' has-img' : '')))))), style: a.reversed ? { direction: 'ltr' } : {} }, visualContent)
)
)
)

View File

@@ -343,6 +343,7 @@ add_action('init', function () {
'bundleAnim' => ['type' => 'boolean', 'default' => false],
'demoAnim' => ['type' => 'boolean', 'default' => false],
'featuresAnim' => ['type' => 'boolean', 'default' => false],
'touchscreenAnim' => ['type' => 'boolean', 'default' => false],
'imgId' => ['type' => 'number', 'default' => 0],
'imgUrl' => ['type' => 'string', 'default' => ''],
'imgAlt' => ['type' => 'string', 'default' => ''],
@@ -1015,7 +1016,7 @@ function oribi_render_intro_section($a)
<h2 style="margin-bottom:1.5rem;"><?php echo wp_kses_post($a['heading']); ?></h2>
<p class="lead"><?php echo wp_kses_post($a['description']); ?></p>
</div>
<div class="about-intro-visual<?php if (!empty($a['cloudAnim'])) echo ' has-cloud-anim'; elseif (!empty($a['bundleAnim'])) echo ' has-pkg-anim'; elseif (!empty($a['demoAnim'])) echo ' has-demo-anim'; elseif (!empty($a['featuresAnim'])) echo ' has-features-anim'; ?>"<?php echo $ltr; ?>>
<div class="about-intro-visual<?php if (!empty($a['cloudAnim'])) echo ' has-cloud-anim'; elseif (!empty($a['bundleAnim'])) echo ' has-pkg-anim'; elseif (!empty($a['demoAnim'])) echo ' has-demo-anim'; elseif (!empty($a['featuresAnim'])) echo ' has-features-anim'; elseif (!empty($a['touchscreenAnim'])) echo ' has-touchscreen-anim'; ?>"<?php echo $ltr; ?>>
<?php
if (!empty($a['cloudAnim'])) {
echo '<div class="ds-anim-container">';
@@ -1105,6 +1106,37 @@ function oribi_render_intro_section($a)
$feat .= '</div>';
echo $feat;
}
elseif (!empty($a['touchscreenAnim'])) {
$ts = '<div class="ts-stage" aria-hidden="true">';
// Large 55" floor-standing panel
$ts .= '<div class="ts-panel ts-panel--large">';
$ts .= '<div class="ts-bezel ts-bezel--large"><div class="ts-screen">';
$ts .= '<div class="ts-ui-header"></div>';
$ts .= '<div class="ts-ui-row ts-ui-row--1"></div>';
$ts .= '<div class="ts-ui-row ts-ui-row--2"></div>';
$ts .= '<div class="ts-ui-row ts-ui-row--3"></div>';
$ts .= '<div class="ts-ui-row ts-ui-row--4"></div>';
$ts .= '<div class="ts-ui-btn"></div>';
$ts .= '<div class="ts-ripple ts-ripple--a"></div>';
$ts .= '<div class="ts-ripple ts-ripple--b"></div>';
$ts .= '<div class="ts-ripple ts-ripple--c"></div>';
$ts .= '</div></div>'; // .ts-screen / .ts-bezel--large
$ts .= '<div class="ts-stand"><div class="ts-stem"></div><div class="ts-base"></div></div>';
$ts .= '</div>'; // .ts-panel--large
// Small 22" countertop unit
$ts .= '<div class="ts-panel ts-panel--small">';
$ts .= '<div class="ts-bezel ts-bezel--small"><div class="ts-screen ts-screen--sm">';
$ts .= '<div class="ts-ui-header ts-ui-header--sm"></div>';
$ts .= '<div class="ts-ui-row ts-ui-row--s1"></div>';
$ts .= '<div class="ts-ui-row ts-ui-row--s2"></div>';
$ts .= '<div class="ts-ui-row ts-ui-row--s3"></div>';
$ts .= '<div class="ts-ripple ts-ripple--d"></div>';
$ts .= '</div></div>'; // .ts-screen / .ts-bezel--small
$ts .= '<div class="ts-feet"><div class="ts-foot"></div><div class="ts-foot"></div></div>';
$ts .= '</div>'; // .ts-panel--small
$ts .= '</div>'; // .ts-stage
echo $ts;
}
else {
echo wp_kses_post($a['visual']);
}
@@ -2574,7 +2606,7 @@ function oribi_render_platform_row($a)
$ea .= '</div>'; // edu-board__rows
$ea .= '<div class="edu-board__alert">';
$ea .= '<span class="edu-alert__icon">!</span>';
$ea .= '<span class="edu-alert__txt">Fire drill scheduled 15:45 today</span>';
$ea .= '<span class="edu-alert__txt">Fire drill scheduled at 15:45 today</span>';
$ea .= '</div>';
$ea .= '</div>'; // edu-board
$ea .= '</div>'; // edu-stage
@@ -2657,7 +2689,7 @@ function oribi_render_platform_row($a)
$la .= '<path id="ld-fill-path" d="M0,40 L0,40 L260,40 Z" fill="url(#ld-grad)"/>';
$la .= '<path id="ld-line-path" d="M0,40 L260,40" stroke="#4CAF50" stroke-width="2" fill="none" stroke-linejoin="round"/>';
$la .= '</svg>';
$la .= '<div class="ld-chart__label">Orders / hr last 60 min</div>';
$la .= '<div class="ld-chart__label">Orders / hr, last 60 min</div>';
$la .= '</div>'; // ld-chart
$la .= '<div class="ld-status">';
@@ -2689,7 +2721,7 @@ function oribi_render_platform_row($a)
$hca .= '<div class="hc-now">';
$hca .= '<div class="hc-now__lbl">Now Serving</div>';
$hca .= '<div class="hc-now__number hc-ticker">A042</div>';
$hca .= '<div class="hc-now__counter">Counter 3 Dr. Patel</div>';
$hca .= '<div class="hc-now__counter">Counter 3: Dr. Patel</div>';
$hca .= '</div>';
$hca .= '<div class="hc-counters">';
@@ -2709,7 +2741,7 @@ function oribi_render_platform_row($a)
}
$hca .= '</div>'; // hc-counters
$hca .= '<div class="hc-board__footer">Take a seat — your number will be called</div>';
$hca .= '<div class="hc-board__footer">Take a seat. Your number will be called shortly.</div>';
$hca .= '</div>'; // hc-board
$hca .= '</div>'; // hc-stage
@@ -2730,11 +2762,11 @@ function oribi_render_platform_row($a)
$ta .= '<div class="transit-rows" id="transit-rows">';
$departures = [
['time' => '10:14', 'destination' => 'London Victoria', 'platform' => '2', 'status' => 'On Time', 'status_cls' => 'on-time'],
['time' => '10:22', 'destination' => 'Brighton', 'platform' => '4', 'status' => 'On Time', 'status_cls' => 'on-time'],
['time' => '10:31', 'destination' => 'Gatwick Airport', 'platform' => '1', 'status' => 'Delayed', 'status_cls' => 'delayed'],
['time' => '10:45', 'destination' => 'London Bridge', 'platform' => '3', 'status' => 'On Time', 'status_cls' => 'on-time'],
['time' => '11:02', 'destination' => 'East Croydon', 'platform' => '2', 'status' => 'On Time', 'status_cls' => 'on-time'],
['time' => '10:14', 'destination' => 'Saratoga Springs', 'platform' => '2', 'status' => 'On Time', 'status_cls' => 'on-time'],
['time' => '10:22', 'destination' => 'Schenectady', 'platform' => '4', 'status' => 'On Time', 'status_cls' => 'on-time'],
['time' => '10:31', 'destination' => 'Albany Airport', 'platform' => '1', 'status' => 'Delayed', 'status_cls' => 'delayed'],
['time' => '10:45', 'destination' => 'Albany-Rensselaer','platform' => '3', 'status' => 'On Time', 'status_cls' => 'on-time'],
['time' => '11:02', 'destination' => 'Hudson', 'platform' => '2', 'status' => 'On Time', 'status_cls' => 'on-time'],
];
foreach ($departures as $d) {
$ta .= '<div class="transit-row">';
@@ -2808,7 +2840,7 @@ function oribi_render_platform_row($a)
$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 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>';
@@ -2860,9 +2892,9 @@ function oribi_render_platform_row($a)
$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 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 Floor</div>';
$wf .= '</div>';
$wf .= '</div>';
$wf .= '</div>';
@@ -2893,7 +2925,7 @@ function oribi_render_platform_row($a)
$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--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>';
@@ -3118,12 +3150,12 @@ function oribi_render_platform_row($a)
$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-node groups-node--region"><span class="groups-node__icon">&#9679;</span><span class="groups-node__name">Saratoga Springs</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 class="groups-node groups-node--site"><span class="groups-node__icon">&#9679;</span><span class="groups-node__name">Broadway</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">Congress Park</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 class="groups-node groups-node--region"><span class="groups-node__icon">&#9679;</span><span class="groups-node__name">Albany</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>';
@@ -3144,7 +3176,7 @@ function oribi_render_platform_row($a)
$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 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;
@@ -3157,7 +3189,7 @@ function oribi_render_platform_row($a)
$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__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>';