From 9fddd43a2cf6690cb2ce97ab98ccdc12f559e36a Mon Sep 17 00:00:00 2001 From: Matt Batchelder Date: Thu, 19 Feb 2026 09:10:01 -0500 Subject: [PATCH] Add custom page templates for Home, Contact, and Services - Created a new Contact Page template with a contact form and information section. - Developed a Home Page template featuring a hero section, core capabilities, and pricing details. - Introduced a Services Page template outlining core services and industry solutions. - Added a default page template for standard pages without a custom template. - Implemented a single post template for displaying individual blog posts. - Created a style.css file for theme metadata and styling. --- .DS_Store | Bin 0 -> 6148 bytes ots-signs-import.xml | 179 +++ ots-signs-setup-plugin.zip | Bin 0 -> 2361 bytes ots-signs-theme.zip | Bin 0 -> 30524 bytes wp-content/.DS_Store | Bin 0 -> 8196 bytes .../ots-signs-setup/ots-signs-setup.php | 139 +++ wp-content/themes/ots-signs.zip | Bin 0 -> 31755 bytes wp-content/themes/ots-signs/404.php | 23 + .../themes/ots-signs/assets/css/main.css | 1042 +++++++++++++++++ wp-content/themes/ots-signs/assets/js/main.js | 142 +++ wp-content/themes/ots-signs/footer.php | 53 + wp-content/themes/ots-signs/functions.php | 336 ++++++ wp-content/themes/ots-signs/header.php | 47 + wp-content/themes/ots-signs/index.php | 45 + wp-content/themes/ots-signs/page-about.php | 149 +++ wp-content/themes/ots-signs/page-contact.php | 163 +++ wp-content/themes/ots-signs/page-home.php | 294 +++++ wp-content/themes/ots-signs/page-services.php | 264 +++++ wp-content/themes/ots-signs/page.php | 34 + wp-content/themes/ots-signs/single.php | 37 + wp-content/themes/ots-signs/style.css | 12 + 21 files changed, 2959 insertions(+) create mode 100644 .DS_Store create mode 100644 ots-signs-import.xml create mode 100644 ots-signs-setup-plugin.zip create mode 100644 ots-signs-theme.zip create mode 100644 wp-content/.DS_Store create mode 100644 wp-content/plugins/ots-signs-setup/ots-signs-setup.php create mode 100644 wp-content/themes/ots-signs.zip create mode 100644 wp-content/themes/ots-signs/404.php create mode 100644 wp-content/themes/ots-signs/assets/css/main.css create mode 100644 wp-content/themes/ots-signs/assets/js/main.js create mode 100644 wp-content/themes/ots-signs/footer.php create mode 100644 wp-content/themes/ots-signs/functions.php create mode 100644 wp-content/themes/ots-signs/header.php create mode 100644 wp-content/themes/ots-signs/index.php create mode 100644 wp-content/themes/ots-signs/page-about.php create mode 100644 wp-content/themes/ots-signs/page-contact.php create mode 100644 wp-content/themes/ots-signs/page-home.php create mode 100644 wp-content/themes/ots-signs/page-services.php create mode 100644 wp-content/themes/ots-signs/page.php create mode 100644 wp-content/themes/ots-signs/single.php create mode 100644 wp-content/themes/ots-signs/style.css diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e39be2c83eff0156e8ba7bc8c8603715547bfc11 GIT binary patch literal 6148 zcmeHKyG{c^3>-s>2%40X`vWQXgH;s1fFD34bWsio5bag@u6$a?kAmo+3r#eZ?Ai5t z_HQyC-DdB=b~KJgZDQvPegxp(-+JC@k|8c9h8O{eGp571 zj#+}(JVES*VLuSI;@5dt0!AcC>BrW{VmF2JyB5#NP%+& zZgacv{{KY(WBxxUX(t7wz*Q+=v-R_O#aF7{I(a$owT=El_nIT!jq9K=L^~!%JLbmQ e@k114UGp{1d*PTEbmoIj)X#wHB9j9Dt-uNDW)+eE literal 0 HcmV?d00001 diff --git a/ots-signs-import.xml b/ots-signs-import.xml new file mode 100644 index 0000000..b8392b0 --- /dev/null +++ b/ots-signs-import.xml @@ -0,0 +1,179 @@ + + + + + OTS Signs + https://ots-signs.com + The Complete Digital Signage Solution + Thu, 19 Feb 2026 00:00:00 +0000 + en-US + 1.2 + https://ots-signs.com + https://ots-signs.com + + + 1 + + + + + + + + + + Home + https://ots-signs.com/ + Thu, 19 Feb 2026 00:00:00 +0000 + + + + 2 + + + + + + + 0 + 0 + + + 0 + + dynamic communication tool for your business.]]> + + + + + + + + + + + + + + + + + + + + + + + + About + https://ots-signs.com/about/ + Thu, 19 Feb 2026 00:00:00 +0000 + + + + 3 + + + + + + + 0 + 1 + + + 0 + + + + + + + + + + + + + + + Services + https://ots-signs.com/services/ + Thu, 19 Feb 2026 00:00:00 +0000 + + + + 4 + + + + + + + 0 + 2 + + + 0 + + + + + + + + + + + + + + + + Contact + https://ots-signs.com/contact/ + Thu, 19 Feb 2026 00:00:00 +0000 + + + + 5 + + + + + + + 0 + 3 + + + 0 + + + + + + + + + + + + + + + diff --git a/ots-signs-setup-plugin.zip b/ots-signs-setup-plugin.zip new file mode 100644 index 0000000000000000000000000000000000000000..460cae42d11980de3971d80009b132626b8e842f GIT binary patch literal 2361 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 literal 0 HcmV?d00001 diff --git a/wp-content/plugins/ots-signs-setup/ots-signs-setup.php b/wp-content/plugins/ots-signs-setup/ots-signs-setup.php new file mode 100644 index 0000000..0749b36 --- /dev/null +++ b/wp-content/plugins/ots-signs-setup/ots-signs-setup.php @@ -0,0 +1,139 @@ +ID ); + } + + // 4. Permalinks — set to post name + update_option( 'permalink_structure', '/%postname%/' ); + flush_rewrite_rules(); + + // 5. Build the Primary navigation menu + ots_build_primary_menu(); + + // 6. Disable comments site-wide (marketing site) + update_option( 'default_comment_status', 'closed' ); + update_option( 'default_ping_status', 'closed' ); + + // 7. Set timezone + update_option( 'timezone_string', 'America/New_York' ); + + // 8. Mark setup as done + update_option( 'ots_setup_done', '1' ); +} + +function ots_build_primary_menu() { + // Delete existing menu with same name if any + $existing = get_term_by( 'name', 'Primary Menu', 'nav_menu' ); + if ( $existing ) { + wp_delete_nav_menu( $existing->term_id ); + } + + $menu_id = wp_create_nav_menu( 'Primary Menu' ); + if ( is_wp_error( $menu_id ) ) return; + + $menu_pages = [ + [ 'slug' => 'home', 'label' => 'Home' ], + [ 'slug' => 'services', 'label' => 'Services' ], + [ 'slug' => 'about', 'label' => 'About' ], + [ 'slug' => 'contact', 'label' => 'Contact' ], + ]; + + foreach ( $menu_pages as $item ) { + $page = get_page_by_path( $item['slug'] ); + if ( ! $page ) continue; + + wp_update_nav_menu_item( $menu_id, 0, [ + 'menu-item-title' => $item['label'], + 'menu-item-object-id' => $page->ID, + 'menu-item-object' => 'page', + 'menu-item-type' => 'post_type', + 'menu-item-status' => 'publish', + ] ); + } + + // Assign menu to the 'primary' theme location + $locations = get_theme_mod( 'nav_menu_locations', [] ); + $locations['primary'] = $menu_id; + set_theme_mod( 'nav_menu_locations', $locations ); +} + +// ─── Admin notice ───────────────────────────────────────────────────────────── +add_action( 'admin_notices', 'ots_setup_admin_notice' ); + +function ots_setup_admin_notice() { + if ( ! current_user_can( 'manage_options' ) ) return; + + $done = get_option( 'ots_setup_done' ); + ?> +
+ +

✓ OTS Signs Setup Complete!

+

+ Your site has been configured:
+ • Front page set to Home
+ • Primary navigation menu created (Home, Services, About, Contact)
+ • Permalink structure set to /%postname%/
+ • Comments disabled site-wide +

+

+ Go to Plugins to delete this setup plugin +  View Site +

+ +

OTS Signs – Site Setup Required

+

+ The OTS Signs setup plugin is installed but hasn't run yet. + Make sure you have imported ots-signs-import.xml via + Tools → Import → WordPress first, then deactivate and reactivate this plugin. +

+

+ Go to Import +

+ +
+ Re-run Setup'; + array_unshift( $links, $run_link ); + return $links; +} + +add_action( 'admin_init', 'ots_maybe_rerun_setup' ); + +function ots_maybe_rerun_setup() { + if ( ! isset( $_GET['ots_rerun_setup'] ) ) return; + if ( ! current_user_can( 'manage_options' ) ) return; + if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'ots_rerun' ) ) return; + + ots_setup_run(); + + wp_redirect( admin_url( 'plugins.php?ots_setup_reran=1' ) ); + exit; +} diff --git a/wp-content/themes/ots-signs.zip b/wp-content/themes/ots-signs.zip new file mode 100644 index 0000000000000000000000000000000000000000..f5d361339e70ffcd29c27d81d65d9a3c12b9175d GIT binary patch literal 31755 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 CBy&sv literal 0 HcmV?d00001 diff --git a/wp-content/themes/ots-signs/404.php b/wp-content/themes/ots-signs/404.php new file mode 100644 index 0000000..a0803d0 --- /dev/null +++ b/wp-content/themes/ots-signs/404.php @@ -0,0 +1,23 @@ + + +

+ +
+
+
🔍
+

404

+

Page Not Found

+

The page you're looking for doesn't exist or has been moved.

+ +
+
+ + diff --git a/wp-content/themes/ots-signs/assets/css/main.css b/wp-content/themes/ots-signs/assets/css/main.css new file mode 100644 index 0000000..f7963fd --- /dev/null +++ b/wp-content/themes/ots-signs/assets/css/main.css @@ -0,0 +1,1042 @@ +/* ============================================================= + OTS Signs — Main Stylesheet + ============================================================= */ + +/* ── 1. CSS Variables ───────────────────────────────────────── */ +:root { + --color-primary: #0A74DA; + --color-primary-dk: #0860b8; + --color-primary-lt: #e8f2fd; + --color-accent: #00C6AE; + --color-dark: #0D1321; + --color-dark-2: #1a2236; + --color-text: #2d3748; + --color-text-muted: #718096; + --color-border: #e2e8f0; + --color-bg: #ffffff; + --color-bg-alt: #f7f9fc; + --color-bg-dark: #0D1321; + + --font-sans: 'Inter', system-ui, -apple-system, sans-serif; + + --radius-sm: 6px; + --radius-md: 12px; + --radius-lg: 20px; + --radius-xl: 32px; + + --shadow-sm: 0 1px 3px rgba(0,0,0,.08); + --shadow-md: 0 4px 16px rgba(0,0,0,.10); + --shadow-lg: 0 12px 40px rgba(0,0,0,.14); + + --transition: 0.2s ease; + + --container-max: 1200px; + --container-pad: clamp(1rem, 5vw, 2rem); +} + +/* ── 2. Reset / Base ────────────────────────────────────────── */ +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } + +html { scroll-behavior: smooth; font-size: 16px; } + +body { + font-family: var(--font-sans); + color: var(--color-text); + background: var(--color-bg); + line-height: 1.65; + -webkit-font-smoothing: antialiased; +} + +img, video { max-width: 100%; display: block; } +a { color: inherit; text-decoration: none; transition: color var(--transition); } +a:hover { color: var(--color-primary); } +ul { list-style: none; } +button { font-family: inherit; cursor: pointer; border: none; background: none; } + +/* ── 3. Layout Utilities ───────────────────────────────────── */ +.container { + width: 100%; + max-width: var(--container-max); + margin-inline: auto; + padding-inline: var(--container-pad); +} + +.section { + padding-block: clamp(4rem, 8vw, 7rem); +} + +.section-alt { background: var(--color-bg-alt); } +.section-dark { + background: var(--color-bg-dark); + color: #fff; +} + +.section-header { + text-align: center; + max-width: 680px; + margin-inline: auto; + margin-bottom: 3.5rem; +} +.section-header .section-label { + display: inline-block; + font-size: .75rem; + font-weight: 700; + letter-spacing: .1em; + text-transform: uppercase; + color: var(--color-primary); + margin-bottom: .75rem; +} +.section-dark .section-header .section-label { color: var(--color-accent); } + +.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2rem; } +.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; } +.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5rem; } + +@media (max-width: 960px) { + .grid-3 { grid-template-columns: repeat(2, 1fr); } + .grid-4 { grid-template-columns: repeat(2, 1fr); } +} +@media (max-width: 640px) { + .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } +} + +/* ── 4. Typography ─────────────────────────────────────────── */ +h1, h2, h3, h4, h5, h6 { + font-weight: 700; + line-height: 1.2; + color: var(--color-dark); +} +.section-dark h1, +.section-dark h2, +.section-dark h3 { color: #fff; } + +h1 { font-size: clamp(2rem, 5vw, 3.5rem); } +h2 { font-size: clamp(1.6rem, 3.5vw, 2.4rem); } +h3 { font-size: clamp(1.1rem, 2vw, 1.35rem); } +h4 { font-size: 1rem; } + +p { margin-bottom: 1rem; } +p:last-child { margin-bottom: 0; } + +.lead { + font-size: clamp(1rem, 2vw, 1.2rem); + color: var(--color-text-muted); + line-height: 1.75; +} +.section-dark .lead { color: rgba(255,255,255,.75); } + +/* ── 5. Buttons ────────────────────────────────────────────── */ +.btn { + display: inline-flex; + align-items: center; + gap: .5rem; + padding: .8rem 1.75rem; + border-radius: var(--radius-sm); + font-size: .95rem; + font-weight: 600; + transition: all var(--transition); + white-space: nowrap; + cursor: pointer; +} + +.btn-primary { + background: var(--color-primary); + color: #fff; +} +.btn-primary:hover { + background: var(--color-primary-dk); + color: #fff; + transform: translateY(-1px); + box-shadow: 0 6px 20px rgba(10,116,218,.3); +} + +.btn-outline { + border: 2px solid var(--color-primary); + color: var(--color-primary); + background: transparent; +} +.btn-outline:hover { + background: var(--color-primary); + color: #fff; + transform: translateY(-1px); +} + +.btn-ghost { + border: 2px solid rgba(255,255,255,.35); + color: #fff; + background: transparent; +} +.btn-ghost:hover { + background: rgba(255,255,255,.1); + border-color: rgba(255,255,255,.6); + color: #fff; +} + +.btn-sm { padding: .55rem 1.2rem; font-size: .875rem; } +.btn-lg { padding: 1rem 2.25rem; font-size: 1.05rem; } + +.btn-group { + display: flex; + align-items: center; + gap: 1rem; + flex-wrap: wrap; +} + +/* ── 6. Header ─────────────────────────────────────────────── */ +.site-header { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 100; + padding-block: 1rem; + background: transparent; + transition: background var(--transition), box-shadow var(--transition), padding var(--transition); + overflow: hidden; +} +.site-header.scrolled { + background: rgba(255,255,255,.97); + box-shadow: var(--shadow-sm); + padding-block: .65rem; + backdrop-filter: blur(8px); +} + +.site-header.scrolled .logo-text { color: var(--color-dark); } +.site-header.scrolled .nav-menu a { color: var(--color-text); } + +.header-inner { + display: flex; + align-items: center; + gap: 2rem; + height: 50px; + overflow: hidden; + position: relative; +} + +/* Logo */ +.site-logo { + display: flex; + align-items: center; + flex-shrink: 0; + max-height: 40px; + overflow: hidden; +} +.site-logo a { display: flex; align-items: center; } +.custom-logo-link { display: flex; align-items: center; } +.site-logo img, +.custom-logo-link img, +.custom-logo, +.header-inner img { + max-height: 40px !important; + max-width: 180px !important; + width: auto !important; + height: auto !important; + display: block !important; + object-fit: contain; + position: static !important; + float: none !important; +} +/* Ensure SVG logos get explicit dimensions (SVGs without intrinsic size can overflow) */ +.site-logo img[src$=".svg"], +.custom-logo-link img[src$=".svg"], +img.custom-logo[src$=".svg"] { + height: 36px !important; + width: auto !important; +} + +/* Nuclear logo containment — clip-path fallback for overflow edge cases */ +.logo-constraint { + max-height: 40px !important; + max-width: 180px !important; + overflow: hidden !important; + clip-path: inset(0) !important; +} +.site-header .site-logo { + max-height: 40px !important; + overflow: hidden !important; + clip-path: inset(0) !important; +} +.site-header img, +.site-header .custom-logo { + max-height: 40px !important; + max-width: 180px !important; + width: auto !important; + height: auto !important; + object-fit: contain !important; + clip-path: inset(0) !important; +} +.logo-text { + font-size: 1.35rem; + font-weight: 300; + color: #fff; + letter-spacing: -.01em; + transition: color var(--transition); +} +.logo-text strong { font-weight: 800; color: var(--color-accent); } + +/* When header is over light background (services, about, contact pages) */ +.page-header-light .site-header { background: var(--color-bg); box-shadow: var(--shadow-sm); } +.page-header-light .logo-text { color: var(--color-dark); } +.page-header-light .nav-menu a { color: var(--color-text); } + +/* Nav */ +.site-nav { margin-left: auto; } +.nav-menu { + display: flex; + align-items: center; + gap: 2rem; +} +.nav-menu a { + font-size: .9rem; + font-weight: 500; + color: rgba(255,255,255,.85); + position: relative; + padding-bottom: 2px; +} +.nav-menu a::after { + content: ''; + position: absolute; + bottom: -2px; + left: 0; + width: 0; + height: 2px; + background: var(--color-accent); + transition: width var(--transition); +} +.nav-menu a:hover, +.nav-menu .current-menu-item > a { color: #fff; } +.nav-menu a:hover::after, +.nav-menu .current-menu-item > a::after { width: 100%; } + +.site-header.scrolled .nav-menu a { color: var(--color-text-muted); } +.site-header.scrolled .nav-menu a:hover, +.site-header.scrolled .nav-menu .current-menu-item > a { color: var(--color-primary); } + +.header-cta { margin-left: 1rem; } + +/* Mobile toggle */ +.nav-toggle { + display: none; + flex-direction: column; + gap: 5px; + margin-left: auto; + padding: 4px; +} +.nav-toggle span { + display: block; + width: 24px; + height: 2px; + background: #fff; + border-radius: 2px; + transition: all var(--transition); +} +.site-header.scrolled .nav-toggle span { background: var(--color-dark); } +.nav-toggle.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); } +.nav-toggle.open span:nth-child(2) { opacity: 0; } +.nav-toggle.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); } + +@media (max-width: 768px) { + .nav-toggle { display: flex; } + .site-nav, .header-cta { display: none; } + .site-nav.open { + display: block; + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + background: var(--color-dark); + z-index: 99; + padding: 5rem 2rem 2rem; + } + .site-nav.open .nav-menu { + flex-direction: column; + align-items: flex-start; + gap: 1.5rem; + } + .site-nav.open .nav-menu a { + color: #fff; + font-size: 1.25rem; + } +} + +/* ── 7. Hero ───────────────────────────────────────────────── */ +.hero { + position: relative; + min-height: 100vh; + display: flex; + align-items: center; + overflow: hidden; + background: linear-gradient(135deg, var(--color-dark) 0%, var(--color-dark-2) 50%, #0a2550 100%); + color: #fff; +} + +.hero-bg-grid { + position: absolute; + inset: 0; + background-image: + linear-gradient(rgba(255,255,255,.04) 1px, transparent 1px), + linear-gradient(90deg, rgba(255,255,255,.04) 1px, transparent 1px); + background-size: 60px 60px; + opacity: .6; +} + +.hero-glow { + position: absolute; + width: 700px; + height: 700px; + border-radius: 50%; + background: radial-gradient(circle, rgba(10,116,218,.35) 0%, transparent 70%); + top: -20%; + right: -10%; + pointer-events: none; +} +.hero-glow-2 { + position: absolute; + width: 500px; + height: 500px; + border-radius: 50%; + background: radial-gradient(circle, rgba(0,198,174,.18) 0%, transparent 70%); + bottom: -10%; + left: 5%; + pointer-events: none; +} + +.hero-inner { + position: relative; + z-index: 2; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 3rem; + align-items: center; + padding-block: 8rem 5rem; +} + +.hero-label { + display: inline-flex; + align-items: center; + gap: .5rem; + background: rgba(0,198,174,.15); + border: 1px solid rgba(0,198,174,.35); + color: var(--color-accent); + font-size: .75rem; + font-weight: 700; + letter-spacing: .1em; + text-transform: uppercase; + padding: .4rem 1rem; + border-radius: 100px; + margin-bottom: 1.5rem; +} + +.hero-title { + font-size: clamp(2.2rem, 5vw, 3.8rem); + font-weight: 900; + line-height: 1.1; + color: #fff; + margin-bottom: 1.5rem; +} +.hero-title .highlight { + color: var(--color-accent); +} + +.hero-description { + font-size: 1.1rem; + color: rgba(255,255,255,.75); + max-width: 520px; + margin-bottom: 2.5rem; + line-height: 1.8; +} + +.hero-stats { + display: flex; + gap: 2.5rem; + margin-top: 3rem; + padding-top: 2rem; + border-top: 1px solid rgba(255,255,255,.1); +} +.hero-stat-value { + font-size: 1.75rem; + font-weight: 800; + color: #fff; +} +.hero-stat-label { + font-size: .8rem; + color: rgba(255,255,255,.55); + margin-top: .2rem; +} + +/* Hero visual */ +.hero-visual { + display: flex; + justify-content: center; + align-items: center; +} +.hero-screen-mock { + position: relative; + width: 100%; + max-width: 480px; +} +.hero-screen-outer { + background: #1a2236; + border-radius: var(--radius-lg); + border: 2px solid rgba(255,255,255,.1); + padding: 1.5rem; + box-shadow: var(--shadow-lg), 0 0 0 1px rgba(255,255,255,.05); + position: relative; + overflow: hidden; +} +.hero-screen-bar { + display: flex; + gap: .5rem; + margin-bottom: 1rem; +} +.hero-screen-bar span { + width: 10px; height: 10px; + border-radius: 50%; +} +.hero-screen-bar span:nth-child(1) { background: #ff5f57; } +.hero-screen-bar span:nth-child(2) { background: #febc2e; } +.hero-screen-bar span:nth-child(3) { background: #28c840; } +.hero-screen-content { + background: #0d1321; + border-radius: var(--radius-md); + overflow: hidden; + aspect-ratio: 16/9; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 1rem; + padding: 1.5rem; +} +.hero-screen-logo { + font-size: 1.5rem; + font-weight: 900; + color: #fff; + letter-spacing: -.02em; +} +.hero-screen-logo span { color: var(--color-accent); } +.hero-screen-tagline { + font-size: .7rem; + color: rgba(255,255,255,.5); + letter-spacing: .12em; + text-transform: uppercase; +} +.hero-screen-bars { + display: flex; + gap: .4rem; + align-items: flex-end; + margin-top: .5rem; +} +.hero-screen-bars div { + width: 10px; + border-radius: 3px 3px 0 0; + background: var(--color-primary); + opacity: .8; + animation: bar-grow 1.5s ease-in-out infinite alternate; +} +.hero-screen-bars div:nth-child(1) { height: 20px; animation-delay: 0s; } +.hero-screen-bars div:nth-child(2) { height: 35px; animation-delay: .15s; background: var(--color-accent); } +.hero-screen-bars div:nth-child(3) { height: 25px; animation-delay: .3s; } +.hero-screen-bars div:nth-child(4) { height: 42px; animation-delay: .45s; background: var(--color-accent); } +.hero-screen-bars div:nth-child(5) { height: 18px; animation-delay: .6s; } +.hero-screen-bars div:nth-child(6) { height: 30px; animation-delay: .75s; } + +@keyframes bar-grow { + from { opacity: .5; transform: scaleY(.8); } + to { opacity: 1; transform: scaleY(1); } +} + +/* Floating badges */ +.hero-badge { + position: absolute; + background: rgba(255,255,255,.95); + border-radius: var(--radius-sm); + padding: .5rem .9rem; + box-shadow: var(--shadow-md); + display: flex; + align-items: center; + gap: .5rem; + font-size: .78rem; + font-weight: 600; + color: var(--color-dark); + backdrop-filter: blur(4px); +} +.hero-badge-dot { + width: 8px; height: 8px; + border-radius: 50%; + background: var(--color-accent); + animation: pulse 2s ease-in-out infinite; +} +@keyframes pulse { + 0%, 100% { transform: scale(1); opacity: 1; } + 50% { transform: scale(1.3); opacity: .7; } +} +.hero-badge-1 { bottom: 20px; left: -30px; } +.hero-badge-2 { top: 20px; right: -30px; } + +@media (max-width: 900px) { + .hero-inner { grid-template-columns: 1fr; text-align: center; } + .hero-description { margin-inline: auto; } + .btn-group { justify-content: center; } + .hero-stats { justify-content: center; } + .hero-visual { margin-top: 2rem; } + .hero-badge { display: none; } +} + +/* ── 8. Feature Cards ──────────────────────────────────────── */ +.feature-card { + background: var(--color-bg); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + padding: 2rem; + transition: all var(--transition); +} +.feature-card:hover { + box-shadow: var(--shadow-md); + transform: translateY(-4px); + border-color: var(--color-primary-lt); +} +.feature-icon { + width: 52px; height: 52px; + background: var(--color-primary-lt); + border-radius: var(--radius-sm); + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 1.25rem; + font-size: 1.4rem; +} +.feature-card h3 { margin-bottom: .5rem; font-size: 1.1rem; } +.feature-card p { color: var(--color-text-muted); font-size: .95rem; } + +/* ── 9. Industry Cards ─────────────────────────────────────── */ +.industry-card { + background: var(--color-dark-2); + border: 1px solid rgba(255,255,255,.08); + border-radius: var(--radius-md); + padding: 2rem; + transition: all var(--transition); + cursor: default; +} +.industry-card:hover { + border-color: var(--color-accent); + transform: translateY(-4px); + box-shadow: 0 8px 32px rgba(0,198,174,.15); +} +.industry-card-icon { + font-size: 2rem; + margin-bottom: 1rem; +} +.industry-card h3 { color: #fff; margin-bottom: .5rem; font-size: 1.05rem; } +.industry-card p { color: rgba(255,255,255,.6); font-size: .9rem; } + +/* ── 10. Pricing ───────────────────────────────────────────── */ +.pricing-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 2rem; + max-width: 800px; + margin-inline: auto; +} +.pricing-card { + background: var(--color-bg); + border: 2px solid var(--color-border); + border-radius: var(--radius-lg); + padding: 2.5rem; + position: relative; + transition: all var(--transition); +} +.pricing-card.featured { + border-color: var(--color-primary); + box-shadow: 0 0 0 4px rgba(10,116,218,.1); +} +.pricing-badge { + position: absolute; + top: -14px; + left: 50%; + transform: translateX(-50%); + background: var(--color-primary); + color: #fff; + font-size: .72rem; + font-weight: 700; + letter-spacing: .1em; + text-transform: uppercase; + padding: .35rem 1rem; + border-radius: 100px; +} +.pricing-name { font-size: 1.25rem; font-weight: 700; margin-bottom: .5rem; } +.pricing-price { margin-bottom: 1.5rem; } +.pricing-amount { + font-size: 2.5rem; + font-weight: 900; + color: var(--color-dark); + line-height: 1; +} +.pricing-amount sup { font-size: 1.25rem; vertical-align: super; } +.pricing-per { font-size: .85rem; color: var(--color-text-muted); margin-top: .35rem; } +.pricing-features { + list-style: none; + margin-bottom: 2rem; +} +.pricing-features li { + display: flex; + align-items: flex-start; + gap: .6rem; + font-size: .9rem; + padding: .5rem 0; + border-bottom: 1px solid var(--color-border); + color: var(--color-text); +} +.pricing-features li:last-child { border-bottom: none; } +.pricing-check { color: var(--color-accent); font-size: 1rem; flex-shrink: 0; margin-top: 1px; } + +@media (max-width: 640px) { + .pricing-grid { grid-template-columns: 1fr; } +} + +/* ── 11. Platform Feature Rows ─────────────────────────────── */ +.platform-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4rem; + align-items: center; + padding-block: 2rem; +} +.platform-row + .platform-row { + border-top: 1px solid var(--color-border); + margin-top: 2rem; +} +.platform-row.reverse .platform-text { order: 2; } +.platform-row.reverse .platform-visual { order: 1; } + +.platform-text h3 { font-size: 1.5rem; margin-bottom: 1rem; } +.platform-text p { color: var(--color-text-muted); } + +.platform-visual { + background: var(--color-bg-alt); + border-radius: var(--radius-md); + aspect-ratio: 4/3; + display: flex; + align-items: center; + justify-content: center; + font-size: 4rem; + border: 1px solid var(--color-border); +} + +@media (max-width: 768px) { + .platform-row { grid-template-columns: 1fr; } + .platform-row.reverse .platform-text, + .platform-row.reverse .platform-visual { order: unset; } +} + +/* ── 12. Page Hero (inner pages) ───────────────────────────── */ +.page-hero { + background: linear-gradient(135deg, var(--color-dark) 0%, #0a2550 100%); + color: #fff; + padding: 8rem 0 5rem; + text-align: center; + position: relative; + overflow: hidden; +} +.page-hero::before { + content: ''; + position: absolute; + inset: 0; + background-image: + linear-gradient(rgba(255,255,255,.03) 1px, transparent 1px), + linear-gradient(90deg, rgba(255,255,255,.03) 1px, transparent 1px); + background-size: 50px 50px; +} +.page-hero .container { position: relative; z-index: 2; } +.page-hero h1 { color: #fff; margin-bottom: 1rem; } +.page-hero .lead { color: rgba(255,255,255,.7); } + +/* ── 13. Service page cards ────────────────────────────────── */ +.service-industry-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; +} +.service-industry-card { + background: var(--color-bg); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + padding: 2rem; + transition: all var(--transition); +} +.service-industry-card:hover { + box-shadow: var(--shadow-md); + transform: translateY(-4px); + border-color: var(--color-primary); +} +.service-industry-card .industry-icon { + font-size: 2.5rem; + margin-bottom: 1rem; +} +.service-industry-card h3 { margin-bottom: .5rem; } +.service-industry-card p { color: var(--color-text-muted); font-size: .9rem; } + +@media (max-width: 900px) { + .service-industry-grid { grid-template-columns: repeat(2, 1fr); } +} +@media (max-width: 560px) { + .service-industry-grid { grid-template-columns: 1fr; } +} + +/* ── 14. About page ────────────────────────────────────────── */ +.about-intro { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4rem; + align-items: center; +} +.about-intro-visual { + background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent) 100%); + border-radius: var(--radius-xl); + aspect-ratio: 1; + max-width: 420px; + display: flex; + align-items: center; + justify-content: center; + font-size: 6rem; + color: #fff; + box-shadow: var(--shadow-lg); +} +@media (max-width: 768px) { + .about-intro { grid-template-columns: 1fr; } + .about-intro-visual { max-width: 280px; margin-inline: auto; } +} + +.value-card { + text-align: center; + padding: 2rem; +} +.value-icon { + width: 64px; height: 64px; + background: var(--color-primary-lt); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-inline: auto; + margin-bottom: 1.25rem; + font-size: 1.5rem; +} + +/* ── 15. Contact ────────────────────────────────────────────── */ +.contact-layout { + display: grid; + grid-template-columns: 1fr 1.6fr; + gap: 4rem; + align-items: start; +} +@media (max-width: 768px) { + .contact-layout { grid-template-columns: 1fr; } +} + +.contact-info h2 { margin-bottom: 1rem; } +.contact-info .lead { margin-bottom: 2rem; } + +.contact-method { + display: flex; + align-items: flex-start; + gap: 1rem; + margin-bottom: 1.5rem; +} +.contact-method-icon { + width: 44px; height: 44px; + background: var(--color-primary-lt); + border-radius: var(--radius-sm); + display: flex; + align-items: center; + justify-content: center; + font-size: 1.1rem; + flex-shrink: 0; +} +.contact-method-label { font-size: .8rem; color: var(--color-text-muted); } +.contact-method-value { font-weight: 600; color: var(--color-dark); font-size: .95rem; } + +.contact-form-wrap { + background: var(--color-bg); + border: 1px solid var(--color-border); + border-radius: var(--radius-lg); + padding: 2.5rem; + box-shadow: var(--shadow-sm); +} +.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; } +@media (max-width: 560px) { .form-row { grid-template-columns: 1fr; } } + +.form-group { margin-bottom: 1.25rem; } +.form-group label { + display: block; + font-size: .85rem; + font-weight: 600; + color: var(--color-text); + margin-bottom: .4rem; +} +.form-group label .req { color: var(--color-primary); } + +.form-group input, +.form-group textarea, +.form-group select { + width: 100%; + padding: .75rem 1rem; + font-family: var(--font-sans); + font-size: .95rem; + color: var(--color-text); + background: var(--color-bg-alt); + border: 1.5px solid var(--color-border); + border-radius: var(--radius-sm); + transition: border-color var(--transition), box-shadow var(--transition); + outline: none; + resize: vertical; +} +.form-group input:focus, +.form-group textarea:focus, +.form-group select:focus { + border-color: var(--color-primary); + box-shadow: 0 0 0 3px rgba(10,116,218,.12); + background: #fff; +} +.form-group textarea { min-height: 140px; } + +.form-notice { + margin-top: 1rem; + font-size: .85rem; + padding: .75rem 1rem; + border-radius: var(--radius-sm); + display: none; +} +.form-notice.success { background: #f0fdf4; color: #16a34a; border: 1px solid #bbf7d0; display: block; } +.form-notice.error { background: #fef2f2; color: #dc2626; border: 1px solid #fecaca; display: block; } + +/* ── 16. Demo CTA Banner ───────────────────────────────────── */ +.cta-banner { + background: linear-gradient(135deg, var(--color-primary) 0%, #0556a8 100%); + color: #fff; + padding-block: 5rem; + text-align: center; +} +.cta-banner h2 { color: #fff; margin-bottom: 1rem; } +.cta-banner p { color: rgba(255,255,255,.8); margin-bottom: 2rem; font-size: 1.1rem; } + +/* ── 17. Footer ────────────────────────────────────────────── */ +.site-footer { + background: var(--color-dark); + color: rgba(255,255,255,.7); + padding-top: 4rem; +} +.footer-inner { + display: grid; + grid-template-columns: 1.5fr 1fr 1fr 1fr; + gap: 2rem; + padding-bottom: 3rem; + border-bottom: 1px solid rgba(255,255,255,.08); +} +@media (max-width: 900px) { + .footer-inner { grid-template-columns: 1fr 1fr; } + .footer-brand { grid-column: 1 / -1; } +} +@media (max-width: 480px) { + .footer-inner { grid-template-columns: 1fr; } +} + +.footer-brand .logo-text { font-size: 1.5rem; color: #fff; } +.footer-tagline { font-size: .9rem; color: rgba(255,255,255,.5); margin-top: .75rem; margin-bottom: .5rem; } +.footer-parent { font-size: .8rem; color: rgba(255,255,255,.4); } +.footer-parent a { color: var(--color-accent); } +.footer-parent a:hover { color: #fff; } + +.footer-links { display: contents; } +.footer-col h4 { + font-size: .8rem; + font-weight: 700; + letter-spacing: .1em; + text-transform: uppercase; + color: rgba(255,255,255,.4); + margin-bottom: 1rem; +} +.footer-col ul { display: flex; flex-direction: column; gap: .6rem; } +.footer-col a { + font-size: .875rem; + color: rgba(255,255,255,.6); + transition: color var(--transition); +} +.footer-col a:hover { color: #fff; } + +.footer-bottom { + padding-block: 1.5rem; +} +.footer-bottom p { + font-size: .8rem; + color: rgba(255,255,255,.3); + text-align: center; + margin: 0; +} + +/* ── 18. Misc ───────────────────────────────────────────────── */ +.text-center { text-align: center; } +.text-primary { color: var(--color-primary); } +.text-accent { color: var(--color-accent); } +.mt-1 { margin-top: .5rem; } +.mt-2 { margin-top: 1rem; } +.mt-3 { margin-top: 1.5rem; } +.mt-4 { margin-top: 2rem; } +.mb-4 { margin-bottom: 2rem; } + +/* Demo link pill */ +.demo-link { + display: inline-flex; + align-items: center; + gap: .5rem; + background: rgba(0,198,174,.12); + border: 1px solid rgba(0,198,174,.35); + color: var(--color-accent); + font-size: .85rem; + font-weight: 600; + padding: .45rem 1.1rem; + border-radius: 100px; + transition: all var(--transition); + margin-bottom: 2rem; +} +.demo-link:hover { + background: rgba(0,198,174,.25); + color: var(--color-accent); +} + +/* Divider */ +.divider { + border: none; + border-top: 1px solid var(--color-border); + margin-block: 3rem; +} + +/* Screen reader only */ +.sr-only { + position: absolute; + width: 1px; height: 1px; + margin: -1px; padding: 0; + overflow: hidden; clip: rect(0,0,0,0); + white-space: nowrap; border: 0; +} + +/* Scroll to top */ +.scroll-top { + position: fixed; + bottom: 2rem; + right: 2rem; + width: 44px; height: 44px; + background: var(--color-primary); + color: #fff; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; + box-shadow: var(--shadow-md); + opacity: 0; + transform: translateY(10px); + transition: all var(--transition); + z-index: 50; + cursor: pointer; +} +.scroll-top.visible { opacity: 1; transform: translateY(0); } +.scroll-top:hover { background: var(--color-primary-dk); color: #fff; } diff --git a/wp-content/themes/ots-signs/assets/js/main.js b/wp-content/themes/ots-signs/assets/js/main.js new file mode 100644 index 0000000..b52e806 --- /dev/null +++ b/wp-content/themes/ots-signs/assets/js/main.js @@ -0,0 +1,142 @@ +/** + * OTS Signs — Main JavaScript + */ + +( function () { + 'use strict'; + + // ── Sticky header ───────────────────────────────────────────────────────── + const header = document.getElementById( 'site-header' ); + if ( header ) { + const onScroll = () => { + header.classList.toggle( 'scrolled', window.scrollY > 40 ); + }; + window.addEventListener( 'scroll', onScroll, { passive: true } ); + onScroll(); // run on init + } + + // ── Mobile nav toggle ────────────────────────────────────────────────────── + const navToggle = document.getElementById( 'nav-toggle' ); + const siteNav = document.getElementById( 'site-nav' ); + if ( navToggle && siteNav ) { + navToggle.addEventListener( 'click', () => { + const isOpen = siteNav.classList.toggle( 'open' ); + navToggle.classList.toggle( 'open', isOpen ); + navToggle.setAttribute( 'aria-expanded', isOpen ); + document.body.style.overflow = isOpen ? 'hidden' : ''; + } ); + + // Close on nav link click + siteNav.querySelectorAll( 'a' ).forEach( link => { + link.addEventListener( 'click', () => { + siteNav.classList.remove( 'open' ); + navToggle.classList.remove( 'open' ); + navToggle.setAttribute( 'aria-expanded', 'false' ); + document.body.style.overflow = ''; + } ); + } ); + } + + // ── Scroll-to-top button ────────────────────────────────────────────────── + const scrollTopBtn = document.querySelector( '.scroll-top' ); + if ( scrollTopBtn ) { + window.addEventListener( 'scroll', () => { + scrollTopBtn.classList.toggle( 'visible', window.scrollY > 400 ); + }, { passive: true } ); + scrollTopBtn.addEventListener( 'click', () => { + window.scrollTo( { top: 0, behavior: 'smooth' } ); + } ); + } + + // ── Contact form AJAX ───────────────────────────────────────────────────── + const contactForm = document.getElementById( 'contact-form' ); + if ( contactForm ) { + const submitBtn = document.getElementById( 'contact-submit' ); + const btnText = submitBtn ? submitBtn.querySelector( '.btn-text' ) : null; + const btnLoading = submitBtn ? submitBtn.querySelector( '.btn-loading' ) : null; + const notice = document.getElementById( 'form-notice' ); + + contactForm.addEventListener( 'submit', async ( e ) => { + e.preventDefault(); + + // Basic client-side validation + const name = contactForm.querySelector( '[name="name"]' ); + const email = contactForm.querySelector( '[name="email"]' ); + const message = contactForm.querySelector( '[name="message"]' ); + + if ( ! name.value.trim() || ! email.value.trim() || ! message.value.trim() ) { + showNotice( 'error', 'Please fill in all required fields.' ); + return; + } + + // Set loading state + if ( submitBtn ) submitBtn.disabled = true; + if ( btnText ) btnText.style.display = 'none'; + if ( btnLoading ) btnLoading.style.display = 'inline'; + if ( notice ) notice.className = 'form-notice'; + + try { + const formData = new FormData( contactForm ); + formData.append( 'action', 'ots_contact' ); + formData.append( 'nonce', otsAjax.nonce ); + + const response = await fetch( otsAjax.url, { + method: 'POST', + body: formData, + credentials: 'same-origin', + } ); + + const data = await response.json(); + + if ( data.success ) { + showNotice( 'success', data.data.message || 'Message sent successfully!' ); + contactForm.reset(); + } else { + showNotice( 'error', data.data.message || 'Something went wrong. Please try again.' ); + } + } catch ( err ) { + showNotice( 'error', 'Network error. Please check your connection and try again.' ); + } finally { + if ( submitBtn ) submitBtn.disabled = false; + if ( btnText ) btnText.style.display = 'inline'; + if ( btnLoading ) btnLoading.style.display = 'none'; + } + } ); + + function showNotice( type, message ) { + if ( ! notice ) return; + notice.textContent = message; + notice.className = 'form-notice ' + type; + notice.style.display = 'block'; + notice.scrollIntoView( { behavior: 'smooth', block: 'nearest' } ); + } + } + + // ── Animate cards on scroll (intersection observer) ────────────────────── + if ( 'IntersectionObserver' in window ) { + const cards = document.querySelectorAll( '.feature-card, .industry-card, .value-card, .service-industry-card, .pricing-card' ); + const style = document.createElement( 'style' ); + style.textContent = ` + .animate-card { opacity: 0; transform: translateY(24px); transition: opacity 0.5s ease, transform 0.5s ease; } + .animate-card.visible { opacity: 1; transform: translateY(0); } + `; + document.head.appendChild( style ); + + cards.forEach( ( card, i ) => { + card.classList.add( 'animate-card' ); + card.style.transitionDelay = ( ( i % 4 ) * 80 ) + 'ms'; + } ); + + const observer = new IntersectionObserver( ( entries ) => { + entries.forEach( entry => { + if ( entry.isIntersecting ) { + entry.target.classList.add( 'visible' ); + observer.unobserve( entry.target ); + } + } ); + }, { threshold: 0.1 } ); + + cards.forEach( card => observer.observe( card ) ); + } + +} )(); diff --git a/wp-content/themes/ots-signs/footer.php b/wp-content/themes/ots-signs/footer.php new file mode 100644 index 0000000..932ff9a --- /dev/null +++ b/wp-content/themes/ots-signs/footer.php @@ -0,0 +1,53 @@ + + + + + + + diff --git a/wp-content/themes/ots-signs/functions.php b/wp-content/themes/ots-signs/functions.php new file mode 100644 index 0000000..e0f1569 --- /dev/null +++ b/wp-content/themes/ots-signs/functions.php @@ -0,0 +1,336 @@ + 60, + 'width' => 200, + 'flex-height' => true, + 'flex-width' => true, + ] ); + + register_nav_menus( [ + 'primary' => __( 'Primary Menu', 'ots-signs' ), + 'footer' => __( 'Footer Menu', 'ots-signs' ), + ] ); +} +add_action( 'after_setup_theme', 'ots_setup' ); + +// ─── Fallback Menu ──────────────────────────────────────────────────────────── +if ( ! function_exists( 'ots_fallback_menu' ) ) { + function ots_fallback_menu() { + echo ''; + } +} + +// ─── Enqueue Assets ─────────────────────────────────────────────────────────── +function ots_enqueue_assets() { + // Google Fonts + wp_enqueue_style( + 'ots-fonts', + 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap', + [], + null + ); + + // Main stylesheet — use filemtime for cache-busting during development + wp_enqueue_style( + 'ots-main', + OTS_THEME_URI . '/assets/css/main.css', + [ 'ots-fonts' ], + filemtime( OTS_THEME_DIR . '/assets/css/main.css' ) + ); + + // Main JS — use filemtime for cache-busting during development + wp_enqueue_script( + 'ots-main', + OTS_THEME_URI . '/assets/js/main.js', + [], + filemtime( OTS_THEME_DIR . '/assets/js/main.js' ), + true + ); + + // Pass ajaxurl and nonce to JS + wp_localize_script( 'ots-main', 'otsAjax', [ + 'url' => admin_url( 'admin-ajax.php' ), + 'nonce' => wp_create_nonce( 'ots_contact_nonce' ), + ] ); +} +add_action( 'wp_enqueue_scripts', 'ots_enqueue_assets' ); + +// ─── Constrain Custom Logo Output ───────────────────────────────────────── +/** + * Force the custom logo image to have inline size constraints and use a + * smaller image size so the browser never paints the full-resolution upload. + */ +add_filter( 'get_custom_logo', 'ots_constrain_custom_logo' ); + +function ots_constrain_custom_logo( $html ) { + if ( empty( $html ) ) { + return $html; + } + + // Swap the full-size src for the 'medium' version (much smaller file) + $custom_logo_id = get_theme_mod( 'custom_logo' ); + if ( $custom_logo_id ) { + $medium = wp_get_attachment_image_url( $custom_logo_id, 'medium' ); + $full = wp_get_attachment_image_url( $custom_logo_id, 'full' ); + if ( $medium && $full && $medium !== $full ) { + $html = str_replace( esc_url( $full ), esc_url( $medium ), $html ); + } + } + + // Inject inline max-height directly on the tag + $html = preg_replace( + '/ 'Please fill in all required fields.' ] ); + } + + if ( ! is_email( $email ) ) { + wp_send_json_error( [ 'message' => 'Please enter a valid email address.' ] ); + } + + $to = get_option( 'admin_email' ); + $subject = 'New Contact Form Submission from ' . $name; + $body = "Name: {$name}\n"; + $body .= "Email: {$email}\n"; + if ( $phone ) $body .= "Phone: {$phone}\n"; + if ( $company ) $body .= "Company: {$company}\n"; + $body .= "\nMessage:\n{$message}"; + + $headers = [ + 'Content-Type: text/plain; charset=UTF-8', + 'Reply-To: ' . $name . ' <' . $email . '>', + ]; + + $sent = wp_mail( $to, $subject, $body, $headers ); + + if ( $sent ) { + wp_send_json_success( [ 'message' => 'Thanks! We\'ll be in touch shortly.' ] ); + } else { + wp_send_json_error( [ 'message' => 'Sorry, there was a problem sending your message. Please try again.' ] ); + } +} +add_action( 'wp_ajax_ots_contact', 'ots_handle_contact' ); +add_action( 'wp_ajax_nopriv_ots_contact', 'ots_handle_contact' ); + +// ─── Custom Page Templates ───────────────────────────────────────────────── +function ots_body_classes( $classes ) { + $classes[] = 'ots-theme'; + return $classes; +} +add_filter( 'body_class', 'ots_body_classes' ); + +// ─── Excerpt length ──────────────────────────────────────────────────────── +function ots_excerpt_length( $length ) { + return 25; +} +add_filter( 'excerpt_length', 'ots_excerpt_length' ); + +// ─── Meta Boxes ──────────────────────────────────────────────────────────── +/** + * Each page template gets its own meta box with the key + * marketing copy fields. All fields fall back to sensible + * defaults so the site works without any editing. + */ +add_action( 'add_meta_boxes', 'ots_register_meta_boxes' ); + +function ots_register_meta_boxes() { + $screens = [ 'page' ]; + + add_meta_box( + 'ots_page_hero', + 'Page Hero Content', + 'ots_render_hero_meta_box', + $screens, + 'normal', + 'high' + ); +} + +function ots_render_hero_meta_box( $post ) { + wp_nonce_field( 'ots_save_meta', 'ots_meta_nonce' ); + + $template = get_page_template_slug( $post->ID ); + $fields = ots_get_meta_fields_for_template( $template ); + + if ( empty( $fields ) ) { + echo '

No editable fields for this page template.

'; + return; + } + + echo ''; + + echo ''; + foreach ( $fields as $field ) { + if ( $field['type'] === 'section' ) { + echo ''; + continue; + } + $value = get_post_meta( $post->ID, $field['key'], true ); + if ( $value === '' ) $value = $field['default'] ?? ''; + echo ''; + echo ''; + echo ''; + } + echo '
' . esc_html( $field['label'] ) . '
'; + if ( $field['type'] === 'textarea' ) { + echo ''; + } else { + echo ''; + } + if ( ! empty( $field['hint'] ) ) { + echo '
' . esc_html( $field['hint'] ) . '
'; + } + echo '
'; + + echo '

+ Fields left blank will use the default content shown above as placeholder text. +

'; +} + +function ots_get_meta_fields_for_template( $template ) { + $templates = [ + 'page-home.php' => [ + [ 'type' => 'section', 'label' => 'Hero Section' ], + [ 'key' => 'hero_title', 'label' => 'Hero Title', 'type' => 'textarea', 'default' => 'Turn any screen into a dynamic communication tool for your business.', 'hint' => 'Wrap a keyword in to colour it teal.' ], + [ 'key' => 'hero_description', 'label' => 'Hero Description', 'type' => 'textarea', 'default' => 'The complete package for engaging digital signage. From eye-catching retail displays to dynamic informational screens, we craft tailored solutions that capture attention and deliver your message.' ], + [ 'key' => 'hero_cta_primary_label', 'label' => 'Primary CTA Label', 'type' => 'text', 'default' => 'Get in Touch' ], + [ 'key' => 'hero_cta_secondary_label', 'label' => 'Secondary CTA Label', 'type' => 'text', 'default' => 'View Demo' ], + [ 'type' => 'section', 'label' => 'Hero Stats' ], + [ 'key' => 'stat_1_value', 'label' => 'Stat 1 Value', 'type' => 'text', 'default' => '500+' ], + [ 'key' => 'stat_1_label', 'label' => 'Stat 1 Label', 'type' => 'text', 'default' => 'Screens Managed' ], + [ 'key' => 'stat_2_value', 'label' => 'Stat 2 Value', 'type' => 'text', 'default' => '6' ], + [ 'key' => 'stat_2_label', 'label' => 'Stat 2 Label', 'type' => 'text', 'default' => 'Industry Verticals' ], + [ 'key' => 'stat_3_value', 'label' => 'Stat 3 Value', 'type' => 'text', 'default' => '99.9%' ], + [ 'key' => 'stat_3_label', 'label' => 'Stat 3 Label', 'type' => 'text', 'default' => 'Uptime SLA' ], + [ 'type' => 'section', 'label' => 'Features Section' ], + [ 'key' => 'features_heading', 'label' => 'Features Heading', 'type' => 'text', 'default' => 'Everything You Need for Engaging Digital Signage' ], + [ 'key' => 'features_subheading', 'label' => 'Features Subheading', 'type' => 'textarea', 'default' => 'We provide a complete, end-to-end digital signage solution — from hardware to content management to live data integrations.' ], + [ 'type' => 'section', 'label' => 'Industries Section' ], + [ 'key' => 'industries_heading', 'label' => 'Industries Heading', 'type' => 'text', 'default' => 'Our Services Empower Your Brand' ], + [ 'key' => 'industries_subheading', 'label' => 'Industries Subheading', 'type' => 'textarea', 'default' => 'Modern businesses need real-time communication. Digital signage helps you connect with your audience where it matters most.' ], + [ 'type' => 'section', 'label' => 'Pricing Section' ], + [ 'key' => 'pricing_heading', 'label' => 'Pricing Heading', 'type' => 'text', 'default' => 'Affordable Solutions, Scalable Options' ], + [ 'key' => 'pricing_subheading', 'label' => 'Pricing Subheading', 'type' => 'textarea', 'default' => 'All plans include content scheduling/day-parting, live data integrations, unlimited user seats, and the ability to publish content to your signs in minutes.' ], + [ 'type' => 'section', 'label' => 'CTA Banner' ], + [ 'key' => 'cta_heading', 'label' => 'CTA Heading', 'type' => 'text', 'default' => 'Ready to Transform Your Screens?' ], + [ 'key' => 'cta_description', 'label' => 'CTA Description', 'type' => 'textarea', 'default' => 'Get in touch today and discover how OTS Signs can revolutionize the way you communicate with your audience.' ], + ], + 'page-about.php' => [ + [ 'type' => 'section', 'label' => 'Page Hero' ], + [ 'key' => 'hero_title', 'label' => 'Page Title', 'type' => 'text', 'default' => 'The Complete Digital Signage Solution' ], + [ 'key' => 'hero_description', 'label' => 'Page Subtitle', 'type' => 'textarea', 'default' => 'We help businesses of all sizes connect with their audiences through powerful, easy-to-manage digital signage.' ], + [ 'type' => 'section', 'label' => 'Who We Are Section' ], + [ 'key' => 'about_heading', 'label' => 'Section Heading', 'type' => 'text', 'default' => 'Bringing Your Message to Life on Every Screen' ], + [ 'key' => 'about_intro', 'label' => 'Intro Paragraph', 'type' => 'textarea', 'default' => 'OTS Signs is a digital signage company dedicated to transforming how businesses communicate with their audiences. We offer a complete, end-to-end solution — from the hardware players to our cloud management platform to custom content creation.' ], + [ 'key' => 'about_body', 'label' => 'Body Paragraph', 'type' => 'textarea', 'default' => 'Digital signage is the modern way to connect with your audience, transforming any screen into a way to communicate and engage. Whether you need an eye-catching retail display, a dynamic menu board, or enterprise-grade live data dashboards, we deliver solutions that capture attention and get results.' ], + [ 'type' => 'section', 'label' => 'CTA Banner' ], + [ 'key' => 'cta_heading', 'label' => 'CTA Heading', 'type' => 'text', 'default' => "Let's Build Something Great Together" ], + [ 'key' => 'cta_description', 'label' => 'CTA Description', 'type' => 'textarea', 'default' => 'Ready to see what OTS Signs can do for your business? Get in touch or explore our demo platform.' ], + ], + 'page-services.php' => [ + [ 'type' => 'section', 'label' => 'Page Hero' ], + [ 'key' => 'hero_title', 'label' => 'Page Title', 'type' => 'text', 'default' => 'Services & Solutions' ], + [ 'key' => 'hero_description', 'label' => 'Page Subtitle', 'type' => 'textarea', 'default' => 'From content creation to cloud management to live data integrations — we deliver everything you need for a complete digital signage deployment.' ], + [ 'type' => 'section', 'label' => 'Core Services Section' ], + [ 'key' => 'services_heading', 'label' => 'Section Heading', 'type' => 'text', 'default' => 'The Complete Package for Engaging Digital Signage' ], + [ 'key' => 'services_subheading', 'label' => 'Section Subheading', 'type' => 'textarea', 'default' => 'Every service we offer is designed to make your digital signage as impactful, reliable, and easy to manage as possible.' ], + [ 'type' => 'section', 'label' => 'Pricing Section' ], + [ 'key' => 'pricing_heading', 'label' => 'Pricing Heading', 'type' => 'text', 'default' => 'Affordable Solutions, Scalable Options' ], + [ 'key' => 'pricing_subheading', 'label' => 'Pricing Subheading', 'type' => 'textarea', 'default' => 'Simple, transparent pricing with no hidden fees. Choose the plan that fits your business size.' ], + [ 'type' => 'section', 'label' => 'CTA Banner' ], + [ 'key' => 'cta_heading', 'label' => 'CTA Heading', 'type' => 'text', 'default' => 'Want to See How Our Platform Works?' ], + [ 'key' => 'cta_description', 'label' => 'CTA Description', 'type' => 'textarea', 'default' => 'Request access to our demo instance and explore the OTS Signs platform hands-on.' ], + ], + 'page-contact.php' => [ + [ 'type' => 'section', 'label' => 'Page Hero' ], + [ 'key' => 'hero_title', 'label' => 'Page Title', 'type' => 'text', 'default' => 'Get in Touch' ], + [ 'key' => 'hero_description', 'label' => 'Page Subtitle', 'type' => 'textarea', 'default' => "Ready to transform your screens? We'd love to hear about your project. Drop us a message and we'll get back to you promptly." ], + [ 'type' => 'section', 'label' => 'Contact Info' ], + [ 'key' => 'contact_heading', 'label' => 'Section Heading', 'type' => 'text', 'default' => "Let's Start the Conversation" ], + [ 'key' => 'contact_subheading', 'label' => 'Section Subheading', 'type' => 'textarea', 'default' => "Whether you're looking for a quote, want to see a demo, or just have questions — we're here to help." ], + [ 'key' => 'contact_email', 'label' => 'Contact Email', 'type' => 'text', 'default' => 'info@ots-signs.com' ], + [ 'type' => 'section', 'label' => 'Demo CTA Section' ], + [ 'key' => 'demo_heading', 'label' => 'Demo Heading', 'type' => 'text', 'default' => 'Explore Our Demo Platform' ], + [ 'key' => 'demo_description', 'label' => 'Demo Description', 'type' => 'textarea', 'default' => 'See the OTS Signs CMS in action. Request access to our live demo instance and experience the platform for yourself before making any commitment.' ], + ], + ]; + + return $templates[ $template ] ?? []; +} + +// Save meta fields +add_action( 'save_post_page', 'ots_save_meta_fields' ); + +function ots_save_meta_fields( $post_id ) { + if ( ! isset( $_POST['ots_meta_nonce'] ) ) return; + if ( ! wp_verify_nonce( $_POST['ots_meta_nonce'], 'ots_save_meta' ) ) return; + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; + if ( ! current_user_can( 'edit_page', $post_id ) ) return; + + if ( ! isset( $_POST['ots_meta'] ) || ! is_array( $_POST['ots_meta'] ) ) return; + + foreach ( $_POST['ots_meta'] as $key => $value ) { + $key = sanitize_key( $key ); + // Allow basic HTML (spans, br, strong, em) for rich text fields + $allowed = array_merge( wp_kses_allowed_html( 'post' ), [] ); + update_post_meta( $post_id, $key, wp_kses_post( $value ) ); + } +} + +/** + * Helper: get a meta value with a default fallback. + */ +function ots_meta( $post_id, $key, $default = '' ) { + $value = get_post_meta( $post_id, $key, true ); + return ( $value !== '' && $value !== false ) ? $value : $default; +} diff --git a/wp-content/themes/ots-signs/header.php b/wp-content/themes/ots-signs/header.php new file mode 100644 index 0000000..ddfba57 --- /dev/null +++ b/wp-content/themes/ots-signs/header.php @@ -0,0 +1,47 @@ + +> + + + + + + +> + + + diff --git a/wp-content/themes/ots-signs/index.php b/wp-content/themes/ots-signs/index.php new file mode 100644 index 0000000..ad1e680 --- /dev/null +++ b/wp-content/themes/ots-signs/index.php @@ -0,0 +1,45 @@ + + +
+ +
+
+

+
+
+ +
+
+ +
+ + + +
+
+ +
+ +

No posts found.

+ +
+
+ + diff --git a/wp-content/themes/ots-signs/page-about.php b/wp-content/themes/ots-signs/page-about.php new file mode 100644 index 0000000..2ab67d7 --- /dev/null +++ b/wp-content/themes/ots-signs/page-about.php @@ -0,0 +1,149 @@ + + +
+ + +
+
+ + +

+

+
+
+ + +
+
+
+
📷
+
+ + +

+

+

+

OTS Signs is a service by Oribi Technology Services, backed by a team of technology professionals passionate about modern communication.

+
+
+
+
+ + +
+
+
+ +

What Sets Us Apart

+

We don't just sell screens — we deliver a complete communication platform built for reliability, ease of use, and real business results.

+
+ +
+
+
+

Easy to Use

+

Our cloud CMS is designed for any skill level. Publish content to your signs in minutes, no technical expertise required.

+
+
+
📈
+

Scalable Platform

+

Whether you manage one screen or 500+, our platform scales effortlessly with your business without sacrificing performance.

+
+
+
🔒
+

Enterprise Security

+

Enterprise-grade security safeguards your content and network with rock-solid reliability and uptime you can count on.

+
+
+
🌐
+

Always Connected

+

Our intelligent player devices keep your content playing even without internet — so your message never goes dark.

+
+
+
🌟
+

Professional Content

+

We offer professional photography and video production to ensure your signage looks polished, engaging, and on-brand.

+
+
+
🤝
+

Ongoing Support

+

We're your digital signage partner — not just a vendor. We're here to help you get the most out of your investment.

+
+
+
+
+ + +
+
+
+ +

Cloud-Native Infrastructure Built for Performance

+

Our application platform lets you publish content instantly across any network, with built-in real-time analytics and a secure, cloud-native architecture.

+
+ +
+
+
💻
+

Cloud CMS

+

Manage all your screens from a single, intuitive dashboard. Schedule content, monitor displays, and push updates in real time from anywhere in the world.

+
+
+
📊
+

Real-Time Analytics

+

Track what's playing, when, and on which screens. Get actionable insights to optimize your content strategy and maximize engagement.

+
+
+
🔌
+

Flexible Hardware

+

Our players work with any HDMI screen, making integration into your existing setup seamless. Or get a complete bundled solution including a commercial display.

+
+
+
+

Live Data Pipelines

+

Connect your web dashboards, APIs, or data feeds to display live metrics, prices, news, or any dynamic content automatically on your screens.

+
+
+
+
+ + +
+
+ +

+

+ +
+
+ + diff --git a/wp-content/themes/ots-signs/page-contact.php b/wp-content/themes/ots-signs/page-contact.php new file mode 100644 index 0000000..d5a32f1 --- /dev/null +++ b/wp-content/themes/ots-signs/page-contact.php @@ -0,0 +1,163 @@ + + +
+ + +
+
+ + +

+

+
+
+ + +
+
+
+ + +
+ + +

+

+ +
+
💌
+
+
Email
+
+
+
+ +
+
🌐
+
+
Demo Platform
+ +
+
+ +
+
🏠
+
+
Company
+ +
+
+ +
+ +

What to Expect

+
    +
  • + 01 + We'll review your message and respond within one business day. +
  • +
  • + 02 + We'll schedule a quick discovery call to understand your needs. +
  • +
  • + 03 + We'll prepare a tailored proposal and walk you through the platform. +
  • +
+
+ + +
+

Send Us a Message

+ +
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ + +
+ + + + +
+
+ +
+
+
+ + +
+
+ + +

+

+ Request Demo Access → +
+
+ + diff --git a/wp-content/themes/ots-signs/page-home.php b/wp-content/themes/ots-signs/page-home.php new file mode 100644 index 0000000..5f402af --- /dev/null +++ b/wp-content/themes/ots-signs/page-home.php @@ -0,0 +1,294 @@ + + + +
+
+
+
+
+ + dynamic communication tool for your business.' ); + $hero_desc = ots_meta( $id, 'hero_description', 'The complete package for engaging digital signage. From eye-catching retail displays to dynamic informational screens, we craft tailored solutions that capture attention and deliver your message.' ); + $cta_primary = ots_meta( $id, 'hero_cta_primary_label', 'Get in Touch' ); + $cta_secondary = ots_meta( $id, 'hero_cta_secondary_label', 'View Demo' ); + $stat_1_val = ots_meta( $id, 'stat_1_value', '500+' ); + $stat_1_lbl = ots_meta( $id, 'stat_1_label', 'Screens Managed' ); + $stat_2_val = ots_meta( $id, 'stat_2_value', '6' ); + $stat_2_lbl = ots_meta( $id, 'stat_2_label', 'Industry Verticals' ); + $stat_3_val = ots_meta( $id, 'stat_3_value', '99.9%' ); + $stat_3_lbl = ots_meta( $id, 'stat_3_label', 'Uptime SLA' ); + ?> +
+ ● Digital Signage Solutions +

+

+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ Live content publishing +
+
+
+ +
+
+ +
Live Data Dashboard
+
+
+
+
+
+
+ Offline playback enabled +
+
+
+ +
+
+ + +
+
+ +
+ +

+

+
+ +
+
+
📷
+

Showcase Your Products

+

Professional photography and video production services to showcase your products and services with high-quality, polished visuals.

+
+
+
📊
+

Live Data Integrations

+

Integrate your existing web dashboards and real-time data with our platform to display up-to-the-minute metrics and insights.

+
+
+
🍽
+

Digital Menu Boards

+

Make your menu as appealing as your product. We incorporate your branding with high-quality photography to showcase your offerings.

+
+
+
🔋
+

Offline Playback

+

Our intelligent player devices keep your message on screen even when the internet isn't available — so communication never stops.

+
+
+
+
+ + +
+
+ +
+ +

+

+
+ +
+
+
🏦
+

Hospitality

+

Showcase menus, promotions, and special events while guiding guests through lobbies, restaurants, and bars.

+
+
+
🛍
+

Retail

+

Drive product upsells, announce flash-sales, and offer in-store navigation with fresh, eye-catching displays.

+
+
+
🌃
+

Outdoor Marketplace

+

Whether it's a weekly farmers market or seasonal fair, digital signage adds a modern, professional touch without losing the charm.

+
+
+
🏢
+

Corporate Office

+

Enhance your meeting experience with Teams meeting rooms. Communicate schedules, company news, and employee alerts.

+
+
+
🔴
+

Live Data Displays

+

Connect existing web dashboards and real-time data to our platform. Bring key metrics and insights to life in real-time.

+
+
+
🏫
+

Education

+

Broadcast class schedules, announcements, and interactive learning content in campuses and auditoriums.

+
+
+
+
+ + +
+
+
+ +

Technology Designed to Work for You

+

Our application platform lets you publish content instantly across any network, with built-in real-time analytics and a secure, cloud-native architecture.

+
+ +
+
+
+

Manage All Your Screens in One Place

+

Our cloud CMS offers the power and flexibility to manage digital displays for businesses of all sizes. Whether you're a single location or a multi-site enterprise, our digital signage network is built to grow with you.

+
+
💻
+
+ +
+
+

Dynamic Content Scheduling

+

Effortlessly schedule your content for maximum impact. Plan ahead by setting content to play at specific times, daypart, or trigger based on real-world events. Automate your messaging to ensure the right information is displayed at the right time.

+
+
📅
+
+ +
+
+

Use Existing Screens

+

Our digital signage players work on any screen with HDMI, so you can easily integrate them into your current setup. We also offer bundled packages that include both the player and a high-quality commercial-grade display.

+
+
📺
+
+ +
+
+

Secure & Reliable

+

Enterprise-grade security safeguards your content and network, while our advanced hosting platform guarantees rock-solid reliability. Our intelligent player devices continue playing content even when offline, so your communication never misses a beat.

+
+
🔒
+
+
+
+
+ + +
+
+ +
+ +

+

+
+ +
+
+
Essentials
+
+
$7
+
per screen / month — or $70 / screen annually
+
+
    +
  • Up to 20 screens
  • +
  • Content scheduling & day-parting
  • +
  • Live data integrations
  • +
  • Unlimited user seats
  • +
  • Custom subdomain
  • +
  • Shared CMS server
  • +
+ Get Started +
+ + +
+ +

+ Want to see the platform in action? + Request access to our demo instance → +

+
+
+ + +
+
+ +

+

+ +
+
+ + diff --git a/wp-content/themes/ots-signs/page-services.php b/wp-content/themes/ots-signs/page-services.php new file mode 100644 index 0000000..921addf --- /dev/null +++ b/wp-content/themes/ots-signs/page-services.php @@ -0,0 +1,264 @@ + + +
+ + +
+
+ + +

+

+
+
+ + +
+
+ +
+ +

+

+
+ +
+
+
+ +

Showcase Your Products

+

High-quality visuals make all the difference. We offer professional photography and video production services to showcase your products, services, or environment. We ensure your content looks polished and engaging — because great signage starts with great content.

+ Get a Quote +
+
📷
+
+ +
+
+ +

Live Data Integrations

+

Integrate your existing web dashboards and real-time data with our platform to bring your most important information to life on digital signage. We make it easy to display up-to-the-minute data and insights — stock prices, KPIs, queue lengths, weather, and more.

+ Learn More +
+
📊
+
+ +
+
+ +

Digital Menu Boards

+

Make your menu as appealing as your product. We incorporate your branding and include high-quality photography to showcase your product in the most enticing way possible. Update menu items, prices, and specials instantly from our cloud CMS — no reprinting required.

+ See Examples +
+
🍽
+
+ +
+
+ +

Offline Playback Support

+

Our intelligent player devices are engineered to keep your message on screen, even when the internet isn't available. So you can rely on them in locations where connecting to the internet is difficult or impossible. Content keeps playing, always.

+ View Devices +
+
🔋
+
+
+
+
+ + +
+
+
+ +

Solutions for Every Industry

+

We understand that every industry has different communication needs. Our platform is flexible enough to serve them all.

+
+ +
+
+
🏦
+

Hospitality

+

Showcase menus, promotions, and special events while guiding guests through lobbies, restaurants, and bars. Create a memorable first impression with polished, dynamic signage throughout your venue.

+
+ +
+
🛍
+

Retail

+

Drive product upsells, announce flash-sales, and offer in-store navigation with fresh, eye-catching displays. Update content instantly in response to stock levels, seasonal campaigns, or breaking promotions.

+
+ +
+
🌃
+

Outdoor Marketplace

+

Whether it's a weekly farmers market or seasonal fairs, digital signage adds a modern, professional touch without losing the charm of the market experience. Perfect for weather-resilient, portable signage solutions.

+
+ +
+
🏢
+

Corporate Office

+

Enhance your meeting experience with Teams-integrated meeting room displays. Communicate meeting schedules, company news, and employee alerts with live dashboards and internal communication screens.

+
+ +
+
🔴
+

Live Data Displays

+

Connect your existing web dashboards and real-time data to our platform for customized digital signage. We bring your key metrics and insights to life in real-time — ideal for trading floors, operations centres, and control rooms.

+
+ +
+
🏫
+

Education

+

Broadcast class schedules, announcements, and interactive learning content in campuses and auditoriums. Keep students and staff informed with centrally managed screens across your entire campus.

+
+
+
+
+ + +
+
+
+ +

Built-In Features Included with Every Plan

+

Every OTS Signs subscription comes loaded with powerful features to help you manage, schedule, and optimize your content.

+
+ +
+
+
📅
+

Content Scheduling

+

Schedule content to play at specific times, or daypart your messaging to show the right content at the right time of day.

+
+
+
📊
+

Live Data Feeds

+

Connect any web-accessible data source to your signage for automated, real-time content updates without manual intervention.

+
+
+
👥
+

Unlimited Users

+

Invite your whole team. Every plan includes unlimited user seats so everyone who needs access can contribute.

+
+
+
+

Instant Publishing

+

Publish content to your signs in minutes. No complex deployments, no waiting — changes appear on screen immediately.

+
+
+
🔋
+

Offline Playback

+

Intelligent caching means your screens never go dark, even during internet outages or in connectivity-limited locations.

+
+
+
🔒
+

Enterprise Security

+

Role-based access control, encrypted connections, and enterprise-grade infrastructure keep your content and data safe.

+
+
+
💻
+

Cloud Management

+

Manage your entire network of screens from any browser on any device — no software installation required.

+
+
+
📺
+

Any Screen

+

Works with any HDMI-compatible display. Transition existing screens into smart signage with our compact player devices.

+
+
+
+
+ + +
+
+ +
+ +

+

+
+ +
+
+
Essentials
+
+
$7
+
per screen / month — or $70 / screen annually
+
+
    +
  • Up to 20 screens
  • +
  • Content scheduling & day-parting
  • +
  • Live data integrations
  • +
  • Unlimited user seats
  • +
  • Custom subdomain
  • +
  • Shared CMS server
  • +
+ Get Started +
+ + +
+
+
+ + +
+ +
+ + diff --git a/wp-content/themes/ots-signs/page.php b/wp-content/themes/ots-signs/page.php new file mode 100644 index 0000000..4fb7782 --- /dev/null +++ b/wp-content/themes/ots-signs/page.php @@ -0,0 +1,34 @@ + + +
+ +
+
+

+
+
+ +
+
+ +
+ +
+ +
+
+ + diff --git a/wp-content/themes/ots-signs/single.php b/wp-content/themes/ots-signs/single.php new file mode 100644 index 0000000..01eb8fb --- /dev/null +++ b/wp-content/themes/ots-signs/single.php @@ -0,0 +1,37 @@ + + +
+ +
+
+

+

+
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/wp-content/themes/ots-signs/style.css b/wp-content/themes/ots-signs/style.css new file mode 100644 index 0000000..55ac783 --- /dev/null +++ b/wp-content/themes/ots-signs/style.css @@ -0,0 +1,12 @@ +/* + Theme Name: OTS Signs + Theme URI: https://ots-signs.com + Author: OTS Signs + Author URI: https://ots-signs.com + Description: A clean, modern marketing theme for OTS Signs digital signage company. + Version: 1.0.0 + License: GNU General Public License v2 or later + License URI: http://www.gnu.org/licenses/gpl-2.0.html + Text Domain: ots-signs + Tags: digital-signage, marketing, modern, business +*/