From 51b2afd3387b4758c2a987290fe723906769944a Mon Sep 17 00:00:00 2001
From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
Date: Tue, 11 Aug 2026 21:41:31 -0400
Subject: [PATCH] feat: add storefront page and Virtual HID launch post
Introduces a new Store section with navigation, product data, a reusable product card include, and a dedicated `store.html` page styled with new store SCSS and gallery modal JS. Seeds the store with the Virtual HID Driver listing, including pricing, features, screenshots, and checkout links. Also adds a launch blog post for libvirtualhid/Virtual HID Driver and fixes a small punctuation typo in Amazon product copy.
---
_config_theme.yml | 1 +
_data/amazon_products.yml | 2 +-
_data/store_products.yml | 49 ++
_includes/store-product-card.html | 200 +++++++
...ng-libvirtualhid-and-virtual-hid-driver.md | 135 +++++
assets/css/store.scss | 505 ++++++++++++++++++
assets/js/store.js | 26 +
store.html | 63 +++
8 files changed, 980 insertions(+), 1 deletion(-)
create mode 100644 _data/store_products.yml
create mode 100644 _includes/store-product-card.html
create mode 100644 _posts/2026-08-11-introducing-libvirtualhid-and-virtual-hid-driver.md
create mode 100644 assets/css/store.scss
create mode 100644 assets/js/store.js
create mode 100644 store.html
diff --git a/_config_theme.yml b/_config_theme.yml
index 694813a3..25a6f273 100644
--- a/_config_theme.yml
+++ b/_config_theme.yml
@@ -13,6 +13,7 @@ navbar-links:
- GitHub: "https://github.com/sponsors/LizardByte"
- Patreon: "https://patreon.com/LizardByte"
- PayPal: "https://www.paypal.com/paypalme/ReenigneArcher"
+ Store: "store"
Resources:
- Blog: "blog"
- Community: "https://github.com/orgs/LizardByte/discussions"
diff --git a/_data/amazon_products.yml b/_data/amazon_products.yml
index 6247b541..b2fd87ed 100644
--- a/_data/amazon_products.yml
+++ b/_data/amazon_products.yml
@@ -230,7 +230,7 @@
# Accessories
- title: >-
Elgato Stream Deck MK.2 –
- Studio Controller, 15 macro keys, trigger actions in apps and software like OBS, Twitch, YouTube and more,
+ Studio Controller, 15 macro keys, trigger actions in apps and software like OBS, Twitch, YouTube and more,
works with Mac and PC
image: "https://m.media-amazon.com/images/I/61gtdFnK+UL._AC_SL1500_.jpg"
link: "https://www.amazon.com/dp/B09738CV2G"
diff --git a/_data/store_products.yml b/_data/store_products.yml
new file mode 100644
index 00000000..0363afab
--- /dev/null
+++ b/_data/store_products.yml
@@ -0,0 +1,49 @@
+---
+- id: virtual-hid-driver
+ name: Virtual HID Driver
+ category: Windows software
+ tagline: Modern virtual gamepads for Sunshine on Windows
+ description: >-
+ Unlock expanded virtual controller support in Sunshine with a user-mode driver built and maintained alongside
+ the rest of the LizardByte input stack.
+ cover:
+ src: https://raw.githubusercontent.com/LizardByte/libvirtualhid/refs/heads/master/libvirtualhid-poster-1440x2160.png
+ alt: A green outline of a game controller on a vertical dark green background
+ aspect: portrait
+ screenshots:
+ - src: "https://raw.githubusercontent.com/LizardByte/libvirtualhid/refs/heads/master/docs/images/screenshots/\
+ libvirtualhid-control-03.png"
+ alt: libvirtualhid control displaying an active Xbox Series virtual controller
+ caption: Inspect virtual controller input, battery state, and output reports.
+ - src: "https://raw.githubusercontent.com/LizardByte/libvirtualhid/refs/heads/master/docs/images/screenshots/\
+ libvirtualhid-control-04.png"
+ alt: libvirtualhid control displaying a DualSense virtual controller
+ caption: Use controller-specific features such as touchpad input and RGB output.
+ - src: "https://raw.githubusercontent.com/LizardByte/libvirtualhid/refs/heads/master/docs/images/screenshots/\
+ windows-driver-game-controllers-and-properties.png"
+ alt: Windows Game Controllers and controller properties showing a Virtual HID Framework device
+ caption: Virtual controllers appear in the familiar Windows Game Controllers panel.
+ badges:
+ - label: Windows
+ icon: fa-brands fa-windows
+ - label: Sunshine compatible
+ icon: fa-solid fa-sun
+ prices:
+ - amount: $14.99
+ label: per year
+ - amount: $49.99
+ label: lifetime
+ price_note: One license can be activated on up to five machines.
+ features:
+ - Generic, Xbox One, Xbox Series, DualShock 4, DualSense, and Switch Pro-style profiles
+ - Support for advanced controller features when the selected controller and game provide them
+ - Ongoing driver maintenance and improvements alongside Sunshine and other LizardByte software
+ details:
+ label: Learn more
+ url: https://app.lizardbyte.dev/libvirtualhid/virtual-hid-driver
+ offers:
+ - label: Purchase
+ url: https://buy.polar.sh/polar_cl_zj6Io5NVukXfZSl97ULtFvImfI5L1jbL2cSnc0Y72Pt
+ store: Polar
+ external: true
+ icon: fa-solid fa-cart-shopping
diff --git a/_includes/store-product-card.html b/_includes/store-product-card.html
new file mode 100644
index 00000000..224abe0c
--- /dev/null
+++ b/_includes/store-product-card.html
@@ -0,0 +1,200 @@
+{% assign product = include.product %}
+
+
+
+
+
+
+
+
{{ product.category }}
+
{{ product.name }}
+
{{ product.tagline }}
+
+
+
{{ product.description }}
+
+ {% if product.features %}
+
+ {% for feature in product.features %}
+
+
+ {{ feature }}
+
+ {% endfor %}
+
+ {% endif %}
+
+
+
+ {% if product.prices %}
+
+ {% for price in product.prices %}
+
+ {{ price.amount }}
+ {{ price.label }}
+
+ {% endfor %}
+
+ {% endif %}
+
+ {% if product.price_note %}
+
+
+ {{ product.price_note }}
+
+ {% endif %}
+
+
+
+ {% for offer in product.offers %}
+ {% if offer.store %}
+
+
+ Checkout provided by {{ offer.store }}
+
+ {% endif %}
+ {% endfor %}
+
+
+
+
+ {% if product.screenshots %}
+
+
+ Gallery
+
Screenshots
+
+
+ {% for screenshot in product.screenshots %}
+
+
+
+
+
+
+ {% endfor %}
+
+
+ {% endif %}
+
+
+{% if product.screenshots %}
+
+
+
+
+
+
+
+ {% for screenshot in product.screenshots %}
+
+
+ {% if screenshot.caption %}
+ {{ screenshot.caption }}
+ {% endif %}
+
+ {% endfor %}
+
+
+ {% if product.screenshots.size > 1 %}
+
+
+ Previous screenshot
+
+
+
+ Next screenshot
+
+ {% endif %}
+
+
+
+
+
+{% endif %}
diff --git a/_posts/2026-08-11-introducing-libvirtualhid-and-virtual-hid-driver.md b/_posts/2026-08-11-introducing-libvirtualhid-and-virtual-hid-driver.md
new file mode 100644
index 00000000..fac6d9d1
--- /dev/null
+++ b/_posts/2026-08-11-introducing-libvirtualhid-and-virtual-hid-driver.md
@@ -0,0 +1,135 @@
+---
+layout: post
+title: Introducing libvirtualhid and Virtual HID Driver
+subtitle: A simpler, more capable input system for Sunshine
+cover-img: https://app.lizardbyte.dev/libvirtualhid/assets/img/banners/libvirtualhid.jpeg
+thumbnail-img: https://app.lizardbyte.dev/libvirtualhid/assets/img/banners/libvirtualhid.jpeg
+share-img: https://app.lizardbyte.dev/libvirtualhid/assets/img/banners/libvirtualhid.jpeg
+gh-repo: LizardByte/libvirtualhid
+gh-badge: [follow, star]
+readtime: true
+tags: [announcements, Sunshine, libvirtualhid, virtual-input]
+comments: true
+authors:
+ - github: ReenigneArcher
+---
+
+Virtual input is the part of Sunshine that turns controls received from Moonlight into button presses, mouse movement,
+touch input, and other actions on the host. It is mostly invisible when it works well, but it affects nearly every
+streaming session.
+
+Starting with [Sunshine](https://github.com/LizardByte/Sunshine) `SUNSHINE_VERSION_PLACEHOLDER`, that work is powered by
+[libvirtualhid](https://github.com/LizardByte/libvirtualhid) `LIBVIRTUALHID_VERSION_PLACEHOLDER`. This first release of
+libvirtualhid gives Sunshine one shared home for virtual input instead of maintaining a different implementation for
+each operating system.
+
+It also introduces [Virtual HID Driver](https://app.lizardbyte.dev/libvirtualhid/virtual-hid-driver), a new Windows
+gamepad option with support for more controller types and features. Because using this Windows driver requires a paid
+license, we want to explain exactly what is changing and what choices remain available.
+
+## What are libvirtualhid and Virtual HID Driver?
+
+[libvirtualhid](https://app.lizardbyte.dev/libvirtualhid/) is a free, open-source library for creating virtual input
+devices. Sunshine uses it for supported gamepads, keyboards, mice, touchscreens, trackpads, and pen input. Other
+projects can use the library too; it is not tied exclusively to Sunshine.
+
+[Virtual HID Driver](https://app.lizardbyte.dev/libvirtualhid/virtual-hid-driver) is the Windows component used to
+create virtual gamepads. It runs in user mode and avoids adding a custom kernel-mode driver to the system. The driver
+is installed separately from Sunshine.
+
+Sunshine remains licensed under GPLv3 and libvirtualhid is licensed under the MIT License. The Windows driver source
+and package use the LizardByte Source-Available License.
+
+## What changes in Sunshine?
+
+Previously, Sunshine relied primarily on ViGEmBus for Windows gamepads, inputtino for Linux input, and separate code
+for several other kinds of virtual input. Sunshine now uses libvirtualhid as the primary path for all supported
+virtual input—not only gamepad input. ViGEmBus remains the Windows compatibility fallback described below.
+
+Bringing this work together provides several benefits:
+
+- Windows gains support for Generic, Xbox One, Xbox Series, DualShock 4, DualSense, and Nintendo Switch Pro-style
+ virtual gamepads. Xbox 360 remains available through the ViGEmBus fallback.
+- Linux supports the full controller selection, including Xbox 360, through its normal Linux input system.
+- Features such as motion, touchpads, LEDs, adaptive triggers, battery information, and rumble can be passed between
+ Moonlight and the virtual controller when the selected controller and game support them.
+- Input fixes and new features can be developed once and shared across operating systems instead of being recreated
+ in several different parts of Sunshine.
+- The Windows driver is actively maintained alongside Sunshine, giving us a path to add profiles and improve
+ compatibility over time.
+
+## Windows licensing and pricing
+
+The paid license applies only to creating gamepads through Virtual HID Driver on Windows. No Virtual HID Driver
+license is needed for streaming, Windows keyboard or mouse input, using libvirtualhid on other platforms, Linux,
+macOS, or the ViGEmBus fallback.
+
+Both Windows license options provide the same features:
+
+- **Yearly:** **$14.99 per year**, billed as a recurring subscription.
+- **Lifetime:** **$49.99 once**, with no recurring subscription.
+
+One license can be activated on up to **five machines**. Machines can be deactivated through the customer portal when
+hardware is replaced. The license does not add its own limit to the number of active virtual gamepads, although
+Sunshine's normal controller limits still apply. Taxes, where applicable, are calculated during checkout.
+
+An internet connection is required when Virtual HID Driver creates a new gamepad so the machine license can be
+checked. Sunshine shows the current status and provides activation, purchase, and account-management options on the
+Troubleshooting page and in the **Virtual HID Driver** system tray menu.
+
+[View the Windows license options](https://buy.polar.sh/polar_cl_zj6Io5NVukXfZSl97ULtFvImfI5L1jbL2cSnc0Y72Pt){: .btn .btn-primary }
+
+This is the first paid feature offered alongside Sunshine. The license helps cover the ongoing work involved in
+signing, testing, distributing, supporting, and improving the Windows driver. Revenue from it will also help fund
+continued development of Sunshine, libvirtualhid, and other LizardByte software. We have kept the license requirement
+focused on the Windows gamepad driver rather than applying it to the shared library as a whole.
+
+## ViGEmBus remains a no-cost option
+
+Windows users can continue using ViGEmBus without purchasing a Virtual HID Driver license. When Virtual HID Driver is
+not available, Sunshine automatically detects ViGEmBus 1.17 or newer and uses it for **Xbox 360** and **DualShock 4**
+virtual controllers.
+
+ViGEmBus does not provide the additional Xbox One, Xbox Series, DualSense, Nintendo Switch Pro-style, or Generic
+profiles offered through Virtual HID Driver. The ViGEmBus repository was archived on November 2, 2023, and the
+project's official [end-of-life announcement](https://docs.nefarius.at/projects/ViGEm/End-of-Life/) explains that
+ViGEmBus and its client libraries will receive no further updates. Sunshine is retaining this fallback so Windows
+users who do not want to purchase a Virtual HID Driver license can continue using Xbox 360 or DualShock 4 emulation.
+
+## Linux stays free and requires no license key
+
+On Linux, libvirtualhid replaces inputtino inside Sunshine. This is an internal change: **there is no paid Linux
+driver and no license key is required**. Sunshine packages continue to configure the normal Linux input permissions,
+and users receive the new shared input system as part of Sunshine.
+
+Moving Linux to libvirtualhid gives it the same controller selection and shared input improvements without bringing
+the Windows driver license along with it. It also restores Sunshine's legacy X11/XTest keyboard and mouse fallback.
+On X11 systems where the normal Linux virtual-input device is unavailable, Sunshine can still use XTest for basic
+keyboard and mouse input.
+
+## macOS gamepad support is planned
+
+Sunshine already uses libvirtualhid for the input types currently supported on macOS, including keyboard and mouse
+input. Virtual gamepads are not supported on macOS yet, but adding them is planned future work. Keeping the macOS
+implementation behind the same library gives us a clear place to add that support without creating another separate
+Sunshine input system.
+
+## Choosing the Windows gamepad option
+
+Windows users have two paths in Sunshine `SUNSHINE_VERSION_PLACEHOLDER`:
+
+1. Install [Virtual HID Driver](https://github.com/LizardByte/libvirtualhid/releases/latest), purchase a yearly or
+ lifetime license, and activate the machine through Sunshine for the expanded controller selection and features.
+2. Keep or install [ViGEmBus 1.17 or newer](https://github.com/nefarius/ViGEmBus/releases/latest) and use the Xbox 360
+ or DualShock 4 fallback without a Virtual HID Driver license.
+
+Sunshine reports which option is available and links to driver installation and license management when needed.
+
+With libvirtualhid, virtual input now has one shared foundation across Sunshine. That gives us room to support more
+controllers, bring improvements to multiple operating systems, and add macOS gamepads in the future. Windows users
+who do not want to purchase a Virtual HID Driver license can continue using the ViGEmBus fallback, and Linux remains
+license-free.
+
+Learn more on the [libvirtualhid project site](https://app.lizardbyte.dev/libvirtualhid/), visit the
+[Virtual HID Driver page](https://app.lizardbyte.dev/libvirtualhid/virtual-hid-driver), or follow development in the
+[libvirtualhid repository](https://github.com/LizardByte/libvirtualhid).
diff --git a/assets/css/store.scss b/assets/css/store.scss
new file mode 100644
index 00000000..68547b87
--- /dev/null
+++ b/assets/css/store.scss
@@ -0,0 +1,505 @@
+---
+layout: null
+---
+
+.header-section {
+ display: none;
+}
+
+.storefront {
+ --store-border: var(--navbar-border-col);
+ --store-muted: var(--footer-text-col);
+ --store-surface: var(--navbar-col);
+ --store-surface-alt: var(--footer-col);
+
+ padding-bottom: 1.5rem;
+ padding-top: 4.75rem;
+}
+
+.storefront-intro {
+ max-width: 48rem;
+}
+
+.storefront-kicker,
+.store-product-category {
+ color: var(--link-col);
+ font-size: 0.75rem;
+ font-weight: 700;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+}
+
+.storefront-kicker {
+ align-items: center;
+ display: inline-flex;
+ gap: 0.5rem;
+}
+
+.storefront-assurance {
+ background: var(--store-surface);
+ border: 1px solid var(--store-border);
+ border-radius: 1rem;
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ margin: 0 auto 2rem;
+ max-width: 64rem;
+ overflow: hidden;
+}
+
+.storefront-assurance li {
+ align-items: center;
+ display: flex;
+ gap: 0.75rem;
+ justify-content: center;
+ padding: 0.75rem 1rem;
+ text-align: center;
+}
+
+.storefront-assurance li + li {
+ border-left: 1px solid var(--store-border);
+}
+
+.storefront-assurance i {
+ color: var(--link-col);
+ font-size: 1.1rem;
+}
+
+.store-product-card {
+ background: var(--store-surface);
+ border: 1px solid var(--store-border);
+ border-radius: 1.25rem;
+ box-shadow: 0 1rem 2.5rem rgba(0, 0, 0, 0.12);
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ overflow: hidden;
+ transition: box-shadow 200ms ease, transform 200ms ease;
+}
+
+.store-product-summary {
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+}
+
+.store-product-card:hover {
+ box-shadow: var(--card-hover-shadow);
+ transform: translateY(-0.25rem);
+}
+
+.store-product-media {
+ background: #101f18;
+ overflow: hidden;
+ position: relative;
+}
+
+.store-product-media-landscape {
+ aspect-ratio: 16 / 9;
+}
+
+.store-product-media-portrait {
+ aspect-ratio: 2 / 3;
+}
+
+.store-product-media-square {
+ aspect-ratio: 1 / 1;
+}
+
+.store-product-media > a {
+ display: block;
+ height: 100%;
+}
+
+.store-product-image {
+ height: 100%;
+ object-fit: contain;
+ transition: transform 350ms ease;
+ width: 100%;
+}
+
+.store-product-card:hover .store-product-image {
+ transform: scale(1.025);
+}
+
+.store-product-badges {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ left: 1rem;
+ margin: 0;
+ position: absolute;
+ top: 1rem;
+}
+
+.store-product-badge {
+ align-items: center;
+ backdrop-filter: blur(0.5rem);
+ background: rgba(15, 17, 18, 0.82);
+ border: 1px solid rgba(255, 255, 255, 0.18);
+ border-radius: 999px;
+ color: #fff;
+ display: inline-flex;
+ font-size: 0.78rem;
+ font-weight: 700;
+ gap: 0.4rem;
+ padding: 0.4rem 0.7rem;
+}
+
+.store-product-content {
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ padding: 1.25rem 1.5rem;
+}
+
+.store-product-title {
+ font-size: clamp(1.5rem, 2.5vw, 1.9rem);
+ font-weight: 800;
+ margin: 0.4rem 0 0.25rem;
+}
+
+.store-product-tagline {
+ color: var(--store-muted);
+ font-size: 1rem;
+ font-weight: 600;
+ margin-bottom: 0;
+}
+
+.store-product-description {
+ line-height: 1.55;
+ margin: 0.8rem 0;
+}
+
+.store-product-features {
+ display: grid;
+ gap: 0.5rem;
+ list-style: none;
+ font-size: 0.92rem;
+ margin: 0 0 0.9rem;
+ padding: 0;
+}
+
+.store-product-features li {
+ align-items: flex-start;
+ display: flex;
+ gap: 0.7rem;
+ line-height: 1.35;
+}
+
+.store-product-features i {
+ color: var(--link-col);
+ margin-top: 0.25rem;
+}
+
+.store-product-purchase {
+ border-top: 1px solid var(--store-border);
+ margin-top: auto;
+ padding-top: 0.9rem;
+}
+
+.store-product-prices {
+ display: grid;
+ gap: 0.75rem;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+}
+
+.store-price-option {
+ background: var(--store-surface-alt);
+ border: 1px solid var(--store-border);
+ border-radius: 0.75rem;
+ display: flex;
+ flex-direction: column;
+ padding: 0.6rem 0.85rem;
+}
+
+.store-price-amount {
+ font-size: 1.2rem;
+ font-weight: 800;
+}
+
+.store-price-label,
+.store-product-price-note,
+.store-product-seller {
+ color: var(--store-muted);
+}
+
+.store-price-label {
+ font-size: 0.82rem;
+ font-weight: 600;
+}
+
+.store-product-price-note {
+ font-size: 0.86rem;
+ margin: 0.55rem 0 0.75rem;
+}
+
+.store-product-price-note i,
+.store-product-seller i {
+ margin-right: 0.35rem;
+}
+
+.store-product-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.75rem;
+}
+
+.store-product-actions .btn {
+ align-items: center;
+ display: inline-flex;
+ gap: 0.55rem;
+ justify-content: center;
+}
+
+.store-product-seller {
+ font-size: 0.78rem;
+ margin: 0.55rem 0 0;
+}
+
+.store-product-gallery {
+ align-items: center;
+ border-top: 1px solid var(--store-border);
+ display: flex;
+ gap: 1rem;
+ padding: 0.8rem 1.25rem;
+}
+
+.store-product-gallery-heading {
+ flex: 0 0 auto;
+}
+
+.store-product-gallery-heading h4 {
+ font-size: 1rem;
+ font-weight: 800;
+ margin: 0.2rem 0 0;
+}
+
+.store-screenshot-grid {
+ display: flex;
+ gap: 0.65rem;
+ min-width: 0;
+}
+
+.store-screenshot-thumbnail {
+ aspect-ratio: 16 / 9;
+ background: #111;
+ border: 1px solid var(--store-border);
+ border-radius: 0.5rem;
+ cursor: zoom-in;
+ flex: 0 1 8rem;
+ overflow: hidden;
+ padding: 0;
+ position: relative;
+}
+
+.store-screenshot-thumbnail img {
+ display: block;
+ height: 100%;
+ object-fit: contain;
+ transition: opacity 200ms ease, transform 200ms ease;
+ width: 100%;
+}
+
+.store-screenshot-thumbnail:hover img,
+.store-screenshot-thumbnail:focus-visible img {
+ opacity: 0.78;
+ transform: scale(1.03);
+}
+
+.store-screenshot-thumbnail:focus-visible {
+ outline: 0.2rem solid var(--link-col);
+ outline-offset: 0.15rem;
+}
+
+.store-screenshot-expand {
+ align-items: center;
+ background: rgba(0, 0, 0, 0.72);
+ border-radius: 50%;
+ color: #fff;
+ display: flex;
+ height: 1.8rem;
+ justify-content: center;
+ opacity: 0;
+ position: absolute;
+ right: 0.4rem;
+ top: 0.4rem;
+ transition: opacity 200ms ease;
+ width: 1.8rem;
+}
+
+.store-screenshot-thumbnail:hover .store-screenshot-expand,
+.store-screenshot-thumbnail:focus-visible .store-screenshot-expand {
+ opacity: 1;
+}
+
+.store-gallery-modal .modal-content {
+ background: var(--store-surface);
+ border-color: var(--store-border);
+}
+
+.store-gallery-modal .modal-header {
+ border-bottom-color: var(--store-border);
+}
+
+.store-gallery-modal .modal-body {
+ padding: 0;
+}
+
+.store-gallery-carousel {
+ background: #111;
+ outline: none;
+}
+
+.store-gallery-carousel .carousel-item {
+ margin-bottom: 0;
+ margin-top: 0;
+ text-align: center;
+}
+
+.store-gallery-image {
+ display: block;
+ height: min(72vh, 48rem);
+ margin: 0 auto;
+ max-width: 100%;
+ object-fit: contain;
+ width: auto;
+}
+
+.store-gallery-caption {
+ background: var(--store-surface);
+ color: var(--text-col);
+ min-height: 3.5rem;
+ padding: 1rem 5rem;
+}
+
+.store-gallery-carousel .carousel-control-prev,
+.store-gallery-carousel .carousel-control-next {
+ bottom: 3.5rem;
+ width: 4rem;
+}
+
+.store-gallery-carousel .carousel-control-prev-icon,
+.store-gallery-carousel .carousel-control-next-icon {
+ background-color: rgba(0, 0, 0, 0.72);
+ background-size: 55%;
+ border-radius: 50%;
+ height: 2.75rem;
+ width: 2.75rem;
+}
+
+.storefront-empty {
+ background: var(--store-surface);
+ border: 1px solid var(--store-border);
+ border-radius: 1rem;
+ margin-inline: auto;
+ max-width: 40rem;
+ padding: 3rem;
+ text-align: center;
+}
+
+@media (min-width: 992px) {
+ .store-product-card-featured .store-product-summary {
+ display: grid;
+ grid-template-columns: minmax(13rem, 0.52fr) minmax(0, 1.48fr);
+ }
+
+ .store-product-card-featured .store-product-media {
+ align-self: center;
+ max-height: 29rem;
+ width: 100%;
+ }
+
+ .store-product-card-featured .store-product-content {
+ display: grid;
+ gap: 1.25rem;
+ grid-template-columns: minmax(0, 1fr) minmax(13.5rem, 0.62fr);
+ }
+
+ .store-product-card-featured .store-product-details {
+ align-self: center;
+ }
+
+ .store-product-card-featured .store-product-purchase {
+ align-self: stretch;
+ border-left: 1px solid var(--store-border);
+ border-top: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin-top: 0;
+ padding-left: 1.25rem;
+ padding-top: 0;
+ }
+
+ .store-product-card-featured .store-product-prices {
+ grid-template-columns: 1fr;
+ }
+}
+
+@media (min-width: 1200px) {
+ .storefront {
+ padding-top: 7.25rem;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .storefront-assurance {
+ grid-template-columns: 1fr;
+ }
+
+ .storefront-assurance li {
+ justify-content: flex-start;
+ text-align: left;
+ }
+
+ .storefront-assurance li + li {
+ border-left: 0;
+ border-top: 1px solid var(--store-border);
+ }
+
+ .store-product-content {
+ padding: 1.25rem;
+ }
+
+ .store-product-gallery {
+ align-items: stretch;
+ flex-direction: column;
+ padding: 1rem 1.25rem;
+ }
+
+ .store-screenshot-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ }
+
+ .store-screenshot-thumbnail {
+ width: 100%;
+ }
+
+ .store-gallery-caption {
+ padding-inline: 3.5rem;
+ }
+
+ .store-product-prices {
+ grid-template-columns: 1fr;
+ }
+
+ .store-product-actions,
+ .store-product-actions .btn {
+ width: 100%;
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .store-product-card,
+ .store-product-image,
+ .store-screenshot-thumbnail img,
+ .store-screenshot-expand {
+ transition: none;
+ }
+
+ .store-product-card:hover,
+ .store-product-card:hover .store-product-image {
+ transform: none;
+ }
+}
diff --git a/assets/js/store.js b/assets/js/store.js
new file mode 100644
index 00000000..bdaff77c
--- /dev/null
+++ b/assets/js/store.js
@@ -0,0 +1,26 @@
+(() => {
+ 'use strict';
+
+ document.querySelectorAll('.store-gallery-modal').forEach((modalElement) => {
+ const carouselElement = modalElement.querySelector('.store-gallery-carousel');
+ if (!carouselElement) {
+ return;
+ }
+
+ modalElement.addEventListener('show.bs.modal', (event) => {
+ const requestedSlide = Number.parseInt(event.relatedTarget?.dataset.storeSlide ?? '0', 10);
+ const carousel = bootstrap.Carousel.getOrCreateInstance(carouselElement, {
+ interval: false,
+ keyboard: true,
+ touch: true,
+ wrap: true,
+ });
+
+ carousel.to(Number.isNaN(requestedSlide) ? 0 : requestedSlide);
+ });
+
+ modalElement.addEventListener('shown.bs.modal', () => {
+ carouselElement.focus();
+ });
+ });
+})();
diff --git a/store.html b/store.html
new file mode 100644
index 00000000..48a7fde6
--- /dev/null
+++ b/store.html
@@ -0,0 +1,63 @@
+---
+title: Store
+layout: page
+full-width: true
+after-content: []
+css:
+ - /assets/css/store.css
+js:
+ - /assets/js/store.js
+---
+
+{% assign products = site.data.store_products %}
+{% assign featured_product = false %}
+{% if products.size == 1 %}
+ {% assign featured_product = true %}
+{% endif %}
+
+
+
+
+
+
+ LizardByte Store
+
+ Tools built for better streaming
+
+ Purchase LizardByte products and help fund continued development across Sunshine and our other
+ open-source projects.
+
+
+
+
+
+
+ Built by LizardByte
+
+
+
+ Trusted checkout providers
+
+
+
+ Documentation and support
+
+
+
+ {% if products and products.size > 0 %}
+
+ {% for product in products %}
+
+ {% include store-product-card.html product=product featured=featured_product %}
+
+ {% endfor %}
+
+ {% else %}
+
+
+
More products are on the way
+
Check back soon for new LizardByte products.
+
+ {% endif %}
+
+