diff --git a/docs/assets/favicon.png b/docs/assets/favicon.png index 5e33185bc..41f55013c 100644 Binary files a/docs/assets/favicon.png and b/docs/assets/favicon.png differ diff --git a/docs/assets/favicon.svg b/docs/assets/favicon.svg new file mode 100644 index 000000000..5cf542cbf --- /dev/null +++ b/docs/assets/favicon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/docs/assets/images/partners/axisflying.png b/docs/assets/images/partners/axisflying.png new file mode 100644 index 000000000..f790eb16d Binary files /dev/null and b/docs/assets/images/partners/axisflying.png differ diff --git a/docs/assets/images/partners/bayckrc.png b/docs/assets/images/partners/bayckrc.png new file mode 100644 index 000000000..4ce7cfd78 Binary files /dev/null and b/docs/assets/images/partners/bayckrc.png differ diff --git a/docs/assets/images/partners/betafpv.png b/docs/assets/images/partners/betafpv.png new file mode 100644 index 000000000..1d885e97d Binary files /dev/null and b/docs/assets/images/partners/betafpv.png differ diff --git a/docs/assets/images/partners/brotherhobby.png b/docs/assets/images/partners/brotherhobby.png new file mode 100644 index 000000000..7fea55c9d Binary files /dev/null and b/docs/assets/images/partners/brotherhobby.png differ diff --git a/docs/assets/images/partners/corewing.png b/docs/assets/images/partners/corewing.png new file mode 100644 index 000000000..157377163 Binary files /dev/null and b/docs/assets/images/partners/corewing.png differ diff --git a/docs/assets/images/partners/dakefpv.png b/docs/assets/images/partners/dakefpv.png new file mode 100644 index 000000000..82729a0e1 Binary files /dev/null and b/docs/assets/images/partners/dakefpv.png differ diff --git a/docs/assets/images/partners/emax.png b/docs/assets/images/partners/emax.png new file mode 100644 index 000000000..22702130e Binary files /dev/null and b/docs/assets/images/partners/emax.png differ diff --git a/docs/assets/images/partners/flysky.png b/docs/assets/images/partners/flysky.png new file mode 100644 index 000000000..693d39288 Binary files /dev/null and b/docs/assets/images/partners/flysky.png differ diff --git a/docs/assets/images/partners/flywoo.png b/docs/assets/images/partners/flywoo.png new file mode 100644 index 000000000..9c101ecda Binary files /dev/null and b/docs/assets/images/partners/flywoo.png differ diff --git a/docs/assets/images/partners/foxeer.png b/docs/assets/images/partners/foxeer.png new file mode 100644 index 000000000..7c33a2db8 Binary files /dev/null and b/docs/assets/images/partners/foxeer.png differ diff --git a/docs/assets/images/partners/geprc.png b/docs/assets/images/partners/geprc.png new file mode 100644 index 000000000..7ad54e05d Binary files /dev/null and b/docs/assets/images/partners/geprc.png differ diff --git a/docs/assets/images/partners/happymodel.png b/docs/assets/images/partners/happymodel.png new file mode 100644 index 000000000..4f7cbb69f Binary files /dev/null and b/docs/assets/images/partners/happymodel.png differ diff --git a/docs/assets/images/partners/hdzero.png b/docs/assets/images/partners/hdzero.png new file mode 100644 index 000000000..2e017623b Binary files /dev/null and b/docs/assets/images/partners/hdzero.png differ diff --git a/docs/assets/images/partners/helloradio.png b/docs/assets/images/partners/helloradio.png new file mode 100644 index 000000000..0b5fc013b Binary files /dev/null and b/docs/assets/images/partners/helloradio.png differ diff --git a/docs/assets/images/partners/hglrc.png b/docs/assets/images/partners/hglrc.png new file mode 100644 index 000000000..311ad4ac1 Binary files /dev/null and b/docs/assets/images/partners/hglrc.png differ diff --git a/docs/assets/images/partners/holybro.png b/docs/assets/images/partners/holybro.png new file mode 100644 index 000000000..35867a326 Binary files /dev/null and b/docs/assets/images/partners/holybro.png differ diff --git a/docs/assets/images/partners/jhemcu.png b/docs/assets/images/partners/jhemcu.png new file mode 100644 index 000000000..bb01fd135 Binary files /dev/null and b/docs/assets/images/partners/jhemcu.png differ diff --git a/docs/assets/images/partners/jumper.png b/docs/assets/images/partners/jumper.png new file mode 100644 index 000000000..ed5736e64 Binary files /dev/null and b/docs/assets/images/partners/jumper.png differ diff --git a/docs/assets/images/partners/newbeedrone.png b/docs/assets/images/partners/newbeedrone.png new file mode 100644 index 000000000..84f272f4b Binary files /dev/null and b/docs/assets/images/partners/newbeedrone.png differ diff --git a/docs/assets/images/partners/omphobby.png b/docs/assets/images/partners/omphobby.png new file mode 100644 index 000000000..02b6b6d45 Binary files /dev/null and b/docs/assets/images/partners/omphobby.png differ diff --git a/docs/assets/images/partners/radiomaster.png b/docs/assets/images/partners/radiomaster.png new file mode 100644 index 000000000..3e794aff4 Binary files /dev/null and b/docs/assets/images/partners/radiomaster.png differ diff --git a/docs/assets/images/partners/sequre.png b/docs/assets/images/partners/sequre.png new file mode 100644 index 000000000..6059bdbea Binary files /dev/null and b/docs/assets/images/partners/sequre.png differ diff --git a/docs/assets/images/partners/skystars.png b/docs/assets/images/partners/skystars.png new file mode 100644 index 000000000..b3a4e5644 Binary files /dev/null and b/docs/assets/images/partners/skystars.png differ diff --git a/docs/assets/images/partners/speedybee.png b/docs/assets/images/partners/speedybee.png new file mode 100644 index 000000000..59e8717ea Binary files /dev/null and b/docs/assets/images/partners/speedybee.png differ diff --git a/docs/assets/stylesheets/home.css b/docs/assets/stylesheets/home.css new file mode 100644 index 000000000..1d1e66459 --- /dev/null +++ b/docs/assets/stylesheets/home.css @@ -0,0 +1,487 @@ +/* + * ExpressLRS Homepage Sections + * All classes prefixed with .mdx- to match existing convention + */ + +/* ========================================================================== + Section Base Styles + ========================================================================== */ + +.mdx-features, +.mdx-partners, +.mdx-community, +.mdx-support, +.mdx-news { + padding: 4rem 0; +} + +.mdx-features > .md-grid, +.mdx-partners > .md-grid, +.mdx-community > .md-grid, +.mdx-support > .md-grid, +.mdx-news > .md-grid { + padding-left: 0.8rem; + padding-right: 0.8rem; +} + +@media screen and (max-width: 29.9375em) { + .mdx-features, + .mdx-partners, + .mdx-community, + .mdx-support, + .mdx-news { + padding: 2.5rem 0; + } +} + +/* ========================================================================== + Section 1: Why ExpressLRS — Feature Grid + ========================================================================== */ + +.mdx-features { + background-color: var(--md-default-bg-color); + margin-top: -2rem !important; + padding-top: 0 !important; +} + +.mdx-features__heading { + text-align: center; + margin-top: 0 !important; + margin-bottom: 2.5rem; + font-weight: 700; +} + +.mdx-features__grid { + display: grid; + grid-template-columns: 1fr; + gap: 1.5rem; +} + +@media screen and (min-width: 30em) { + .mdx-features__grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media screen and (min-width: 60em) { + .mdx-features__grid { + grid-template-columns: repeat(3, 1fr); + } +} + +.mdx-features__item { + padding: 1.5rem; + border-radius: 0.5rem; + border: 1px solid var(--md-default-fg-color--lightest); + transition: box-shadow 0.2s, border-color 0.2s; +} + +.mdx-features__item:hover { + border-color: var(--md-accent-fg-color); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08); +} + +.mdx-features__icon { + width: 2.5rem; + height: 2.5rem; + margin-bottom: 0.75rem; + color: var(--md-primary-fg-color); +} + +.mdx-features__icon svg { + width: 100%; + height: 100%; + fill: currentColor; +} + +.mdx-features__item h3 { + margin: 0 0 0.5rem; + font-weight: 600; +} + +.mdx-features__item p { + margin: 0; + color: var(--md-default-fg-color--light); + font-size: 0.8rem; +} + +/* ========================================================================== + Section 2: Trusted by Leading Brands — Partner Logo Grid + ========================================================================== */ + +.mdx-partners { + background-color: var(--md-footer-bg-color, #1e1e1e); + color: var(--md-footer-fg-color, #fff); +} + +.mdx-partners__heading { + text-align: center; + margin-bottom: 0.5rem; + font-weight: 700; + color: var(--md-footer-fg-color, #fff); +} + +.mdx-partners__subheading { + text-align: center; + margin-bottom: 2.5rem; + opacity: 0.7; + font-size: 0.85rem; +} + +.mdx-partners__grid { + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; + gap: 1.5rem 2rem; + margin-bottom: 2rem; + max-width: 56rem; + margin-left: auto; + margin-right: auto; +} + +.mdx-partners__logo { + height: 2rem; + width: 7rem; + object-fit: contain; + object-position: center; + opacity: 0.5; + filter: brightness(0) invert(1); + mix-blend-mode: screen; + transition: opacity 0.2s; +} + +.mdx-partners__logo:hover { + opacity: 0.9; +} + +.mdx-partners__logo--md { + height: 1.7rem !important; +} + +.mdx-partners__logo--sm { + height: 1.5rem !important; +} + +.mdx-partners__logo--xs { + height: 1.2rem !important; +} + +.mdx-partners__more { + text-align: center; + opacity: 0.5; + font-size: 0.9rem; + font-style: italic; + margin-top: 1.5rem; + margin-bottom: 0; +} + +.mdx-partners__cta { + display: block; + text-align: center; + margin-top: 1.5rem; +} + +.mdx-partners__cta a { + color: var(--md-accent-fg-color); + font-weight: 600; + font-size: 0.85rem; + text-decoration: none; +} + +.mdx-partners__cta a:hover { + text-decoration: underline; +} + +/* ========================================================================== + Section 3: Join the Community + ========================================================================== */ + +.mdx-community { + background-color: var(--md-default-bg-color); +} + +.mdx-community__heading { + text-align: center; + font-weight: 700; + margin-bottom: 0.5rem; +} + +.mdx-community__subheading { + text-align: center; + color: var(--md-default-fg-color--light); + margin-bottom: 2.5rem; + max-width: 40rem; + margin-left: auto; + margin-right: auto; + font-size: 0.9rem; +} + +.mdx-community__grid { + display: grid; + grid-template-columns: 1fr; + gap: 1.5rem; +} + +@media screen and (min-width: 60em) { + .mdx-community__grid { + grid-template-columns: repeat(2, 1fr); + max-width: 50rem; + margin-left: auto; + margin-right: auto; + } +} + +.mdx-community__card { + display: block; + padding: 2rem; + border-radius: 0.5rem; + border: 1px solid var(--md-default-fg-color--lightest); + text-decoration: none; + color: var(--md-default-fg-color); + transition: transform 0.2s, box-shadow 0.2s; +} + +.mdx-community__card:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); +} + +.mdx-community__card-icon { + width: 3rem; + height: 3rem; + margin-bottom: 1rem; +} + +.mdx-community__card--discord .mdx-community__card-icon { + color: #5865F2; +} + +.mdx-community__card--facebook .mdx-community__card-icon { + color: #1877F2; +} + +.mdx-community__card--github .mdx-community__card-icon { + color: var(--md-default-fg-color); +} + +.mdx-community__card-icon svg { + width: 100%; + height: 100%; + fill: currentColor; +} + +.mdx-community__card h3 { + margin: 0 0 0.5rem; +} + +.mdx-community__card p { + color: var(--md-default-fg-color--light); + font-size: 0.8rem; + margin: 0 0 1rem; +} + +.mdx-community__cta { + font-weight: 600; + color: var(--md-accent-fg-color); + font-size: 0.8rem; +} + +/* ========================================================================== + Section 4: Support the Project + ========================================================================== */ + +.mdx-support { + background-color: var(--md-footer-bg-color, #1e1e1e); + color: var(--md-footer-fg-color, #fff); +} + +.mdx-support__heading { + font-weight: 700; + margin-top: 0 !important; + margin-bottom: 1rem !important; + color: var(--md-footer-fg-color, #fff); +} + +.mdx-support__inner { + display: grid; + grid-template-columns: 1fr; + gap: 2rem; + align-items: center; +} + +@media screen and (min-width: 60em) { + .mdx-support__inner { + grid-template-columns: 1fr 1fr; + gap: 4rem; + } +} + +.mdx-support__text { + font-size: 1rem; + opacity: 0.85; + line-height: 1.7; + max-width: 28rem; +} + +.mdx-support__text p { + margin: 0; +} + +.mdx-support__cards { + display: grid; + grid-template-columns: 1fr; + gap: 1.5rem; +} + +@media screen and (min-width: 30em) { + .mdx-support__cards { + grid-template-columns: repeat(2, 1fr); + } +} + +.mdx-support__card { + background-color: rgba(255, 255, 255, 0.05); + border-radius: 0.5rem; + padding: 2rem 1.5rem; + text-align: center; + border: 1px solid rgba(255, 255, 255, 0.12); + transition: border-color 0.2s, background-color 0.2s; +} + +.mdx-support__card:hover { + border-color: rgba(255, 255, 255, 0.25); + background-color: rgba(255, 255, 255, 0.08); +} + +.mdx-support__card-logo { + width: 2.5rem; + height: 2.5rem; + margin: 0 auto 0.75rem; +} + +.mdx-support__card-logo svg { + width: 100%; + height: 100%; + fill: currentColor; +} + +.mdx-support__card-name { + font-weight: 700; + font-size: 1.1rem; + margin-bottom: 0.75rem; +} + +.mdx-support__card-desc { + font-size: 0.8rem; + opacity: 0.6; + margin-bottom: 1.5rem; + line-height: 1.5; +} + +.mdx-support__card-btn { + display: inline-block; + width: 100%; + padding: 0.7rem 1.5rem; + background-color: var(--md-accent-fg-color); + color: #1e1e1e !important; + border-radius: 0.25rem; + text-decoration: none; + font-weight: 700; + font-size: 0.85rem; + text-transform: uppercase; + letter-spacing: 0.05em; + transition: opacity 0.2s; + box-sizing: border-box; +} + +.mdx-support__card-btn:hover { + opacity: 0.85; +} + +/* ========================================================================== + Section 5: Latest News + ========================================================================== */ + +.mdx-news { + background-color: var(--md-default-bg-color); +} + +.mdx-news__heading { + text-align: center; + font-weight: 700; + margin-bottom: 2.5rem; +} + +.mdx-news__list { + display: grid; + grid-template-columns: 1fr; + gap: 1.5rem; + max-width: 50rem; + margin: 0 auto; +} + +@media screen and (min-width: 60em) { + .mdx-news__list { + grid-template-columns: repeat(3, 1fr); + max-width: none; + } +} + +.mdx-news__item { + display: block; + padding: 1.5rem; + border-radius: 0.5rem; + border: 1px solid var(--md-default-fg-color--lightest); + text-decoration: none; + color: var(--md-default-fg-color); + transition: transform 0.2s, box-shadow 0.2s; +} + +.mdx-news__item:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); +} + +.mdx-news__date { + font-size: 0.75rem; + color: var(--md-default-fg-color--light); + margin-bottom: 0.5rem; +} + +.mdx-news__category { + display: inline-block; + margin-top: 0.75rem; + font-size: 0.65rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + padding: 0.15rem 0.5rem; + border-radius: 1rem; + background-color: var(--md-primary-fg-color); + color: #fff; +} + +.mdx-news__title { + font-weight: 600; + font-size: 0.9rem; + line-height: 1.4; + margin: 0; +} + +.mdx-news__cta { + display: block; + text-align: center; + margin-top: 2rem; +} + +.mdx-news__cta a { + color: var(--md-accent-fg-color); + font-weight: 600; + font-size: 0.85rem; + text-decoration: none; +} + +.mdx-news__cta a:hover { + text-decoration: underline; +} diff --git a/docs/assets/stylesheets/main.css b/docs/assets/stylesheets/main.css index 128d3da60..7f519a239 100644 --- a/docs/assets/stylesheets/main.css +++ b/docs/assets/stylesheets/main.css @@ -209,4 +209,4 @@ kbd { .md-typeset figure img { display: inline; -} +} \ No newline at end of file diff --git a/docs/partners-program.md b/docs/partners-program.md index e08d02327..e45bb9fb5 100644 --- a/docs/partners-program.md +++ b/docs/partners-program.md @@ -4,7 +4,7 @@ hide: - navigation --- -# Partners program +# Partners Program Interested in developing ExpressLRS-compatible hardware or collaborating with our project? diff --git a/mkdocs-material b/mkdocs-material new file mode 160000 index 000000000..4fde47572 --- /dev/null +++ b/mkdocs-material @@ -0,0 +1 @@ +Subproject commit 4fde47572c68f2c32f7cd307c13bc6788483b1ec diff --git a/mkdocs.yml b/mkdocs.yml index 4ee28a4a3..11686a25b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,9 +2,9 @@ site_name: ExpressLRS site_url: https://www.expresslrs.org/ site_author: ExpressLRS site_description: >- - ExpressLRS aims to provide the best completely open, high refresh radio - control link while maintaining a maximum achievable range at that rate with - low latency. Vast support of hardware in both 900 MHz and 2.4 GHz frequencies. + ExpressLRS is a fully open radio control link built for maximum + range, speed, and data throughput. Wide hardware support across both + 900 MHz and 2.4 GHz frequencies. # Repository repo_name: ExpressLRS/ExpressLRS @@ -63,6 +63,9 @@ theme: logo: assets/images/logotype.svg # Plugins +hooks: + - overrides/hooks/blog_posts.py + plugins: - blog: enabled: true @@ -98,6 +101,7 @@ plugins: extra_css: - assets/stylesheets/main.css - assets/stylesheets/colors.css + - assets/stylesheets/home.css # Analytics extra: diff --git a/overrides/home.html b/overrides/home.html index f98d08ec7..db6425a89 100644 --- a/overrides/home.html +++ b/overrides/home.html @@ -83,6 +83,186 @@

High Performance Open Source Radio Control Link

+ + +
+
+

Why ExpressLRS

+
+ +
+
+ {% include ".icons/material/flash.svg" %} +
+

Blazing Fast

+

Up to 1000Hz packet rate. LoRa, FLRC, and FSK modes let you optimize for speed, range, or throughput for any mission.

+
+ +
+
+ {% include ".icons/material/map-marker-distance.svg" %} +
+

Extreme Range

+

Go as far as you dare. Rock-solid control on both 900MHz and 2.4GHz - you decide when to turn back, not your radio.

+
+ +
+
+ {% include ".icons/material/all-inclusive.svg" %} +
+

Built for Everything

+

From tiny whoops to long-range wings. Planes, helis, cars, boats - reliable control for any craft, any mission.

+
+ +
+
+ {% include ".icons/material/puzzle.svg" %} +
+

Vast Hardware Ecosystem

+

From 0.46g nano receivers to dual-band TX modules. Over 50 manufacturers and hundreds of devices. Choose the gear that fits your build.

+
+ +
+
+ {% include ".icons/material/satellite-uplink.svg" %} +
+

Full Telemetry

+

Bidirectional MAVLink over a single link. Mission planning, real-time telemetry, and ground station connectivity - everything you need for autonomous and long-range operations.

+
+ +
+
+ {% include ".icons/material/open-source-initiative.svg" %} +
+

Open Source

+

Fully open source and built by a global community of pilots and developers. Anyone can contribute, audit, and improve the code that controls their craft.

+
+ +
+
+
+ + +
+
+

You're in Good Company

+

Over 50 manufacturers. Hundreds of officially supported devices.

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

...and many more

+ +
+
+ + +
+
+

Join the Community

+

Thousands of pilots and developers are already here.

+ +
+
+ + +
+
+
+
+

Support the Project

+

Want to get involved? Whether you write code, improve documentation, report bugs, or back the project - every contribution matters.

+
+
+ +
+ +
GitHub
+
Help build the future of RC. Code, documentation, testing - every contribution matters.
+ Contribute +
+ +
+ +
OpenCollective
+
Support ExpressLRS development with a one-time or recurring contribution.
+ Support +
+ +
+
+
+
+ + +{% if recent_posts %} +
+
+

Latest News

+ + +
+
+{% endif %} + {% endblock %} diff --git a/overrides/hooks/blog_posts.py b/overrides/hooks/blog_posts.py new file mode 100644 index 000000000..b27fe7806 --- /dev/null +++ b/overrides/hooks/blog_posts.py @@ -0,0 +1,63 @@ +"""Hook to inject recent blog posts into the homepage context.""" + +import os +import yaml +import datetime + + +def on_page_context(context, page, config, nav): + """Inject recent blog posts into the homepage template context.""" + if page.file.src_path != "index.md": + return context + + posts_dir = os.path.join(config["docs_dir"], "blog", "posts") + if not os.path.isdir(posts_dir): + return context + + posts = [] + for filename in os.listdir(posts_dir): + if not filename.endswith(".md"): + continue + filepath = os.path.join(posts_dir, filename) + with open(filepath, "r", encoding="utf-8") as f: + content = f.read() + + # Parse front matter + if not content.startswith("---"): + continue + end = content.index("---", 3) + front_matter = yaml.safe_load(content[3:end]) + + title = front_matter.get("title", "Untitled") + post_date = front_matter.get("date") + slug = front_matter.get("slug", filename.replace(".md", "")) + + # Normalize date to datetime.date + if isinstance(post_date, str): + post_date = datetime.datetime.strptime(post_date, "%Y-%m-%d").date() + elif isinstance(post_date, datetime.datetime): + post_date = post_date.date() + elif isinstance(post_date, datetime.date): + pass # already a date + else: + continue + + # Build URL matching mkdocs-material blog plugin URL pattern + date_path = post_date.strftime("%Y/%m/%d") + url = f"blog/{date_path}/{slug}/" + + categories = front_matter.get("categories", []) + + posts.append({ + "title": title, + "date": post_date, + "date_formatted": post_date.strftime("%B %d, %Y"), + "url": url, + "category": categories[0] if categories else None, + }) + + # Sort by date descending, take latest 3 + posts.sort(key=lambda p: p["date"], reverse=True) + context["recent_posts"] = posts[:3] + + return context diff --git a/overrides/main.html b/overrides/main.html index cc2667d6e..fad9ca696 100644 --- a/overrides/main.html +++ b/overrides/main.html @@ -2,10 +2,6 @@ {% block extrahead %} {{ super() }} -