Compare commits
121 Commits
oribi-sync
...
d689a06640
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d689a06640 | ||
|
|
32488c4b79 | ||
| 1cef43301f | |||
|
|
1688e136b1 | ||
|
|
c91975db12 | ||
|
|
5ea06c2332 | ||
|
|
59295b15db | ||
|
|
82d6ecba1e | ||
|
|
e90e644b62 | ||
|
|
afccdca783 | ||
|
|
d88070949c | ||
|
|
2a0b949ea9 | ||
|
|
2c82b2e432 | ||
|
|
97bbe90ed1 | ||
| 668c92aff6 | |||
| a8ba4a1fef | |||
| edacab26b3 | |||
| 0a18e35943 | |||
| b264511d34 | |||
| 6254fff0c0 | |||
| 3c07a4733c | |||
| e54b94222a | |||
| 44b501b4da | |||
| 4f596dbf30 | |||
|
|
a7d6623eec | ||
|
|
985ba72212 | ||
|
|
cfb216f73e | ||
|
|
ce163d25e3 | ||
|
|
6b8b6b2328 | ||
|
|
f9f15708e3 | ||
|
|
80b36032e8 | ||
|
|
7b4caa1267 | ||
| a69521ab25 | |||
| e03b6e150e | |||
| 8eea9d95ce | |||
| 0fd40020b0 | |||
| afd49f2165 | |||
| c476a79cee | |||
| 369da66d4c | |||
| 402804018a | |||
| 93e1c59e29 | |||
| 170f134927 | |||
|
|
5be6eae083 | ||
|
|
7bb9a0bdd3 | ||
|
|
3027f3da40 | ||
|
|
c50087d669 | ||
|
|
8c3c7a1d8a | ||
|
|
4e4549e865 | ||
|
|
25da755378 | ||
|
|
dc89009cfa | ||
|
|
21d41b24d8 | ||
|
|
8f43b6c584 | ||
|
|
66b6b9cbfb | ||
|
|
018928dd9b | ||
|
|
78065e0143 | ||
|
|
131ef8448c | ||
|
|
a89f9067e2 | ||
|
|
8926a9b071 | ||
|
|
1540aa9f13 | ||
|
|
3dcffaeb06 | ||
| 7aee3eab85 | |||
| 20b655d490 | |||
| 3e3578823d | |||
| b96bdfe355 | |||
| dcb8acb1e5 | |||
| a2821b4c2c | |||
| f12928690e | |||
| 6ddd3ba399 | |||
| 4fe3f6e283 | |||
| 4e5ab8b3fa | |||
|
|
48432c1931 | ||
|
|
2826a3ec4a | ||
|
|
2edbf9732b | ||
|
|
82a2dacbef | ||
|
|
75588a5151 | ||
|
|
624a5c2d4e | ||
|
|
61a7070b0f | ||
|
|
bb30f38090 | ||
|
|
d8c12e3f3b | ||
|
|
ebb4b7668c | ||
|
|
5783fa7ebc | ||
|
|
df794be0d8 | ||
|
|
150fe5a291 | ||
|
|
b0167f2505 | ||
|
|
0407269e79 | ||
|
|
ecba27595c | ||
|
|
c4f3d7e881 | ||
|
|
e5c3be6ec5 | ||
|
|
201e4e4606 | ||
|
|
ef0532ef9b | ||
|
|
1d49929ed3 | ||
|
|
c5d5ad33e5 | ||
|
|
c42c7d7dbc | ||
|
|
5d09382d0d | ||
|
|
accdfa9d70 | ||
|
|
a9697dd714 | ||
|
|
ab6f4212bd | ||
|
|
7e0c216e1c | ||
|
|
d68c2c1d31 | ||
|
|
4591578cb2 | ||
|
|
954c418556 | ||
|
|
b37bcfb72b | ||
|
|
0ec0e71d38 | ||
|
|
e1d9b1a402 | ||
|
|
a33a6d62d2 | ||
|
|
38d585e071 | ||
|
|
f8321568ce | ||
|
|
be30e4d59f | ||
|
|
3e211c376f | ||
|
|
618ba6ded4 | ||
| 3100a93d9a | |||
|
|
8ceb81008c | ||
|
|
0420be8bd6 | ||
|
|
01235c2042 | ||
| ea988f09b1 | |||
| 978c63f9b9 | |||
|
|
68a8cc9578 | ||
|
|
bfe2bf8bf1 | ||
|
|
15d1acbb14 | ||
|
|
06b0831a40 | ||
|
|
2c9825b72d |
@@ -1,27 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* Title: About
|
||||
* Slug: ots-signs/page-about
|
||||
* Categories: oribi-pages
|
||||
* Keywords: about, company, mission, team, digital signage
|
||||
* Post Types: page
|
||||
* Slug: about
|
||||
* Post Type: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"About Us","title":"The Complete Digital Signage Solution","description":"An Oribi Technology Services company, OTS Signs delivers enterprise-grade digital signage solutions that help businesses communicate, engage, and grow."} /-->
|
||||
|
||||
<!-- wp:oribi/intro-section {"variant":"normal","label":"Our Story","heading":"Built by People Who Understand Technology","description":"OTS Signs was born from a simple idea: digital signage should be powerful yet simple. As part of the Oribi Technology Services family, we bring years of IT infrastructure expertise to the signage industry. We understand networks, security, and reliability, and we\u0027ve built a platform that reflects that knowledge. Our team combines deep technical skills with creative vision to deliver signage solutions that truly work for your business.","visual":""} /-->
|
||||
return <<<'ORIBI_SYNC_CONTENT'
|
||||
<!-- wp:oribi/page-hero-animated {"label":"About Us","title":"Digital Signage, Done Properly","description":"OTS Signs is the digital signage arm of Oribi Technology Services. We combine deep IT expertise with creative production to deliver signage that businesses can genuinely rely on."} /-->
|
||||
|
||||
<!-- wp:oribi/intro-section {"variant":"alt","label":"Our Mission","heading":"Empowering Businesses to Communicate Better","description":"We believe every business deserves access to professional-grade digital signage. Our mission is to make it affordable, reliable, and effortless, so you can focus on what matters most: your customers. Whether you\u0027re a single-location café or a multi-site enterprise, our platform scales to meet your needs without compromising on quality or support.","visual":"","reversed":true} /-->
|
||||
<!-- wp:oribi/intro-section {"label":"Our Story","heading":"Born from Infrastructure, Built for Signage","description":"OTS Signs grew out of a gap we kept seeing: businesses wanted digital signage but were stuck choosing between complex enterprise platforms and unreliable consumer tools. As part of Oribi Technology Services, we already understood networks, uptime, and security at a deep level. We took that foundation and built a signage platform that is powerful enough for large deployments yet simple enough for a single-site café. Every decision we make, from hardware selection to Command Center design, is grounded in real-world infrastructure experience."} /-->
|
||||
|
||||
<!-- wp:oribi/value-section {"variant":"normal","label":"What Sets Us Apart","heading":"Why Businesses Choose OTS Signs","lead":"We\u0027re not just a software company. We\u0027re a full-service digital signage partner.","columns":3} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-camera","title":"In-House Content Production","description":"Professional photography, video production, and graphic design services to ensure your signage always looks its best."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-server","title":"Infrastructure Expertise","description":"Built on enterprise-grade cloud infrastructure by the same team that manages IT systems for businesses across the region."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-handshake","title":"Partnership Approach","description":"We work as an extension of your team. Dedicated support, personalised onboarding, and ongoing optimisation."} /-->
|
||||
<!-- wp:oribi/value-section {"variant":"alt","label":"Our Heritage","heading":"Backed by Years of Enterprise IT","lead":"OTS Signs is built on the infrastructure expertise of Oribi Technology Services \u2014 a team that has spent years designing, deploying, and supporting business-critical technology.","columns":3} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-network-wired","title":"Enterprise Networking","description":"We\u0027ve designed and managed networks for organisations that can\u0027t afford downtime. That same rigour underpins every signage deployment we build."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-lock","title":"Security-First Mindset","description":"Two-factor authentication, role-based access control, and audit trails are built into the platform \u2014 not added as an afterthought."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-people-group","title":"A Team That Ships","description":"Our team spans cloud engineering, hardware, creative production, and customer success. We handle every layer of your signage deployment in-house."} /-->
|
||||
<!-- /wp:oribi/value-section -->
|
||||
|
||||
<!-- wp:oribi/trust-section {"label":"Our Commitment","heading":"We Stand Behind Every Screen","lead":"Your success is our success. From initial concept to ongoing management, we\u0027re with you every step of the way.","btnText":"Get in Touch","btnUrl":"/contact","btnSub":"Let\u0027s discuss your digital signage needs"} -->
|
||||
<!-- wp:oribi/trust-item {"heading":"Reliable Technology","description":"Enterprise-grade security, 99.9% uptime, and intelligent offline playback ensure your message is always on screen."} /-->
|
||||
<!-- wp:oribi/trust-item {"heading":"Continuous Innovation","description":"We\u0027re constantly improving our platform with new features, integrations, and content tools to keep you ahead of the curve."} /-->
|
||||
<!-- /wp:oribi/trust-section -->
|
||||
<!-- wp:oribi/intro-section {"variant":"alt","label":"Our Mission","heading":"Making Professional Signage Accessible to Everyone","description":"Too many signage providers lock essential features behind enterprise price tags. We took a different approach. Our platform gives every customer access to the same professional-grade tools: \u003cbr\u003e- Cloud Content Management\u003cbr\u003e- Intelligent Scheduling\u003cbr\u003e- Live Data Integration \u003cbr\u003e- Content that looks outstanding on screen\u003cbr\u003e\u003cbr\u003eWe handle the complexity so you can focus on running your business.","reversed":true} /-->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Let\u0027s Build Something Together","text":"Whether you\u0027re starting fresh or upgrading an existing setup, we\u0027re ready to help.","btnText":"Contact Us","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/value-section {"label":"What Sets Us Apart","heading":"A Full-Service Signage Partner","lead":"Software alone isn't enough. We pair our platform with hands-on services that make the difference.","columns":3} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-camera","title":"Studio-Quality Creative","description":"Photography, videography, motion graphics, and graphic design produced in-house. Your screens always look polished, on-brand, and impossible to ignore. Available as included hours on Pro, or quoted separately for Essentials customers."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-server","title":"IT-Grade Infrastructure","description":"Our roots are in enterprise IT. That means proper networking, redundancy, and security baked into every layer of the platform."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-handshake","title":"Genuine Partnership","description":"Dedicated onboarding, a named point of contact, and ongoing optimisation. We operate as an extension of your own team."} /-->
|
||||
<!-- /wp:oribi/value-section -->
|
||||
|
||||
<!-- wp:oribi/trust-section {"label":"Our Commitment","heading":"Promises We Actually Keep","lead":"Every screen in your network reflects on your business. We take that responsibility seriously.","btnText":"Start a Conversation","btnUrl":"/contact","btnSub":"Tell us what you need and we'll take it from there"} -->
|
||||
<!-- wp:oribi/trust-item {"heading":"Uptime You Can Count On","description":"99.9% platform availability, and intelligent offline playback mean your message stays on screen no matter what."} /-->
|
||||
|
||||
<!-- wp:oribi/trust-item {"heading":"Security Built In, Not Bolted On","description":"Two-factor authentication, role-based access control, and full audit trails. Your content and your customers\u0027 data are protected at every layer."} /-->
|
||||
|
||||
<!-- wp:oribi/trust-item {"heading":"A Platform That Keeps Improving","description":"Regular feature releases, new integrations, and expanded content tools ensure you're always working with the latest capabilities, at no extra cost."} /-->
|
||||
<!-- /wp:oribi/trust-section -->
|
||||
<!-- wp:oribi/stat-section {"variant":"normal","label":"By the Numbers","heading":"The Platform Behind the Screens","lead":"Real metrics from a platform built for reliability and scale.","columns":4} -->
|
||||
<!-- wp:oribi/stat-card {"value":"99.9%","label":"Platform Uptime","description":"Enterprise-grade availability backed by redundant cloud infrastructure and contractual SLA guarantees."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"1,000+","label":"Screen Capacity","description":"From single-site caf\u00e9s to multi-location enterprises, our platform scales with your business."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"4K","label":"Ultra-HD Output","description":"Every player delivers crisp 4K resolution over HDMI for stunning visuals on any display."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"24/7","label":"Always-On Operation","description":"Commercial-grade hardware with offline playback ensures your screens never go dark."} /-->
|
||||
<!-- /wp:oribi/stat-section -->
|
||||
<!-- wp:oribi/cta-banner {"heading":"Ready to See What We Can Do?","text":"Whether you're planning your first screen or scaling to hundreds, we'd love to hear about your project.","btnText":"Get in Touch","btnUrl":"/contact"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
|
||||
@@ -1,20 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* Title: Contact
|
||||
* Slug: ots-signs/page-contact
|
||||
* Categories: oribi-pages
|
||||
* Keywords: contact, sales, support, inquiry, get in touch
|
||||
* Post Types: page
|
||||
* Slug: contact
|
||||
* Post Type: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Contact Us","title":"Get in Touch","description":"Ready to transform your screens? Whether you\u0027re exploring options or ready to get started, we\u0027re here to help."} /-->
|
||||
|
||||
<!-- wp:oribi/contact-section {"heading":"Let\u0027s Talk","lead":"Tell us about your digital signage needs and we\u0027ll get back to you within one business day.","email":"hello@ots-signs.com","supportUrl":"https://ots-signs.com/support","portalUrl":"https://ots-signs.com/portal","location":"An Oribi Technology Services Company","formHeading":"Send Us a Message"} /-->
|
||||
return <<<'ORIBI_SYNC_CONTENT'
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Contact Us","title":"Let's Start a Conversation","description":"Whether you're researching digital signage for the first time or ready to roll out screens next week, we're here to help you move forward."} /-->
|
||||
|
||||
<!-- wp:oribi/value-section {"variant":"alt","label":"How We Can Help","heading":"Reach Out For","lead":"Whatever stage you\u0027re at, we have the expertise to guide you.","columns":3} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-comments","title":"Sales Inquiries","description":"Explore our plans, get a custom quote, or learn how digital signage can benefit your business."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-headset","title":"Technical Support","description":"Need help with your existing setup? Our support team is ready to troubleshoot and resolve any issues."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-handshake","title":"Partnerships","description":"Interested in reselling or integrating our platform? Let\u0027s discuss partnership opportunities."} /-->
|
||||
<!-- wp:oribi/contact-section {"heading":"Send Us a Message","lead":"Tell us what you're working on. We respond within one business day, usually faster.","email":"hello@ots-signs.com","phone":"+44 (0) 330 088 3665","supportUrl":"https://ots-signs.com/support","portalUrl":"https://ots-signs.com/portal","location":"An Oribi Technology Services Company","formHeading":"How Can We Help?"} /-->
|
||||
|
||||
<!-- wp:oribi/value-section {"variant":"alt","label":"How We Can Help","heading":"Whatever You Need, We're Here","lead":"From your first question to ongoing support, our team has you covered."} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-comments","title":"Sales \u0026 Quotes","description":"Talk through your requirements, get a custom quote, or simply learn how digital signage fits your business."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-headset","title":"Technical Support","description":"Already a customer? Our support team is ready to troubleshoot, advise, and resolve any issue quickly."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-camera","title":"Creative Services","description":"Need content for your screens? Our in-house studio produces photography, video, motion graphics, and design — quoted separately or included with Pro."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-handshake","title":"Partnerships","description":"Interested in reselling, white-labelling, or integrating our platform into your own offering? Let's talk."} /-->
|
||||
<!-- /wp:oribi/value-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Prefer a Live Demo?","text":"See our platform in action before you commit. Request access to our live demo instance.","btnText":"Request Demo","btnUrl":"/demo"} /-->
|
||||
<!-- wp:oribi/value-section {"variant":"normal","label":"Partner With Us","heading":"Reselling, White-Label & Integration","lead":"Build OTS Signs into your own offering — under your brand or alongside your services.","columns":3} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-tags","title":"White-Label","description":"Rebrand the entire platform with your logo, domain, and colour scheme. Your clients see your brand — we provide the infrastructure."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-handshake","title":"Reseller Programme","description":"Sell OTS Signs alongside your AV, IT, or consultancy services. Volume pricing, co-marketing, and a dedicated partner manager."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-code","title":"API Integration","description":"Embed signage capabilities into your own SaaS product via our REST API. Custom workflows, automated content, and full platform control."} /-->
|
||||
<!-- /wp:oribi/value-section -->
|
||||
|
||||
<!-- wp:oribi/intro-section {"variant":"alt","label":"Learn More","heading":"Explore Our Partner Programme","description":"Full details on partnership models, benefits, and how to apply are on our dedicated partners page.","visual":"","btnText":"View Partner Programme","btnUrl":"/partners"} /-->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Rather See It First?","text":"Get hands-on with our platform before committing. Request a live demo and explore at your own pace.","btnText":"Request Demo","btnUrl":"/demo"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
|
||||
@@ -1,25 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* Title: Demo
|
||||
* Slug: ots-signs/page-demo
|
||||
* Categories: oribi-pages
|
||||
* Keywords: demo, trial, try, preview, platform
|
||||
* Post Types: page
|
||||
* Slug: demo
|
||||
* Post Type: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Try It","title":"See It in Action","description":"Experience our digital signage platform firsthand. Request access to our live demo instance and explore every feature, no commitment required."} /-->
|
||||
|
||||
<!-- wp:oribi/intro-section {"variant":"normal","label":"Live Demo","heading":"Explore Our Demo Instance","description":"Our demo environment gives you full access to the OTS Signs CMS platform. Create content, schedule displays, explore integrations, and see exactly how your digital signage will look and feel in production. No credit card needed. Just fill in the form below and we\u0027ll send you access within 24 hours.","visual":""} /-->
|
||||
return <<<'ORIBI_SYNC_CONTENT'
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Try It","title":"Hands-On in Minutes, Not Weeks","description":"Skip the slideshow. Request access to a live instance of our platform and explore every feature at your own pace, no sales call required."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"alt","label":"What You\u0027ll See","heading":"Full Platform Access","lead":"The demo instance includes all the features available on our Pro plan.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-desktop","title":"Content Management","description":"Upload images, videos, and HTML content. Create playlists and manage your media library."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-clock","title":"Scheduling","description":"Set up content schedules with day-parting and time-based triggers to see automated playback in action."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-line","title":"Live Data Feeds","description":"Connect sample data sources and see how real-time information appears on your digital signage displays."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-th-large","title":"Template Library","description":"Browse our collection of professionally designed templates for menus, promotions, and informational displays."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-users-cog","title":"User Management","description":"See how roles and permissions work to manage team access across your signage network."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-pie","title":"Analytics Dashboard","description":"View playback analytics and screen health metrics to understand how your content is performing."} /-->
|
||||
<!-- wp:oribi/intro-section {"label":"Live Demo","heading":"Your Own Sandbox to Explore","description":"We'll set you up with full access to the OTS Signs Command Center, the same platform our paying customers use. Build playlists, schedule content, connect data feeds, and preview exactly how your signage will look in production. No credit card, no time limit on the trial. Fill in the form below and we'll send you credentials within 24 hours."} /-->
|
||||
|
||||
<!-- wp:oribi/intro-section {"variant":"alt","label":"Quick Look","heading":"Want to See It Now?","description":"Don\u0027t want to wait? Watch a 3-minute walkthrough of the platform in action \u2014 from content creation to live screen publishing.","visual":"video","videoUrl":"https://ots-signs.com/demo-video"} /-->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"alt","label":"What You\u0027ll See","heading":"Full Pro-Tier Access","lead":"The demo includes every feature available, nothing held back.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-desktop","title":"Content Management","description":"Upload images, videos, and HTML. Organise media, create playlists, and preview how content looks on screen."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-clock","title":"Smart Scheduling","description":"Build day-parted schedules, set date ranges, and see how automated playback works across multiple screens."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-line","title":"Live Data Feeds","description":"Connect sample data sources to experience real-time information flowing directly onto display layouts."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-th-large","title":"Template Library","description":"Browse and customize professional templates for menus, promotions, announcements, and informational displays."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-users-cog","title":"Team \u0026 Permissions","description":"Test role-based access, invite collaborators, and see how multi-user management works across your network."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-pie","title":"Playback Analytics","description":"Explore screen health monitoring, content playback logs, and performance dashboards."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/contact-section {"heading":"Request Demo Access","lead":"Fill in your details and we\u0027ll send you credentials for our demo instance within 24 hours.","email":"hello@ots-signs.com","supportUrl":"https://demo.ots-signs.com/","portalUrl":"https://demo.ots-signs.com/","location":"Online Demo Available 24/7","formHeading":"Get Your Demo Access"} /-->
|
||||
<!-- wp:oribi/contact-section {"heading":"Request Demo Access","lead":"Fill in your details below. We'll have your login credentials ready within 24 hours.","email":"hello@ots-signs.com","supportUrl":"https://demo.ots-signs.com/","portalUrl":"https://demo.ots-signs.com/","location":"Online Demo Available 24/7","formHeading":"Get Your Demo Login"} /-->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Ready to Skip the Demo?","text":"If you already know what you need, let\u0027s get started right away.","btnText":"View Pricing","btnUrl":"/pricing"} /-->
|
||||
<!-- wp:oribi/cta-banner {"heading":"Already Convinced?","text":"If you've seen enough and want to get started, jump straight to our plans or start a free trial.","btnText":"Start Free Trial","btnUrl":"/trial","secondaryBtnText":"View Pricing","secondaryBtnUrl":"/pricing"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
|
||||
46
pages/design.php
Normal file
46
pages/design.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/*
|
||||
* Title: Design
|
||||
* Slug: design
|
||||
* Post Type: page
|
||||
*/
|
||||
|
||||
return <<<'ORIBI_SYNC_CONTENT'
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Creative Services","title":"Content That Demands Attention","description":"Great signage starts with great content. Our in-house creative team produces photography, video, motion graphics, and branded layouts — so every screen in your network looks polished, professional, and impossible to ignore."} /-->
|
||||
|
||||
<!-- wp:oribi/platform-section {"label":"What We Create","heading":"Professional Content for Every Screen","lead":"We handle the entire creative process — from concept to screen-ready assets — so you can focus on running your business."} -->
|
||||
<!-- wp:oribi/platform-row {"heading":"Photography That Sells","description":"Our photographers capture your products, venues, and team in the best possible light. Whether it's plated dishes for a digital menu board, hero shots for a retail promotion, or environmental photography for a hotel lobby — every image is composed, lit, and retouched specifically for screen display. No stock photos, no compromises.","btnText":"Get a Quote","btnUrl":"/contact","cameraAnim":true} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Video \u0026amp; Motion Graphics","description":"Short-form video content grabs attention like nothing else. We produce promotional videos, product loops, animated backgrounds, and kinetic typography — all optimised for digital signage playback. From scripting and shooting to editing and export, we deliver files ready to drop straight into your CMS.","btnText":"See Examples","btnUrl":"/contact","reversed":true} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Branded Layout Design","description":"Your screens should feel like a natural extension of your brand. We design custom layouts that match your visual identity — fonts, colours, logo placement, and spacing — across every display format. Whether you need a single hero layout or a full library of templates for your team to reuse, we build it to your spec.","btnUrl":"/features"} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Digital Menu Boards","description":"Menu boards that update in seconds, not hours. We design structured menu layouts with clear categories, pricing, and imagery — then connect them to the platform so you can change a price, swap a photo, or add a seasonal item without touching the design. One update, every screen, instantly.","btnText":"View Platform","btnUrl":"/features","reversed":true} /-->
|
||||
<!-- /wp:oribi/platform-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"alt","label":"How We Work","heading":"From Brief to Screen in Days, Not Weeks","lead":"A straightforward process that gets professional content onto your displays quickly — with revisions built in and no surprises on cost.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-comments","title":"1. Discovery \u0026amp; Brief","description":"We learn about your brand, your audience, and your goals. You tell us what you need — we'll recommend what works best on screen and scope the project."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-pencil","title":"2. Create \u0026amp; Review","description":"We produce your content — photography, video, layouts, or all three — and share drafts for your feedback. Revisions are included until you're completely happy."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-rocket","title":"3. Publish \u0026amp; Go Live","description":"Approved content goes straight into your CMS, scheduled and ready to play. We handle the upload so you don't have to lift a finger."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/value-section {"label":"Why In-House","heading":"The Advantage of a Single Partner","lead":"When your creative team and your signage platform are under the same roof, everything moves faster and fits better."} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-display","title":"Designed for Screen","description":"Every asset is created specifically for digital display — correct resolutions, aspect ratios, colour profiles, and file formats. No guesswork, no re-exporting."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-layer-group","title":"Platform-Native Layouts","description":"We design directly within the CMS layout engine, so what you approve in the draft is exactly what plays on screen. No design-to-development handoff."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-arrows-rotate","title":"Ongoing Content Refresh","description":"Screens that never change get ignored. We offer ongoing content packages — monthly or quarterly — to keep your displays fresh, seasonal, and relevant."} /-->
|
||||
<!-- /wp:oribi/value-section -->
|
||||
|
||||
<!-- wp:oribi/stat-section {"variant":"alt","label":"Content Impact","heading":"Why Content Quality Matters","lead":"The difference between signage that works and signage that gets ignored almost always comes down to the content on screen."} -->
|
||||
<!-- wp:oribi/stat-card {"value":"400%","label":"More Views","description":"Digital displays capture 400% more eyeballs than static signage — but only when the content is worth looking at."} /-->
|
||||
|
||||
<!-- wp:oribi/stat-card {"value":"80%","label":"Content Recall","description":"Eight out of ten people remember what they see on a digital display. Professional visuals make that memory count."} /-->
|
||||
|
||||
<!-- wp:oribi/stat-card {"value":"30%","label":"Sales Uplift","description":"Retail locations with well-designed digital signage report up to 30% higher in-store sales."} /-->
|
||||
<!-- /wp:oribi/stat-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Let's Make Your Screens Look Outstanding","text":"Tell us about your brand, your locations, and what you want your screens to do. We'll put together a creative plan and a clear quote — no obligation.","btnText":"Start a Project","btnUrl":"/contact"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
@@ -1,29 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Player Devices
|
||||
* Slug: ots-signs/page-devices
|
||||
* Categories: oribi-pages
|
||||
* Keywords: devices, hardware, player, screens, HDMI, commercial display
|
||||
* Post Types: page
|
||||
/*
|
||||
* Title: Devices
|
||||
* Slug: devices
|
||||
* Post Type: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Hardware","title":"Player Devices Built for Reliability","description":"Our digital signage players are engineered for performance, security, and simplicity. Plug in, connect, and start displaying. It\u0027s that easy."} /-->
|
||||
|
||||
<!-- wp:oribi/platform-section {"label":"Our Devices","heading":"Hardware That Just Works","lead":"Purpose-built player devices designed for 24/7 commercial use with zero maintenance."} -->
|
||||
<!-- wp:oribi/platform-row {"heading":"Use Existing Screens","description":"Our digital signage players work on any screen with HDMI, so you can easily integrate them into your current setup. No need to replace your existing displays. Just plug in our player and start broadcasting. If you need a complete solution, we also offer bundled packages that include both the player and a high-quality commercial-grade display.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Intelligent Offline Playback","description":"Our player devices are engineered to keep your message on screen, even when the internet isn\u0027t available. Content is cached locally so your displays continue running seamlessly. When connectivity returns, new content syncs automatically, no manual intervention needed.","btnText":"See Features","btnUrl":"/features","reversed":true} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Enterprise-Grade Security","description":"Every device is hardened with enterprise-grade security protocols. Encrypted communications, secure boot, and remote management capabilities ensure your signage network stays protected. Automatic firmware updates keep your devices current without any downtime.","btnText":"Learn More","btnUrl":"/about"} /-->
|
||||
return <<<'ORIBI_SYNC_CONTENT'
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Hardware","title":"Signage Players Engineered for the Real World","description":"Compact, silent, and built for 24/7 operation. Plug into any HDMI screen, connect to your network, and your content is live in minutes."} /-->
|
||||
|
||||
<!-- wp:oribi/platform-section {"label":"Our Devices","heading":"Commercial-Grade Hardware, Consumer-Level Simplicity","lead":"Our players are designed to be set up in minutes and forgotten about for years. No IT degree required. "} -->
|
||||
<!-- wp:oribi/platform-row {"heading":"Works With Your Existing Screens","description":"Our player devices connect to any screen with an HDMI port, no proprietary hardware required. Already have displays? Plug in and go. Need a full setup? We offer bundled player-and-display packages too.","btnText":"Get a Quote","btnUrl":"/contact","deviceAnim":true} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Never Goes Dark","description":"Every player caches content locally. If your internet connection drops, your displays continue running seamlessly with the latest synced content. When connectivity returns, new content pulls down automatically. No manual steps, no reboots.","btnText":"See Features","btnUrl":"/features","reversed":true,"neverGoesDark":true} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Custom Display Solutions","description":"Create a polished, on-brand experience with our Custom Display Platform. Seamlessly integrated with your interactive signage, it ensures your logo and branding appear consistently across every screen, reinforcing recognition at every touchpoint. Ideal for businesses looking to elevate their presence and deliver a professional, cohesive visual identity.","btnText":"Get a Quote","btnUrl":"/contact","brandedAnim":true} /-->
|
||||
<!-- /wp:oribi/platform-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"alt","label":"Device Specifications","heading":"What\u0027s Inside Every Player","lead":"Commercial-grade components designed for continuous operation in any environment.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-display","title":"4K Output","description":"Crystal-clear 4K resolution output via HDMI for stunning visual quality on any display."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-wifi","title":"Dual Connectivity","description":"Built-in Wi-Fi and Ethernet for flexible network connectivity options in any installation."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-hard-drive","title":"Local Storage","description":"On-device storage caches your content for seamless offline playback and instant startup."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-shield-halved","title":"Secure Boot","description":"Hardware-level security with encrypted storage and secure boot ensures tamper-proof operation."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-rotate","title":"Auto Updates","description":"Over-the-air firmware updates keep your devices current without manual intervention or downtime."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-temperature-low","title":"Silent Operation","description":"Fanless design means zero noise, making our players perfect for quiet environments like lobbies and restaurants."} /-->
|
||||
<!-- wp:oribi/feature-section {"variant":"alt","label":"Device Specifications","heading":"What's Inside Every Player","lead":"Purpose-built components selected for reliability, performance, and silent operation in any environment."} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-display","title":"4K Output","description":"Crisp 4K resolution over HDMI for stunning visuals on any display size, from 32-inch panels to 75-inch video walls."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-wifi","title":"Dual Connectivity","description":"We offer players with Wi-Fi and Ethernet connectivity. Choose the connection that suits your environment, or use both for redundancy."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-hard-drive","title":"Local Storage","description":"On-device storage caches your full content library for instant startup and uninterrupted offline playback."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-rotate","title":"Over-the-Air Updates","description":"Firmware updates deploy remotely and automatically. Your devices stay current without site visits or manual intervention."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-temperature-low","title":"Silent \u0026amp; Fanless","description":"Passive cooling means zero noise. Ideal for quiet spaces like hotel lobbies, meeting rooms, and restaurants."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/intro-section {"variant":"normal","label":"Bundles Available","heading":"Complete Display Solutions","description":"Need screens too? We offer bundled packages that include our player device paired with a commercial-grade display, rated for 24/7 operation with enhanced brightness and durability. Available in a range of sizes from 32\" to 75\". Contact us for custom configurations and volume pricing.","visual":""} /-->
|
||||
<!-- wp:oribi/feature-section {"variant":"normal","label":"Outdoor Hardware","heading":"Built for the Elements","lead":"For outdoor markets, forecourts, and external signage \u2014 weather-resistant display options that perform rain or shine.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-cloud-sun-rain","title":"IP-Rated Enclosures","description":"Weather-resistant housings protect player hardware from rain, dust, and temperature extremes. Rated for outdoor deployment year-round."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-sun","title":"High-Brightness Displays","description":"Commercial outdoor panels with 2,500+ nit brightness ensure content remains vivid and readable in direct sunlight."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-signal","title":"Cellular Connectivity","description":"Optional 4G/5G module for locations without Wi-Fi or wired internet. Combined with offline playback for total deployment flexibility."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Need Help Choosing?","text":"Our team can recommend the right device and display combination for your specific environment and use case.","btnText":"Request a Quote","btnUrl":"/contact"} /-->
|
||||
<!-- wp:html -->
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="devices-split-card">
|
||||
<div class="devices-split-card__panel">
|
||||
<h3>Pre-Configured OTS Players</h3>
|
||||
<p>Every player device ordered through OTS arrives pre-configured and already paired with your Command Center. Plug in power and HDMI, connect to your network, and your screens are ready to publish.</p>
|
||||
</div>
|
||||
<div class="devices-split-card__panel devices-split-card__panel--brand">
|
||||
<h3>Bring Your Own Player (BYO)</h3>
|
||||
<p>Already have compatible media players? We can onboard BYO hardware and connect it to your Command Center. Our team will confirm compatibility requirements and provide setup guidance before rollout.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- /wp:html -->
|
||||
|
||||
<!-- wp:oribi/intro-section {"variant":"normal","label":"Bundles Available","heading":"Player + Display Packages","description":"Don\u0027t have screens yet? We offer turnkey bundles pairing our player device with a commercial-grade display rated for 24/7 operation — brighter, tougher, and longer-lasting than consumer TVs. Available from 32\" to 75\". Contact us for volume pricing and custom configurations."} /-->
|
||||
|
||||
<!-- wp:oribi/value-section {"variant":"alt","label":"Warranty & Support","heading":"Protected Long After Setup","lead":"Every device ships with comprehensive coverage so you can deploy with confidence.","columns":3} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-file-shield","title":"Hardware Warranty","description":"Every player includes a standard manufacturer warranty covering defects and hardware failures. Extended warranty options are available for enterprise deployments."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-arrows-rotate","title":"Advance Replacement","description":"If a device fails, we ship a replacement immediately \u2014 before you return the faulty unit. Minimise downtime with our swap-first approach."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-headset","title":"Remote Diagnostics","description":"Our support team can diagnose and troubleshoot most issues remotely. Firmware updates, configuration changes, and health checks \u2014 all handled without a site visit."} /-->
|
||||
<!-- /wp:oribi/value-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Not Sure What You Need?","text":"Tell us about your space and we'll recommend the right player, display, and mounting solution for your environment.","btnText":"Request a Quote","btnUrl":"/contact"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
|
||||
@@ -1,33 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: FAQ
|
||||
* Slug: ots-signs/page-faq
|
||||
* Categories: oribi-pages
|
||||
* Keywords: faq, questions, answers, support, help
|
||||
* Post Types: page
|
||||
/*
|
||||
* Title: Faq
|
||||
* Slug: faq
|
||||
* Post Type: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"FAQ","title":"Frequently Asked Questions","description":"Got questions? We\u0027ve got answers. Find everything you need to know about our digital signage platform, pricing, and support."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-section {"label":"Platform \u0026 Pricing","heading":"Plans, Pricing \u0026 Platform","lead":"Common questions about our plans, what\u0027s included, and how pricing works."} -->
|
||||
<!-- wp:oribi/faq-item {"question":"What\u0027s included in the Essentials plan?","answer":"The Essentials plan includes up to 20 screens, a custom subdomain, shared CMS server, content scheduling with day-parting, integration with live data sources, unlimited user seats, and the ability to publish content to your signs in minutes. It\u0027s $7 per screen per month, or $70 per screen annually."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"What does the Pro plan include?","answer":"The Pro plan supports 500+ screens with a custom domain, dedicated CMS server, custom live data integrations, priority support, advanced analytics, SSO and role-based access, SLA guarantee, and a dedicated account manager. Contact us for pricing tailored to your needs."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"Are there any hidden fees?","answer":"No. Our pricing is fully transparent. The per-screen monthly or annual fee covers everything. CMS access, software updates, cloud hosting, and standard support. Content creation services and hardware are quoted separately."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"Can I switch plans later?","answer":"Absolutely. You can upgrade from Essentials to Pro at any time as your business grows. We\u0027ll handle the migration seamlessly with no disruption to your displays."} /-->
|
||||
return <<<'ORIBI_SYNC_CONTENT'
|
||||
<!-- wp:oribi/page-hero-animated {"label":"FAQ","title":"Your Questions, Answered","description":"Everything you need to know about our platform, pricing, setup, and support, in plain language."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-section {"label":"Platform u0026 Pricing","heading":"Plans, Pricing \u0026amp; What's Included","lead":"Straightforward answers about what you get and what it costs."} -->
|
||||
<!-- wp:oribi/faq-item {"question":"What's included in the Essentials plan?","answer":"Essentials gives you up to 50 screens on a shared CMS instance with a custom subdomain. You get full content scheduling with day-parting, DataSets, RSS feeds, social widgets, embedded HTML, menu boards, interactive layouts, Canva integration, offline playback, Proof of Play analytics with 30-day retention, unlimited users with standard roles, and two-factor authentication. Pricing is $7 per screen per month, or $70 per screen if you pay annually."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-item {"question":"What extra do I get with Pro?","answer":"Pro gives you unlimited screens on a dedicated CMS instance with a custom domain. On top of everything in Essentials, you get geo-location and weather-triggered scheduling, video wall support, ad campaigns with SSP monetisation, Dashboard Connector and custom API integrations, Audience Reporting with scheduled PDF reports, Proof of Play with 12+ month retention, SSO via SAML or CAS, custom user roles, extended audit trails, display map view, shell commands, in-house creative services, white-glove onboarding, priority support with a 4-hour SLA, a dedicated account manager, and a contractual SLA guarantee. Contact us for a tailored quote."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-item {"question":"Are there any hidden fees?","answer":"None. Your per-screen fee covers the CMS, cloud hosting, software updates, and standard support. Content creation services and hardware are quoted separately and always upfront."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-item {"question":"Can I upgrade later?","answer":"Yes, at any time. Moving from Essentials to Pro is seamless. We handle the migration behind the scenes with no disruption to your live displays."} /-->
|
||||
<!-- /wp:oribi/faq-section -->
|
||||
|
||||
<!-- wp:oribi/faq-section {"variant":"alt","label":"Setup \u0026 Integration","heading":"Getting Started","lead":"Everything about setup, installation, and integrating with your existing systems."} -->
|
||||
<!-- wp:oribi/faq-item {"question":"How long does setup take?","answer":"Most installations are up and running within a day. Plug in our player device, connect to your network, and your content appears on screen. Our team handles the CMS configuration and can have your first content ready to display immediately."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"Can I use my existing screens?","answer":"Yes! Our players work with any screen that has an HDMI input. TVs, commercial displays, or monitors. If it has HDMI, our player works with it. No need to replace your existing hardware."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"How do live data integrations work?","answer":"We can connect your existing web dashboards, APIs, RSS feeds, social media accounts, and other data sources to your digital signage. Data updates are reflected in real-time on your displays. The Essentials plan supports standard integrations, while Pro includes custom integration development."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"Do I need special internet bandwidth?","answer":"Our players are designed to be bandwidth-efficient. Content is cached locally and synced incrementally. A standard business internet connection is more than sufficient. For locations with limited connectivity, our offline playback ensures your content keeps running."} /-->
|
||||
<!-- wp:oribi/faq-section {"variant":"alt","label":"Setup \u0026 Integration","heading":"Getting Up and Running","lead":"What to expect when you set up your first screen and connect your systems."} -->
|
||||
<!-- wp:oribi/faq-item {"question":"How quickly can I be up and running?","answer":"Most installations go live within a day. Plug in the player device, connect it to your network, and your content appears on screen. We configure your CMS in advance and can have your first content loaded and ready before the hardware arrives."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-item {"question":"Do I need to buy new screens?","answer":"No. Our players work with any display that has an HDMI port, consumer TVs, commercial panels, or monitors you already own. If you do need screens, we offer bundled player-and-display packages built for commercial use."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-item {"question":"How do live data integrations work?","answer":"Every plan includes DataSets, RSS feeds, social widgets, and embedded HTML, data updates appear on screen in real time. Pro adds the Dashboard Connector for secure third-party service connections, custom API integrations for bespoke data sources, and the SSP Connector for ad monetisation."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-item {"question":"What kind of internet connection do I need?","answer":"A standard business broadband connection is more than enough. Our players sync content incrementally and cache everything locally, so bandwidth usage is minimal. For locations with unreliable connectivity, offline playback ensures your displays never go dark."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"Can I use touchscreens for interactive kiosks?","answer":"Yes. Our platform supports interactive touchscreen actions including wayfinding directories, self-check-in flows, product lookup, and multi-level navigation menus. Pair a compatible touchscreen display with our player device, and the CMS handles the rest \u2014 no custom development needed. Interactive layouts are available on both Essentials and Pro plans."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"Does the platform support multiple languages?","answer":"Yes. You can create and schedule content in any language, and use day-parting or location-based scheduling to show the right language at the right time. The CMS interface itself is in English, but all screen-facing content supports full Unicode character sets including CJK, Arabic, and Cyrillic scripts."} /-->
|
||||
<!-- /wp:oribi/faq-section -->
|
||||
|
||||
<!-- wp:oribi/faq-section {"label":"Support \u0026 Security","heading":"Support, Security \u0026 Reliability","lead":"How we keep your signage network secure, reliable, and fully supported."} -->
|
||||
<!-- wp:oribi/faq-item {"question":"What happens if my internet goes down?","answer":"Our intelligent player devices continue playing cached content even when offline. When connectivity returns, new content syncs automatically. Your displays never go dark."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"How secure is the platform?","answer":"We use enterprise-grade security throughout our stack: end-to-end encryption for all communications, secure boot on player devices, role-based access control in the CMS, and SOC 2-aligned cloud infrastructure. Your content and network are always protected."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"What kind of support do you offer?","answer":"Essentials plans include email support with a 24-hour response time. Pro plans include priority support with a dedicated account manager, phone support, and guaranteed SLA response times."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"Can I create content myself, or do you do it for me?","answer":"Both! Our CMS is designed for self-service content creation with drag-and-drop simplicity. We also offer professional content creation services: photography, video production, and graphic design, to make your signage look its absolute best."} /-->
|
||||
<!-- wp:oribi/faq-section {"label":"Support u0026 Security","heading":"Keeping Your Network Secure and Supported","lead":"How we protect your content, keep your screens online, and support you when you need us."} -->
|
||||
<!-- wp:oribi/faq-item {"question":"What happens if the internet goes down?","answer":"Your displays carry on. Every player caches content locally and keeps playing even without a connection. When the internet returns, new content syncs automatically. Your screens will never go dark because of a network blip."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"How secure is the platform?","answer":"Security is built into every layer of the platform. Two-factor authentication, role-based access control, and audit trails keep your CMS locked down. Pro adds SSO via SAML or CAS for enterprise identity management. Your content and your network stay protected."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-item {"question":"How do you handle data privacy?","answer":"We take data privacy seriously. All data is processed and stored securely. We can provide data processing agreements (DPAs) on request, and we\u0027re happy to discuss your specific data handling requirements. Contact us for full details on our privacy practices."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-item {"question":"What warranty comes with the player devices?","answer":"Every player device ships with a standard manufacturer warranty covering hardware defects and failures. Extended warranty options are available for enterprise deployments. If a device fails under warranty, we offer advance replacement \u2014 we ship the new unit before you return the faulty one, so your screens stay live."} /-->
|
||||
<!-- wp:oribi/faq-item {"question":"What support is available?","answer":"Essentials customers get email support with next-business-day response. Pro customers get priority support, a dedicated account manager, phone access, and guaranteed SLA response times."} /-->
|
||||
|
||||
<!-- wp:oribi/faq-item {"question":"Can I create my own content or do you handle it?","answer":"Both. The CMS is designed for self-service content creation with drag-and-drop simplicity. If you'd prefer polished visuals, our in-house creative team offers professional photography, video production, and graphic design services."} /-->
|
||||
<!-- /wp:oribi/faq-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Still Have Questions?","text":"Our team is happy to answer anything not covered here. Get in touch and we\u0027ll help.","btnText":"Contact Us","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/cta-banner {"heading":"Something Not Covered Here?","text":"Drop us a message and we'll get back to you with a clear answer, usually within one business day.","btnText":"Contact Us","btnUrl":"/contact"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
|
||||
@@ -1,34 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* Title: Features
|
||||
* Slug: ots-signs/page-features
|
||||
* Categories: oribi-pages
|
||||
* Keywords: features, platform, content scheduling, cloud CMS, real-time data
|
||||
* Post Types: page
|
||||
* Slug: features
|
||||
* Post Type: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Platform","title":"Technology Designed to Work for You","description":"Our application platform lets you publish content instantly across any network, with built-in real-time analytics. Its secure, cloud-native architecture scales effortlessly while keeping deployments fast and maintenance minimal."} /-->
|
||||
|
||||
<!-- wp:oribi/platform-section {"label":"Core Features","heading":"Powerful Tools, Simple Experience","lead":"Everything you need to create, schedule, and manage stunning digital signage content, from a single dashboard."} -->
|
||||
<!-- wp:oribi/platform-row {"heading":"Manage All Your Screens in One Place","description":"Our cloud CMS offers the power and flexibility to manage digital displays for businesses of all sizes. Whether you\u0027re a single location or a multi-site enterprise, our digital signage network is built to grow with you.","btnText":"Get Started","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Dynamic Content Scheduling","description":"Effortlessly schedule your content for maximum impact. Plan ahead by setting content to play at specific times, daypart, or even trigger based on real-world events. Automate your messaging to ensure the right information is displayed at the right time.","btnText":"See Pricing","btnUrl":"/pricing","reversed":true} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Use Existing Screens","description":"Our digital signage players work on any screen with HDMI, so you can easily integrate them into your current setup. If you need a complete solution, we also offer bundled packages that include both the player and a high-quality commercial-grade display.","btnText":"View Devices","btnUrl":"/devices"} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Secure \u0026 Reliable","description":"Enterprise-grade security safeguards your content and network, while our advanced hosting platform guarantees rock-solid reliability. Plus, our intelligent player devices are designed to continue playing content even when offline.","btnText":"Learn More","btnUrl":"/about","reversed":true} /-->
|
||||
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":"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":"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-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"alt","label":"Capabilities","heading":"Built for Modern Business","lead":"From content creation to analytics, our platform covers every step of your digital signage journey.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-cloud","title":"Cloud-Native CMS","description":"Access your content management system from anywhere. No software to install. Just log in and start publishing."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-clock","title":"Content Scheduling","description":"Set content to play at specific times with day-parting. Automate your messaging for maximum impact."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-line","title":"Live Data Integration","description":"Connect your existing web dashboards, social feeds, and real-time data sources directly to your displays."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-wifi","title":"Offline Playback","description":"Content keeps playing even when the internet goes down. Our players cache content locally for uninterrupted display."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-users","title":"Unlimited User Seats","description":"Add as many team members as you need. No per-user fees or access restrictions on any plan."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-shield-halved","title":"Enterprise Security","description":"End-to-end encryption, role-based access control, and secure cloud infrastructure protect your content and network."} /-->
|
||||
<!-- 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."} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-clock","title":"Day-Part Scheduling","description":"Assign content to specific times of day — breakfast menus in the morning, happy hour promos in the evening. Set it once and it repeats automatically."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-arrows-rotate","title":"Recurring Campaigns","description":"Schedule campaigns with daily, weekly, or custom recurrence patterns. Plan weeks of content ahead and let the platform execute on time, every time."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-location-dot","title":"Location \u0026amp; Weather Triggers","description":"Show region-specific promotions based on player location. Trigger content automatically when weather conditions change — sunscreen ads when it's sunny, hot drinks when it rains."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-bolt","title":"Interrupt \u0026amp; Priority Content","description":"Push emergency alerts or time-sensitive content to any screen instantly. Interrupt layouts override the schedule without disrupting your planned campaigns."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/value-section {"variant":"normal","label":"Why Choose Us","heading":"The OTS Signs Advantage","lead":"We don\u0027t just provide software. We deliver a complete digital signage experience.","columns":3} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-camera","title":"Professional Content","description":"Our in-house photography and video production team creates stunning visuals that make your signage stand out."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-rocket","title":"Publish in Minutes","description":"Upload content and push it to your screens instantly. No waiting, no complex workflows. Just fast deployment."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-headset","title":"Dedicated Support","description":"Our team is always available to help with setup, content creation, troubleshooting, and ongoing optimisation."} /-->
|
||||
<!-- 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":"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":"Runs on Your Hardware","description":"Our player software runs on Android, Windows, Linux, Samsung Tizen, LG webOS, and Chrome OS. Portrait or landscape. Single screen or synchronised video wall. Content is cached locally, so your displays keep running seamlessly even when the internet drops. Not sure which hardware to choose? We'll recommend and configure the right player for your setup.","btnText":"See Devices","btnUrl":"/devices"} /-->
|
||||
<!-- /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} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-database","title":"Live Data Feeds","description":"Connect DataSets, remote JSON sources, and CSV imports directly to your layouts. Data refreshes automatically so your screens always show the latest information."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-utensils","title":"Digital Menu Boards","description":"Build product categories and pricing lists that update across every location. Change a price once and it's live everywhere — no screen-by-screen editing."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-code","title":"Web Pages \u0026amp; Dashboards","description":"Embed any web page, internal dashboard, or HTML content directly on screen. Show operational KPIs, analytics dashboards, or custom web apps in real time."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-rss","title":"Tickers \u0026amp; Social Feeds","description":"Display RSS news tickers, social media feeds, and live notifications. Keep your audience informed with auto-updating content streams."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-palette","title":"Canva \u0026amp; Stock Images","description":"Design in Canva and publish straight to your displays — no export/import steps. Browse Pixabay's stock image library directly from the CMS."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-hand-pointer","title":"Interactive Touchscreens","description":"Add buttons, navigation, and actions to your layouts. Let your audience browse products, find directions, or explore content on touch-enabled displays."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"normal","label":"Integrations","heading":"Connects to Your Existing Tools","lead":"Bring your data, content, and workflows to screen without custom development.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-line","title":"Live Dashboards","description":"Stream web dashboards, BI tools, and real-time KPIs directly to office screens, operations centres, and management displays. Pro only."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-palette","title":"Canva Integration","description":"Design content in Canva and publish directly to your signage network. Included on both Essentials and Pro plans — no export-and-upload workflow needed."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-cash-register","title":"POS & Menu Sync","description":"Connect your point-of-sale system to digital menu boards. Prices, items, and availability update on screen automatically as you update your POS."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-plug","title":"Dashboard Connector","description":"Securely pipe data from web dashboards, BI tools, and internal portals to any display. Ideal for KPI walls, operations centres, and trading floors. Pro only."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-code","title":"REST API","description":"Full API access for developers. Integrate custom data sources, automate content workflows, or build your own front-end on top of the OTS Signs platform."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-rectangle-ad","title":"SSP & Ad Monetisation","description":"Turn your screens into revenue streams. Connect supply-side platforms, set plays-per-hour caps, and run ad campaigns alongside your own content. Pro only."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"label":"Analytics \u0026amp; Reporting","heading":"Prove Every Play","lead":"Know exactly what's playing, where, and when. Export reports, automate delivery, and monitor the health of every screen in your network."} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-pie","title":"Proof of Play","description":"Track every piece of content at the layout, media, and widget level. Configurable retention depth lets you store as much history as you need."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-file-pdf","title":"Scheduled Reports","description":"Set up automated PDF reports and have them emailed to stakeholders on your schedule. Export raw data as CSV for deeper analysis."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-heart-pulse","title":"Display Health","description":"Monitor connection status, storage usage, and player performance in real time. Spot issues before they affect your audience."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-box-archive","title":"Content Usage","description":"See which media is assigned to layouts and which is unused. Library usage reports by user help you manage storage and keep your library clean."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/value-section {"variant":"alt","label":"Secure \u0026amp; Scalable","heading":"Enterprise Trust, Simple Setup","lead":"Every plan includes the security foundations your business needs. Scale your team and your network without worrying about per-user fees or access limits.","columns":4} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-lock","title":"Two-Factor Auth","description":"Secure every login with 2FA on every plan. Your CMS and player devices are protected at every layer."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-user-shield","title":"Roles \u0026amp; Permissions","description":"Predefined admin, editor, and viewer roles on every plan. Pro adds SSO via SAML or CAS, custom role definitions, and feature-level access control."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-clipboard-list","title":"Audit Trail","description":"Full activity logging with configurable retention. Know who changed what, when — for compliance, accountability, and peace of mind."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-users","title":"Unlimited Users","description":"Invite your entire team at no extra cost. No per-seat charges, no access restrictions, no gatekeeping — on any plan."} /-->
|
||||
<!-- /wp:oribi/value-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"See It in Action","text":"Request access to our live demo instance and experience the platform for yourself.","btnText":"Request Demo","btnUrl":"/demo"} /-->
|
||||
<!-- wp:oribi/cta-banner {"heading":"More Than Just Software","text":"Our in-house creative team produces professional photography, video, and graphic design for your screens. Our support team is available when you need us — not hidden behind a ticket queue. Get hands-on access to a live demo and see every feature in action.","btnText":"Request Demo","btnUrl":"/demo"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
|
||||
@@ -1,32 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Home Page
|
||||
* Slug: ots-signs/page-home
|
||||
* Categories: oribi-pages
|
||||
* Keywords: home, digital signage, landing, hero
|
||||
* Post Types: page
|
||||
/*
|
||||
* Title: Home
|
||||
* Slug: home
|
||||
* Post Type: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/hero-animated {"label":"● Digital Signage Solutions","title":"Turn any screen into a dynamic communication tool.","highlightWord":"dynamic","description":"Digital signage is the modern way to connect with your audience. From eye-catching retail displays to dynamic informational screens, we craft tailored solutions that capture attention and deliver your message.","primaryBtnText":"Get Started","primaryBtnUrl":"/contact","secondaryBtnText":"Request Demo","secondaryBtnUrl":"/demo","stat1Value":"6+","stat1Label":"Industries Served","stat2Value":"500+","stat2Label":"Screens Supported","stat3Value":"99.9%","stat3Label":"Uptime"} /-->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"normal","label":"The Complete Package","heading":"Everything You Need for Engaging Digital Signage","lead":"High-quality visuals, real-time data, and reliable playback, all managed from one powerful platform.","columns":4} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-camera","title":"Showcase Your Products","description":"Professional photography and video production services to showcase your products, services, or environment with polished, engaging content.","url":"/features"} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-line","title":"Live Data Integrations","description":"Integrate your existing web dashboards and real-time data with our platform to bring your most important information to life on digital signage.","url":"/features"} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-utensils","title":"Digital Menu Boards","description":"Make your menu as appealing as your product. We incorporate your branding and include high-quality photography to showcase your offerings.","url":"/solutions"} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-wifi","title":"Offline Playback Support","description":"Our intelligent player devices keep your message on screen even when the internet isn\u0027t available, ensuring reliability in any location.","url":"/devices"} /-->
|
||||
return <<<'ORIBI_SYNC_CONTENT'
|
||||
<!-- wp:oribi/hero-animated {"label":"● Digital Signage Solutions","title":"Turn any screen into a dynamic communication tool.","highlightWord":"dynamic","description":"Digital signage is the modern way to connect with your audience. From eye-catching retail displays to dynamic informational screens, we craft tailored solutions that capture attention and deliver your message.","secondaryBtnText":"Request Demo","secondaryBtnUrl":"/demo","stat1Value":"4K","stat1Label":"Resolution Supported","stat2Value":"500+","stat2Label":"Screens Supported","stat3Value":"99.9%","stat3Label":"Uptime"} /-->
|
||||
|
||||
<!-- wp:oribi/use-cases /-->
|
||||
|
||||
<!-- wp:oribi/platform-section {"label":"The Complete Package","heading":"Everything You Need for Engaging Digital Signage","lead":"High-quality visuals, real-time data, and reliable playback, all managed from one powerful platform."} -->
|
||||
<!-- wp:oribi/platform-row {"heading":"Professional Content Creation","description":"Our in-house photography and video production services showcase your products, services, and environment with polished, engaging visuals. From digital menu boards to branded promotions, we create content that captures attention.","btnText":"Creative Services","btnUrl":"/design","cameraAnim":true} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Live Data \u0026amp; Web Dashboards","description":"Integrate your existing web dashboards, social feeds, and real-time data sources directly to your displays. Bring your most important information to life on screen, automatically and effortlessly.","btnUrl":"/features","reversed":true,"isDashboard":true} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Reliable on Any Screen","description":"Our intelligent player devices work on any screen with HDMI, and keep your message running even when the internet goes down. Enterprise-grade hardware designed for uninterrupted, always-on signage.","btnText":"View Devices","btnUrl":"/devices","tvStick":true} /-->
|
||||
<!-- /wp:oribi/platform-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"alt","label":"Who It\u0027s For","heading":"Solutions for Every Industry","lead":"Modern businesses need real-time communication. Digital signage helps you connect, inform, and engage.","columns":4} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-hotel","title":"Hospitality","description":"Showcase menus, promotions, and special events while guiding guests through lobbies, restaurants, and bars.","url":"/solutions"} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-store","title":"Retail","description":"Drive product upsells, announce flash-sales, and offer in-store navigation with fresh, eye-catching displays.","url":"/solutions"} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-building","title":"Corporate","description":"Display company announcements, KPI dashboards, and employee alerts across office screens and common areas.","url":"/solutions"} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-graduation-cap","title":"Education","description":"Broadcast class schedules, announcements, and interactive learning content in campuses and auditoriums.","url":"/solutions"} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-heart-pulse","title":"Healthcare","description":"Queue management, patient wayfinding, and public health messaging across clinics, hospitals, and waiting areas.","url":"/solutions"} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-dumbbell","title":"Fitness & Leisure","description":"Class schedules, motivational content, and live performance metrics on screens throughout gyms and leisure centres.","url":"/solutions"} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-cloud-sun-rain","title":"Outdoor Signage","description":"Weather-resistant displays with high-brightness panels, IP-rated enclosures, and 4G/5G connectivity for markets, forecourts, and events.","url":"/outdoor"} /-->
|
||||
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-hand-pointer","title":"Interactive Kiosks","description":"Touchscreen wayfinding, self-check-in, product lookup, and directory navigation for retail, healthcare, and transport.","url":"/kiosks"} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/image-section {"variant":"alt","label":"Who It's For","heading":"Solutions for Every Industry","lead":"Modern businesses need real-time communication. Digital signage helps you connect, inform, and engage.","columns":4} -->
|
||||
<!-- wp:oribi/image-card {"iconType":"fontawesome","faIcon":"fas fa-hotel","title":"Hospitality","description":"Showcase menus, promotions, and special events while guiding guests through lobbies, restaurants, and bars.","url":"/solutions"} /-->
|
||||
<!-- wp:oribi/image-card {"iconType":"fontawesome","faIcon":"fas fa-store","title":"Retail","description":"Drive product upsells, announce flash-sales, and offer in-store navigation with fresh, eye-catching displays.","url":"/solutions"} /-->
|
||||
<!-- wp:oribi/image-card {"iconType":"fontawesome","faIcon":"fas fa-building","title":"Corporate","description":"Enhance meeting experiences with Teams integration. Communicate schedules, company news, and employee alerts.","url":"/solutions"} /-->
|
||||
<!-- wp:oribi/image-card {"iconType":"fontawesome","faIcon":"fas fa-graduation-cap","title":"Education","description":"Broadcast class schedules, announcements, and interactive learning content in campuses and auditoriums.","url":"/solutions"} /-->
|
||||
<!-- /wp:oribi/image-section -->
|
||||
<!-- wp:oribi/feature-section {"variant":"alt","label":"Integrations","heading":"Connects to the Tools You Already Use","lead":"Bring your existing systems, content tools, and data sources directly to your screens — no custom development required.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-line","title":"Live Dashboards","description":"Stream web dashboards, BI tools, and real-time KPIs directly to your displays. Ideal for operations centres and management screens.","url":"/features"} /-->
|
||||
|
||||
<!-- wp:oribi/link-section {"label":"Explore","heading":"Take the Next Step","lead":"See our plans, explore devices, or request a demo.","columns":3} -->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-tags","title":"Pricing Plans","description":"Affordable, scalable options for businesses of all sizes. See what\u0027s included at every level.","linkText":"View Pricing","linkUrl":"/pricing"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-microchip","title":"Player Devices","description":"Enterprise-grade hardware designed for reliability, with offline playback and HDMI compatibility.","linkText":"See Devices","linkUrl":"/devices"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-play-circle","title":"Request a Demo","description":"See our platform in action. Request access to our live demo instance.","linkText":"Try It Out","linkUrl":"/demo"} /-->
|
||||
<!-- /wp:oribi/link-section -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-palette","title":"Canva","description":"Design stunning signage content in Canva and publish it directly to your screens — included on every plan.","url":"/features"} /-->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Ready to Transform Your Screens?","text":"Get in touch to discuss your digital signage needs. No pressure, no jargon. Just a conversation about how we can help.","btnText":"Get Started Today","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-cash-register","title":"POS Systems","description":"Sync your menu boards with your point-of-sale system so prices, items, and availability update automatically.","url":"/solutions"} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/stat-section {"variant":"normal","label":"Trusted Platform","heading":"Built for Businesses That Can\u0027t Afford Downtime","lead":"From independent cafés to multi-site enterprises, our platform runs where reliability matters most.","columns":4} -->
|
||||
<!-- wp:oribi/stat-card {"value":"99.9%","label":"Platform Uptime","description":"Reliable cloud infrastructure with built-in redundancy to keep your screens running."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"24/7","label":"Always-On Operation","description":"Commercial-grade players rated for continuous operation with offline playback built in."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"4K","label":"Ultra-HD Output","description":"Crisp, vibrant visuals on any HDMI display from 32-inch panels to 75-inch video walls."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"0","label":"Per-User Fees","description":"Unlimited team access on every plan. No seat charges, no gatekeeping."} /-->
|
||||
<!-- /wp:oribi/stat-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Ready to Transform Your Screens?","text":"See our plans, explore player devices, or request a live demo. No pressure, just a conversation about how we can help.","btnText":"Start Free Trial","btnUrl":"/trial","secondaryBtnText":"Get in Touch","secondaryBtnUrl":"/contact"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
|
||||
35
pages/kiosks.php
Normal file
35
pages/kiosks.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Interactive Kiosks
|
||||
* Slug: ots-signs/page-kiosks
|
||||
* Categories: oribi-pages
|
||||
* Keywords: kiosks, interactive, touchscreen, wayfinding, self-service
|
||||
* Post Types: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Interactive Kiosks","title":"Turn Screens into Self-Service Experiences","description":"Touchscreen kiosks for wayfinding, self-check-in, product lookup, and self-ordering — powered by the same platform you use for all your digital signage."} /-->
|
||||
|
||||
<!-- wp:oribi/platform-section {"label":"Capabilities","heading":"Interactive Signage, No Custom Development","lead":"Our platform\u0027s interactive mode transforms any compatible touchscreen into a self-service kiosk — configured entirely from the CMS."} -->
|
||||
<!-- wp:oribi/platform-row {"heading":"Wayfinding \u0026 Directories","description":"Guide visitors through buildings, campuses, and venues with interactive maps and searchable directories. Visitors tap to find rooms, departments, or points of interest — with turn-by-turn guidance on screen. Ideal for hospitals, universities, corporate offices, and transport hubs.","btnText":"See Features","btnUrl":"/features"} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Self-Check-In \u0026 Registration","description":"Replace front-desk queues with touchscreen check-in flows. Visitors, patients, and guests register on arrival, receive queue numbers, and get directed to the right location — all without staff intervention. Frees your team to focus on the people who need personal attention.","btnText":"See Pricing","btnUrl":"/pricing","reversed":true} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Product Lookup \u0026 Self-Ordering","description":"Let customers browse your catalogue, check availability, and place orders directly from in-store kiosks. Sync with your POS system to keep prices and stock levels accurate in real time. Perfect for retail, QSR, and hospitality environments.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
|
||||
<!-- /wp:oribi/platform-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"alt","label":"Use Cases","heading":"Kiosks for Every Environment","lead":"Interactive displays solve different problems in different industries. Here\u0027s how businesses use them.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-heart-pulse","title":"Healthcare","description":"Patient self-check-in, department wayfinding, and queue management across clinics, hospitals, and multi-site health networks."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-store","title":"Retail","description":"In-store product lookup, catalogue browsing, loyalty programme sign-up, and self-ordering kiosks that reduce queue times."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-hotel","title":"Hospitality","description":"Guest self-check-in, restaurant menu browsing, concierge information, and venue wayfinding for hotels and conference centres."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-train-subway","title":"Transport","description":"Station wayfinding, service information, and interactive journey planners at terminals, stations, and transport hubs."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-building","title":"Corporate","description":"Visitor registration, meeting room directories, and campus wayfinding for offices, co-working spaces, and business parks."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-graduation-cap","title":"Education","description":"Campus maps, building directories, event information boards, and student self-service terminals across university and school sites."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/value-section {"variant":"normal","label":"How It Works","heading":"From CMS to Touchscreen in Minutes","lead":"No app development, no custom code. Build interactive experiences using the same tools you already know.","columns":3} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-layer-group","title":"Visual Layout Builder","description":"Design interactive screens with our drag-and-drop layout editor. Add buttons, navigation menus, search bars, and content zones \u2014 all visually."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-arrows-rotate","title":"Real-Time Sync","description":"Update kiosk content from the CMS and it goes live instantly. Change directories, menus, or maps without touching the physical device."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-shield-halved","title":"Locked-Down Mode","description":"Kiosk mode locks the device to your application. Users can only interact with your content \u2014 no access to system settings, browsers, or other apps."} /-->
|
||||
<!-- /wp:oribi/value-section -->
|
||||
|
||||
<!-- wp:oribi/intro-section {"variant":"alt","label":"Hardware","heading":"Compatible Touchscreen Displays","description":"Our player devices work with any HDMI touchscreen display. We can recommend and supply commercial-grade interactive panels rated for high-traffic public environments \u2014 from compact 22-inch countertop units to freestanding 55-inch floor kiosks. Contact us for recommendations and bundled pricing.","visual":""} /-->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Ready to Deploy Interactive Kiosks?","text":"Tell us about your environment and we\u0027ll recommend the right hardware, layout, and configuration for your use case.","btnText":"Start Free Trial","btnUrl":"/trial","secondaryBtnText":"Get a Quote","secondaryBtnUrl":"/contact"} /-->
|
||||
40
pages/outdoor.php
Normal file
40
pages/outdoor.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Outdoor Signage
|
||||
* Slug: ots-signs/page-outdoor
|
||||
* Categories: oribi-pages
|
||||
* Keywords: outdoor, weatherproof, high-brightness, IP-rated, enclosures
|
||||
* Post Types: page
|
||||
*/
|
||||
?>
|
||||
<!-- 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-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} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-cloud-sun-rain","title":"Weather-Triggered Scheduling","description":"Automatically switch content based on local weather conditions. Promote ice cream on sunny days, hot drinks when it\u0027s cold, or umbrellas when it rains. Pro plan feature."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-map-location-dot","title":"Geo-Location Scheduling","description":"Show different content on different screens based on their geographic location. Run region-specific promotions, localised messaging, or market-specific offers. Pro plan feature."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-clock","title":"Daylight-Aware Day-Parting","description":"Schedule content by time of day to match foot traffic patterns. Morning commuters see different messaging than evening shoppers. Available on both plans."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"normal","label":"Use Cases","heading":"Where Outdoor Signage Works","lead":"Digital displays are replacing static posters and billboards across every outdoor environment.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-tent","title":"Markets \u0026 Events","description":"From farmers\u0027 markets to music festivals, outdoor displays add a professional edge for vendor listings, schedules, wayfinding, and sponsor promotions."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-gas-pump","title":"Forecourts \u0026 Drive-Throughs","description":"High-visibility menu boards, promotional offers, and queue management displays for petrol stations, car washes, and drive-through restaurants."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-bus","title":"Transport Stops","description":"Real-time departure boards, route maps, service alerts, and passenger information at bus stops, train platforms, and ferry terminals."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-building-columns","title":"Building Exteriors","description":"Promotional displays, tenant directories, and digital notice boards mounted on building fa\u00e7ades, entrances, and public-facing walls."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-dumbbell","title":"Sports \u0026 Leisure","description":"Scoreboards, fixture schedules, sponsor displays, and wayfinding at stadiums, sports centres, and outdoor recreational facilities."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-tree-city","title":"Public Spaces","description":"Council information boards, park signage, civic announcements, and community event listings for local authorities and public venues."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/stat-section {"variant":"alt","label":"Built to Last","heading":"Hardware Specifications for Outdoor Deployment","lead":"Every component is selected for durability, performance, and long-term reliability in harsh conditions.","columns":4} -->
|
||||
<!-- wp:oribi/stat-card {"value":"2,500+","label":"Nit Brightness","description":"Commercial outdoor panels visible in direct sunlight \u2014 5x brighter than a standard indoor TV."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"IP65","label":"Weather Rating","description":"Sealed enclosures protect against rain, dust, and humidity for permanent outdoor installation."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"4G/5G","label":"Cellular Ready","description":"Optional cellular module for locations without Wi-Fi or wired broadband infrastructure."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"24/7","label":"Continuous Operation","description":"Fanless, solid-state hardware rated for year-round outdoor operation without maintenance."} /-->
|
||||
<!-- /wp:oribi/stat-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Planning an Outdoor Deployment?","text":"Tell us about your location, environment, and what you want your screens to show. We\u0027ll recommend the right hardware and configuration.","btnText":"Get a Quote","btnUrl":"/contact","secondaryBtnText":"View All Devices","secondaryBtnUrl":"/devices"} /-->
|
||||
33
pages/partners.php
Normal file
33
pages/partners.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Partners
|
||||
* Slug: ots-signs/page-partners
|
||||
* Categories: oribi-pages
|
||||
* Keywords: partners, reseller, white-label, channel, integration
|
||||
* Post Types: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Partner Programme","title":"Build Digital Signage into Your Offering","description":"White-label our platform, resell alongside your services, or embed signage capabilities into your own product via our API. Three ways to partner \u2014 one powerful platform."} /-->
|
||||
|
||||
<!-- wp:oribi/platform-section {"label":"Partnership Models","heading":"Choose the Model That Fits Your Business","lead":"Whether you\u0027re an AV integrator, IT consultancy, or SaaS company, we have a programme designed for you."} -->
|
||||
<!-- wp:oribi/platform-row {"heading":"White-Label Platform","description":"Rebrand the entire OTS Signs CMS with your own logo, domain, and colour scheme. Your clients see your brand \u2014 we provide the infrastructure, hosting, updates, and support behind the scenes. Deploy under your own identity with zero platform development cost. Ideal for agencies, managed service providers, and AV companies building a recurring revenue stream.","btnText":"Apply to Partner","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Reseller Programme","description":"Sell OTS Signs alongside your existing AV installations, IT services, or consultancy engagements. Access volume pricing, co-marketing materials, and a dedicated partner account manager. We handle the platform and support \u2014 you own the customer relationship and earn margin on every screen deployed.","btnText":"Learn More","btnUrl":"/contact","reversed":true} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"API \u0026 Platform Integration","description":"Embed digital signage capabilities directly into your own SaaS product using our REST API. Automate content workflows, manage screens programmatically, and build custom integrations that extend your platform\u0027s value. Full API documentation and developer support included.","btnText":"View API Docs","btnUrl":"/resources"} /-->
|
||||
<!-- /wp:oribi/platform-section -->
|
||||
|
||||
<!-- wp:oribi/value-section {"variant":"alt","label":"Why Partner With Us","heading":"What You Get as a Partner","lead":"Every partnership model includes the tools, support, and margins you need to grow your signage business.","columns":3} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-percent","title":"Competitive Margins","description":"Volume-based pricing ensures healthy margins on every deployment. The more screens you manage, the better your economics."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-user-tie","title":"Dedicated Partner Manager","description":"A named point of contact who understands your business, helps close deals, and ensures smooth onboarding for every customer you bring."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-bullhorn","title":"Co-Marketing Support","description":"Joint case studies, branded collateral, and co-marketing campaigns to help you promote digital signage to your existing customer base."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-graduation-cap","title":"Sales \u0026 Technical Training","description":"Get your team up to speed with platform training, sales enablement materials, and demo environments so you can sell and support with confidence."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-headset","title":"Priority Partner Support","description":"Escalated support for partner-managed accounts with faster SLAs, direct engineering access, and proactive issue resolution."} /-->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-rocket","title":"Early Access to Features","description":"Get advance notice and early access to new platform features, integrations, and hardware so you\u0027re always ahead of the curve."} /-->
|
||||
<!-- /wp:oribi/value-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"normal","label":"Ideal For","heading":"Who Partners With Us","lead":"Our partner programme is designed for businesses that already serve customers who need screens.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-tv","title":"AV Integrators","description":"Add software and managed services revenue to your hardware installations. Offer clients a complete signage solution under one roof."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-server","title":"IT Service Providers","description":"Extend your managed services portfolio with digital signage. Deploy and support screens as part of your existing IT infrastructure offering."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-code","title":"SaaS Companies","description":"Embed signage as a feature within your own platform. Use our API to power screen management without building the infrastructure yourself."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Ready to Partner?","text":"Tell us about your business and the partnership model you\u0027re interested in. We\u0027ll get back to you within one business day.","btnText":"Apply to Partner","btnUrl":"/contact"} /-->
|
||||
@@ -1,26 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* Title: Pricing
|
||||
* Slug: ots-signs/page-pricing
|
||||
* Categories: oribi-pages
|
||||
* Keywords: pricing, plans, affordable, scalable, essentials, pro
|
||||
* Post Types: page
|
||||
* Slug: pricing
|
||||
* Post Type: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Pricing","title":"Affordable Solutions, Scalable Options","description":"Simple, transparent pricing designed to grow with your business. Every plan includes our core platform features, no hidden fees, no surprises."} /-->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"normal","label":"All Plans Include","heading":"Core Features on Every Plan","lead":"No matter which plan you choose, you get the full power of our digital signage platform.","columns":4} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-clock","title":"Content Scheduling","description":"Day-parting, time-based triggers, and automated content rotation included on every plan."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-line","title":"Live Data Integration","description":"Connect your web dashboards and real-time data sources directly to your digital signage."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-users","title":"Unlimited User Seats","description":"Add your entire team, no per-user charges or access limitations."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-rocket","title":"Publish in Minutes","description":"Upload content and push it to your screens instantly across your entire network."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
return <<<'ORIBI_SYNC_CONTENT'
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Pricing","title":"Straightforward Pricing, No Surprises","description":"Every plan includes the full content engine. Scale your infrastructure, integrations, and support as you grow. No hidden fees, no per-user charges."} /-->
|
||||
|
||||
<!-- wp:oribi/pricing-section {"variant":"alt","label":"Choose Your Plan","heading":"Plans That Fit Your Business","lead":"Start small and scale as you grow. All plans come with our full-featured cloud CMS."} -->
|
||||
<!-- wp:oribi/pricing-card {"name":"Essentials","tagline":"$7/Screen Monthly · $70/Screen Annually","features":["Up to 20 screens","Custom subdomain","Shared CMS server","Content scheduling & day-parting","Integration with live data sources","Unlimited user seats","Publish content in minutes","Offline playback support","Email support"],"btnText":"Get Started","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/pricing-card {"name":"Pro","tagline":"Contact us for more information","features":["500+ screens","Custom domain","Dedicated CMS server","Custom live data integrations","Priority support","Advanced analytics","SSO & role-based access","SLA guarantee","Dedicated account manager"],"btnText":"Contact Sales","btnUrl":"/contact","featured":true,"badge":"Enterprise"} /-->
|
||||
<!-- wp:oribi/value-section {"label":"Included on Every Plan","heading":"The Full Content Engine, From Day One","lead":"Whether you choose Essentials or Pro, your team gets the same powerful tools to create, schedule, and publish.","columns":4} -->
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-clock","title":"Automated Scheduling","description":"Day-parting, date ranges, and recurring schedules. Your content plays at exactly the right time, automatically."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-rss","title":"Live Data to Screen","description":"Pull DataSets, RSS feeds, social widgets, and embedded HTML directly to your displays, updated in real time."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-users","title":"Unlimited Team Access","description":"Invite everyone who needs access. No per-user fees, no seat limits, no gatekeeping."} /-->
|
||||
|
||||
<!-- wp:oribi/value-card {"iconType":"fontawesome","faIcon":"fas fa-rocket","title":"Instant Publishing","description":"Upload content and push it live across your network in seconds, not hours."} /-->
|
||||
<!-- /wp:oribi/value-section -->
|
||||
|
||||
<!-- wp:oribi/pricing-section {"variant":"alt","label":"Choose Your Plan","heading":"Scale When You're Ready","lead":"Start with Essentials and upgrade seamlessly as your network grows. No disruption, no data loss."} -->
|
||||
<!-- wp:oribi/pricing-card {"name":"Essentials","tagline":"The full content engine for growing networks","price":"$7","pricePer":"per screen / month · or $70/screen annually (save 17%)","features":["Up to 50 screens","Custom subdomain","Shared CMS instance","Content scheduling \u0026amp; day-parting","DataSets, RSS, social \u0026amp; embedded widgets","Menu boards \u0026amp; interactive layouts","Unlimited users with standard roles","Canva integration","Offline playback","Proof of Play analytics (30-day retention)","Email support (next-business-day)"],"btnText":"Start Free Trial","btnUrl":"/trial"} /-->
|
||||
|
||||
<!-- wp:oribi/pricing-card {"name":"Pro","tagline":"Dedicated infrastructure, enterprise integrations u0026 white-glove service","price":"Custom","pricePer":"tailored to your network size","features":["Unlimited screens","Custom domain","Dedicated CMS instance","Geo-location \u0026amp; weather-triggered scheduling","Dashboard Connector \u0026amp; custom API integrations","Video wall support","Ad campaigns \u0026amp; SSP monetisation","SSO (SAML/CAS) \u0026amp; custom user roles","Proof of Play analytics (12+ month retention)","Audience Reporting \u0026amp; scheduled PDF reports","Priority support (4-hour SLA)","Contractual SLA guarantee","Custom Live Data Integrations"],"btnText":"Contact Sales","featured":true,"badge":"Enterprise"} /-->
|
||||
<!-- /wp:oribi/pricing-section -->
|
||||
|
||||
<!-- wp:oribi/intro-section {"variant":"normal","label":"Try Before You Buy","heading":"Want to See How Our Platform Works?","description":"Request access to our demo instance and explore the full platform, no commitment required. See how easy it is to create, schedule, and publish digital signage content.","visual":""} /-->
|
||||
<!-- wp:oribi/comparison-table {"label":"Plan Comparison","heading":"See Exactly What's Included","lead":"A full breakdown of what you get on each plan — so there are no surprises.","columns":["Essentials","Pro"],"rows":[{"group":"Scale \u0026 Infrastructure"},{"feature":"Screen limit","values":["Up to 50","Unlimited"]},{"feature":"CMS instance","values":["Shared","Dedicated"]},{"feature":"Custom subdomain","values":[true,true]},{"feature":"Custom domain","values":[false,true]},{"group":"Content \u0026 Scheduling"},{"feature":"Day-parting \u0026 date scheduling","values":[true,true]},{"feature":"Playlists \u0026 campaigns","values":[true,true]},{"feature":"Menu boards","values":[true,true]},{"feature":"Multi-language content","values":[true,true]},{"feature":"Interactive touchscreen actions","values":[true,true]},{"feature":"Multi-zone layouts","values":[true,true]},{"feature":"Emergency alerts \u0026 override","values":[false,true]},{"feature":"Geo-location scheduling","values":[false,true]},{"feature":"Weather-triggered scheduling","values":[false,true]},{"feature":"Video wall","values":[false,true]},{"feature":"Ad campaigns \u0026 plays-per-hour control","values":[false,true]},{"group":"Data \u0026 Integrations"},{"feature":"DataSets, RSS \u0026 tickers","values":[true,true]},{"feature":"Embedded HTML \u0026 web pages","values":[true,true]},{"feature":"Social feeds","values":[true,true]},{"feature":"Canva integration","values":[true,true]},{"feature":"POS \u0026 menu board sync","values":[true,true]},{"feature":"Dashboard Connector","values":[false,true]},{"feature":"Custom API integrations","values":[false,true]},{"feature":"SSP Connector (ad monetisation)","values":[false,true]},{"feature":"Custom Live Data Integrations","values":[false,true]},{"group":"Analytics \u0026 Reporting"},{"feature":"Proof of Play reporting","values":["30-day retention","12+ month retention"]},{"feature":"Scheduled PDF reports","values":[false,true]},{"feature":"Audience Reporting","values":[false,true]},{"feature":"Display health monitoring","values":[true,true]},{"group":"Users \u0026 Security"},{"feature":"Unlimited user seats","values":[true,true]},{"feature":"Predefined roles (admin/editor/viewer)","values":[true,true]},{"feature":"Custom user roles \u0026 feature access","values":[false,true]},{"feature":"Two-factor authentication","values":[true,true]},{"feature":"SSO (SAML / CAS)","values":[false,true]},{"feature":"Audit trail","values":["7-day retention","Extended retention"]},{"group":"Display Management"},{"feature":"Screen power on/off control","values":[true,true]},{"feature":"Offline playback","values":[true,true]},{"feature":"Portrait / landscape","values":[true,true]},{"feature":"Email alerts (player offline)","values":[true,true]},{"feature":"Periodic screenshots","values":[false,true]},{"feature":"Display map view","values":[false,true]},{"feature":"Shell commands \u0026 RS232","values":[false,true]},{"group":"Support \u0026 Services"},{"feature":"Email support","values":["Next-business-day","Same-day"]},{"feature":"Priority support","values":[false,"4-hour SLA"]},{"feature":"Dedicated account manager","values":[false,true]},{"feature":"In-house creative services","values":[false,"Included hours"]},{"feature":"White-glove onboarding","values":[false,true]},{"feature":"Contractual SLA guarantee","values":[false,true]}]} /-->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Ready to Get Started?","text":"Contact us to find the right plan for your business, or request a demo to see the platform in action.","btnText":"Get in Touch","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/intro-section {"label":"Try Before You Commit","heading":"Want to Explore the Platform First?","description":"Request access to our live demo instance and take the full CMS for a spin — create content, set up schedules, and see exactly how it works. No credit card, no obligation."} /-->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Questions About Pricing?","text":"We're happy to walk you through the plans, build a custom quote, or set up a demo so you can see the value firsthand.","btnText":"Get in Touch","btnUrl":"/contact"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
|
||||
@@ -1,30 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* Title: Resources
|
||||
* Slug: ots-signs/page-resources
|
||||
* Categories: oribi-pages
|
||||
* Keywords: resources, documentation, guides, knowledge base, support
|
||||
* Post Types: page
|
||||
* Slug: resources
|
||||
* Post Type: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Resources","title":"Knowledge \u0026 Support Resources","description":"Guides, documentation, and tools to help you get the most out of your digital signage platform."} /-->
|
||||
|
||||
<!-- wp:oribi/link-section {"variant":"normal","label":"Getting Started","heading":"Essential Resources","lead":"Everything you need to set up, manage, and optimise your digital signage network.","columns":3} -->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-book","title":"Getting Started Guide","description":"Step-by-step instructions to set up your first screen, configure your CMS, and publish your first content.","linkText":"Read the Guide","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-code","title":"API Documentation","description":"Developer resources for integrating your systems with our digital signage platform via REST API.","linkText":"View API Docs","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-plug","title":"Integration Guides","description":"How to connect live data sources, social media feeds, POS systems, and web dashboards to your displays.","linkText":"See Integrations","linkUrl":"/contact"} /-->
|
||||
return <<<'ORIBI_SYNC_CONTENT'
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Resources","title":"Guides, Docs u0026 Tools","description":"Everything you need to set up, manage, and get the most out of your digital signage — all in one place."} /-->
|
||||
|
||||
<!-- wp:oribi/link-section {"variant":"normal","label":"Getting Started","heading":"Hit the Ground Running","lead":"From first login to first screen, these resources walk you through every step.","columns":3} -->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-book","title":"Quick Start Guide","description":"Set up your first screen, configure your CMS, and publish content — step by step, start to finish.","linkText":"Read the Guide","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-code","title":"API Documentation","description":"REST API reference for developers integrating their own systems, data sources, or workflows with OTS Signs.","linkText":"View API Docs","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-plug","title":"Integration Guides","description":"Connect POS systems, social feeds, web dashboards, and third-party APIs to your signage displays.","linkText":"See Integrations","linkUrl":"/contact"} /-->
|
||||
<!-- /wp:oribi/link-section -->
|
||||
|
||||
<!-- wp:oribi/link-section {"variant":"alt","label":"Support","heading":"Help \u0026 Support","lead":"Get assistance with setup, troubleshooting, or any questions about the platform.","columns":3} -->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-headset","title":"Support Portal","description":"Submit support tickets, track issue resolution, and access our knowledge base for common troubleshooting steps.","linkText":"Open Support Portal","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-video","title":"Video Tutorials","description":"Watch step-by-step video guides on content creation, scheduling, device management, and platform features.","linkText":"Watch Tutorials","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-question-circle","title":"FAQ","description":"Find answers to the most common questions about our platform, pricing, setup, and support options.","linkText":"Browse FAQ","linkUrl":"/faq"} /-->
|
||||
<!-- wp:oribi/link-section {"variant":"alt","label":"Support","heading":"Get Help When You Need It","lead":"Troubleshooting, video walkthroughs, and answers to common questions.","columns":3} -->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-headset","title":"Support Portal","description":"Submit tickets, track resolutions, and search our knowledge base for step-by-step troubleshooting.","linkText":"Open Support Portal","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-video","title":"Video Tutorials","description":"Short, focused videos covering content creation, scheduling, device setup, and platform features.","linkText":"Watch Tutorials","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-question-circle","title":"FAQ","description":"Quick answers to the most common questions about pricing, setup, security, and support.","linkText":"Browse FAQ","linkUrl":"/faq"} /-->
|
||||
<!-- /wp:oribi/link-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"normal","label":"Content Tools","heading":"Create Better Content","lead":"Tools and templates to help you create engaging digital signage content.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-palette","title":"Template Library","description":"Browse our collection of professionally designed templates for menus, promotions, wayfinding, and informational displays.","url":"/contact"} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-image","title":"Media Best Practices","description":"Guidelines for image resolution, video formats, file sizes, and aspect ratios optimised for digital signage.","url":"/contact"} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-lightbulb","title":"Content Strategy Tips","description":"Learn how to structure your content rotation, day-parting schedules, and messaging for maximum audience impact.","url":"/contact"} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
<!-- wp:oribi/link-section {"variant":"normal","label":"Content Tools","heading":"Make Your Screens Look Great","lead":"Templates, guidelines, and strategy tips to elevate the content on your displays.","columns":3} -->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-palette","title":"Template Library","description":"Professionally designed, ready-to-use templates for menus, promotions, wayfinding, and informational layouts.","linkText":"Browse Templates","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-image","title":"Media Specifications","description":"Recommended resolutions, video formats, file sizes, and aspect ratios for crisp, optimised signage content.","linkText":"View Specs","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-lightbulb","title":"Content Strategy Tips","description":"Practical advice on content rotation, day-parting schedules, and messaging that keeps your audience engaged.","linkText":"Read Tips","linkUrl":"/contact"} /-->
|
||||
<!-- /wp:oribi/link-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Need Personalised Help?","text":"Our team is available to walk you through any aspect of the platform or help with content creation.","btnText":"Contact Support","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-section {"variant":"alt","label":"Creative Services","heading":"Let Our Team Create Your Content","lead":"Don\u0027t have a design team? Our in-house creative studio produces professional signage content from scratch.","columns":3} -->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-camera","title":"Photography & Video","description":"Professional product photography, venue videography, and promotional video production tailored to your brand and screens.","linkText":"Get a Quote","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-wand-magic-sparkles","title":"Motion Graphics","description":"Animated content, transitions, and dynamic layouts that bring your signage to life and hold viewer attention.","linkText":"See Examples","linkUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-pen-ruler","title":"Graphic Design","description":"Brand-aligned layouts, menu designs, promotional graphics, and campaign assets optimised for digital displays.","linkText":"Start a Project","linkUrl":"/contact"} /-->
|
||||
<!-- /wp:oribi/link-section -->
|
||||
|
||||
<!-- wp:oribi/link-section {"variant":"normal","label":"Partners","heading":"White-Label & Reseller Programme","lead":"Integrate our platform into your own offering, or resell OTS Signs under your brand.","columns":3} -->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-tags","title":"White-Label Platform","description":"Rebrand the entire CMS with your logo, domain, and colour scheme. Your clients see your brand — we power the infrastructure behind it.","linkText":"Learn More","linkUrl":"/partners"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-handshake","title":"Reseller Programme","description":"Sell OTS Signs alongside your AV installations, IT services, or consultancy. Volume pricing, co-marketing support, and dedicated partner account management.","linkText":"Become a Partner","linkUrl":"/partners"} /-->
|
||||
<!-- wp:oribi/link-card {"iconType":"fontawesome","faIcon":"fas fa-code","title":"Platform Integration","description":"Embed our signage capabilities into your own SaaS product via our REST API. Build custom workflows, automate content, and extend your platform.","linkText":"View Partner Programme","linkUrl":"/partners"} /-->
|
||||
<!-- /wp:oribi/link-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Need a Hand?","text":"Our team is happy to walk you through any part of the platform, help with content, or answer questions one-on-one.","btnText":"Contact Us","btnUrl":"/contact"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
|
||||
33
pages/security.php
Normal file
33
pages/security.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Security
|
||||
* Slug: ots-signs/page-security
|
||||
* Categories: oribi-pages
|
||||
* Keywords: security, compliance, GDPR, data privacy, encryption, access control
|
||||
* Post Types: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Security \u0026 Compliance","title":"Enterprise Security, Built In from Day One","description":"Your signage network handles business-critical content. Our platform protects it at every layer \u2014 from authentication and access control to encrypted communications and data privacy."} /-->
|
||||
|
||||
<!-- wp:oribi/platform-section {"label":"Platform Security","heading":"Security at Every Layer","lead":"As a division of Oribi Technology Services, security is in our DNA. Every feature is designed with enterprise-grade protection as standard."} -->
|
||||
<!-- wp:oribi/platform-row {"heading":"Authentication \u0026 Access Control","description":"Two-factor authentication is available on every plan. Role-based access control lets you define exactly who can create, edit, approve, and publish content. Essentials includes predefined roles (admin, editor, viewer). Pro adds custom role definitions with granular feature-level permissions, plus SSO via SAML or CAS to integrate with your existing identity provider.","btnText":"See Pricing","btnUrl":"/pricing"} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Encrypted Communications","description":"All data in transit between your browser, the CMS, and your player devices is encrypted using TLS. Content syncs to players over secure channels, and device management commands are authenticated end-to-end. No unencrypted data ever leaves the platform.","reversed":true} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Audit Trails \u0026 Accountability","description":"Every action in the CMS is logged \u2014 content changes, user logins, permission modifications, and device commands. Essentials retains 7 days of audit history. Pro provides extended retention for compliance requirements, with exportable audit logs for your security team."} /-->
|
||||
<!-- /wp:oribi/platform-section -->
|
||||
|
||||
<!-- wp:oribi/feature-section {"variant":"alt","label":"Data Protection","heading":"Your Data, Your Control","lead":"We handle your data with the same care we\u0027d want for our own. Here\u0027s how we protect it.","columns":3} -->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-shield-halved","title":"Data Processing Agreements","description":"DPAs are available on request for all customers. We clearly define how your data is processed, stored, and protected \u2014 and your obligations as a data controller."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-database","title":"Secure Cloud Infrastructure","description":"The platform runs on redundant cloud infrastructure with automated backups, failover, and disaster recovery. Your content and configuration are protected against data loss."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-user-lock","title":"Data Minimisation","description":"We only collect and process the data necessary to operate the platform. No tracking pixels, no third-party data sharing, no advertising profiles built from your content."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-globe-europe","title":"GDPR Compliance","description":"Our platform and processes are designed with GDPR principles in mind. We support data subject access requests, right to erasure, and data portability obligations."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-file-contract","title":"Privacy by Design","description":"Privacy considerations are built into every feature from the design stage \u2014 not added after the fact. Default settings favour data protection without sacrificing usability."} /-->
|
||||
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-lock","title":"Device Security","description":"Player devices are secured out of the box with encrypted local storage, locked-down operating systems, and over-the-air firmware updates. No open ports, no unnecessary services."} /-->
|
||||
<!-- /wp:oribi/feature-section -->
|
||||
|
||||
<!-- wp:oribi/comparison-table {"label":"Security by Plan","heading":"What\u0027s Included on Each Plan","lead":"Both plans include strong security foundations. Pro extends with enterprise identity and compliance features.","columns":["Essentials","Pro"],"rows":[{"group":"Authentication"},{"feature":"Two-factor authentication","values":[true,true]},{"feature":"SSO (SAML / CAS)","values":[false,true]},{"group":"Access Control"},{"feature":"Predefined roles (admin/editor/viewer)","values":[true,true]},{"feature":"Custom user roles \u0026 feature access","values":[false,true]},{"feature":"Unlimited user seats","values":[true,true]},{"group":"Monitoring \u0026 Compliance"},{"feature":"Audit trail","values":["7-day retention","Extended retention"]},{"feature":"Display health monitoring","values":[true,true]},{"feature":"Email alerts (player offline)","values":[true,true]},{"feature":"Periodic screenshots","values":[false,true]},{"group":"Data Protection"},{"feature":"TLS encryption (data in transit)","values":[true,true]},{"feature":"Encrypted device storage","values":[true,true]},{"feature":"Data Processing Agreement (DPA)","values":["On request","On request"]},{"feature":"GDPR-aligned processes","values":[true,true]}]} /-->
|
||||
|
||||
<!-- wp:oribi/trust-section {"label":"Our Commitment","heading":"Security Practices We Follow","lead":"Transparency builds trust. Here\u0027s how we approach security across the organisation.","btnText":"Talk to Us About Security","btnUrl":"/contact","btnSub":"We\u0027re happy to answer detailed security questionnaires"} -->
|
||||
<!-- wp:oribi/trust-item {"heading":"Regular Security Reviews","description":"We conduct regular security assessments of our platform, infrastructure, and processes to identify and address vulnerabilities proactively."} /--><!-- wp:oribi/trust-item {"heading":"Responsible Disclosure","description":"We welcome responsible security disclosures. If you discover a vulnerability, contact us at hello@ots-signs.com and we\u0027ll investigate promptly."} /--><!-- wp:oribi/trust-item {"heading":"Vendor Security Assessment","description":"Need to run a security questionnaire or vendor assessment before onboarding? We\u0027re happy to complete your security review process and provide documentation as needed."} /-->
|
||||
<!-- /wp:oribi/trust-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Have Security Questions?","text":"We understand that enterprise and public-sector buyers need detailed security information before committing. Get in touch and we\u0027ll provide whatever you need.","btnText":"Contact Us","btnUrl":"/contact"} /-->
|
||||
@@ -1,28 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Industry Solutions
|
||||
* Slug: ots-signs/page-solutions
|
||||
* Categories: oribi-pages
|
||||
* Keywords: solutions, industries, hospitality, retail, corporate, education, marketplace
|
||||
* Post Types: page
|
||||
/*
|
||||
* Title: Solutions
|
||||
* Slug: solutions
|
||||
* Post Type: page
|
||||
*/
|
||||
?>
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Industry Solutions","title":"Solutions for Every Industry","description":"From hospitality to education, our digital signage platform adapts to the unique needs of your industry. Discover how we can transform your customer experience."} /-->
|
||||
|
||||
<!-- wp:oribi/platform-section {"label":"Industries We Serve","heading":"Tailored Solutions for Your Sector","lead":"Every industry has unique communication challenges. Our platform is built to address them all."} -->
|
||||
<!-- wp:oribi/platform-row {"heading":"Hospitality","description":"Showcase menus, promotions, and special events while guiding guests through lobbies, restaurants, and bars. Digital signage creates a premium guest experience, drives upsells, and keeps your visitors informed, from check-in to checkout. Integrate with your POS for real-time menu updates and pricing changes.","btnText":"Get Started","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Retail","description":"Drive product upsells, announce flash-sales, and offer in-store navigation with fresh, eye-catching displays. Digital signage in retail has been shown to increase sales by up to 30%. Our platform makes it easy to update promotions across all locations instantly with targeted, data-driven content.","btnText":"See Pricing","btnUrl":"/pricing","reversed":true} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Corporate Office","description":"Enhance your meeting experience with Microsoft Teams room integration. Communicate meeting schedules, company news, KPIs, and employee alerts with interactive dashboards. Transform your lobby and common areas into dynamic communication hubs that keep your workforce informed and engaged.","btnText":"Learn More","btnUrl":"/features"} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Education","description":"Broadcast class schedules, announcements, campus wayfinding, and interactive learning content in campuses and auditoriums. Digital signage helps educational institutions communicate effectively with students, faculty, and visitors across multiple buildings and campuses.","btnText":"Contact Us","btnUrl":"/contact","reversed":true} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Outdoor Marketplace","description":"Whether it\u0027s a weekly farmers market or seasonal fairs, digital signage adds a modern, professional touch without losing the charm of the market experience. Weather-resistant display options and offline playback ensure your signage works reliably in any outdoor environment.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Live Data Displays","description":"Connect your existing web dashboards and real-time data to our platform for customised digital signage displays that bring your key metrics and insights to life. Perfect for operations centres, trading floors, and management dashboards that need to be visible to entire teams.","btnText":"See Features","btnUrl":"/features","reversed":true} /-->
|
||||
return <<<'ORIBI_SYNC_CONTENT'
|
||||
<!-- wp:oribi/page-hero-animated {"label":"Industry Solutions","title":"Built for the Way You Work","description":"Every industry communicates differently. Our platform adapts to your environment — whether that's a hotel lobby, a shop floor, a boardroom, or a lecture hall."} /-->
|
||||
|
||||
<!-- wp:oribi/platform-section {"label":"Industries We Serve","heading":"One Platform, Tailored to Your Sector","lead":"We've worked with businesses across six key industries. Here's how our platform fits into each one."} -->
|
||||
<!-- wp:oribi/platform-row {"heading":"Hospitality","description":"Digital menu boards that update with your POS, lobby displays that guide guests, and promotional screens that drive upsells in bars and restaurants. Create a polished guest experience from the moment they walk in — and keep it fresh without touching a single printed sign. Multi-language scheduling lets you switch content for international guests automatically.","btnText":"Get Started","btnUrl":"/contact","galleryIds":[418,417]} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Retail","description":"Launch promotions across every store instantly, spotlight seasonal products, and guide shoppers with in-store wayfinding. Retailers using digital signage see up to 30% more sales. Use day-parting to show breakfast offers in the morning and evening deals after 5pm. Interactive touchscreens turn browsing into self-service product lookup and ordering.","btnText":"See Pricing","btnUrl":"/pricing","reversed":true} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Corporate Office","description":"Meeting room displays with native Microsoft Teams integration, company-wide announcement boards, and live KPI dashboards in common areas. Turn your office into a connected, well-informed workplace where important information is always visible.","btnUrl":"/features"} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Education","description":"Timetable displays, campus wayfinding, emergency alerts, and event boards — all managed centrally. Push safety notifications to every screen instantly with emergency override. Keep students, faculty, and visitors informed across multiple buildings without the overhead of maintaining individual screens.","btnText":"Contact Us","btnUrl":"/contact","reversed":true} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Outdoor Marketplace","description":"From farmers' markets to seasonal fairs, digital signage adds a professional edge without losing the character of your venue. Weather-resistant display options and built-in offline playback ensure your screens perform reliably, rain or shine.","btnText":"Get a Quote","btnUrl":"/contact"} /-->
|
||||
|
||||
<!-- wp:oribi/platform-row {"heading":"Live Data Displays","description":"Bring your web dashboards, real-time KPIs, and operational data to large-format screens. Ideal for operations centres, trading floors, and management war rooms where critical information needs to be visible to the entire team at a glance.","btnText":"See Features","btnUrl":"/features","reversed":true} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Healthcare","description":"Queue management displays, patient wayfinding, waiting room information screens, and public health messaging. Interactive kiosks handle self-check-in and directory navigation. Centrally managed across clinics, hospitals, and multi-site health networks \u2014 with platform security and role-based access control built in.","btnText":"Learn More","btnUrl":"/features"} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Transport & Transit","description":"Real-time departure boards, route information, service alerts, and passenger wayfinding across stations, terminals, and transport hubs. Offline playback ensures displays stay live even when connectivity is intermittent.","btnText":"See Devices","btnUrl":"/devices","reversed":true} /-->
|
||||
<!-- wp:oribi/platform-row {"heading":"Fitness \u0026 Leisure","description":"Class timetables, motivational content, live performance metrics, and promotional offers on screens throughout gyms, leisure centres, and sports facilities. Schedule content by time of day to match peak hours and class rotations. Use multi-zone layouts to show live TV alongside class schedules and branded promotions simultaneously.","btnText":"Get Started","btnUrl":"/contact"} /-->
|
||||
<!-- /wp:oribi/platform-section -->
|
||||
|
||||
<!-- wp:oribi/stat-section {"variant":"alt","label":"By the Numbers","heading":"Impact Across Industries","lead":"Digital signage delivers measurable results for businesses of all sizes.","columns":4} -->
|
||||
<!-- wp:oribi/stat-card {"value":"400%","label":"Increase in Views","description":"Digital displays capture 400% more views than static signs."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"30%","label":"Sales Uplift","description":"Retail digital signage drives up to 30% increase in sales."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"80%","label":"Brand Awareness","description":"Customers recall digital signage content 80% of the time."} /-->
|
||||
<!-- wp:oribi/stat-card {"value":"50%","label":"Wait Time Perception","description":"Perceived wait times drop by 50% with engaging displays."} /-->
|
||||
<!-- wp:oribi/stat-section {"variant":"alt","label":"By the Numbers","heading":"The Results Speak for Themselves","lead":"Businesses that invest in digital signage see measurable returns across every metric that matters.","columns":4} -->
|
||||
<!-- wp:oribi/stat-card {"value":"400%","label":"More Views","description":"Digital displays capture 400% more attention than traditional static signage. <a href='https://mvix.com/blog/digital-signage-statistics/' target='_blank' rel='noopener'>Mvix Research →</a>"} /-->
|
||||
|
||||
<!-- wp:oribi/stat-card {"value":"30%","label":"Revenue Uplift","description":"Retail locations with digital signage report up to 30% higher in-store sales. <a href='https://www.digitalsignagetoday.com/news/nielsen-study-dooh-increases-revenue-at-the-point-of-sale-2/' target='_blank' rel='noopener'>Nielsen DOOH Study →</a>"} /-->
|
||||
|
||||
<!-- wp:oribi/stat-card {"value":"80%","label":"Content Recall","description":"Eight out of ten customers remember what they see on a digital display. <a href='https://www.databeat.net/databeatblog/15-surprising-statistics-about-digital-signage' target='_blank' rel='noopener'>Databeat Research →</a>"} /-->
|
||||
|
||||
<!-- wp:oribi/stat-card {"value":"50%","label":"Shorter Perceived Waits","description":"Engaging displays cut perceived wait times in half for customers in queues. <a href='https://www.digitalsignagetoday.com/articles/the-business-case-for-digital-signage-in-the-waiting-line/' target='_blank' rel='noopener'>Digital Signage Today →</a>"} /-->
|
||||
<!-- /wp:oribi/stat-section -->
|
||||
|
||||
<!-- wp:oribi/cta-banner {"heading":"Not Sure Which Solution Fits?","text":"Tell us about your industry and use case, and we\u0027ll recommend the perfect setup.","btnText":"Talk to an Expert","btnUrl":"/contact"} /-->
|
||||
<!-- wp:oribi/cta-banner {"heading":"Let Us Match You to the Right Setup","text":"Tell us about your industry, your locations, and what you want your screens to do. We'll recommend the ideal configuration.","btnText":"Talk to an Expert","btnUrl":"/contact"} /-->
|
||||
ORIBI_SYNC_CONTENT;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
157
theme/assets/js/dashboard-animator.js
Normal file
157
theme/assets/js/dashboard-animator.js
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Dashboard Chart Animator
|
||||
* Gently animates SVG bar charts, line graph, and pie chart.
|
||||
* Pauses off-screen via IntersectionObserver for performance.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var SPEED = 0.002; // phase increment per frame
|
||||
var BAR_H = 120; // max bar height (SVG units)
|
||||
var BAR_MIN = 0.15; // min bar ratio
|
||||
var LINE_PTS = 8;
|
||||
var LINE_W = 340; // line graph width in SVG units
|
||||
var PIE_R = 55; // pie chart radius
|
||||
|
||||
var DARK = { text: '#E0E0E0', muted: '#9E9E9E', border: '#333', center: '#1A1A1A' };
|
||||
var LIGHT = { text: '#333333', muted: '#666666', border: '#E0E0E0', center: '#fff' };
|
||||
|
||||
function isDark() { return document.documentElement.getAttribute('data-theme') === 'dark'; }
|
||||
function pal() { return isDark() ? DARK : LIGHT; }
|
||||
|
||||
function wave(t, off) {
|
||||
return Math.max(0, Math.min(1,
|
||||
0.55 +
|
||||
Math.sin(t + off) * 0.25 +
|
||||
Math.sin(t * 1.8 + off * 1.3) * 0.15
|
||||
));
|
||||
}
|
||||
|
||||
function makeState(svg) {
|
||||
return {
|
||||
svg: svg,
|
||||
bars1: svg.querySelectorAll('#bars-group-1 .bar'),
|
||||
bars2: svg.querySelectorAll('#bars-group-2 .bar'),
|
||||
vals1: svg.querySelectorAll('#values-group-1 text'),
|
||||
vals2: svg.querySelectorAll('#values-group-2 text'),
|
||||
linePath: svg.querySelector('#line-path'),
|
||||
lineFill: svg.querySelector('#line-fill'),
|
||||
pieSegs: svg.querySelectorAll('.pie-segment'),
|
||||
phase: Math.random() * Math.PI * 2,
|
||||
paused: false,
|
||||
themeN: 0
|
||||
};
|
||||
}
|
||||
|
||||
function updateBars(bars, vals, st, pct) {
|
||||
for (var i = 0; i < bars.length; i++) {
|
||||
var v = Math.max(BAR_MIN, wave(st.phase, i * 1.1));
|
||||
var h = v * BAR_H;
|
||||
bars[i].setAttribute('height', h);
|
||||
bars[i].setAttribute('y', BAR_H - h);
|
||||
}
|
||||
for (var j = 0; j < Math.min(bars.length, vals.length); j++) {
|
||||
var val = Math.max(BAR_MIN, wave(st.phase, j * 1.1));
|
||||
vals[j].textContent = pct ? Math.round(val * 100) + '%' : Math.round(val * 5000);
|
||||
}
|
||||
}
|
||||
|
||||
function updateLine(st) {
|
||||
if (!st.linePath) return;
|
||||
var d = 'M';
|
||||
for (var i = 0; i < LINE_PTS; i++) {
|
||||
var x = (i / (LINE_PTS - 1)) * LINE_W;
|
||||
var y = 25 + (1 - wave(st.phase * 0.8, i * 0.9)) * 110;
|
||||
d += (i ? ' L' : '') + x.toFixed(1) + ',' + y.toFixed(1);
|
||||
}
|
||||
st.linePath.setAttribute('d', d);
|
||||
if (st.lineFill) st.lineFill.setAttribute('d', d + ' L' + LINE_W + ',145 L0,145 Z');
|
||||
}
|
||||
|
||||
/* Pie: each segment gently shifts its slice size, no spinning */
|
||||
function updatePie(st) {
|
||||
if (!st.pieSegs.length) return;
|
||||
var n = st.pieSegs.length;
|
||||
// Generate proportional weights that shift over time
|
||||
var weights = [], total = 0;
|
||||
for (var i = 0; i < n; i++) {
|
||||
var w = 0.5 + wave(st.phase * 0.4, i * 2.0) * 0.5;
|
||||
weights.push(w);
|
||||
total += w;
|
||||
}
|
||||
// Convert to cumulative angles
|
||||
var angle = 0;
|
||||
for (var j = 0; j < n; j++) {
|
||||
var sweep = (weights[j] / total) * 360;
|
||||
var startA = angle * Math.PI / 180;
|
||||
var endA = (angle + sweep) * Math.PI / 180;
|
||||
// Large-arc flag needed when sweep > 180
|
||||
var large = sweep > 180 ? 1 : 0;
|
||||
var r = PIE_R;
|
||||
var x1 = Math.sin(startA) * r, y1 = -Math.cos(startA) * r;
|
||||
var x2 = Math.sin(endA) * r, y2 = -Math.cos(endA) * r;
|
||||
var path = st.pieSegs[j].querySelector('path');
|
||||
if (path) {
|
||||
path.setAttribute('d',
|
||||
'M0,0 L' + x1.toFixed(2) + ',' + y1.toFixed(2) +
|
||||
' A' + r + ',' + r + ' 0 ' + large + ',1 ' +
|
||||
x2.toFixed(2) + ',' + y2.toFixed(2) + ' Z'
|
||||
);
|
||||
}
|
||||
// Remove any rotation transform — segments are positioned by path geometry
|
||||
st.pieSegs[j].removeAttribute('transform');
|
||||
angle += sweep;
|
||||
}
|
||||
}
|
||||
|
||||
function applyTheme(st) {
|
||||
var c = pal(), q = st.svg.querySelectorAll.bind(st.svg), all, k;
|
||||
all = q('.ct'); for (k = 0; k < all.length; k++) all[k].setAttribute('fill', c.text);
|
||||
all = q('.cl'); for (k = 0; k < all.length; k++) all[k].setAttribute('fill', c.muted);
|
||||
all = q('.cv'); for (k = 0; k < all.length; k++) all[k].setAttribute('fill', c.text);
|
||||
all = q('.grid-line'); for (k = 0; k < all.length; k++) all[k].setAttribute('stroke', c.border);
|
||||
var cc = st.svg.querySelector('#pie-center');
|
||||
if (cc) { cc.setAttribute('fill', c.center); cc.setAttribute('stroke', c.border); }
|
||||
var pt = st.svg.querySelector('#pie-center-text');
|
||||
if (pt) pt.setAttribute('fill', c.text);
|
||||
}
|
||||
|
||||
function tick(st) {
|
||||
if (!st.paused) {
|
||||
st.phase += SPEED * 16;
|
||||
updateBars(st.bars1, st.vals1, st, true);
|
||||
updateBars(st.bars2, st.vals2, st, false);
|
||||
updateLine(st);
|
||||
updatePie(st);
|
||||
if (++st.themeN > 30) { st.themeN = 0; applyTheme(st); }
|
||||
}
|
||||
requestAnimationFrame(function () { tick(st); });
|
||||
}
|
||||
|
||||
function observe(st) {
|
||||
if (!('IntersectionObserver' in window)) return;
|
||||
new IntersectionObserver(function (entries) {
|
||||
for (var i = 0; i < entries.length; i++) st.paused = !entries[i].isIntersecting;
|
||||
}, { rootMargin: '200px', threshold: 0.05 }).observe(st.svg);
|
||||
}
|
||||
|
||||
function boot() {
|
||||
var svgs = document.querySelectorAll('.dashboard-chart');
|
||||
if (!svgs.length) return;
|
||||
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
||||
for (var i = 0; i < svgs.length; i++) {
|
||||
if (svgs[i]._dbAnim) continue;
|
||||
var st = makeState(svgs[i]);
|
||||
svgs[i]._dbAnim = st;
|
||||
applyTheme(st);
|
||||
tick(st);
|
||||
observe(st);
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', boot);
|
||||
} else {
|
||||
boot();
|
||||
}
|
||||
})();
|
||||
61
theme/assets/js/industry-animator.js
Normal file
61
theme/assets/js/industry-animator.js
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Gallery TV Slideshow
|
||||
* Cycles through images inside gallery-TV blocks.
|
||||
* Pauses off-screen via IntersectionObserver for performance.
|
||||
* Respects prefers-reduced-motion.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var INTERVAL = 4000; // ms between slides
|
||||
|
||||
function boot() {
|
||||
var stages = document.querySelectorAll('[data-gtv-slideshow]');
|
||||
if (!stages.length) return;
|
||||
|
||||
/* Honour reduced-motion – show first slide only */
|
||||
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
||||
|
||||
for (var i = 0; i < stages.length; i++) {
|
||||
initSlideshow(stages[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function initSlideshow(stage) {
|
||||
var slides = stage.querySelectorAll('.gtv-slide');
|
||||
if (slides.length < 2) return;
|
||||
|
||||
var state = { current: 0, paused: false, timer: null };
|
||||
|
||||
/* IntersectionObserver – pause when off-screen */
|
||||
if ('IntersectionObserver' in window) {
|
||||
new IntersectionObserver(function (entries) {
|
||||
for (var j = 0; j < entries.length; j++) {
|
||||
state.paused = !entries[j].isIntersecting;
|
||||
}
|
||||
if (!state.paused && !state.timer) {
|
||||
state.timer = setInterval(function () { advance(slides, state); }, INTERVAL);
|
||||
} else if (state.paused && state.timer) {
|
||||
clearInterval(state.timer);
|
||||
state.timer = null;
|
||||
}
|
||||
}, { rootMargin: '200px', threshold: 0.05 }).observe(stage);
|
||||
}
|
||||
|
||||
/* Start cycling */
|
||||
state.timer = setInterval(function () { advance(slides, state); }, INTERVAL);
|
||||
}
|
||||
|
||||
function advance(slides, state) {
|
||||
if (state.paused) return;
|
||||
slides[state.current].classList.remove('is-active');
|
||||
state.current = (state.current + 1) % slides.length;
|
||||
slides[state.current].classList.add('is-active');
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', boot);
|
||||
} else {
|
||||
boot();
|
||||
}
|
||||
})();
|
||||
@@ -17,6 +17,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
window.addEventListener('scroll', () => {
|
||||
header.classList.toggle('scrolled', window.scrollY > 40);
|
||||
}, { passive: true });
|
||||
|
||||
/* Detect whether the hero beneath the header has a light background.
|
||||
.hero (homepage) is white in light mode; .page-hero stays dark.
|
||||
Re-evaluate when the theme toggle changes data-theme. */
|
||||
function updateHeroContrast() {
|
||||
const isLight = document.documentElement.getAttribute('data-theme') !== 'dark';
|
||||
const hasLightHero = isLight && document.querySelector('.hero') && !document.querySelector('.page-hero');
|
||||
header.classList.toggle('over-light-hero', !!hasLightHero);
|
||||
}
|
||||
updateHeroContrast();
|
||||
new MutationObserver(updateHeroContrast).observe(document.documentElement, {
|
||||
attributes: true, attributeFilter: ['data-theme']
|
||||
});
|
||||
}
|
||||
|
||||
/* ── Mobile nav toggle ──────────────────────────────────── */
|
||||
@@ -26,6 +39,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
toggle.addEventListener('click', () => {
|
||||
toggle.classList.toggle('open');
|
||||
nav.classList.toggle('open');
|
||||
document.body.classList.toggle('menu-open');
|
||||
const expanded = toggle.getAttribute('aria-expanded') === 'true';
|
||||
toggle.setAttribute('aria-expanded', !expanded);
|
||||
});
|
||||
@@ -119,18 +133,33 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
/* ── Animate cards on scroll ────────────────────────────── */
|
||||
const cards = document.querySelectorAll('.oribi-card, .feature-card, .industry-card, .pricing-card, .value-card, .platform-row');
|
||||
if (cards.length && 'IntersectionObserver' in window) {
|
||||
cards.forEach(c => { c.style.opacity = '0'; c.style.transform = 'translateY(24px)'; c.style.transition = 'opacity .5s ease, transform .5s ease'; });
|
||||
const io = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.style.opacity = '1';
|
||||
entry.target.style.transform = 'translateY(0)';
|
||||
io.unobserve(entry.target);
|
||||
if (cards.length && 'IntersectionObserver' in window &&
|
||||
!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
cards.forEach(c => c.classList.add('scroll-hidden'));
|
||||
/* Use rAF to ensure the class is applied before observing – avoids
|
||||
Safari quirk where elements already in-viewport don't fire. */
|
||||
requestAnimationFrame(() => {
|
||||
const io = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.remove('scroll-hidden');
|
||||
entry.target.classList.add('scroll-visible');
|
||||
io.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.05, rootMargin: '0px 0px 80px 0px' });
|
||||
cards.forEach(c => io.observe(c));
|
||||
});
|
||||
/* Safety net: reveal any still-hidden elements after 4 s so content
|
||||
is never permanently invisible (e.g. iOS Safari edge-cases). */
|
||||
setTimeout(() => {
|
||||
cards.forEach(c => {
|
||||
if (c.classList.contains('scroll-hidden')) {
|
||||
c.classList.remove('scroll-hidden');
|
||||
c.classList.add('scroll-visible');
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.1 });
|
||||
cards.forEach(c => io.observe(c));
|
||||
}, 4000);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -610,3 +639,117 @@ 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);
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
/* ── TV Stick Plug Animation ─────────────────────────────────────────────── */
|
||||
(function () {
|
||||
var stages = document.querySelectorAll('[data-tv-stick-anim]');
|
||||
if (!stages.length) return;
|
||||
|
||||
// Honour reduced-motion: show plugged-in state immediately
|
||||
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
stages.forEach(function (stage) {
|
||||
stage.classList.add('is-plugged');
|
||||
startTsSlides(stage);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if ('IntersectionObserver' in window) {
|
||||
var io = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (e) {
|
||||
if (e.isIntersecting) {
|
||||
var stage = e.target;
|
||||
stage.classList.add('is-animating');
|
||||
// Add plugged state after slide-in completes (1.4s)
|
||||
setTimeout(function () {
|
||||
stage.classList.add('is-plugged');
|
||||
// Start promotional slide cycling after screen glow (0.9s)
|
||||
setTimeout(function () {
|
||||
startTsSlides(stage);
|
||||
}, 900);
|
||||
}, 1400);
|
||||
io.unobserve(stage);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.3 });
|
||||
stages.forEach(function (stage) { io.observe(stage); });
|
||||
}
|
||||
|
||||
function startTsSlides(stage) {
|
||||
var slides = stage.querySelectorAll('.ts-slide');
|
||||
if (!slides.length) return;
|
||||
var current = 0;
|
||||
slides[0].classList.add('is-active');
|
||||
stage.classList.add('is-playing');
|
||||
setInterval(function () {
|
||||
slides[current].classList.remove('is-active');
|
||||
current = (current + 1) % slides.length;
|
||||
slides[current].classList.add('is-active');
|
||||
}, 3000);
|
||||
}
|
||||
})();
|
||||
|
||||
110
theme/assets/js/video-editor-animator.js
Normal file
110
theme/assets/js/video-editor-animator.js
Normal file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Video Editor Timeline Animator
|
||||
* Animates playhead scrubbing across the timeline and video preview crossfades.
|
||||
* Mirrors the structure and conventions of dashboard-animator.js.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var DURATION = 10000; // ms for one full playhead sweep (left → right, then loop)
|
||||
var X_MIN = 104; // leftmost playhead centre (SVG units)
|
||||
var X_MAX = 504; // rightmost playhead centre (end of clip area)
|
||||
|
||||
function makeState(svg) {
|
||||
return {
|
||||
svg: svg,
|
||||
playheadLine: svg.querySelector('#ve-playhead-line'),
|
||||
playheadHead: svg.querySelector('#ve-playhead-head'),
|
||||
scene1: svg.querySelector('#ve-scene-1'),
|
||||
scene2: svg.querySelector('#ve-scene-2'),
|
||||
scene3: svg.querySelector('#ve-scene-3'),
|
||||
innerScreen: svg.querySelector('#ve-inner-screen'),
|
||||
timecode: svg.querySelector('#ve-timecode'),
|
||||
scrubPct: 0,
|
||||
lastTime: performance.now(),
|
||||
paused: false
|
||||
};
|
||||
}
|
||||
|
||||
function lerp(a, b, t) { return a + (b - a) * t; }
|
||||
|
||||
function updatePlayhead(st) {
|
||||
var xC = lerp(X_MIN, X_MAX, st.scrubPct);
|
||||
if (st.playheadLine) st.playheadLine.setAttribute('x', (xC - 1).toFixed(1));
|
||||
if (st.playheadHead) st.playheadHead.setAttribute('transform', 'translate(' + xC.toFixed(1) + ',234)');
|
||||
if (st.timecode) {
|
||||
var s = Math.floor(st.scrubPct * 10);
|
||||
st.timecode.textContent = '0:' + (s < 10 ? '0' + s : s);
|
||||
}
|
||||
}
|
||||
|
||||
function updateScenes(st) {
|
||||
var p = st.scrubPct;
|
||||
var o1, o2, o3, fade;
|
||||
if (p < 0.30) {
|
||||
o1 = 1; o2 = 0; o3 = 0;
|
||||
} else if (p < 0.40) {
|
||||
fade = (p - 0.30) / 0.10; o1 = 1 - fade; o2 = fade; o3 = 0;
|
||||
} else if (p < 0.65) {
|
||||
o1 = 0; o2 = 1; o3 = 0;
|
||||
} else if (p < 0.75) {
|
||||
fade = (p - 0.65) / 0.10; o1 = 0; o2 = 1 - fade; o3 = fade;
|
||||
} else {
|
||||
o1 = 0; o2 = 0; o3 = 1;
|
||||
}
|
||||
if (st.scene1) st.scene1.setAttribute('opacity', o1.toFixed(3));
|
||||
if (st.scene2) st.scene2.setAttribute('opacity', o2.toFixed(3));
|
||||
if (st.scene3) st.scene3.setAttribute('opacity', o3.toFixed(3));
|
||||
if (st.innerScreen) {
|
||||
st.innerScreen.setAttribute('fill',
|
||||
p < 0.38 ? 'url(#ve-scr-warm)' :
|
||||
p < 0.72 ? 'url(#ve-scr-cold)' :
|
||||
'url(#ve-scr-go)'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function loop(st, now) {
|
||||
if (!st.paused) {
|
||||
var delta = now - st.lastTime;
|
||||
st.lastTime = now;
|
||||
st.scrubPct += delta / DURATION;
|
||||
if (st.scrubPct >= 1) st.scrubPct -= 1;
|
||||
updatePlayhead(st);
|
||||
updateScenes(st);
|
||||
} else {
|
||||
st.lastTime = now; // keep fresh so there is no jump on resume
|
||||
}
|
||||
requestAnimationFrame(function (t) { loop(st, t); });
|
||||
}
|
||||
|
||||
function observe(st) {
|
||||
if (!('IntersectionObserver' in window)) return;
|
||||
new IntersectionObserver(function (entries) {
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
st.paused = !entries[i].isIntersecting;
|
||||
}
|
||||
}, { rootMargin: '200px', threshold: 0.05 }).observe(st.svg);
|
||||
}
|
||||
|
||||
function boot() {
|
||||
var svgs = document.querySelectorAll('.ve-svg');
|
||||
if (!svgs.length) return;
|
||||
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
||||
for (var i = 0; i < svgs.length; i++) {
|
||||
(function (svg) {
|
||||
if (svg._veAnim) return;
|
||||
var st = makeState(svg);
|
||||
svg._veAnim = st;
|
||||
observe(st);
|
||||
requestAnimationFrame(function (t) { loop(st, t); });
|
||||
})(svgs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', boot);
|
||||
} else {
|
||||
boot();
|
||||
}
|
||||
})();
|
||||
@@ -1067,6 +1067,8 @@ reg('oribi/pricing-card', {
|
||||
faIcon: { type: 'string', default: '' },
|
||||
name: { type: 'string', default: '' },
|
||||
tagline: { type: 'string', default: '' },
|
||||
price: { type: 'string', default: '' },
|
||||
pricePer: { type: 'string', default: '' },
|
||||
features: { type: 'array', default: [] },
|
||||
btnText: { type: 'string', default: 'Get Started' },
|
||||
btnUrl: { type: 'string', default: '/contact' },
|
||||
@@ -1122,6 +1124,17 @@ reg('oribi/pricing-card', {
|
||||
onChange: function(v){s({name:v});}, placeholder: 'Plan name...' }),
|
||||
el(RT, { tagName: 'p', className: 'pricing-tagline', value: a.tagline,
|
||||
onChange: function(v){s({tagline:v});}, placeholder: 'Tagline...' }),
|
||||
a.price || a.pricePer ? el('div', { className: 'pricing-price' },
|
||||
el(RT, { tagName: 'div', className: 'pricing-amount', value: a.price || '',
|
||||
onChange: function(v){s({price:v});}, placeholder: '$0' }),
|
||||
el(RT, { tagName: 'div', className: 'pricing-per', value: a.pricePer || '',
|
||||
onChange: function(v){s({pricePer:v});}, placeholder: 'per screen / month' })
|
||||
) : el('div', { className: 'pricing-price' },
|
||||
el(RT, { tagName: 'div', className: 'pricing-amount', value: '',
|
||||
onChange: function(v){s({price:v});}, placeholder: '$0' }),
|
||||
el(RT, { tagName: 'div', className: 'pricing-per', value: '',
|
||||
onChange: function(v){s({pricePer:v});}, placeholder: 'per screen / month' })
|
||||
),
|
||||
el('ul', { className: 'pricing-features' },
|
||||
features.map(function (f, fi) {
|
||||
return el('li', { key: fi, style: { display: 'flex', alignItems: 'center', gap: '4px' } },
|
||||
@@ -1157,26 +1170,105 @@ reg('oribi/platform-row', {
|
||||
parent: ['oribi/platform-section'],
|
||||
supports: { html: false, reusable: false },
|
||||
attributes: {
|
||||
heading: { type: 'string', default: '' },
|
||||
description: { type: 'string', default: '' },
|
||||
btnText: { type: 'string', default: 'Learn More' },
|
||||
btnUrl: { type: 'string', default: '' },
|
||||
visual: { type: 'string', default: '' },
|
||||
reversed: { type: 'boolean', default: false },
|
||||
imgId: { type: 'number', default: 0 },
|
||||
imgUrl: { type: 'string', default: '' },
|
||||
imgAlt: { type: 'string', default: '' },
|
||||
imgWidth: { type: 'number', default: 300 },
|
||||
heading: { type: 'string', default: '' },
|
||||
description: { type: 'string', default: '' },
|
||||
btnText: { type: 'string', default: 'Learn More' },
|
||||
btnUrl: { type: 'string', default: '' },
|
||||
visual: { type: 'string', default: '' },
|
||||
reversed: { type: 'boolean', default: false },
|
||||
imgId: { type: 'number', default: 0 },
|
||||
imgUrl: { type: 'string', default: '' },
|
||||
imgAlt: { type: 'string', default: '' },
|
||||
imgWidth: { type: 'number', default: 300 },
|
||||
isDashboard: { type: 'boolean', default: false },
|
||||
deviceAnim: { type: 'boolean', default: false },
|
||||
tvStick: { type: 'boolean', default: false },
|
||||
cameraAnim: { type: 'boolean', default: false },
|
||||
neverGoesDark: { type: 'boolean', default: false },
|
||||
brandedAnim: { type: 'boolean', default: false },
|
||||
galleryIds: { type: 'array', default: [] },
|
||||
},
|
||||
edit: function (props) {
|
||||
var a = props.attributes, s = props.setAttributes;
|
||||
var imgW = a.imgWidth || 300;
|
||||
|
||||
/* ── Animation HTML strings (mirror PHP render, used via dangerouslySetInnerHTML) ── */
|
||||
var DA_SCREEN = '<div class="da-screen"><div class="da-promo"><div class="da-promo__top"><span class="da-promo__dot"></span><span class="da-promo__brand"></span></div><div class="da-promo__hero"></div><div class="da-promo__row"><span class="da-promo__line da-promo__line--lg"></span><span class="da-promo__line da-promo__line--sm"></span></div><div class="da-promo__row"><span class="da-promo__line da-promo__line--md"></span><span class="da-promo__line da-promo__line--xs"></span></div><div class="da-promo__ticker"><span class="da-promo__chip"></span><span class="da-promo__chip"></span><span class="da-promo__chip"></span></div></div></div>';
|
||||
var DA_HTML = '<div class="da-stage" aria-hidden="true">' +
|
||||
'<div class="da-device da-tablet"><div class="da-body">' + DA_SCREEN + '</div><span class="da-label">Tablet</span></div>' +
|
||||
'<div class="da-device da-monitor-sm"><div class="da-body">' + DA_SCREEN + '</div><div class="da-stand"><div class="da-stem"></div><div class="da-base"></div></div><span class="da-label">Small Monitor</span></div>' +
|
||||
'<div class="da-device da-monitor-lg"><div class="da-body">' + DA_SCREEN + '</div><div class="da-stand"><div class="da-stem"></div><div class="da-base"></div></div><span class="da-label">Large Monitor</span></div>' +
|
||||
'<div class="da-device da-tv"><div class="da-body">' + DA_SCREEN + '</div><div class="da-feet"><div class="da-foot"></div><div class="da-foot"></div></div><span class="da-label">TV</span></div>' +
|
||||
'<div class="da-device da-projector"><div class="da-proj-layout"><div class="da-proj-body"><div class="da-lens"></div></div><div class="da-beam"></div><div class="da-proj-screen">' + DA_SCREEN + '</div></div><span class="da-label">Projector</span></div>' +
|
||||
'<div class="da-device da-vwall"><div class="da-vwall-grid"><div class="da-panel">' + DA_SCREEN + '</div><div class="da-panel">' + DA_SCREEN + '</div><div class="da-panel">' + DA_SCREEN + '</div><div class="da-panel">' + DA_SCREEN + '</div></div><span class="da-label">Video Wall</span></div>' +
|
||||
'</div>';
|
||||
|
||||
var TS_MI = '<div class="ts-menu__item"><span class="ts-menu__name"></span><span class="ts-menu__dots"></span><span class="ts-menu__price"></span></div>';
|
||||
var TS_COL = '<div class="ts-menu__col"><div class="ts-menu__cat"></div>' + TS_MI + TS_MI + TS_MI + '</div>';
|
||||
var TS_HTML = '<div class="ts-stage" data-tv-stick-anim aria-hidden="true">' +
|
||||
'<div class="ts-tv"><div class="ts-tv__body"><div class="ts-tv__screen"><div class="ts-slides">' +
|
||||
'<div class="ts-slide ts-slide--menu"><div class="ts-menu"><div class="ts-menu__header"><div class="ts-menu__logo"></div><div class="ts-menu__title"></div></div><div class="ts-menu__cols">' + TS_COL + TS_COL + '</div></div></div>' +
|
||||
'<div class="ts-slide ts-slide--wayfind"><div class="ts-wf"><div class="ts-wf__header"><div class="ts-wf__building"></div></div><div class="ts-wf__rows"><div class="ts-wf__row"><span class="ts-wf__arrow ts-wf__arrow--left"></span><span class="ts-wf__label ts-wf__label--w1"></span><span class="ts-wf__floor"></span></div><div class="ts-wf__row"><span class="ts-wf__arrow ts-wf__arrow--right"></span><span class="ts-wf__label ts-wf__label--w2"></span><span class="ts-wf__floor"></span></div><div class="ts-wf__row"><span class="ts-wf__arrow ts-wf__arrow--up"></span><span class="ts-wf__label ts-wf__label--w3"></span><span class="ts-wf__floor"></span></div><div class="ts-wf__row"><span class="ts-wf__arrow ts-wf__arrow--left"></span><span class="ts-wf__label ts-wf__label--w4"></span><span class="ts-wf__floor"></span></div></div></div></div>' +
|
||||
'<div class="ts-slide ts-slide--sched"><div class="ts-sched"><div class="ts-sched__header"><div class="ts-sched__title"></div><div class="ts-sched__date"></div></div><div class="ts-sched__table"><div class="ts-sched__hrow"><span class="ts-sched__hcell"></span><span class="ts-sched__hcell"></span><span class="ts-sched__hcell"></span><span class="ts-sched__hcell"></span></div><div class="ts-sched__row"><span class="ts-sched__time"></span><span class="ts-sched__event ts-sched__event--a"></span><span class="ts-sched__cell"></span><span class="ts-sched__cell"></span></div><div class="ts-sched__row"><span class="ts-sched__time"></span><span class="ts-sched__cell"></span><span class="ts-sched__event ts-sched__event--b"></span><span class="ts-sched__cell"></span></div><div class="ts-sched__row"><span class="ts-sched__time"></span><span class="ts-sched__cell"></span><span class="ts-sched__cell"></span><span class="ts-sched__event ts-sched__event--c"></span></div><div class="ts-sched__row"><span class="ts-sched__time"></span><span class="ts-sched__event ts-sched__event--a"></span><span class="ts-sched__event ts-sched__event--b"></span><span class="ts-sched__cell"></span></div></div></div></div>' +
|
||||
'</div></div><div class="ts-tv__port"></div></div><div class="ts-tv__feet"><div class="ts-tv__foot"></div><div class="ts-tv__foot"></div></div></div>' +
|
||||
'<div class="ts-stick"><div class="ts-stick__body"><div class="ts-stick__led"></div></div><div class="ts-stick__connector"></div></div>' +
|
||||
'</div>';
|
||||
|
||||
var NGD_ROW = '<div class="ngd-menu__row"><span class="ngd-menu__name"></span><span class="ngd-menu__price"></span></div>';
|
||||
var NGD_ROWH = '<div class="ngd-menu__row ngd-menu__row--hl"><span class="ngd-menu__name"></span><span class="ngd-menu__price"></span></div>';
|
||||
var NGD_HTML = '<div class="ngd-stage" aria-hidden="true">' +
|
||||
'<div class="ngd-tv"><div class="ngd-tv__body"><div class="ngd-tv__screen"><div class="ngd-menu"><div class="ngd-menu__hd"><div class="ngd-menu__logo"></div><div class="ngd-menu__ttl"></div></div><div class="ngd-menu__cols"><div class="ngd-menu__col"><div class="ngd-menu__cat"></div>' + NGD_ROW + NGD_ROWH + NGD_ROW + '</div><div class="ngd-menu__col"><div class="ngd-menu__cat"></div>' + NGD_ROW + NGD_ROW + NGD_ROWH + '</div></div><div class="ngd-menu__ticker"><div class="ngd-menu__ticker-inner"></div></div></div></div><div class="ngd-tv__port"></div></div><div class="ngd-tv__feet"><div class="ngd-tv__foot"></div><div class="ngd-tv__foot"></div></div></div>' +
|
||||
'<div class="ngd-player"><div class="ngd-player__connector"></div><div class="ngd-player__body"><div class="ngd-player__led"></div></div><div class="ngd-player__check"><svg viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="11" cy="11" r="10" stroke="#4CAF50" stroke-width="1.5"/><polyline points="6,11 9.5,14.5 16,7.5" stroke="#4CAF50" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div></div>' +
|
||||
'<div class="ngd-signal-wrap"><div class="ngd-cloud"><svg class="ngd-cloud__svg" viewBox="0 0 64 46" fill="none" xmlns="http://www.w3.org/2000/svg"><circle class="ngd-cloud__path" cx="32" cy="23" r="14" stroke-width="2.2" fill="none"/><path class="ngd-cloud__path" d="M18.5 23C23 20 41 20 45.5 23" stroke-width="1.9" stroke-linecap="round" fill="none"/><path class="ngd-cloud__path" d="M20.5 29C25.5 31 38.5 31 43.5 29" stroke-width="1.9" stroke-linecap="round" fill="none"/><path class="ngd-cloud__path" d="M24.5 12C21.5 16.5 21.5 29.5 24.5 34" stroke-width="1.9" stroke-linecap="round" fill="none"/><path class="ngd-cloud__path" d="M39.5 12C42.5 16.5 42.5 29.5 39.5 34" stroke-width="1.9" stroke-linecap="round" fill="none"/></svg></div><div class="ngd-signal-line"><div class="ngd-signal__dots"><div class="ngd-signal__dot ngd-signal__dot--1"></div><div class="ngd-signal__dot ngd-signal__dot--2"></div><div class="ngd-signal__dot ngd-signal__dot--3"></div></div><div class="ngd-signal__break"><svg viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="9" cy="9" r="8" fill="rgba(239,68,68,0.12)" stroke="#ef4444" stroke-width="1.2"/><line x1="5.5" y1="5.5" x2="12.5" y2="12.5" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/><line x1="12.5" y1="5.5" x2="5.5" y2="12.5" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg></div></div></div>' +
|
||||
'</div>';
|
||||
|
||||
var BD_SPLASH = '<div class="bd-splash"><div class="bd-splash__logo"></div></div>';
|
||||
var BD_HDR = '<div class="bd-ui__header"><div class="bd-ui__logo"></div><div class="bd-ui__brand-bar"></div></div>';
|
||||
var BD_HTML = '<div class="bd-stage" aria-hidden="true">' +
|
||||
'<div class="bd-device bd-device--tablet"><span class="bd-device__label">Kiosk</span><div class="bd-device__body"><div class="bd-device__screen">' + BD_SPLASH + '<div class="bd-ui">' + BD_HDR + '<div class="bd-ui__content"><div class="bd-promo bd-promo--welcome"><div class="bd-promo__hero"></div><div class="bd-promo__heading"></div><div class="bd-promo__text"></div><div class="bd-promo__btn"></div></div></div></div></div></div></div>' +
|
||||
'<div class="bd-device bd-device--wall"><span class="bd-device__label">Wall Display</span><div class="bd-device__body"><div class="bd-device__screen">' + BD_SPLASH + '<div class="bd-ui">' + BD_HDR + '<div class="bd-ui__content"><div class="bd-promo bd-promo--sale"><div class="bd-promo__cols"><div class="bd-promo__visual"></div><div class="bd-promo__info"><div class="bd-promo__badge"></div><div class="bd-promo__heading"></div><div class="bd-promo__text"></div><div class="bd-promo__text bd-promo__text--short"></div><div class="bd-promo__price"></div></div></div></div></div></div></div></div><div class="bd-mount"></div></div>' +
|
||||
'<div class="bd-device bd-device--interactive"><span class="bd-device__label">Interactive</span><div class="bd-device__body"><div class="bd-device__screen">' + BD_SPLASH + '<div class="bd-ui">' + BD_HDR + '<div class="bd-ui__content"><div class="bd-promo bd-promo--menu"><div class="bd-promo__heading"></div><div class="bd-promo__grid"><div class="bd-promo__tile"><div class="bd-promo__tile-img"></div><div class="bd-promo__tile-lbl"></div></div><div class="bd-promo__tile"><div class="bd-promo__tile-img"></div><div class="bd-promo__tile-lbl"></div></div><div class="bd-promo__tile"><div class="bd-promo__tile-img"></div><div class="bd-promo__tile-lbl"></div></div><div class="bd-promo__tile"><div class="bd-promo__tile-img"></div><div class="bd-promo__tile-lbl"></div></div></div></div></div></div></div></div><div class="bd-table"></div></div>' +
|
||||
'</div>';
|
||||
|
||||
var DB_HTML = '<div class="dashboard-tv" data-dashboard-container="true"><div class="dashboard-tv__body"><div class="dashboard-tv__screen"><svg viewBox="0 0 800 450" xmlns="http://www.w3.org/2000/svg" class="dashboard-chart" role="img" aria-label="Animated dashboard charts"><defs><linearGradient id="dbe-barGrad" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stop-color="#D83302" stop-opacity="1"/><stop offset="100%" stop-color="#4CAF50" stop-opacity=".8"/></linearGradient><linearGradient id="dbe-lineGrad" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stop-color="#4CAF50" stop-opacity=".3"/><stop offset="100%" stop-color="#4CAF50" stop-opacity="0"/></linearGradient></defs><g transform="translate(35,20)"><text class="ct" x="0" y="0" font-size="14" font-weight="600" fill="#888">Performance</text><g id="dbe-bars1" transform="translate(0,25)"><rect x="0" y="60" width="28" height="60" fill="url(#dbe-barGrad)"/><rect x="40" y="80" width="28" height="40" fill="url(#dbe-barGrad)"/><rect x="80" y="40" width="28" height="80" fill="url(#dbe-barGrad)"/><rect x="120" y="70" width="28" height="50" fill="url(#dbe-barGrad)"/><rect x="160" y="50" width="28" height="70" fill="url(#dbe-barGrad)"/></g><g transform="translate(0,152)"><text class="cl" x="14" y="0" font-size="10" text-anchor="middle" fill="#aaa">API</text><text class="cl" x="54" y="0" font-size="10" text-anchor="middle" fill="#aaa">Cache</text><text class="cl" x="94" y="0" font-size="10" text-anchor="middle" fill="#aaa">DB</text><text class="cl" x="134" y="0" font-size="10" text-anchor="middle" fill="#aaa">Queue</text><text class="cl" x="174" y="0" font-size="10" text-anchor="middle" fill="#aaa">Worker</text></g></g><g transform="translate(430,20)"><text class="ct" x="0" y="0" font-size="14" font-weight="600" fill="#888">Requests/sec</text><g transform="translate(0,25)"><rect x="0" y="50" width="28" height="70" fill="url(#dbe-barGrad)"/><rect x="40" y="30" width="28" height="90" fill="url(#dbe-barGrad)"/><rect x="80" y="65" width="28" height="55" fill="url(#dbe-barGrad)"/><rect x="120" y="45" width="28" height="75" fill="url(#dbe-barGrad)"/></g><g transform="translate(0,152)"><text class="cl" x="14" y="0" font-size="10" text-anchor="middle" fill="#aaa">Read</text><text class="cl" x="54" y="0" font-size="10" text-anchor="middle" fill="#aaa">Write</text><text class="cl" x="94" y="0" font-size="10" text-anchor="middle" fill="#aaa">Update</text><text class="cl" x="134" y="0" font-size="10" text-anchor="middle" fill="#aaa">Delete</text></g></g><g transform="translate(35,245)"><text class="ct" x="0" y="0" font-size="14" font-weight="600" fill="#888">Traffic Trend</text><g transform="translate(0,25)"><line class="grid-line" x1="0" y1="0" x2="340" y2="0" stroke="#ddd" stroke-width=".5"/><line class="grid-line" x1="0" y1="40" x2="340" y2="40" stroke="#ddd" stroke-width=".5"/><line class="grid-line" x1="0" y1="80" x2="340" y2="80" stroke="#ddd" stroke-width=".5"/><line class="grid-line" x1="0" y1="120" x2="340" y2="120" stroke="#ddd" stroke-width=".5"/><path d="M0,90 L42,70 L85,50 L127,80 L170,45 L212,65 L255,55 L297,75 L340,60 L340,145 L0,145 Z" fill="url(#dbe-lineGrad)"/><path d="M0,90 L42,70 L85,50 L127,80 L170,45 L212,65 L255,55 L297,75 L340,60" stroke="#4CAF50" stroke-width="2.5" fill="none" stroke-linecap="round"/></g></g><g transform="translate(490,245)"><text class="ct" x="100" y="0" font-size="14" font-weight="600" text-anchor="middle" fill="#888">Distribution</text><g transform="translate(100,90)"><path d="M0,0 L0,-55 A55,55 0 0,1 38.89,-38.89 Z" fill="#D83302" opacity=".9"/><path d="M0,0 L38.89,-38.89 A55,55 0 0,1 55,0 Z" fill="#4CAF50" opacity=".8"/><path d="M0,0 L55,0 A55,55 0 0,1 0,55 Z" fill="#f59e0b" opacity=".7"/><path d="M0,0 L0,55 A55,55 0 1,1 0,-55 Z" fill="#ef4444" opacity=".7"/><circle cx="0" cy="0" r="22" fill="#f5f5f5" stroke="#ddd" stroke-width="1"/></g></g></svg></div></div><div class="dashboard-tv__feet"><div class="dashboard-tv__foot"></div><div class="dashboard-tv__foot"></div></div></div>';
|
||||
|
||||
return el(Frag, null,
|
||||
el(IC, null,
|
||||
el(PB, { title: 'Row Settings' },
|
||||
el(TC, { label: 'Visual (emoji)', value: a.visual, onChange: function(v){s({visual:v});} }),
|
||||
el(TC, { label: 'Button URL', value: a.btnUrl, onChange: function(v){s({btnUrl:v});} }),
|
||||
el(TG, { label: 'Reversed', checked: !!a.reversed, onChange: function(v){s({reversed:v});} })
|
||||
el(TG, { label: 'Reversed', checked: !!a.reversed, onChange: function(v){s({reversed:v});} }),
|
||||
el(TG, { label: 'Dashboard Animation', checked: !!a.isDashboard, onChange: function(v){s({isDashboard:v});} }),
|
||||
el(TG, { label: 'Device Animation', checked: !!a.deviceAnim, onChange: function(v){s({deviceAnim:v});} }),
|
||||
el(TG, { label: 'TV Stick Animation', checked: !!a.tvStick, onChange: function(v){s({tvStick:v});} }),
|
||||
el(TG, { label: 'Camera Animation', checked: !!a.cameraAnim, onChange: function(v){s({cameraAnim:v});} }),
|
||||
el(TG, { label: 'Never Goes Dark', checked: !!a.neverGoesDark, onChange: function(v){s({neverGoesDark:v});} }),
|
||||
el(TG, { label: 'Branded Display', checked: !!a.brandedAnim, onChange: function(v){s({brandedAnim:v});} })
|
||||
),
|
||||
el(PB, { title: 'Gallery TV Slideshow', initialOpen: false },
|
||||
el(MUC, null,
|
||||
el(MU, {
|
||||
onSelect: function(media) {
|
||||
s({ galleryIds: media.map(function(m){ return m.id; }) });
|
||||
},
|
||||
allowedTypes: ['image'],
|
||||
gallery: true,
|
||||
multiple: true,
|
||||
value: a.galleryIds || [],
|
||||
render: function(ref) {
|
||||
return el(Frag, null,
|
||||
a.galleryIds && a.galleryIds.length
|
||||
? el('div', { style: { marginBottom: '8px' } },
|
||||
el('p', { style: { margin: '0 0 4px' } }, a.galleryIds.length + ' image(s) selected'),
|
||||
el(Btn, { variant: 'link', isDestructive: true, onClick: function(){ s({ galleryIds: [] }); } }, 'Clear gallery')
|
||||
)
|
||||
: null,
|
||||
el(Btn, { onClick: ref.open, variant: 'secondary', __next40pxDefaultSize: true },
|
||||
a.galleryIds && a.galleryIds.length ? 'Edit gallery' : 'Select images for TV slideshow')
|
||||
);
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
el(PB, { title: 'Visual Image', initialOpen: false },
|
||||
el(MUC, null,
|
||||
@@ -1207,7 +1299,77 @@ reg('oribi/platform-row', {
|
||||
a.btnUrl ? el(RT, { tagName: 'span', className: 'btn btn-outline mt-3',
|
||||
value: a.btnText, onChange: function(v){s({btnText:v});}, placeholder: 'Button...' }) : null
|
||||
),
|
||||
a.imgUrl
|
||||
a.isDashboard
|
||||
? el('div', { className: 'platform-visual has-dashboard', dangerouslySetInnerHTML: { __html: DB_HTML } })
|
||||
: a.cameraAnim
|
||||
? el('div', { className: 'platform-visual has-camera' },
|
||||
el('div', { className: 'cam-stage', 'aria-hidden': 'true' },
|
||||
// Photo camera (left)
|
||||
el('div', { className: 'pc-wrap' },
|
||||
el('div', { className: 'pc-body' },
|
||||
el('div', { className: 'pc-flash-unit' }),
|
||||
el('div', { className: 'pc-top' },
|
||||
el('div', { className: 'pc-shutter-btn' }),
|
||||
el('div', { className: 'pc-viewfinder' })
|
||||
),
|
||||
el('div', { className: 'pc-front' },
|
||||
el('div', { className: 'pc-lens-ring' },
|
||||
el('div', { className: 'pc-lens-glass' },
|
||||
el('div', { className: 'pc-lens-reflex' })
|
||||
)
|
||||
),
|
||||
el('div', { className: 'pc-grip' })
|
||||
)
|
||||
),
|
||||
el('div', { className: 'pc-prints' },
|
||||
el('div', { className: 'pc-print pc-print--1', style: { opacity: '1', transform: 'rotate(-12deg) translateY(0)' } },
|
||||
el('div', { className: 'pc-print__img' })
|
||||
)
|
||||
)
|
||||
),
|
||||
// Centre scene
|
||||
el('div', { className: 'cam-scene' },
|
||||
el('div', { className: 'cam-subject cam-subject--1' }),
|
||||
el('div', { className: 'cam-flash-overlay' }),
|
||||
el('div', { className: 'cam-vid-overlay' })
|
||||
),
|
||||
// Video camera on tripod (right)
|
||||
el('div', { className: 'vc-wrap' },
|
||||
el('div', { className: 'vc-camera' },
|
||||
el('div', { className: 'vc-handle' }),
|
||||
el('div', { className: 'vc-body' },
|
||||
el('div', { className: 'vc-lens-barrel' },
|
||||
el('div', { className: 'vc-lens-tip' },
|
||||
el('div', { className: 'vc-lens-glass' },
|
||||
el('div', { className: 'vc-lens-reflex' })
|
||||
)
|
||||
)
|
||||
),
|
||||
el('div', { className: 'vc-top-rail' }),
|
||||
el('div', { className: 'vc-rec-light' }),
|
||||
el('div', { className: 'vc-eyepiece' })
|
||||
)
|
||||
),
|
||||
el('div', { className: 'vc-tripod' },
|
||||
el('div', { className: 'vc-stem' }),
|
||||
el('div', { className: 'vc-legs' },
|
||||
el('div', { className: 'vc-leg vc-leg--l' }),
|
||||
el('div', { className: 'vc-leg vc-leg--c' }),
|
||||
el('div', { className: 'vc-leg vc-leg--r' })
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
: a.deviceAnim
|
||||
? el('div', { className: 'platform-visual has-anim', dangerouslySetInnerHTML: { __html: DA_HTML } })
|
||||
: a.tvStick
|
||||
? el('div', { className: 'platform-visual has-tv-stick', dangerouslySetInnerHTML: { __html: TS_HTML } })
|
||||
: a.neverGoesDark
|
||||
? el('div', { className: 'platform-visual has-ngd', dangerouslySetInnerHTML: { __html: NGD_HTML } })
|
||||
: a.brandedAnim
|
||||
? el('div', { className: 'platform-visual has-branded', dangerouslySetInnerHTML: { __html: BD_HTML } })
|
||||
: a.imgUrl
|
||||
? el('div', { className: 'platform-visual has-img' },
|
||||
el('img', { src: a.imgUrl, style: { width: imgW + 'px', maxWidth: '100%', height: 'auto', borderRadius: '4px', objectFit: 'contain', display: 'block', marginInline: 'auto' } })
|
||||
)
|
||||
@@ -1543,6 +1705,74 @@ reg('oribi/comparison-table', {
|
||||
var a = props.attributes, s = props.setAttributes;
|
||||
var cols = a.columns || [];
|
||||
var rows = a.rows || [];
|
||||
|
||||
/* ── Column helpers ─────────────────────────────────────── */
|
||||
function updateCol(idx, val) {
|
||||
var c = cols.slice(); c[idx] = val; s({ columns: c });
|
||||
}
|
||||
function addCol() {
|
||||
var newRows = rows.map(function(r) {
|
||||
if (r.group) return r;
|
||||
return Object.assign({}, r, { values: (r.values || []).concat([false]) });
|
||||
});
|
||||
s({ columns: cols.concat(['Plan']), rows: newRows });
|
||||
}
|
||||
function removeCol(idx) {
|
||||
var c = cols.slice(); c.splice(idx, 1);
|
||||
var newRows = rows.map(function(r) {
|
||||
if (r.group) return r;
|
||||
var v = (r.values || []).slice(); v.splice(idx, 1);
|
||||
return Object.assign({}, r, { values: v });
|
||||
});
|
||||
s({ columns: c, rows: newRows });
|
||||
}
|
||||
|
||||
/* ── Row helpers ────────────────────────────────────────── */
|
||||
function updateRow(idx, key, val) {
|
||||
var r = rows.slice();
|
||||
r[idx] = Object.assign({}, r[idx]);
|
||||
r[idx][key] = val;
|
||||
s({ rows: r });
|
||||
}
|
||||
function updateCell(ri, ci, val) {
|
||||
var r = rows.slice();
|
||||
r[ri] = Object.assign({}, r[ri]);
|
||||
var v = (r[ri].values || []).slice();
|
||||
v[ci] = val;
|
||||
r[ri].values = v;
|
||||
s({ rows: r });
|
||||
}
|
||||
function toggleCell(ri, ci) {
|
||||
var val = (rows[ri].values || [])[ci];
|
||||
updateCell(ri, ci, val === true ? false : val === false ? true : true);
|
||||
}
|
||||
function switchCellToText(ri, ci) { updateCell(ri, ci, ''); }
|
||||
function addFeatureRow() {
|
||||
var vals = cols.map(function() { return false; });
|
||||
s({ rows: rows.concat([{ feature: 'New feature', values: vals }]) });
|
||||
}
|
||||
function addGroupRow() {
|
||||
s({ rows: rows.concat([{ group: 'New Group' }]) });
|
||||
}
|
||||
function removeRow(idx) {
|
||||
var r = rows.slice(); r.splice(idx, 1); s({ rows: r });
|
||||
}
|
||||
function moveRow(idx, dir) {
|
||||
var t = idx + dir;
|
||||
if (t < 0 || t >= rows.length) return;
|
||||
var r = rows.slice();
|
||||
var tmp = r[idx]; r[idx] = r[t]; r[t] = tmp;
|
||||
s({ rows: r });
|
||||
}
|
||||
|
||||
/* ── Inline styles for editor controls ──────────────────── */
|
||||
var inputStyle = { width: '100%', padding: '4px 6px', border: '1px solid #ddd', borderRadius: '3px', fontSize: '13px', background: 'transparent', boxSizing: 'border-box' };
|
||||
var thInputStyle = Object.assign({}, inputStyle, { fontWeight: 600, textAlign: 'center' });
|
||||
var smallBtnStyle = { background: 'none', border: 'none', cursor: 'pointer', padding: '2px 4px', fontSize: '11px', lineHeight: 1, opacity: 0.6, verticalAlign: 'middle' };
|
||||
var rowCtrlStyle = { whiteSpace: 'nowrap', width: '1%', padding: '4px', verticalAlign: 'middle', border: 'none', background: 'transparent' };
|
||||
var cellBtnStyle = { background: 'none', border: '1px solid #ddd', borderRadius: '3px', cursor: 'pointer', padding: '2px 6px', fontSize: '13px', lineHeight: '1.4', margin: '0 1px' };
|
||||
|
||||
/* ── Render ─────────────────────────────────────────────── */
|
||||
return el(Frag, null,
|
||||
el(IC, null,
|
||||
el(PB, { title: 'Table Settings' },
|
||||
@@ -1550,6 +1780,21 @@ reg('oribi/comparison-table', {
|
||||
{ label: 'Normal', value: 'normal' }, { label: 'Alternate', value: 'alt' }
|
||||
], onChange: function(v){s({variant:v});} }),
|
||||
el(TC, { label: 'Label', value: a.label, onChange: function(v){s({label:v});} })
|
||||
),
|
||||
el(PB, { title: 'Columns', initialOpen: false },
|
||||
cols.map(function(col, i) {
|
||||
return el('div', { key: i, style: { display: 'flex', gap: '4px', marginBottom: '8px', alignItems: 'center' } },
|
||||
el(TC, { label: '', value: col, onChange: function(v){ updateCol(i, v); }, style: { flex: 1 } }),
|
||||
el(Btn, { isDestructive: true, isSmall: true, onClick: function(){ removeCol(i); } }, '\u2715')
|
||||
);
|
||||
}),
|
||||
el(Btn, { isSecondary: true, isSmall: true, onClick: addCol }, '+ Add Column')
|
||||
),
|
||||
el(PB, { title: 'Add Rows', initialOpen: false },
|
||||
el('div', { style: { display: 'flex', gap: '8px' } },
|
||||
el(Btn, { isSecondary: true, isSmall: true, onClick: addFeatureRow }, '+ Feature Row'),
|
||||
el(Btn, { isSecondary: true, isSmall: true, onClick: addGroupRow }, '+ Group Row')
|
||||
)
|
||||
)
|
||||
),
|
||||
el('section', { className: a.variant === 'alt' ? 'section section-alt' : 'section' },
|
||||
@@ -1564,26 +1809,62 @@ reg('oribi/comparison-table', {
|
||||
el('thead', null,
|
||||
el('tr', null,
|
||||
el('th', { className: 'comparison-feature-col' }, 'Feature'),
|
||||
cols.map(function(col, i) { return el('th', { key: i }, col); })
|
||||
cols.map(function(col, i) {
|
||||
return el('th', { key: i },
|
||||
el('input', { type: 'text', value: col, style: thInputStyle, onChange: function(e){ updateCol(i, e.target.value); } })
|
||||
);
|
||||
}),
|
||||
el('th', { style: rowCtrlStyle })
|
||||
)
|
||||
),
|
||||
el('tbody', null,
|
||||
rows.map(function(row, i) {
|
||||
rows.map(function(row, ri) {
|
||||
if (row.group) {
|
||||
return el('tr', { key: i, className: 'comparison-group-row' },
|
||||
el('td', { colSpan: cols.length + 1 }, row.group)
|
||||
return el('tr', { key: ri, className: 'comparison-group-row' },
|
||||
el('td', { colSpan: cols.length + 1 },
|
||||
el('input', { type: 'text', value: row.group, style: Object.assign({}, inputStyle, { fontWeight: 700 }), onChange: function(e){ updateRow(ri, 'group', e.target.value); } })
|
||||
),
|
||||
el('td', { style: rowCtrlStyle },
|
||||
el('button', { style: smallBtnStyle, onClick: function(){ moveRow(ri, -1); }, title: 'Move up' }, '\u25B2'),
|
||||
el('button', { style: smallBtnStyle, onClick: function(){ moveRow(ri, 1); }, title: 'Move down' }, '\u25BC'),
|
||||
el('button', { style: Object.assign({}, smallBtnStyle, { color: '#b00' }), onClick: function(){ removeRow(ri); }, title: 'Remove row' }, '\u2715')
|
||||
)
|
||||
);
|
||||
}
|
||||
return el('tr', { key: i },
|
||||
el('td', { className: 'comparison-feature-name' }, row.feature || ''),
|
||||
(row.values || []).map(function(val, j) {
|
||||
return el('td', { key: j, className: 'comparison-cell' },
|
||||
val === true ? '\u2713' : val === false ? '\u2014' : String(val)
|
||||
return el('tr', { key: ri },
|
||||
el('td', { className: 'comparison-feature-name' },
|
||||
el('input', { type: 'text', value: row.feature || '', style: inputStyle, placeholder: 'Feature name\u2026', onChange: function(e){ updateRow(ri, 'feature', e.target.value); } })
|
||||
),
|
||||
(row.values || []).map(function(val, ci) {
|
||||
if (typeof val === 'boolean') {
|
||||
return el('td', { key: ci, className: 'comparison-cell', style: { textAlign: 'center' } },
|
||||
el('button', { style: Object.assign({}, cellBtnStyle, { color: val ? '#2e7d32' : '#c62828' }), onClick: function(){ toggleCell(ri, ci); }, title: 'Toggle \u2713/\u2717' },
|
||||
val ? '\u2713' : '\u2717'
|
||||
),
|
||||
el('button', { style: Object.assign({}, smallBtnStyle, { fontSize: '10px' }), onClick: function(){ switchCellToText(ri, ci); }, title: 'Switch to text' }, 'Aa')
|
||||
);
|
||||
}
|
||||
return el('td', { key: ci, className: 'comparison-cell' },
|
||||
el('div', { style: { display: 'flex', alignItems: 'center', gap: '2px' } },
|
||||
el('input', { type: 'text', value: String(val), style: Object.assign({}, inputStyle, { flex: 1, minWidth: '60px' }), placeholder: 'Value\u2026', onChange: function(e){ updateCell(ri, ci, e.target.value); } }),
|
||||
el('button', { style: Object.assign({}, smallBtnStyle, { color: '#2e7d32' }), onClick: function(){ updateCell(ri, ci, true); }, title: 'Set as \u2713' }, '\u2713'),
|
||||
el('button', { style: Object.assign({}, smallBtnStyle, { color: '#c62828' }), onClick: function(){ updateCell(ri, ci, false); }, title: 'Set as \u2717' }, '\u2717')
|
||||
)
|
||||
);
|
||||
})
|
||||
}),
|
||||
el('td', { style: rowCtrlStyle },
|
||||
el('button', { style: smallBtnStyle, onClick: function(){ moveRow(ri, -1); }, title: 'Move up' }, '\u25B2'),
|
||||
el('button', { style: smallBtnStyle, onClick: function(){ moveRow(ri, 1); }, title: 'Move down' }, '\u25BC'),
|
||||
el('button', { style: Object.assign({}, smallBtnStyle, { color: '#b00' }), onClick: function(){ removeRow(ri); }, title: 'Remove row' }, '\u2715')
|
||||
)
|
||||
);
|
||||
})
|
||||
)
|
||||
),
|
||||
el('div', { style: { display: 'flex', gap: '8px', marginTop: '12px', justifyContent: 'center' } },
|
||||
el(Btn, { isSecondary: true, isSmall: true, onClick: addFeatureRow }, '+ Feature Row'),
|
||||
el(Btn, { isSecondary: true, isSmall: true, onClick: addGroupRow }, '+ Group Row'),
|
||||
el(Btn, { isSecondary: true, isSmall: true, onClick: addCol }, '+ Column')
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -513,6 +513,8 @@ add_action( 'init', function () {
|
||||
'faIcon' => [ 'type' => 'string', 'default' => '' ],
|
||||
'name' => [ 'type' => 'string', 'default' => '' ],
|
||||
'tagline' => [ 'type' => 'string', 'default' => '' ],
|
||||
'price' => [ 'type' => 'string', 'default' => '' ],
|
||||
'pricePer' => [ 'type' => 'string', 'default' => '' ],
|
||||
'features' => [ 'type' => 'array', 'default' => [] ],
|
||||
'btnText' => [ 'type' => 'string', 'default' => 'Get Started' ],
|
||||
'btnUrl' => [ 'type' => 'string', 'default' => '/contact' ],
|
||||
@@ -551,6 +553,13 @@ add_action( 'init', function () {
|
||||
'imgUrl' => [ 'type' => 'string', 'default' => '' ],
|
||||
'imgAlt' => [ 'type' => 'string', 'default' => '' ],
|
||||
'imgWidth' => [ 'type' => 'number', 'default' => 300 ],
|
||||
'isDashboard' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'deviceAnim' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'tvStick' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'cameraAnim' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'neverGoesDark'=> [ 'type' => 'boolean', 'default' => false ],
|
||||
'brandedAnim' => [ 'type' => 'boolean', 'default' => false ],
|
||||
'galleryIds' => [ 'type' => 'array', 'default' => [], 'items' => [ 'type' => 'number' ] ],
|
||||
],
|
||||
'supports' => $block_supports,
|
||||
'render_callback' => 'oribi_render_platform_row',
|
||||
@@ -666,9 +675,8 @@ function oribi_render_site_header() {
|
||||
<div class="site-logo">
|
||||
<?php if ( $has_logo ) : ?>
|
||||
<?php the_custom_logo(); ?>
|
||||
<?php else : ?>
|
||||
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" class="logo-text"><strong>Oribi</strong> Tech</a>
|
||||
<?php endif; ?>
|
||||
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" class="logo-text"><strong>OTS</strong> Signs</a>
|
||||
</div>
|
||||
<button class="nav-toggle" id="nav-toggle" aria-expanded="false" aria-label="<?php esc_attr_e( 'Toggle navigation', 'ots-theme' ); ?>">
|
||||
<span></span><span></span><span></span>
|
||||
@@ -698,9 +706,11 @@ function oribi_render_site_header() {
|
||||
/** Fallback menu when no WP menu is assigned. */
|
||||
function oribi_fallback_menu() {
|
||||
echo '<ul class="nav-menu">';
|
||||
echo '<li><a href="' . esc_url( home_url( '/managed-it' ) ) . '">Services</a></li>';
|
||||
echo '<li><a href="' . esc_url( home_url( '/solutions' ) ) . '">Solutions</a></li>';
|
||||
echo '<li><a href="' . esc_url( home_url( '/features' ) ) . '">Features</a></li>';
|
||||
echo '<li><a href="' . esc_url( home_url( '/pricing' ) ) . '">Pricing</a></li>';
|
||||
echo '<li><a href="' . esc_url( home_url( '/partners' ) ) . '">Partners</a></li>';
|
||||
echo '<li><a href="' . esc_url( home_url( '/about' ) ) . '">About</a></li>';
|
||||
echo '<li><a href="' . esc_url( home_url( '/faq' ) ) . '">FAQ</a></li>';
|
||||
echo '<li><a href="' . esc_url( home_url( '/contact' ) ) . '">Contact</a></li>';
|
||||
echo '</ul>';
|
||||
}
|
||||
@@ -718,25 +728,34 @@ function oribi_render_site_footer() {
|
||||
<?php else : ?>
|
||||
<div class="logo-text"><strong>Oribi</strong> Tech</div>
|
||||
<?php endif; ?>
|
||||
<p class="footer-tagline">IT solutions tailored for your business.</p>
|
||||
<p class="footer-location">Saratoga Springs, Upstate New York</p>
|
||||
<p class="footer-tagline">Digital signage solutions that communicate, engage, and grow your business.</p>
|
||||
<p class="footer-location">An Oribi Technology Services Company</p>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<div class="footer-col">
|
||||
<h4>Services</h4>
|
||||
<h4>Platform</h4>
|
||||
<ul>
|
||||
<li><a href="<?php echo esc_url( home_url( '/365care' ) ); ?>">365Care</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/endpointcare' ) ); ?>">EndpointCare</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/netcare' ) ); ?>">NetCare</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/servercare' ) ); ?>">ServerCare</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/features' ) ); ?>">Features</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/pricing' ) ); ?>">Pricing</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/devices' ) ); ?>">Devices</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/demo' ) ); ?>">Demo</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/security' ) ); ?>">Security</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>Solutions</h4>
|
||||
<ul>
|
||||
<li><a href="<?php echo esc_url( home_url( '/solutions' ) ); ?>">Industries</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/kiosks' ) ); ?>">Interactive Kiosks</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/outdoor' ) ); ?>">Outdoor Signage</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/partners' ) ); ?>">Partners</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>Company</h4>
|
||||
<ul>
|
||||
<li><a href="<?php echo esc_url( home_url( '/about' ) ); ?>">About</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/managed-it' ) ); ?>">Managed IT</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/services-comparison' ) ); ?>">Compare</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/resources' ) ); ?>">Resources</a></li>
|
||||
<li><a href="<?php echo esc_url( home_url( '/faq' ) ); ?>">FAQ</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -744,14 +763,14 @@ function oribi_render_site_footer() {
|
||||
<h4>Connect</h4>
|
||||
<ul>
|
||||
<li><a href="<?php echo esc_url( home_url( '/contact' ) ); ?>">Contact</a></li>
|
||||
<li><a href="https://portal.oribi-tech.com/" target="_blank" rel="noopener">Client Portal</a></li>
|
||||
<li><a href="mailto:solutions@oribi-tech.com">Email Us</a></li>
|
||||
<li><a href="https://ots-signs.com/portal" target="_blank" rel="noopener">Client Portal</a></li>
|
||||
<li><a href="mailto:hello@ots-signs.com">Email Us</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<p>© <?php echo esc_html( $year ); ?> OTS Themenology Services. All rights reserved.</p>
|
||||
<p>© <?php echo esc_html( $year ); ?> Oribi Technology Services. All rights reserved.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -950,12 +969,13 @@ function oribi_render_contact_section( $a ) {
|
||||
<div class="form-group">
|
||||
<label for="cf-interest">Interested In</label>
|
||||
<select id="cf-interest" name="interest">
|
||||
<option value="">Select a service…</option>
|
||||
<option value="365Care">365Care</option>
|
||||
<option value="EndpointCare">EndpointCare</option>
|
||||
<option value="NetCare">NetCare</option>
|
||||
<option value="ServerCare">ServerCare</option>
|
||||
<option value="Full Managed IT">Full Managed IT</option>
|
||||
<option value="">Select a topic…</option>
|
||||
<option value="Digital Signage">Digital Signage Solutions</option>
|
||||
<option value="Content Creation">Content Creation</option>
|
||||
<option value="Hardware">Player Devices & Hardware</option>
|
||||
<option value="Pricing">Pricing & Plans</option>
|
||||
<option value="Demo">Request a Demo</option>
|
||||
<option value="Support">Technical Support</option>
|
||||
<option value="Other">Other / Not sure</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -1294,6 +1314,12 @@ function oribi_render_pricing_card( $a ) {
|
||||
<?php if ( oribi_has_icon( $a ) ) : ?><div class="feature-icon" style="margin-inline:auto;"><?php echo oribi_render_icon( $a ); ?></div><?php endif; ?>
|
||||
<div class="pricing-name"><?php echo esc_html( $a['name'] ); ?></div>
|
||||
<p class="pricing-tagline"><?php echo wp_kses_post( $a['tagline'] ); ?></p>
|
||||
<?php if ( ! empty( $a['price'] ) ) : ?>
|
||||
<div class="pricing-price">
|
||||
<div class="pricing-amount"><?php echo wp_kses_post( $a['price'] ); ?></div>
|
||||
<?php if ( ! empty( $a['pricePer'] ) ) : ?><div class="pricing-per"><?php echo wp_kses_post( $a['pricePer'] ); ?></div><?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<ul class="pricing-features">
|
||||
<?php foreach ( ( $a['features'] ?? [] ) as $f ) : ?>
|
||||
<li><span class="pricing-check">✓</span> <?php echo wp_kses_post( $f ); ?></li>
|
||||
@@ -1321,6 +1347,208 @@ function oribi_render_platform_section( $a, $content ) {
|
||||
}
|
||||
|
||||
/* ── Platform Row (child - renders one service row) ────────────────────────── */
|
||||
function oribi_render_camera_animation() {
|
||||
return <<<'HTML'
|
||||
<div class="ve-stage" aria-hidden="true"><svg viewBox="0 0 540 360" xmlns="http://www.w3.org/2000/svg" class="ve-svg" role="img" aria-label="Animated video editor timeline">
|
||||
<defs>
|
||||
<clipPath id="ve-preview-clip">
|
||||
<rect x="54" y="36" width="256" height="184"/>
|
||||
</clipPath>
|
||||
<linearGradient id="ve-sg-warm" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#3d0800"/>
|
||||
<stop offset="50%" stop-color="#a02500"/>
|
||||
<stop offset="100%" stop-color="#1d0400"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="ve-sg-cold" x1="100%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#0a1f3d"/>
|
||||
<stop offset="50%" stop-color="#0e3d6e"/>
|
||||
<stop offset="100%" stop-color="#06111e"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="ve-sg-go" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#07180d"/>
|
||||
<stop offset="50%" stop-color="#1c6038"/>
|
||||
<stop offset="100%" stop-color="#040e07"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="ve-scr-warm" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#ff9500"/>
|
||||
<stop offset="100%" stop-color="#ff4500"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="ve-scr-cold" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#1a8aff"/>
|
||||
<stop offset="100%" stop-color="#0055cc"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="ve-scr-go" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#00cc66"/>
|
||||
<stop offset="100%" stop-color="#008844"/>
|
||||
</linearGradient>
|
||||
<pattern id="ve-scanlines" x="0" y="0" width="1" height="3" patternUnits="userSpaceOnUse">
|
||||
<rect width="1" height="1" fill="rgba(0,0,0,0.18)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<!-- Laptop lid outer shell -->
|
||||
<rect x="20" y="5" width="500" height="300" rx="12" fill="#d2d2d0" stroke="#b0aca8" stroke-width="1.5"/>
|
||||
<rect x="28" y="12" width="484" height="280" rx="8" fill="#1c1c1c"/>
|
||||
<rect x="32" y="16" width="476" height="272" rx="5" fill="#0e1117"/>
|
||||
<!-- Laptop base -->
|
||||
<rect x="10" y="305" width="520" height="26" rx="5" fill="#c8c8c8" stroke="#b0ada8" stroke-width="0.8"/>
|
||||
<rect x="80" y="301" width="380" height="5" rx="2" fill="#a8a6a2"/>
|
||||
<rect x="205" y="311" width="130" height="13" rx="5" fill="#b8b5b0" stroke="#a0a09a" stroke-width="0.7"/>
|
||||
<rect x="38" y="306" width="155" height="18" rx="2" fill="#bcbab6" opacity="0.45"/>
|
||||
<rect x="347" y="306" width="155" height="18" rx="2" fill="#bcbab6" opacity="0.45"/>
|
||||
|
||||
<!-- Editor title bar -->
|
||||
<rect x="32" y="16" width="476" height="20" rx="4" fill="#1e2229"/>
|
||||
<circle cx="50" cy="26" r="5" fill="#FF5F56"/>
|
||||
<circle cx="66" cy="26" r="5" fill="#FFBD2E"/>
|
||||
<circle cx="82" cy="26" r="5" fill="#27C93F"/>
|
||||
<rect x="180" y="21" width="180" height="10" rx="3" fill="#3a3f48"/>
|
||||
<rect x="100" y="22" width="28" height="8" rx="2" fill="#2e333c"/>
|
||||
<rect x="132" y="22" width="24" height="8" rx="2" fill="#2e333c"/>
|
||||
<rect x="160" y="22" width="16" height="8" rx="2" fill="#2e333c"/>
|
||||
|
||||
<!-- Left toolbar -->
|
||||
<rect x="32" y="36" width="22" height="184" fill="#181c22"/>
|
||||
<line x1="54" y1="36" x2="54" y2="220" stroke="#2a2e38" stroke-width="1"/>
|
||||
<rect x="36" y="46" width="14" height="14" rx="2" fill="#3a4152"/>
|
||||
<rect x="36" y="66" width="14" height="14" rx="2" fill="#3a4152"/>
|
||||
<rect x="36" y="86" width="14" height="14" rx="2" fill="#3a4152"/>
|
||||
<rect x="36" y="106" width="14" height="14" rx="2" fill="#3a4152"/>
|
||||
<rect x="36" y="126" width="14" height="14" rx="2" fill="#3a4152"/>
|
||||
<rect x="33" y="46" width="3" height="14" rx="1" fill="#D83302"/>
|
||||
|
||||
<!-- Preview pane -->
|
||||
<rect x="54" y="36" width="256" height="184" fill="#0a0b0e"/>
|
||||
<g clip-path="url(#ve-preview-clip)">
|
||||
<rect id="ve-scene-1" x="54" y="36" width="256" height="184" fill="url(#ve-sg-warm)" opacity="1"/>
|
||||
<rect id="ve-scene-2" x="54" y="36" width="256" height="184" fill="url(#ve-sg-cold)" opacity="0"/>
|
||||
<rect id="ve-scene-3" x="54" y="36" width="256" height="184" fill="url(#ve-sg-go)" opacity="0"/>
|
||||
<!-- Laptop in the preview video -->
|
||||
<rect x="102" y="52" width="156" height="106" rx="5" fill="#1c1c1c" stroke="#2e2e2e" stroke-width="1"/>
|
||||
<rect x="106" y="56" width="148" height="98" rx="3" fill="#111111"/>
|
||||
<rect id="ve-inner-screen" x="108" y="58" width="144" height="94" rx="1" fill="url(#ve-scr-warm)"/>
|
||||
<polygon points="108,58 160,58 108,88" fill="white" opacity="0.04"/>
|
||||
<rect x="108" y="58" width="144" height="94" fill="url(#ve-scanlines)" opacity="0.45"/>
|
||||
<circle cx="180" cy="55" r="2.5" fill="#232323" stroke="#2e2e2e" stroke-width="0.5"/>
|
||||
<rect x="92" y="158" width="176" height="17" rx="2" fill="#222222" stroke="#2d2d2d" stroke-width="0.5"/>
|
||||
<rect x="150" y="162" width="60" height="9" rx="3" fill="#2a2a2a" stroke="#353535" stroke-width="0.5"/>
|
||||
<rect x="97" y="159" width="166" height="1" fill="#2c2c2c"/>
|
||||
<line x1="54" y1="175" x2="310" y2="175" stroke="#1c1c1c" stroke-width="2"/>
|
||||
<rect x="54" y="175" width="256" height="45" fill="#040507" opacity="0.75"/>
|
||||
<rect x="54" y="36" width="256" height="184" fill="url(#ve-scanlines)" opacity="0.25"/>
|
||||
</g>
|
||||
<rect x="54" y="36" width="256" height="184" fill="none" stroke="#2a2e38" stroke-width="0.5"/>
|
||||
<line x1="310" y1="36" x2="310" y2="220" stroke="#2a2e38" stroke-width="1"/>
|
||||
|
||||
<!-- Inspector / Properties panel -->
|
||||
<rect x="310" y="36" width="198" height="184" fill="#141619"/>
|
||||
<rect x="310" y="36" width="198" height="20" fill="#1a1e25"/>
|
||||
<rect x="318" y="42" width="80" height="8" rx="2" fill="#3a3f48"/>
|
||||
<rect x="318" y="64" width="50" height="7" rx="2" fill="#2a2e38"/>
|
||||
<rect x="378" y="64" width="82" height="7" rx="2" fill="#333a45"/>
|
||||
<rect x="318" y="78" width="45" height="7" rx="2" fill="#2a2e38"/>
|
||||
<rect x="378" y="78" width="96" height="7" rx="2" fill="#333a45"/>
|
||||
<rect x="318" y="92" width="35" height="7" rx="2" fill="#2a2e38"/>
|
||||
<rect x="378" y="92" width="62" height="7" rx="2" fill="#333a45"/>
|
||||
<rect x="318" y="106" width="55" height="7" rx="2" fill="#2a2e38"/>
|
||||
<rect x="378" y="106" width="72" height="7" rx="2" fill="#333a45"/>
|
||||
<rect x="318" y="120" width="40" height="7" rx="2" fill="#2a2e38"/>
|
||||
<rect x="378" y="120" width="54" height="7" rx="2" fill="#333a45"/>
|
||||
<line x1="318" y1="136" x2="498" y2="136" stroke="#2a2e38" stroke-width="0.5"/>
|
||||
<rect x="310" y="136" width="198" height="12" fill="#1a1e25"/>
|
||||
<rect x="318" y="140" width="60" height="6" rx="2" fill="#2a2e38"/>
|
||||
<rect x="318" y="150" width="32" height="24" rx="1" fill="#C0390A" opacity="0.8"/>
|
||||
<rect x="354" y="150" width="32" height="24" rx="1" fill="#1a52c8" opacity="0.8"/>
|
||||
<rect x="390" y="150" width="32" height="24" rx="1" fill="#1a7a3d" opacity="0.8"/>
|
||||
<rect x="426" y="150" width="32" height="24" rx="1" fill="#c07800" opacity="0.8"/>
|
||||
<rect x="462" y="150" width="32" height="24" rx="1" fill="#7030d0" opacity="0.8"/>
|
||||
|
||||
<!-- Timeline section -->
|
||||
<rect x="32" y="220" width="476" height="68" fill="#161616"/>
|
||||
<line x1="32" y1="220" x2="508" y2="220" stroke="#2a2e38" stroke-width="1"/>
|
||||
<rect x="32" y="220" width="476" height="14" fill="#1a1e24"/>
|
||||
<rect x="32" y="220" width="72" height="68" fill="#1a1e24"/>
|
||||
<line x1="104" y1="220" x2="104" y2="288" stroke="#2a2e38" stroke-width="1"/>
|
||||
<!-- Ruler ticks and labels -->
|
||||
<line x1="104" y1="220" x2="104" y2="232" stroke="#4a4e58" stroke-width="1"/>
|
||||
<text x="105" y="231" fill="#565a64" font-size="8" font-family="monospace">0:00</text>
|
||||
<line x1="184" y1="220" x2="184" y2="232" stroke="#4a4e58" stroke-width="1"/>
|
||||
<text x="185" y="231" fill="#565a64" font-size="8" font-family="monospace">0:02</text>
|
||||
<line x1="264" y1="220" x2="264" y2="232" stroke="#4a4e58" stroke-width="1"/>
|
||||
<text x="265" y="231" fill="#565a64" font-size="8" font-family="monospace">0:04</text>
|
||||
<line x1="344" y1="220" x2="344" y2="232" stroke="#4a4e58" stroke-width="1"/>
|
||||
<text x="345" y="231" fill="#565a64" font-size="8" font-family="monospace">0:06</text>
|
||||
<line x1="424" y1="220" x2="424" y2="232" stroke="#4a4e58" stroke-width="1"/>
|
||||
<text x="425" y="231" fill="#565a64" font-size="8" font-family="monospace">0:08</text>
|
||||
<line x1="144" y1="220" x2="144" y2="226" stroke="#2e3240" stroke-width="0.5"/>
|
||||
<line x1="224" y1="220" x2="224" y2="226" stroke="#2e3240" stroke-width="0.5"/>
|
||||
<line x1="304" y1="220" x2="304" y2="226" stroke="#2e3240" stroke-width="0.5"/>
|
||||
<line x1="384" y1="220" x2="384" y2="226" stroke="#2e3240" stroke-width="0.5"/>
|
||||
<line x1="464" y1="220" x2="464" y2="226" stroke="#2e3240" stroke-width="0.5"/>
|
||||
<!-- Track label colour strips -->
|
||||
<rect x="36" y="237" width="56" height="14" rx="2" fill="#283040"/>
|
||||
<rect x="36" y="255" width="56" height="14" rx="2" fill="#203020"/>
|
||||
<rect x="36" y="273" width="56" height="14" rx="2" fill="#302818"/>
|
||||
|
||||
<!-- Track 1: VIDEO clips -->
|
||||
<rect x="104" y="234" width="404" height="18" fill="#1a1a22"/>
|
||||
<rect x="104" y="235" width="88" height="16" rx="2" fill="#2563EB"/>
|
||||
<rect x="104" y="235" width="88" height="5" rx="2" fill="rgba(255,255,255,0.07)"/>
|
||||
<rect x="196" y="235" width="66" height="16" rx="2" fill="#1D4ED8"/>
|
||||
<rect x="196" y="235" width="66" height="5" rx="2" fill="rgba(255,255,255,0.07)"/>
|
||||
<rect x="266" y="235" width="106" height="16" rx="2" fill="#2563EB"/>
|
||||
<rect x="266" y="235" width="106" height="5" rx="2" fill="rgba(255,255,255,0.07)"/>
|
||||
<rect x="376" y="235" width="88" height="16" rx="2" fill="#1E40AF"/>
|
||||
<rect x="376" y="235" width="88" height="5" rx="2" fill="rgba(255,255,255,0.07)"/>
|
||||
|
||||
<!-- Track 2: AUDIO/MUSIC clips -->
|
||||
<rect x="104" y="252" width="404" height="18" fill="#141c12"/>
|
||||
<rect x="104" y="253" width="178" height="16" rx="2" fill="#15803D"/>
|
||||
<rect x="104" y="253" width="178" height="5" rx="2" fill="rgba(255,255,255,0.06)"/>
|
||||
<!-- Inline waveform bars -->
|
||||
<rect x="108" y="259" width="2" height="5" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="112" y="257" width="2" height="8" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="116" y="260" width="2" height="4" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="120" y="257" width="2" height="7" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="124" y="260" width="2" height="5" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="128" y="257" width="2" height="7" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="132" y="259" width="2" height="5" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="136" y="257" width="2" height="8" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="140" y="260" width="2" height="4" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="144" y="258" width="2" height="7" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="148" y="261" width="2" height="4" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="152" y="258" width="2" height="6" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="156" y="259" width="2" height="5" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="160" y="257" width="2" height="7" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="164" y="259" width="2" height="5" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="168" y="257" width="2" height="8" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="172" y="261" width="2" height="4" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="176" y="259" width="2" height="5" fill="rgba(255,255,255,0.22)"/>
|
||||
<rect x="286" y="253" width="148" height="16" rx="2" fill="#166534"/>
|
||||
<rect x="286" y="253" width="148" height="5" rx="2" fill="rgba(255,255,255,0.06)"/>
|
||||
<rect x="438" y="253" width="66" height="16" rx="2" fill="#15803D"/>
|
||||
<rect x="438" y="253" width="66" height="5" rx="2" fill="rgba(255,255,255,0.06)"/>
|
||||
|
||||
<!-- Track 3: GFX / TEXT clips -->
|
||||
<rect x="104" y="270" width="404" height="18" fill="#181710"/>
|
||||
<rect x="120" y="271" width="60" height="16" rx="2" fill="#D97706"/>
|
||||
<rect x="120" y="271" width="60" height="5" rx="2" fill="rgba(255,255,255,0.07)"/>
|
||||
<rect x="226" y="271" width="52" height="16" rx="2" fill="#B45309"/>
|
||||
<rect x="226" y="271" width="52" height="5" rx="2" fill="rgba(255,255,255,0.07)"/>
|
||||
<rect x="334" y="271" width="78" height="16" rx="2" fill="#D97706"/>
|
||||
<rect x="334" y="271" width="78" height="5" rx="2" fill="rgba(255,255,255,0.07)"/>
|
||||
<rect x="452" y="271" width="50" height="16" rx="2" fill="#B45309"/>
|
||||
<rect x="452" y="271" width="50" height="5" rx="2" fill="rgba(255,255,255,0.07)"/>
|
||||
|
||||
<!-- Animated playhead -->
|
||||
<polygon id="ve-playhead-head" points="0,-8 -6,-2 6,-2" transform="translate(104,234)" fill="#FF4500"/>
|
||||
<rect id="ve-playhead-line" x="103" y="220" width="2" height="68" fill="#FF4500" opacity="0.92"/>
|
||||
<!-- Timecode display -->
|
||||
<text id="ve-timecode" x="36" y="230" fill="#8a8e98" font-size="8" font-family="monospace">0:00</text>
|
||||
</svg></div>
|
||||
HTML;
|
||||
}
|
||||
|
||||
function oribi_render_platform_row( $a ) {
|
||||
$rev = ! empty( $a['reversed'] ) ? ' reverse' : '';
|
||||
$img_id = ! empty( $a['imgId'] ) ? intval( $a['imgId'] ) : 0;
|
||||
@@ -1328,7 +1556,128 @@ function oribi_render_platform_row( $a ) {
|
||||
$img_alt = ! empty( $a['imgAlt'] ) ? $a['imgAlt'] : '';
|
||||
$img_w = ! empty( $a['imgWidth'] ) ? intval( $a['imgWidth'] ) : 300;
|
||||
|
||||
if ( $img_url ) {
|
||||
// Only render animated dashboard when explicitly flagged
|
||||
$is_dashboard = ! empty( $a['isDashboard'] );
|
||||
|
||||
if ( $is_dashboard ) {
|
||||
// Render animated dashboard chart SVG
|
||||
// Text uses class hooks: .ct = title, .cl = label, .cv = value
|
||||
// JS will dynamically set fill colours based on data-theme
|
||||
$visual_html = '<div class="dashboard-tv" data-dashboard-container="true">
|
||||
<div class="dashboard-tv__body">
|
||||
<div class="dashboard-tv__screen">
|
||||
<svg viewBox="0 0 800 450" xmlns="http://www.w3.org/2000/svg" class="dashboard-chart" role="img" aria-label="Animated dashboard charts">
|
||||
<defs>
|
||||
<linearGradient id="barGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#D83302" stop-opacity="1"/>
|
||||
<stop offset="100%" stop-color="#4CAF50" stop-opacity=".8"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="lineGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#4CAF50" stop-opacity=".3"/>
|
||||
<stop offset="100%" stop-color="#4CAF50" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- ── Top-left: Performance bars ── -->
|
||||
<g transform="translate(35,20)">
|
||||
<text class="ct" x="0" y="0" font-size="14" font-weight="600" fill="#333">Performance</text>
|
||||
<g id="bars-group-1" transform="translate(0,25)">
|
||||
<rect class="bar" x="0" y="120" width="28" height="0" fill="url(#barGradient)"/>
|
||||
<rect class="bar" x="40" y="120" width="28" height="0" fill="url(#barGradient)"/>
|
||||
<rect class="bar" x="80" y="120" width="28" height="0" fill="url(#barGradient)"/>
|
||||
<rect class="bar" x="120" y="120" width="28" height="0" fill="url(#barGradient)"/>
|
||||
<rect class="bar" x="160" y="120" width="28" height="0" fill="url(#barGradient)"/>
|
||||
</g>
|
||||
<g transform="translate(0,152)">
|
||||
<text class="cl" x="14" y="0" font-size="10" text-anchor="middle" fill="#666">API</text>
|
||||
<text class="cl" x="54" y="0" font-size="10" text-anchor="middle" fill="#666">Cache</text>
|
||||
<text class="cl" x="94" y="0" font-size="10" text-anchor="middle" fill="#666">DB</text>
|
||||
<text class="cl" x="134" y="0" font-size="10" text-anchor="middle" fill="#666">Queue</text>
|
||||
<text class="cl" x="174" y="0" font-size="10" text-anchor="middle" fill="#666">Worker</text>
|
||||
</g>
|
||||
<g id="values-group-1" transform="translate(0,168)">
|
||||
<text class="cv" x="14" y="0" font-size="11" font-weight="600" text-anchor="middle" fill="#333">0%</text>
|
||||
<text class="cv" x="54" y="0" font-size="11" font-weight="600" text-anchor="middle" fill="#333">0%</text>
|
||||
<text class="cv" x="94" y="0" font-size="11" font-weight="600" text-anchor="middle" fill="#333">0%</text>
|
||||
<text class="cv" x="134" y="0" font-size="11" font-weight="600" text-anchor="middle" fill="#333">0%</text>
|
||||
<text class="cv" x="174" y="0" font-size="11" font-weight="600" text-anchor="middle" fill="#333">0%</text>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- ── Top-right: Requests/sec bars ── -->
|
||||
<g transform="translate(430,20)">
|
||||
<text class="ct" x="0" y="0" font-size="14" font-weight="600" fill="#333">Requests/sec</text>
|
||||
<g id="bars-group-2" transform="translate(0,25)">
|
||||
<rect class="bar" x="0" y="120" width="28" height="0" fill="url(#barGradient)"/>
|
||||
<rect class="bar" x="40" y="120" width="28" height="0" fill="url(#barGradient)"/>
|
||||
<rect class="bar" x="80" y="120" width="28" height="0" fill="url(#barGradient)"/>
|
||||
<rect class="bar" x="120" y="120" width="28" height="0" fill="url(#barGradient)"/>
|
||||
</g>
|
||||
<g transform="translate(0,152)">
|
||||
<text class="cl" x="14" y="0" font-size="10" text-anchor="middle" fill="#666">Read</text>
|
||||
<text class="cl" x="54" y="0" font-size="10" text-anchor="middle" fill="#666">Write</text>
|
||||
<text class="cl" x="94" y="0" font-size="10" text-anchor="middle" fill="#666">Update</text>
|
||||
<text class="cl" x="134" y="0" font-size="10" text-anchor="middle" fill="#666">Delete</text>
|
||||
</g>
|
||||
<g id="values-group-2" transform="translate(0,168)">
|
||||
<text class="cv" x="14" y="0" font-size="11" font-weight="600" text-anchor="middle" fill="#333">0</text>
|
||||
<text class="cv" x="54" y="0" font-size="11" font-weight="600" text-anchor="middle" fill="#333">0</text>
|
||||
<text class="cv" x="94" y="0" font-size="11" font-weight="600" text-anchor="middle" fill="#333">0</text>
|
||||
<text class="cv" x="134" y="0" font-size="11" font-weight="600" text-anchor="middle" fill="#333">0</text>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- ── Bottom-left: Traffic Trend line ── -->
|
||||
<g id="line-graph" transform="translate(35,245)">
|
||||
<text class="ct" x="0" y="0" font-size="14" font-weight="600" fill="#333">Traffic Trend</text>
|
||||
<g transform="translate(0,25)">
|
||||
<line class="grid-line" x1="0" y1="0" x2="340" y2="0" stroke="#E0E0E0" stroke-width=".5"/>
|
||||
<line class="grid-line" x1="0" y1="40" x2="340" y2="40" stroke="#E0E0E0" stroke-width=".5"/>
|
||||
<line class="grid-line" x1="0" y1="80" x2="340" y2="80" stroke="#E0E0E0" stroke-width=".5"/>
|
||||
<line class="grid-line" x1="0" y1="120" x2="340" y2="120" stroke="#E0E0E0" stroke-width=".5"/>
|
||||
</g>
|
||||
<g transform="translate(0,25)">
|
||||
<path id="line-fill" d="M0,80 L340,80 L340,145 L0,145 Z" fill="url(#lineGradient)"/>
|
||||
<path id="line-path" d="M0,80 L340,80" stroke="#4CAF50" stroke-width="2.5" fill="none" stroke-linecap="round"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- ── Bottom-right: Distribution pie ── -->
|
||||
<g transform="translate(490,245)">
|
||||
<text class="ct" x="100" y="0" font-size="14" font-weight="600" text-anchor="middle" fill="#333">Distribution</text>
|
||||
<g transform="translate(100,90)">
|
||||
<g class="pie-segment" transform="rotate(0)">
|
||||
<path d="M0,0 L0,-55 A55,55 0 0,1 38.89,-38.89 Z" fill="#D83302" opacity=".9"/>
|
||||
</g>
|
||||
<g class="pie-segment" transform="rotate(90)">
|
||||
<path d="M0,0 L0,-55 A55,55 0 0,1 38.89,-38.89 Z" fill="#4CAF50" opacity=".8"/>
|
||||
</g>
|
||||
<g class="pie-segment" transform="rotate(180)">
|
||||
<path d="M0,0 L0,-55 A55,55 0 0,1 38.89,-38.89 Z" fill="#f59e0b" opacity=".7"/>
|
||||
</g>
|
||||
<g class="pie-segment" transform="rotate(270)">
|
||||
<path d="M0,0 L0,-55 A55,55 0 0,1 38.89,-38.89 Z" fill="#ef4444" opacity=".7"/>
|
||||
</g>
|
||||
<circle id="pie-center" cx="0" cy="0" r="22" fill="#fff" stroke="#E0E0E0" stroke-width="1"/>
|
||||
<text id="pie-center-text" x="0" y="5" text-anchor="middle" font-size="13" font-weight="600" fill="#333">100%</text>
|
||||
</g>
|
||||
<g transform="translate(30,170)">
|
||||
<rect x="0" y="0" width="8" height="8" fill="#D83302"/>
|
||||
<text class="cl" x="12" y="8" font-size="11" fill="#666">Service A</text>
|
||||
<rect x="0" y="15" width="8" height="8" fill="#4CAF50"/>
|
||||
<text class="cl" x="12" y="23" font-size="11" fill="#666">Service B</text>
|
||||
<rect x="100" y="0" width="8" height="8" fill="#f59e0b"/>
|
||||
<text class="cl" x="112" y="8" font-size="11" fill="#666">Service C</text>
|
||||
<rect x="100" y="15" width="8" height="8" fill="#ef4444"/>
|
||||
<text class="cl" x="112" y="23" font-size="11" fill="#666">Service D</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div></div>
|
||||
<div class="dashboard-tv__feet"><div class="dashboard-tv__foot"></div><div class="dashboard-tv__foot"></div></div>
|
||||
</div>';
|
||||
$visual_cls = 'platform-visual has-dashboard';
|
||||
} elseif ( $img_url ) {
|
||||
$img_style = 'width:' . $img_w . 'px;max-width:100%;height:auto;border-radius:var(--radius-sm);object-fit:contain;display:block;margin-inline:auto;';
|
||||
if ( $img_id ) {
|
||||
$visual_html = wp_get_attachment_image( $img_id, 'full', false, [ 'style' => $img_style, 'alt' => $img_alt ] );
|
||||
@@ -1336,6 +1685,292 @@ function oribi_render_platform_row( $a ) {
|
||||
$visual_html = '<img src="' . esc_url( $img_url ) . '" alt="' . esc_attr( $img_alt ) . '" style="' . esc_attr( $img_style ) . '">';
|
||||
}
|
||||
$visual_cls = 'platform-visual has-img';
|
||||
} elseif ( ! empty( $a['deviceAnim'] ) ) {
|
||||
$da_screen = '<div class="da-screen"><div class="da-promo"><div class="da-promo__top"><span class="da-promo__dot"></span><span class="da-promo__brand"></span></div><div class="da-promo__hero"></div><div class="da-promo__row"><span class="da-promo__line da-promo__line--lg"></span><span class="da-promo__line da-promo__line--sm"></span></div><div class="da-promo__row"><span class="da-promo__line da-promo__line--md"></span><span class="da-promo__line da-promo__line--xs"></span></div><div class="da-promo__ticker"><span class="da-promo__chip"></span><span class="da-promo__chip"></span><span class="da-promo__chip"></span></div></div></div>';
|
||||
$da = '<div class="da-stage" aria-hidden="true">';
|
||||
$da .= '<div class="da-device da-tablet"><div class="da-body">' . $da_screen . '</div><span class="da-label">Tablet</span></div>';
|
||||
$da .= '<div class="da-device da-monitor-sm"><div class="da-body">' . $da_screen . '</div><div class="da-stand"><div class="da-stem"></div><div class="da-base"></div></div><span class="da-label">Small Monitor</span></div>';
|
||||
$da .= '<div class="da-device da-monitor-lg"><div class="da-body">' . $da_screen . '</div><div class="da-stand"><div class="da-stem"></div><div class="da-base"></div></div><span class="da-label">Large Monitor</span></div>';
|
||||
$da .= '<div class="da-device da-tv"><div class="da-body">' . $da_screen . '</div><div class="da-feet"><div class="da-foot"></div><div class="da-foot"></div></div><span class="da-label">TV</span></div>';
|
||||
$da .= '<div class="da-device da-projector"><div class="da-proj-layout"><div class="da-proj-body"><div class="da-lens"></div></div><div class="da-beam"></div><div class="da-proj-screen">' . $da_screen . '</div></div><span class="da-label">Projector</span></div>';
|
||||
$da .= '<div class="da-device da-vwall"><div class="da-vwall-grid"><div class="da-panel">' . $da_screen . '</div><div class="da-panel">' . $da_screen . '</div><div class="da-panel">' . $da_screen . '</div><div class="da-panel">' . $da_screen . '</div></div><span class="da-label">Video Wall</span></div>';
|
||||
$da .= '</div>';
|
||||
$visual_html = $da;
|
||||
$visual_cls = 'platform-visual has-anim';
|
||||
} elseif ( ! empty( $a['tvStick'] ) ) {
|
||||
$ts = '<div class="ts-stage" data-tv-stick-anim aria-hidden="true">';
|
||||
$ts .= '<div class="ts-tv">';
|
||||
$ts .= '<div class="ts-tv__body">';
|
||||
$ts .= '<div class="ts-tv__screen">';
|
||||
$ts .= '<div class="ts-slides">';
|
||||
|
||||
// Slide 1 — Menu Board
|
||||
$ts .= '<div class="ts-slide ts-slide--menu">';
|
||||
$ts .= '<div class="ts-menu">';
|
||||
$ts .= '<div class="ts-menu__header"><div class="ts-menu__logo"></div><div class="ts-menu__title"></div></div>';
|
||||
$ts .= '<div class="ts-menu__cols">';
|
||||
$ts .= '<div class="ts-menu__col">';
|
||||
$ts .= '<div class="ts-menu__cat"></div>';
|
||||
$ts .= '<div class="ts-menu__item"><span class="ts-menu__name"></span><span class="ts-menu__dots"></span><span class="ts-menu__price"></span></div>';
|
||||
$ts .= '<div class="ts-menu__item"><span class="ts-menu__name"></span><span class="ts-menu__dots"></span><span class="ts-menu__price"></span></div>';
|
||||
$ts .= '<div class="ts-menu__item"><span class="ts-menu__name"></span><span class="ts-menu__dots"></span><span class="ts-menu__price"></span></div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '<div class="ts-menu__col">';
|
||||
$ts .= '<div class="ts-menu__cat"></div>';
|
||||
$ts .= '<div class="ts-menu__item"><span class="ts-menu__name"></span><span class="ts-menu__dots"></span><span class="ts-menu__price"></span></div>';
|
||||
$ts .= '<div class="ts-menu__item"><span class="ts-menu__name"></span><span class="ts-menu__dots"></span><span class="ts-menu__price"></span></div>';
|
||||
$ts .= '<div class="ts-menu__item"><span class="ts-menu__name"></span><span class="ts-menu__dots"></span><span class="ts-menu__price"></span></div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '</div>';
|
||||
|
||||
// Slide 2 — Wayfinding Sign
|
||||
$ts .= '<div class="ts-slide ts-slide--wayfind">';
|
||||
$ts .= '<div class="ts-wf">';
|
||||
$ts .= '<div class="ts-wf__header"><div class="ts-wf__building"></div></div>';
|
||||
$ts .= '<div class="ts-wf__rows">';
|
||||
$ts .= '<div class="ts-wf__row"><span class="ts-wf__arrow ts-wf__arrow--left"></span><span class="ts-wf__label ts-wf__label--w1"></span><span class="ts-wf__floor"></span></div>';
|
||||
$ts .= '<div class="ts-wf__row"><span class="ts-wf__arrow ts-wf__arrow--right"></span><span class="ts-wf__label ts-wf__label--w2"></span><span class="ts-wf__floor"></span></div>';
|
||||
$ts .= '<div class="ts-wf__row"><span class="ts-wf__arrow ts-wf__arrow--up"></span><span class="ts-wf__label ts-wf__label--w3"></span><span class="ts-wf__floor"></span></div>';
|
||||
$ts .= '<div class="ts-wf__row"><span class="ts-wf__arrow ts-wf__arrow--left"></span><span class="ts-wf__label ts-wf__label--w4"></span><span class="ts-wf__floor"></span></div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '</div>';
|
||||
|
||||
// Slide 3 — Schedule / Timetable
|
||||
$ts .= '<div class="ts-slide ts-slide--sched">';
|
||||
$ts .= '<div class="ts-sched">';
|
||||
$ts .= '<div class="ts-sched__header"><div class="ts-sched__title"></div><div class="ts-sched__date"></div></div>';
|
||||
$ts .= '<div class="ts-sched__table">';
|
||||
$ts .= '<div class="ts-sched__hrow"><span class="ts-sched__hcell"></span><span class="ts-sched__hcell"></span><span class="ts-sched__hcell"></span><span class="ts-sched__hcell"></span></div>';
|
||||
$ts .= '<div class="ts-sched__row"><span class="ts-sched__time"></span><span class="ts-sched__event ts-sched__event--a"></span><span class="ts-sched__cell"></span><span class="ts-sched__cell"></span></div>';
|
||||
$ts .= '<div class="ts-sched__row"><span class="ts-sched__time"></span><span class="ts-sched__cell"></span><span class="ts-sched__event ts-sched__event--b"></span><span class="ts-sched__cell"></span></div>';
|
||||
$ts .= '<div class="ts-sched__row"><span class="ts-sched__time"></span><span class="ts-sched__cell"></span><span class="ts-sched__cell"></span><span class="ts-sched__event ts-sched__event--c"></span></div>';
|
||||
$ts .= '<div class="ts-sched__row"><span class="ts-sched__time"></span><span class="ts-sched__event ts-sched__event--a"></span><span class="ts-sched__event ts-sched__event--b"></span><span class="ts-sched__cell"></span></div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '</div>';
|
||||
|
||||
$ts .= '</div>'; // ts-slides
|
||||
$ts .= '</div>'; // ts-tv__screen
|
||||
$ts .= '<div class="ts-tv__port"></div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '<div class="ts-tv__feet"><div class="ts-tv__foot"></div><div class="ts-tv__foot"></div></div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '<div class="ts-stick">';
|
||||
$ts .= '<div class="ts-stick__body">';
|
||||
$ts .= '<div class="ts-stick__led"></div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '<div class="ts-stick__connector"></div>';
|
||||
$ts .= '</div>';
|
||||
$ts .= '</div>';
|
||||
$visual_html = $ts;
|
||||
$visual_cls = 'platform-visual has-tv-stick';
|
||||
} elseif ( ! empty( $a['neverGoesDark'] ) ) {
|
||||
/* ── Never Goes Dark: player + TV + cloud connection/break animation ── */
|
||||
$ngd = '<div class="ngd-stage" aria-hidden="true">';
|
||||
|
||||
/* TV */
|
||||
$ngd .= '<div class="ngd-tv">';
|
||||
$ngd .= '<div class="ngd-tv__body">';
|
||||
$ngd .= '<div class="ngd-tv__screen">';
|
||||
$ngd .= '<div class="ngd-menu">';
|
||||
$ngd .= '<div class="ngd-menu__hd">';
|
||||
$ngd .= '<div class="ngd-menu__logo"></div>';
|
||||
$ngd .= '<div class="ngd-menu__ttl"></div>';
|
||||
$ngd .= '</div>';
|
||||
$ngd .= '<div class="ngd-menu__cols">';
|
||||
$ngd .= '<div class="ngd-menu__col">';
|
||||
$ngd .= '<div class="ngd-menu__cat"></div>';
|
||||
$ngd .= '<div class="ngd-menu__row"><span class="ngd-menu__name"></span><span class="ngd-menu__price"></span></div>';
|
||||
$ngd .= '<div class="ngd-menu__row ngd-menu__row--hl"><span class="ngd-menu__name"></span><span class="ngd-menu__price"></span></div>';
|
||||
$ngd .= '<div class="ngd-menu__row"><span class="ngd-menu__name"></span><span class="ngd-menu__price"></span></div>';
|
||||
$ngd .= '</div>';
|
||||
$ngd .= '<div class="ngd-menu__col">';
|
||||
$ngd .= '<div class="ngd-menu__cat"></div>';
|
||||
$ngd .= '<div class="ngd-menu__row"><span class="ngd-menu__name"></span><span class="ngd-menu__price"></span></div>';
|
||||
$ngd .= '<div class="ngd-menu__row"><span class="ngd-menu__name"></span><span class="ngd-menu__price"></span></div>';
|
||||
$ngd .= '<div class="ngd-menu__row ngd-menu__row--hl"><span class="ngd-menu__name"></span><span class="ngd-menu__price"></span></div>';
|
||||
$ngd .= '</div>';
|
||||
$ngd .= '</div>'; /* cols */
|
||||
$ngd .= '<div class="ngd-menu__ticker"><div class="ngd-menu__ticker-inner"></div></div>';
|
||||
$ngd .= '</div>'; /* ngd-menu */
|
||||
$ngd .= '</div>'; /* ngd-tv__screen */
|
||||
$ngd .= '<div class="ngd-tv__port"></div>';
|
||||
$ngd .= '</div>'; /* ngd-tv__body */
|
||||
$ngd .= '<div class="ngd-tv__feet"><div class="ngd-tv__foot"></div><div class="ngd-tv__foot"></div></div>';
|
||||
$ngd .= '</div>'; /* ngd-tv */
|
||||
|
||||
/* Player device (stick style, plugged into TV right-side HDMI port) */
|
||||
$ngd .= '<div class="ngd-player">';
|
||||
$ngd .= '<div class="ngd-player__connector"></div>';
|
||||
$ngd .= '<div class="ngd-player__body">';
|
||||
$ngd .= '<div class="ngd-player__led"></div>';
|
||||
$ngd .= '</div>';
|
||||
$ngd .= '<div class="ngd-player__check">';
|
||||
$ngd .= '<svg viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">';
|
||||
$ngd .= '<circle cx="11" cy="11" r="10" stroke="#4CAF50" stroke-width="1.5"/>';
|
||||
$ngd .= '<polyline points="6,11 9.5,14.5 16,7.5" stroke="#4CAF50" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>';
|
||||
$ngd .= '</svg>';
|
||||
$ngd .= '</div>';
|
||||
$ngd .= '</div>'; /* ngd-player */
|
||||
|
||||
/* Signal wrap: vertical line connecting player to globe above */
|
||||
$ngd .= '<div class="ngd-signal-wrap">';
|
||||
$ngd .= '<div class="ngd-cloud">';
|
||||
$ngd .= '<svg class="ngd-cloud__svg" viewBox="0 0 64 46" fill="none" xmlns="http://www.w3.org/2000/svg">';
|
||||
$ngd .= '<circle class="ngd-cloud__path" cx="32" cy="23" r="14" stroke-width="2.2" fill="none"/>';
|
||||
$ngd .= '<path class="ngd-cloud__path" d="M18.5 23C23 20 41 20 45.5 23" stroke-width="1.9" stroke-linecap="round" fill="none"/>';
|
||||
$ngd .= '<path class="ngd-cloud__path" d="M20.5 29C25.5 31 38.5 31 43.5 29" stroke-width="1.9" stroke-linecap="round" fill="none"/>';
|
||||
$ngd .= '<path class="ngd-cloud__path" d="M24.5 12C21.5 16.5 21.5 29.5 24.5 34" stroke-width="1.9" stroke-linecap="round" fill="none"/>';
|
||||
$ngd .= '<path class="ngd-cloud__path" d="M39.5 12C42.5 16.5 42.5 29.5 39.5 34" stroke-width="1.9" stroke-linecap="round" fill="none"/>';
|
||||
$ngd .= '</svg>';
|
||||
$ngd .= '</div>';
|
||||
$ngd .= '<div class="ngd-signal-line">';
|
||||
$ngd .= '<div class="ngd-signal__dots">';
|
||||
$ngd .= '<div class="ngd-signal__dot ngd-signal__dot--1"></div>';
|
||||
$ngd .= '<div class="ngd-signal__dot ngd-signal__dot--2"></div>';
|
||||
$ngd .= '<div class="ngd-signal__dot ngd-signal__dot--3"></div>';
|
||||
$ngd .= '</div>';
|
||||
$ngd .= '<div class="ngd-signal__break">';
|
||||
$ngd .= '<svg viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">';
|
||||
$ngd .= '<circle cx="9" cy="9" r="8" fill="rgba(239,68,68,0.12)" stroke="#ef4444" stroke-width="1.2"/>';
|
||||
$ngd .= '<line x1="5.5" y1="5.5" x2="12.5" y2="12.5" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/>';
|
||||
$ngd .= '<line x1="12.5" y1="5.5" x2="5.5" y2="12.5" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/>';
|
||||
$ngd .= '</svg>';
|
||||
$ngd .= '</div>';
|
||||
$ngd .= '</div>'; /* ngd-signal-line */
|
||||
$ngd .= '</div>'; /* ngd-signal-wrap */
|
||||
|
||||
$ngd .= '</div>'; /* ngd-stage */
|
||||
|
||||
$visual_html = $ngd;
|
||||
$visual_cls = 'platform-visual has-ngd';
|
||||
} elseif ( ! empty( $a['brandedAnim'] ) ) {
|
||||
/* ── Custom Display Solutions: branded screens cascade animation ── */
|
||||
$bd = '<div class="bd-stage" aria-hidden="true">';
|
||||
|
||||
/* ── Screen 1: Tablet (portrait kiosk) ── */
|
||||
$bd .= '<div class="bd-device bd-device--tablet">';
|
||||
$bd .= '<span class="bd-device__label">Kiosk</span>';
|
||||
$bd .= '<div class="bd-device__body">';
|
||||
$bd .= '<div class="bd-device__screen">';
|
||||
$bd .= '<div class="bd-splash">';
|
||||
$bd .= '<div class="bd-splash__logo"></div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '<div class="bd-ui">';
|
||||
$bd .= '<div class="bd-ui__header"><div class="bd-ui__logo"></div><div class="bd-ui__brand-bar"></div></div>';
|
||||
$bd .= '<div class="bd-ui__content">';
|
||||
$bd .= '<div class="bd-promo bd-promo--welcome">';
|
||||
$bd .= '<div class="bd-promo__hero"></div>';
|
||||
$bd .= '<div class="bd-promo__heading"></div>';
|
||||
$bd .= '<div class="bd-promo__text"></div>';
|
||||
$bd .= '<div class="bd-promo__btn"></div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
|
||||
/* ── Screen 2: Wide wall-mount (landscape) ── */
|
||||
$bd .= '<div class="bd-device bd-device--wall">';
|
||||
$bd .= '<span class="bd-device__label">Wall Display</span>';
|
||||
$bd .= '<div class="bd-device__body">';
|
||||
$bd .= '<div class="bd-device__screen">';
|
||||
$bd .= '<div class="bd-splash">';
|
||||
$bd .= '<div class="bd-splash__logo"></div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '<div class="bd-ui">';
|
||||
$bd .= '<div class="bd-ui__header"><div class="bd-ui__logo"></div><div class="bd-ui__brand-bar"></div></div>';
|
||||
$bd .= '<div class="bd-ui__content">';
|
||||
$bd .= '<div class="bd-promo bd-promo--sale">';
|
||||
$bd .= '<div class="bd-promo__cols">';
|
||||
$bd .= '<div class="bd-promo__visual"></div>';
|
||||
$bd .= '<div class="bd-promo__info">';
|
||||
$bd .= '<div class="bd-promo__badge"></div>';
|
||||
$bd .= '<div class="bd-promo__heading"></div>';
|
||||
$bd .= '<div class="bd-promo__text"></div>';
|
||||
$bd .= '<div class="bd-promo__text bd-promo__text--short"></div>';
|
||||
$bd .= '<div class="bd-promo__price"></div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '<div class="bd-mount"></div>';
|
||||
$bd .= '</div>';
|
||||
|
||||
/* ── Screen 3: Interactive tablet on table ── */
|
||||
$bd .= '<div class="bd-device bd-device--interactive">';
|
||||
$bd .= '<span class="bd-device__label">Interactive</span>';
|
||||
$bd .= '<div class="bd-device__body">';
|
||||
$bd .= '<div class="bd-device__screen">';
|
||||
$bd .= '<div class="bd-splash">';
|
||||
$bd .= '<div class="bd-splash__logo"></div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '<div class="bd-ui">';
|
||||
$bd .= '<div class="bd-ui__header"><div class="bd-ui__logo"></div><div class="bd-ui__brand-bar"></div></div>';
|
||||
$bd .= '<div class="bd-ui__content">';
|
||||
$bd .= '<div class="bd-promo bd-promo--menu">';
|
||||
$bd .= '<div class="bd-promo__heading"></div>';
|
||||
$bd .= '<div class="bd-promo__grid">';
|
||||
$bd .= '<div class="bd-promo__tile"><div class="bd-promo__tile-img"></div><div class="bd-promo__tile-lbl"></div></div>';
|
||||
$bd .= '<div class="bd-promo__tile"><div class="bd-promo__tile-img"></div><div class="bd-promo__tile-lbl"></div></div>';
|
||||
$bd .= '<div class="bd-promo__tile"><div class="bd-promo__tile-img"></div><div class="bd-promo__tile-lbl"></div></div>';
|
||||
$bd .= '<div class="bd-promo__tile"><div class="bd-promo__tile-img"></div><div class="bd-promo__tile-lbl"></div></div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '</div>';
|
||||
$bd .= '<div class="bd-table"></div>';
|
||||
$bd .= '</div>';
|
||||
|
||||
$bd .= '</div>'; /* bd-stage */
|
||||
$visual_html = $bd;
|
||||
$visual_cls = 'platform-visual has-branded';
|
||||
} elseif ( ! empty( $a['cameraAnim'] ) ) {
|
||||
$visual_html = oribi_render_camera_animation();
|
||||
$visual_cls = 'platform-visual has-video-editor';
|
||||
|
||||
/* ── Gallery TV Slideshow ───────────────────────────────── */
|
||||
} elseif ( ! empty( $a['galleryIds'] ) && is_array( $a['galleryIds'] ) && count( $a['galleryIds'] ) > 0 ) {
|
||||
$slides = '';
|
||||
$count = 0;
|
||||
foreach ( $a['galleryIds'] as $gid ) {
|
||||
$gid = intval( $gid );
|
||||
if ( ! $gid ) continue;
|
||||
$url = wp_get_attachment_url( $gid );
|
||||
$alt = get_post_meta( $gid, '_wp_attachment_image_alt', true );
|
||||
if ( ! $url ) continue;
|
||||
$active = $count === 0 ? ' is-active' : '';
|
||||
$slides .= '<div class="gtv-slide' . $active . '">';
|
||||
$slides .= '<img src="' . esc_url( $url ) . '" alt="' . esc_attr( $alt ) . '" loading="lazy" />';
|
||||
$slides .= '</div>';
|
||||
$count++;
|
||||
}
|
||||
if ( $count > 0 ) {
|
||||
$visual_html = '<div class="gtv-stage" data-gtv-slideshow aria-hidden="true">';
|
||||
$visual_html .= '<div class="gtv-tv">';
|
||||
$visual_html .= '<div class="gtv-tv__body">';
|
||||
$visual_html .= '<div class="gtv-tv__screen">';
|
||||
$visual_html .= '<div class="gtv-slides">' . $slides . '</div>';
|
||||
$visual_html .= '</div>'; // screen
|
||||
$visual_html .= '</div>'; // body
|
||||
$visual_html .= '<div class="gtv-tv__feet"><div class="gtv-tv__foot"></div><div class="gtv-tv__foot"></div></div>';
|
||||
$visual_html .= '</div>'; // tv
|
||||
$visual_html .= '</div>'; // stage
|
||||
$visual_cls = 'platform-visual has-gallery-tv';
|
||||
} else {
|
||||
$visual_html = oribi_render_icon( $a['visual'] ?? '' );
|
||||
$visual_cls = 'platform-visual';
|
||||
}
|
||||
|
||||
} else {
|
||||
$visual_html = oribi_render_icon( $a['visual'] ?? '' );
|
||||
$visual_cls = 'platform-visual';
|
||||
@@ -1354,7 +1989,6 @@ function oribi_render_platform_row( $a ) {
|
||||
</div>
|
||||
<?php return ob_get_clean();
|
||||
}
|
||||
|
||||
/* ── Trust Section (parent - wraps child trust-item blocks) ────────────────── */
|
||||
function oribi_render_trust_section( $a, $content ) {
|
||||
ob_start(); ?>
|
||||
@@ -1546,3 +2180,107 @@ function oribi_render_page_hero_animated( $a ) {
|
||||
</section>
|
||||
<?php return ob_get_clean();
|
||||
}
|
||||
|
||||
/* ── Use Cases Showcase ────────────────────────────────────────────────── */
|
||||
function oribi_uc_anim_inner( $mod ) {
|
||||
switch ( $mod ) {
|
||||
case 'menu':
|
||||
return '
|
||||
<div class="uc-inner uc-inner--menu" aria-hidden="true">
|
||||
<div class="uc-menu-header"></div>
|
||||
<div class="uc-menu-row"><span class="uc-menu-name"></span><span class="uc-menu-price"></span></div>
|
||||
<div class="uc-menu-row uc-menu-row--highlight"><span class="uc-menu-name"></span><span class="uc-menu-price"></span></div>
|
||||
<div class="uc-menu-row"><span class="uc-menu-name uc-menu-name--sm"></span><span class="uc-menu-price"></span></div>
|
||||
<div class="uc-menu-row"><span class="uc-menu-name"></span><span class="uc-menu-price"></span></div>
|
||||
<div class="uc-menu-divider"></div>
|
||||
<div class="uc-menu-row"><span class="uc-menu-name uc-menu-name--sm"></span><span class="uc-menu-price"></span></div>
|
||||
</div>';
|
||||
case 'event':
|
||||
return '
|
||||
<div class="uc-inner uc-inner--event" aria-hidden="true">
|
||||
<div class="uc-event-cursor"></div>
|
||||
<div class="uc-event-header">Schedule</div>
|
||||
<div class="uc-event-row">
|
||||
<div class="uc-event-time">9:00</div>
|
||||
<div class="uc-event-title uc-event-title--active">Keynote Speech</div>
|
||||
</div>
|
||||
<div class="uc-event-row">
|
||||
<div class="uc-event-time">10:30</div>
|
||||
<div class="uc-event-title">Panel Discussion</div>
|
||||
</div>
|
||||
<div class="uc-event-row">
|
||||
<div class="uc-event-time">11:45</div>
|
||||
<div class="uc-event-title uc-event-title--accent">Coffee Break</div>
|
||||
</div>
|
||||
<div class="uc-event-row">
|
||||
<div class="uc-event-time">12:30</div>
|
||||
<div class="uc-event-title">Networking Lunch</div>
|
||||
</div>
|
||||
</div>';
|
||||
case 'dashboard':
|
||||
return '
|
||||
<div class="uc-inner uc-inner--dashboard" aria-hidden="true">
|
||||
<div class="uc-db-bars">
|
||||
<div class="uc-db-bar uc-db-bar--1"></div>
|
||||
<div class="uc-db-bar uc-db-bar--2"></div>
|
||||
<div class="uc-db-bar uc-db-bar--3"></div>
|
||||
<div class="uc-db-bar uc-db-bar--4"></div>
|
||||
</div>
|
||||
<div class="uc-db-baseline"></div>
|
||||
<div class="uc-db-labels">
|
||||
<div class="uc-db-lbl"></div>
|
||||
<div class="uc-db-lbl"></div>
|
||||
<div class="uc-db-lbl"></div>
|
||||
<div class="uc-db-lbl"></div>
|
||||
</div>
|
||||
</div>';
|
||||
case 'wayfinding':
|
||||
return '
|
||||
<div class="uc-inner uc-inner--wayfinding" aria-hidden="true">
|
||||
<div class="uc-wf-corridor uc-wf-corridor--h"></div>
|
||||
<div class="uc-wf-corridor uc-wf-corridor--v"></div>
|
||||
<div class="uc-wf-room uc-wf-room--1"></div>
|
||||
<div class="uc-wf-room uc-wf-room--2"></div>
|
||||
<div class="uc-wf-room uc-wf-room--3"></div>
|
||||
<div class="uc-wf-dot"></div>
|
||||
<div class="uc-wf-arrow"></div>
|
||||
</div>';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function oribi_render_use_cases( $a ) {
|
||||
$cases = [
|
||||
[ 'title' => $a['case1Title'], 'desc' => $a['case1Desc'], 'mod' => 'menu' ],
|
||||
[ 'title' => $a['case2Title'], 'desc' => $a['case2Desc'], 'mod' => 'event' ],
|
||||
[ 'title' => $a['case3Title'], 'desc' => $a['case3Desc'], 'mod' => 'dashboard' ],
|
||||
[ 'title' => $a['case4Title'], 'desc' => $a['case4Desc'], 'mod' => 'wayfinding' ],
|
||||
];
|
||||
ob_start(); ?>
|
||||
<section class="section use-cases-section">
|
||||
<div class="container">
|
||||
<?php if ( $a['label'] || $a['heading'] || $a['lead'] ) : ?>
|
||||
<div class="section-header">
|
||||
<?php if ( $a['label'] ) : ?><span class="section-label"><?php echo esc_html( $a['label'] ); ?></span><?php endif; ?>
|
||||
<?php if ( $a['heading'] ) : ?><h2><?php echo wp_kses_post( $a['heading'] ); ?></h2><?php endif; ?>
|
||||
<?php if ( $a['lead'] ) : ?><p class="lead"><?php echo wp_kses_post( $a['lead'] ); ?></p><?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="uc-track">
|
||||
<?php foreach ( $cases as $c ) : ?>
|
||||
<div class="uc-item">
|
||||
<div class="uc-circle uc-anim--<?php echo esc_attr( $c['mod'] ); ?>">
|
||||
<?php echo oribi_uc_anim_inner( $c['mod'] ); ?>
|
||||
</div>
|
||||
<div class="uc-item-body">
|
||||
<div class="uc-item-title"><?php echo esc_html( $c['title'] ); ?></div>
|
||||
<?php if ( $c['desc'] ) : ?><p class="uc-item-desc"><?php echo esc_html( $c['desc'] ); ?></p><?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php return ob_get_clean();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,33 @@ add_action( 'wp_enqueue_scripts', function () {
|
||||
true
|
||||
);
|
||||
|
||||
// Dashboard chart animator - smooth continuous animations for dashboard cards
|
||||
wp_enqueue_script(
|
||||
'oribi-dashboard-animator',
|
||||
ORIBI_URI . '/assets/js/dashboard-animator.js',
|
||||
[],
|
||||
ORIBI_VERSION . '.' . filemtime( ORIBI_DIR . '/assets/js/dashboard-animator.js' ),
|
||||
true
|
||||
);
|
||||
|
||||
// Gallery TV slideshow - cycles images in TV-frame cards
|
||||
wp_enqueue_script(
|
||||
'oribi-gallery-tv',
|
||||
ORIBI_URI . '/assets/js/industry-animator.js',
|
||||
[],
|
||||
ORIBI_VERSION . '.' . filemtime( ORIBI_DIR . '/assets/js/industry-animator.js' ),
|
||||
true
|
||||
);
|
||||
|
||||
// Video editor timeline animator - animated playhead and preview crossfades
|
||||
wp_enqueue_script(
|
||||
'oribi-video-editor-animator',
|
||||
ORIBI_URI . '/assets/js/video-editor-animator.js',
|
||||
[],
|
||||
ORIBI_VERSION . '.' . filemtime( ORIBI_DIR . '/assets/js/video-editor-animator.js' ),
|
||||
true
|
||||
);
|
||||
|
||||
// Localize AJAX endpoint for the contact form
|
||||
wp_localize_script( 'oribi-main', 'oribiAjax', [
|
||||
'url' => admin_url( 'admin-ajax.php' ),
|
||||
|
||||
@@ -24,9 +24,9 @@ function oribi_get_theme_defaults() {
|
||||
return [
|
||||
|
||||
/* ── Light-mode colour palette ──────────────────────── */
|
||||
'color_primary' => '#004225',
|
||||
'color_primary_dk' => '#002E1A',
|
||||
'color_primary_lt' => '#E8F5E9',
|
||||
'color_primary' => '#D83302',
|
||||
'color_primary_dk' => '#A22702',
|
||||
'color_primary_lt' => '#FFF0EB',
|
||||
'color_accent' => '#4CAF50',
|
||||
'color_accent_dk' => '#388E3C',
|
||||
'color_accent_lt' => '#E8F5E9',
|
||||
@@ -39,9 +39,9 @@ function oribi_get_theme_defaults() {
|
||||
'color_bg_alt' => '#F5F5F5',
|
||||
|
||||
/* ── Dark-mode colour palette ───────────────────────── */
|
||||
'dark_primary' => '#4CAF50',
|
||||
'dark_primary_dk' => '#004225',
|
||||
'dark_primary_lt' => 'rgba(0,66,37,0.15)',
|
||||
'dark_primary' => '#FF6B3D',
|
||||
'dark_primary_dk' => '#D83302',
|
||||
'dark_primary_lt' => 'rgba(216,51,2,0.15)',
|
||||
'dark_accent' => '#66BB6A',
|
||||
'dark_accent_dk' => '#4CAF50',
|
||||
'dark_accent_lt' => 'rgba(76,175,80,0.15)',
|
||||
@@ -94,18 +94,21 @@ function oribi_get_setting( $key ) {
|
||||
*/
|
||||
function oribi_maybe_seed_defaults() {
|
||||
|
||||
if ( get_theme_mod( 'oribi_defaults_seeded' ) ) {
|
||||
$defaults = oribi_get_theme_defaults();
|
||||
$hash = md5( wp_json_encode( $defaults ) );
|
||||
$stored = get_theme_mod( 'oribi_defaults_hash', '' );
|
||||
|
||||
if ( $stored === $hash ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$defaults = oribi_get_theme_defaults();
|
||||
|
||||
foreach ( $defaults as $key => $value ) {
|
||||
// Only set if the user hasn't already saved a value.
|
||||
if ( false === get_theme_mod( 'oribi_' . $key, false ) ) {
|
||||
set_theme_mod( 'oribi_' . $key, $value );
|
||||
}
|
||||
set_theme_mod( 'oribi_' . $key, $value );
|
||||
}
|
||||
|
||||
set_theme_mod( 'oribi_defaults_hash', $hash );
|
||||
set_theme_mod( 'oribi_defaults_seeded', true );
|
||||
|
||||
// Force CSS regeneration on next check.
|
||||
set_theme_mod( 'oribi_css_theme_version', '' );
|
||||
}
|
||||
|
||||
@@ -227,11 +227,11 @@ function oribi_build_css() {
|
||||
--color-bg-alt: {$dk_bg_alt};
|
||||
--color-bg-dark: {$dk_bg_dark};
|
||||
--color-heading: {$dk_heading};
|
||||
--header-scrolled-bg: rgba(15,23,36,.97);
|
||||
--header-scrolled-bg: rgba(26,26,26,.97);
|
||||
--header-scrolled-text: {$dk_text};
|
||||
--card-bg: {$dk_card_bg};
|
||||
--form-bg: {$dk_card_bg};
|
||||
--form-bg-focus: #1A2538;
|
||||
--form-bg-focus: {$dk_card_bg};
|
||||
}
|
||||
|
||||
/* ── Typography application ────────────────────────────────────── */
|
||||
@@ -295,12 +295,32 @@ function oribi_write_generated_css() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate the CSS file if it doesn't exist yet (e.g. first page load).
|
||||
* Regenerate the CSS file when it is missing or the theme version has changed.
|
||||
*
|
||||
* Hooked early so the file is ready before wp_enqueue_scripts fires.
|
||||
* Also re-seeds defaults if the palette has changed, so the generated
|
||||
* CSS always reflects the current default values.
|
||||
*/
|
||||
add_action( 'init', function () {
|
||||
if ( ! file_exists( oribi_generated_css_path() ) ) {
|
||||
|
||||
// Re-seed defaults if the defaults array has changed (e.g. new palette).
|
||||
if ( function_exists( 'oribi_maybe_seed_defaults' ) ) {
|
||||
oribi_maybe_seed_defaults();
|
||||
}
|
||||
|
||||
$needs_regen = ! file_exists( oribi_generated_css_path() );
|
||||
|
||||
if ( ! $needs_regen && defined( 'ORIBI_VERSION' ) ) {
|
||||
$stored = get_theme_mod( 'oribi_css_theme_version', '' );
|
||||
if ( $stored !== ORIBI_VERSION ) {
|
||||
$needs_regen = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $needs_regen ) {
|
||||
oribi_write_generated_css();
|
||||
if ( defined( 'ORIBI_VERSION' ) ) {
|
||||
set_theme_mod( 'oribi_css_theme_version', ORIBI_VERSION );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
@@ -636,7 +636,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
if (heroText) heroText.style.color = 'rgba(255,255,255,.8)';
|
||||
}
|
||||
if (btnP) {
|
||||
btnP.style.backgroundColor = get('oribi_color_primary') || '#004225';
|
||||
btnP.style.backgroundColor = get('oribi_color_primary') || '#D83302';
|
||||
btnP.style.borderRadius = (get('oribi_radius_sm') || '6') + 'px';
|
||||
}
|
||||
if (btnA) {
|
||||
|
||||
@@ -4,7 +4,7 @@ Theme URI: https://oribi-tech.com
|
||||
Author: Oribi Technology Services
|
||||
Author URI: https://oribi-tech.com
|
||||
Description: Custom marketing theme for Oribi Technology Services - Managed IT, 365Care, EndpointCare, NetCare, ServerCare.
|
||||
Version: 1.0.0
|
||||
Version: 1.1.0
|
||||
Requires at least: 6.4
|
||||
Tested up to: 6.7
|
||||
Requires PHP: 7.4
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
"customDuotone": false,
|
||||
"customGradient": false,
|
||||
"palette": [
|
||||
{ "slug": "primary", "color": "#004225", "name": "Primary" },
|
||||
{ "slug": "primary-dk", "color": "#002E1A", "name": "Primary Dark" },
|
||||
{ "slug": "primary-lt", "color": "#E8F5E9", "name": "Primary Light" },
|
||||
{ "slug": "primary", "color": "#D83302", "name": "Primary" },
|
||||
{ "slug": "primary-dk", "color": "#A22702", "name": "Primary Dark" },
|
||||
{ "slug": "primary-lt", "color": "#FFF0EB", "name": "Primary Light" },
|
||||
{ "slug": "accent", "color": "#4CAF50", "name": "Accent" },
|
||||
{ "slug": "accent-dk", "color": "#388E3C", "name": "Accent Dark" },
|
||||
{ "slug": "accent-lt", "color": "#E8F5E9", "name": "Accent Light" },
|
||||
@@ -85,9 +85,9 @@
|
||||
},
|
||||
"custom": {
|
||||
"dark": {
|
||||
"primary": "#4CAF50",
|
||||
"primary-dk": "#004225",
|
||||
"primary-lt": "rgba(0,66,37,0.15)",
|
||||
"primary": "#FF6B3D",
|
||||
"primary-dk": "#D83302",
|
||||
"primary-lt": "rgba(216,51,2,0.15)",
|
||||
"accent": "#66BB6A",
|
||||
"accent-dk": "#388E3C",
|
||||
"accent-lt": "rgba(76,175,80,0.12)",
|
||||
|
||||
Reference in New Issue
Block a user