diff --git a/pages/home.php b/pages/home.php
index 991af6b..e4958af 100644
--- a/pages/home.php
+++ b/pages/home.php
@@ -13,7 +13,7 @@ return <<<'ORIBI_SYNC_CONTENT'
-
+
diff --git a/theme/assets/css/main.css b/theme/assets/css/main.css
index e0acbe8..430c0c5 100644
--- a/theme/assets/css/main.css
+++ b/theme/assets/css/main.css
@@ -1984,6 +1984,348 @@ p:last-child { margin-bottom: 0; }
.platform-row.reverse .platform-visual { order: unset; }
}
+/* ── 10b. Device Animator ───────────────────────────────────── */
+.platform-visual.has-anim {
+ padding: 0;
+ overflow: hidden;
+ position: relative;
+ font-size: inherit;
+}
+.da-stage {
+ position: absolute;
+ inset: 0;
+}
+/* Each device panel – hidden by default, centred in stage */
+.da-device {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%) scale(0.88);
+ opacity: 0;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ transition: opacity 0.55s cubic-bezier(0.4,0,0.2,1),
+ transform 0.55s cubic-bezier(0.4,0,0.2,1);
+ will-change: opacity, transform;
+}
+.da-device.is-active {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+}
+.da-device.is-leaving {
+ opacity: 0;
+ transform: translate(-50%, -50%) scale(1.07);
+}
+/* Screen surface */
+.da-screen {
+ width: 100%;
+ height: 100%;
+ border-radius: 2px;
+ position: relative;
+ overflow: hidden;
+ background:
+ repeating-linear-gradient(
+ 180deg,
+ transparent,
+ transparent 3px,
+ rgba(0,0,0,0.10) 3px,
+ rgba(0,0,0,0.10) 4px
+ ),
+ linear-gradient(135deg, #0c1016 0%, #151c28 60%, #0c1016 100%);
+}
+.da-screen::before {
+ content: '';
+ position: absolute;
+ top: -20%;
+ left: -10%;
+ width: 60%;
+ height: 60%;
+ background: radial-gradient(ellipse, rgba(74,222,128,0.12) 0%, transparent 70%);
+ pointer-events: none;
+}
+@keyframes da-scan {
+ 0% { top: -6%; opacity: 0; }
+ 5% { opacity: 1; }
+ 95% { opacity: 1; }
+ 100% { top: 106%; opacity: 0; }
+}
+.da-screen::after {
+ content: '';
+ position: absolute;
+ left: 0;
+ width: 100%;
+ height: 3px;
+ background: linear-gradient(90deg, transparent, rgba(74,222,128,0.28), transparent);
+ animation: da-scan 3s linear infinite;
+ pointer-events: none;
+}
+/* Device label */
+.da-label {
+ display: block;
+ margin-top: 11px;
+ font-size: 0.68rem;
+ font-weight: 600;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ color: var(--color-text-muted);
+ text-align: center;
+}
+/* ── Tablet ────────────────────────────────────── */
+.da-tablet .da-body {
+ width: 128px;
+ height: 194px;
+ background: var(--color-bg-alt);
+ border: 2px solid var(--color-border);
+ border-radius: 14px;
+ padding: 10px 8px 14px;
+ display: flex;
+ align-items: stretch;
+ position: relative;
+ box-shadow: 0 16px 48px rgba(0,0,0,0.50);
+}
+.da-tablet .da-body::before {
+ content: '';
+ position: absolute;
+ top: 5px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 6px;
+ height: 6px;
+ background: var(--color-border);
+ border-radius: 50%;
+}
+.da-tablet .da-body::after {
+ content: '';
+ position: absolute;
+ bottom: 5px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 36px;
+ height: 3px;
+ background: var(--color-border);
+ border-radius: 2px;
+}
+/* ── Small Monitor ─────────────────────────────── */
+.da-monitor-sm .da-body {
+ width: 236px;
+ height: 146px;
+ background: var(--color-bg-alt);
+ border: 5px solid var(--color-bg-alt);
+ border-radius: 6px;
+ outline: 1px solid var(--color-border);
+ padding: 3px;
+ display: flex;
+ align-items: stretch;
+ position: relative;
+ box-shadow: 0 10px 36px rgba(0,0,0,0.50);
+}
+.da-monitor-sm .da-body::after {
+ content: '';
+ position: absolute;
+ bottom: -9px;
+ right: 8px;
+ width: 5px;
+ height: 5px;
+ background: var(--color-primary);
+ border-radius: 50%;
+ box-shadow: 0 0 5px var(--color-primary);
+}
+.da-monitor-sm .da-stand,
+.da-monitor-lg .da-stand { display: flex; flex-direction: column; align-items: center; }
+.da-monitor-sm .da-stem {
+ width: 14px;
+ height: 20px;
+ background: var(--color-bg-alt);
+ border-left: 1px solid var(--color-border);
+ border-right: 1px solid var(--color-border);
+}
+.da-monitor-sm .da-base {
+ width: 68px;
+ height: 5px;
+ background: var(--color-bg-alt);
+ border: 1px solid var(--color-border);
+ border-radius: 3px;
+}
+/* ── Large Monitor ─────────────────────────────── */
+.da-monitor-lg .da-body {
+ width: 298px;
+ height: 177px;
+ background: var(--color-bg-alt);
+ border: 4px solid var(--color-bg-alt);
+ border-radius: 6px;
+ outline: 1px solid var(--color-border);
+ padding: 3px;
+ display: flex;
+ align-items: stretch;
+ position: relative;
+ box-shadow: 0 12px 40px rgba(0,0,0,0.50);
+}
+.da-monitor-lg .da-stem {
+ width: 16px;
+ height: 26px;
+ background: var(--color-bg-alt);
+ border-left: 1px solid var(--color-border);
+ border-right: 1px solid var(--color-border);
+}
+.da-monitor-lg .da-base {
+ width: 88px;
+ height: 5px;
+ background: var(--color-bg-alt);
+ border: 1px solid var(--color-border);
+ border-radius: 3px;
+}
+/* ── TV ────────────────────────────────────────── */
+.da-tv .da-body {
+ width: 320px;
+ height: 188px;
+ background: var(--color-bg-alt);
+ border: 4px solid var(--color-bg-alt);
+ border-radius: 6px 6px 4px 4px;
+ outline: 1px solid var(--color-border);
+ padding: 3px;
+ display: flex;
+ align-items: stretch;
+ position: relative;
+ box-shadow: 0 14px 48px rgba(0,0,0,0.55);
+}
+.da-tv .da-body::after {
+ content: '\25B6';
+ position: absolute;
+ bottom: -13px;
+ left: 50%;
+ transform: translateX(-50%);
+ font-size: 8px;
+ color: rgba(74,222,128,0.7);
+}
+.da-tv .da-feet { display: flex; justify-content: space-between; width: 180px; }
+.da-tv .da-foot {
+ width: 12px;
+ height: 8px;
+ background: var(--color-bg-alt);
+ border: 1px solid var(--color-border);
+ border-radius: 0 0 4px 4px;
+}
+/* ── Projector ─────────────────────────────────── */
+.da-projector .da-proj-layout { display: flex; flex-direction: column; align-items: center; }
+.da-projector .da-proj-body {
+ width: 156px;
+ height: 62px;
+ background: var(--color-bg-alt);
+ border: 1px solid var(--color-border);
+ border-radius: 10px 10px 8px 8px;
+ display: flex;
+ align-items: center;
+ padding: 0 14px;
+ gap: 10px;
+ box-shadow: 0 6px 20px rgba(0,0,0,0.45);
+ position: relative;
+}
+.da-projector .da-proj-body::after {
+ content: '';
+ position: absolute;
+ top: 8px;
+ right: 10px;
+ width: 7px;
+ height: 7px;
+ background: var(--color-primary);
+ border-radius: 50%;
+ box-shadow: 0 0 6px var(--color-primary);
+}
+.da-projector .da-proj-body::before {
+ content: '';
+ position: absolute;
+ right: 10px;
+ bottom: 8px;
+ width: 28px;
+ height: 8px;
+ background: repeating-linear-gradient(
+ 90deg,
+ var(--color-border) 0px,
+ var(--color-border) 2px,
+ transparent 2px,
+ transparent 5px
+ );
+ border-radius: 1px;
+}
+.da-projector .da-lens {
+ width: 38px;
+ height: 38px;
+ background: #080c12;
+ border: 2px solid var(--color-border);
+ border-radius: 50%;
+ flex-shrink: 0;
+ position: relative;
+ box-shadow: inset 0 0 8px rgba(0,0,0,0.8);
+}
+.da-projector .da-lens::after {
+ content: '';
+ position: absolute;
+ inset: 5px;
+ background: radial-gradient(circle at 35% 35%, rgba(74,222,128,0.30) 0%, #080c12 65%);
+ border-radius: 50%;
+}
+.da-projector .da-beam {
+ width: 240px;
+ height: 50px;
+ clip-path: polygon(31% 0%, 69% 0%, 100% 100%, 0% 100%);
+ background: linear-gradient(
+ 180deg,
+ rgba(74,222,128,0.07) 0%,
+ rgba(74,222,128,0.02) 100%
+ );
+}
+.da-projector .da-proj-screen {
+ width: 240px;
+ height: 72px;
+ background: var(--color-bg-alt);
+ border: 1px solid var(--color-border);
+ border-radius: 3px;
+ overflow: hidden;
+ padding: 3px;
+ box-shadow: 0 4px 14px rgba(0,0,0,0.40);
+}
+/* ── Video Wall (2×2) ──────────────────────────── */
+.da-vwall .da-vwall-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ grid-template-rows: 1fr 1fr;
+ gap: 5px;
+ background: #0a0d12;
+ padding: 5px;
+ border: 1px solid var(--color-border);
+ border-radius: 4px;
+ box-shadow: 0 14px 48px rgba(0,0,0,0.60);
+}
+.da-vwall .da-panel {
+ width: 148px;
+ height: 90px;
+ background: var(--color-bg-alt);
+ border: 2px solid var(--color-bg-alt);
+ padding: 2px;
+ display: flex;
+ align-items: stretch;
+ overflow: hidden;
+}
+.da-vwall .da-panel:nth-child(2) .da-screen::after { animation-delay: -0.75s; }
+.da-vwall .da-panel:nth-child(3) .da-screen::after { animation-delay: -1.5s; }
+.da-vwall .da-panel:nth-child(4) .da-screen::after { animation-delay: -2.25s; }
+/* ── Responsive scale-down ─────────────────────── */
+@media (max-width: 900px) {
+ .da-device { transform: translate(-50%,-50%) scale(0.76); }
+ .da-device.is-active { transform: translate(-50%,-50%) scale(0.84); }
+ .da-device.is-leaving { transform: translate(-50%,-50%) scale(0.91); }
+}
+@media (max-width: 640px) {
+ .da-device { transform: translate(-50%,-50%) scale(0.56); }
+ .da-device.is-active { transform: translate(-50%,-50%) scale(0.64); }
+ .da-device.is-leaving { transform: translate(-50%,-50%) scale(0.70); }
+}
+@media (prefers-reduced-motion: reduce) {
+ .da-device { transition: none; }
+ .da-screen::after { animation: none; }
+}
+
/* ── 11. Page Hero (inner pages) ───────────────────────────── */
.page-hero {
background: #111111;
diff --git a/theme/assets/js/main.js b/theme/assets/js/main.js
index cc9139e..75b457c 100644
--- a/theme/assets/js/main.js
+++ b/theme/assets/js/main.js
@@ -610,3 +610,68 @@ document.addEventListener('DOMContentLoaded', () => {
paintBg();
start();
})();
+
+/* ── Device Animator ──────────────────────────────────────────────────────── */
+(function () {
+ const DEVICES = [
+ 'da-tablet', 'da-monitor-sm', 'da-monitor-lg',
+ 'da-tv', 'da-projector', 'da-vwall'
+ ];
+ const DWELL = 2500; // ms each device is shown
+
+ document.querySelectorAll('.da-stage').forEach(function (stage) {
+ let current = 0;
+ let timer = null;
+
+ // Collect the 6 device panels
+ const panels = DEVICES.map(function (cls) {
+ return stage.querySelector('.' + cls);
+ });
+
+ function show(idx) {
+ panels.forEach(function (el, i) {
+ if (!el) return;
+ el.classList.toggle('is-active', i === idx);
+ el.classList.remove('is-leaving');
+ });
+ }
+
+ function advance() {
+ const leaving = current;
+ current = (current + 1) % DEVICES.length;
+ if (panels[leaving]) panels[leaving].classList.add('is-leaving');
+ show(current);
+ setTimeout(function () {
+ if (panels[leaving]) panels[leaving].classList.remove('is-leaving');
+ }, 600);
+ }
+
+ function startCycle() {
+ if (timer) return;
+ timer = setInterval(advance, DWELL);
+ }
+
+ function stopCycle() {
+ clearInterval(timer);
+ timer = null;
+ }
+
+ // Honour reduced-motion preference: show first device statically
+ if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
+ show(0);
+ return;
+ }
+
+ show(0);
+ startCycle();
+
+ // Pause when scrolled out of view to save resources
+ if ('IntersectionObserver' in window) {
+ new IntersectionObserver(function (entries) {
+ entries.forEach(function (e) {
+ e.isIntersecting ? startCycle() : stopCycle();
+ });
+ }, { threshold: 0.2 }).observe(stage);
+ }
+ });
+})();
diff --git a/theme/blocks/index.php b/theme/blocks/index.php
index 02f20ef..40b74ed 100644
--- a/theme/blocks/index.php
+++ b/theme/blocks/index.php
@@ -553,6 +553,7 @@ add_action( 'init', function () {
'imgUrl' => [ 'type' => 'string', 'default' => '' ],
'imgAlt' => [ 'type' => 'string', 'default' => '' ],
'imgWidth' => [ 'type' => 'number', 'default' => 300 ],
+ 'deviceAnim' => [ 'type' => 'boolean', 'default' => false ],
],
'supports' => $block_supports,
'render_callback' => 'oribi_render_platform_row',
@@ -1346,6 +1347,17 @@ function oribi_render_platform_row( $a ) {
$visual_html = '';
}
$visual_cls = 'platform-visual has-img';
+ } elseif ( ! empty( $a['deviceAnim'] ) ) {
+ $da = '