From 4b602c89b77ce688e82e891cf23777dca7de9300 Mon Sep 17 00:00:00 2001 From: Inoki Date: Mon, 26 Jan 2026 21:55:12 +0100 Subject: [PATCH] Add landing page --- .github/workflows/deploy-landing-page.yml | 49 ++ landing-page/.gitignore | 11 + landing-page/.nojekyll | 0 landing-page/README.md | 104 ++++ landing-page/assets/css/style.css | 619 ++++++++++++++++++++++ landing-page/assets/js/main.js | 140 +++++ landing-page/index.html | 313 +++++++++++ 7 files changed, 1236 insertions(+) create mode 100644 .github/workflows/deploy-landing-page.yml create mode 100644 landing-page/.gitignore create mode 100644 landing-page/.nojekyll create mode 100644 landing-page/README.md create mode 100644 landing-page/assets/css/style.css create mode 100644 landing-page/assets/js/main.js create mode 100644 landing-page/index.html diff --git a/.github/workflows/deploy-landing-page.yml b/.github/workflows/deploy-landing-page.yml new file mode 100644 index 0000000..7b78a25 --- /dev/null +++ b/.github/workflows/deploy-landing-page.yml @@ -0,0 +1,49 @@ +name: Deploy Landing Page to GitHub Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["master", "landing-page"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + # Upload entire landing-page directory + path: './landing-page' + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/landing-page/.gitignore b/landing-page/.gitignore new file mode 100644 index 0000000..08c2968 --- /dev/null +++ b/landing-page/.gitignore @@ -0,0 +1,11 @@ +# Ignore development server files +.DS_Store +*.log +node_modules/ +.vscode/ +.idea/ + +# Ignore any build artifacts if using a build tool +dist/ +build/ +.cache/ diff --git a/landing-page/.nojekyll b/landing-page/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/landing-page/README.md b/landing-page/README.md new file mode 100644 index 0000000..cea6415 --- /dev/null +++ b/landing-page/README.md @@ -0,0 +1,104 @@ +# QEFI Entry Manager Landing Page + +A modern, responsive landing page for the QEFI Entry Manager project, deployed to GitHub Pages. + +## Features + +- Modern, clean design with gradient accents +- Fully responsive layout (mobile, tablet, desktop) +- Download links for all supported platforms +- Screenshot gallery +- Feature showcase +- Build from source instructions +- Smooth scrolling and animations +- Dark code blocks with copy functionality + +## Local Development + +To view the landing page locally: + +1. Simply open `index.html` in a web browser, or +2. Use a local server for better testing: + +```bash +# Python 3 +cd landing-page +python -m http.server 8000 + +# Node.js (if you have http-server installed) +npx http-server landing-page + +# PHP +php -S localhost:8000 -t landing-page +``` + +Then visit `http://localhost:8000` + +## Deployment + +The landing page is automatically deployed to GitHub Pages using the workflow in `.github/workflows/deploy-landing-page.yml`. + +### Manual Deployment + +The workflow runs automatically on pushes to the `master` or `landing-page` branches. You can also trigger it manually from the Actions tab in GitHub. + +### GitHub Pages Configuration + +To enable GitHub Pages: + +1. Go to your repository Settings +2. Navigate to Pages +3. Under "Build and deployment", select "Source" as "GitHub Actions" +4. The workflow will automatically deploy the `landing-page` directory + +## Customization + +### Colors + +Edit the CSS variables in `assets/css/style.css`: + +```css +:root { + --color-primary: #4CAF50; + --color-secondary: #2196F3; + --color-accent: #FF9800; + /* ... more variables */ +} +``` + +### Content + +Edit `index.html` to modify: +- Hero section text +- Feature descriptions +- Download links +- Screenshots +- Build instructions + +### Screenshots + +Place screenshots in the `.github/` directory (referenced with relative paths like `../.github/screenshot.png`). + +## Structure + +``` +landing-page/ +├── index.html # Main HTML file +├── assets/ +│ ├── css/ +│ │ └── style.css # Main stylesheet +│ └── js/ +│ └── main.js # Interactive functionality +└── README.md # This file +``` + +## Browser Support + +- Chrome/Edge (latest) +- Firefox (latest) +- Safari (latest) +- Mobile browsers (iOS Safari, Chrome Mobile) + +## License + +Same as the main project (GPL-3.0) diff --git a/landing-page/assets/css/style.css b/landing-page/assets/css/style.css new file mode 100644 index 0000000..c43b884 --- /dev/null +++ b/landing-page/assets/css/style.css @@ -0,0 +1,619 @@ +:root { + --color-primary: #4CAF50; + --color-primary-dark: #45a049; + --color-secondary: #2196F3; + --color-accent: #FF9800; + --color-dark: #1a1a1a; + --color-dark-light: #2d2d2d; + --color-gray: #666; + --color-gray-light: #999; + --color-light: #f5f5f5; + --color-white: #ffffff; + --color-border: #e0e0e0; + --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.1); + --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1); + --shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.15); + --shadow-xl: 0 20px 40px rgba(0, 0, 0, 0.2); + --transition: all 0.3s ease; + --font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: var(--font-family); + font-size: 16px; + line-height: 1.6; + color: var(--color-dark); + background-color: var(--color-white); +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; +} + +/* Header */ +.header { + background: var(--color-white); + border-bottom: 1px solid var(--color-border); + position: sticky; + top: 0; + z-index: 1000; + box-shadow: var(--shadow-sm); +} + +.nav { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 0; +} + +.nav-logo { + display: flex; + align-items: center; + gap: 0.75rem; + font-weight: 600; + font-size: 1.25rem; + color: var(--color-dark); +} + +.nav-menu { + display: flex; + align-items: center; + gap: 2rem; +} + +.nav-link { + color: var(--color-gray); + text-decoration: none; + font-weight: 500; + transition: var(--transition); +} + +.nav-link:hover { + color: var(--color-primary); +} + +.btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.625rem 1.25rem; + border-radius: 8px; + font-weight: 600; + text-decoration: none; + transition: var(--transition); + cursor: pointer; + border: 2px solid transparent; + font-size: 0.95rem; +} + +.btn-primary { + background: var(--color-primary); + color: var(--color-white); +} + +.btn-primary:hover { + background: var(--color-primary-dark); + transform: translateY(-2px); + box-shadow: var(--shadow-md); +} + +.btn-secondary { + background: var(--color-dark-light); + color: var(--color-white); +} + +.btn-secondary:hover { + background: var(--color-dark); + transform: translateY(-2px); + box-shadow: var(--shadow-md); +} + +.btn-outline { + background: transparent; + color: var(--color-dark); + border-color: var(--color-border); +} + +.btn-outline:hover { + border-color: var(--color-primary); + color: var(--color-primary); +} + +/* Hero Section */ +.hero { + padding: 6rem 0; + background: linear-gradient(135deg, #f5f7fa 0%, #e8ecf1 100%); + text-align: center; +} + +.hero-title { + font-size: 3.5rem; + font-weight: 700; + line-height: 1.2; + margin-bottom: 1.5rem; + color: var(--color-dark); +} + +.gradient-text { + background: linear-gradient(135deg, var(--color-primary), var(--color-secondary)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.hero-description { + font-size: 1.25rem; + color: var(--color-gray); + max-width: 700px; + margin: 0 auto 2rem; + line-height: 1.7; +} + +.hero-actions { + display: flex; + gap: 1rem; + justify-content: center; + margin-bottom: 2rem; +} + +.hero-badges { + display: flex; + gap: 1rem; + justify-content: center; + flex-wrap: wrap; + margin-bottom: 2rem; +} + +.hero-badges img { + height: 20px; +} + +.hero-stats { + display: flex; + gap: 1.5rem; + justify-content: center; + flex-wrap: wrap; +} + +.stat-card { + display: flex; + align-items: center; + gap: 1rem; + padding: 1rem 1.5rem; + background: var(--color-white); + border-radius: 12px; + box-shadow: var(--shadow-md); + text-decoration: none; + color: var(--color-dark); + transition: var(--transition); + border: 2px solid transparent; +} + +.stat-card:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-lg); + border-color: var(--color-primary); +} + +.stat-icon { + color: var(--color-primary); + flex-shrink: 0; +} + +.stat-info { + display: flex; + flex-direction: column; + align-items: flex-start; +} + +.stat-value { + font-size: 1.5rem; + font-weight: 700; + color: var(--color-primary); + line-height: 1.2; +} + +.stat-label { + font-size: 0.875rem; + color: var(--color-gray); + font-weight: 500; +} + +/* Features Section */ +.features { + padding: 5rem 0; + background: var(--color-white); +} + +.section-title { + font-size: 2.5rem; + font-weight: 700; + text-align: center; + margin-bottom: 1rem; + color: var(--color-dark); +} + +.section-subtitle { + font-size: 1.125rem; + color: var(--color-gray); + text-align: center; + margin-bottom: 3rem; +} + +.features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); + gap: 2rem; + margin-top: 3rem; +} + +.feature-card { + background: var(--color-white); + border: 1px solid var(--color-border); + border-radius: 12px; + padding: 2rem; + transition: var(--transition); +} + +.feature-card:hover { + transform: translateY(-4px); + box-shadow: var(--shadow-lg); + border-color: var(--color-primary); +} + +.feature-icon { + width: 64px; + height: 64px; + background: linear-gradient(135deg, var(--color-primary), var(--color-secondary)); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + color: var(--color-white); + margin-bottom: 1.5rem; +} + +.feature-card h3 { + font-size: 1.5rem; + font-weight: 600; + margin-bottom: 0.75rem; + color: var(--color-dark); +} + +.feature-card p { + color: var(--color-gray); + line-height: 1.7; +} + +/* Screenshots Section */ +.screenshots { + padding: 5rem 0; + background: var(--color-light); +} + +.screenshots-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); + gap: 2rem; + margin-top: 3rem; +} + +.screenshot-card { + background: var(--color-white); + border-radius: 12px; + overflow: hidden; + box-shadow: var(--shadow-md); + transition: var(--transition); +} + +.screenshot-card:hover { + transform: translateY(-4px); + box-shadow: var(--shadow-xl); +} + +.screenshot-card img { + width: 100%; + height: auto; + display: block; +} + +.screenshot-caption { + padding: 1rem; + text-align: center; + font-weight: 600; + color: var(--color-gray); + background: var(--color-white); + border-top: 1px solid var(--color-border); +} + +/* Downloads Section */ +.downloads { + padding: 5rem 0; + background: var(--color-white); +} + +.downloads-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + margin-bottom: 3rem; +} + +.download-card { + background: var(--color-white); + border: 2px solid var(--color-border); + border-radius: 12px; + padding: 2.5rem 2rem; + text-align: center; + transition: var(--transition); +} + +.download-card:hover { + border-color: var(--color-primary); + box-shadow: var(--shadow-lg); + transform: translateY(-4px); +} + +.download-icon { + color: var(--color-primary); + margin-bottom: 1.5rem; + display: flex; + justify-content: center; +} + +.download-card h3 { + font-size: 1.75rem; + font-weight: 700; + margin-bottom: 0.5rem; + color: var(--color-dark); +} + +.download-card p { + color: var(--color-gray); + margin-bottom: 1.5rem; +} + +.download-links { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.download-link { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + padding: 0.75rem 1.5rem; + background: var(--color-dark-light); + color: var(--color-white); + text-decoration: none; + border-radius: 8px; + font-weight: 600; + transition: var(--transition); +} + +.download-link:hover { + background: var(--color-primary); + transform: translateX(4px); +} + +.requirements { + background: var(--color-light); + border-radius: 12px; + padding: 2rem; + max-width: 800px; + margin: 0 auto; +} + +.requirements h3 { + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--color-dark); +} + +.requirements-list { + list-style: none; + padding: 0; +} + +.requirements-list li { + padding: 0.75rem 0; + color: var(--color-gray); + border-bottom: 1px solid var(--color-border); +} + +.requirements-list li:last-child { + border-bottom: none; +} + +.requirements-list strong { + color: var(--color-dark); +} + +/* Build Section */ +.build { + padding: 5rem 0; + background: var(--color-light); +} + +.build-instructions { + max-width: 800px; + margin: 0 auto; +} + +.code-block { + background: var(--color-dark); + border-radius: 12px; + overflow: hidden; + box-shadow: var(--shadow-lg); + margin-bottom: 1.5rem; +} + +.code-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 1.5rem; + background: var(--color-dark-light); + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + color: var(--color-white); + font-weight: 600; +} + +.copy-btn { + background: transparent; + border: 1px solid rgba(255, 255, 255, 0.3); + color: var(--color-white); + padding: 0.5rem 1rem; + border-radius: 6px; + cursor: pointer; + font-size: 0.875rem; + transition: var(--transition); +} + +.copy-btn:hover { + background: rgba(255, 255, 255, 0.1); + border-color: var(--color-white); +} + +.code-block pre { + padding: 1.5rem; + overflow-x: auto; +} + +.code-block code { + font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; + font-size: 0.9rem; + line-height: 1.7; + color: var(--color-white); +} + +.build-note { + text-align: center; + color: var(--color-gray); + font-size: 0.95rem; + padding: 1rem; + background: var(--color-white); + border-radius: 8px; + border-left: 4px solid var(--color-accent); +} + +/* Footer */ +.footer { + background: var(--color-dark); + color: var(--color-white); + padding: 3rem 0 1.5rem; +} + +.footer-content { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 2rem; + margin-bottom: 2rem; +} + +.footer-section h4 { + font-size: 1.125rem; + margin-bottom: 1rem; + color: var(--color-white); +} + +.footer-section p { + color: rgba(255, 255, 255, 0.7); + line-height: 1.7; +} + +.footer-section a { + display: block; + color: rgba(255, 255, 255, 0.7); + text-decoration: none; + margin-bottom: 0.5rem; + transition: var(--transition); +} + +.footer-section a:hover { + color: var(--color-primary); +} + +/* Responsive Design */ +@media (max-width: 768px) { + .hero-title { + font-size: 2.5rem; + } + + .hero-description { + font-size: 1rem; + } + + .hero-actions { + flex-direction: column; + align-items: center; + } + + .nav-menu { + gap: 1rem; + } + + .nav-link { + display: none; + } + + .hero-stats { + flex-direction: column; + align-items: center; + gap: 1rem; + } + + .stat-card { + width: 100%; + max-width: 300px; + justify-content: center; + } + + .screenshots-grid { + grid-template-columns: 1fr; + } + + .features-grid { + grid-template-columns: 1fr; + } + + .downloads-grid { + grid-template-columns: 1fr; + } +} + +@media (max-width: 480px) { + .hero { + padding: 4rem 0; + } + + .hero-title { + font-size: 2rem; + } + + .features, + .screenshots, + .downloads, + .build { + padding: 3rem 0; + } + + .section-title { + font-size: 2rem; + } +} diff --git a/landing-page/assets/js/main.js b/landing-page/assets/js/main.js new file mode 100644 index 0000000..95968dd --- /dev/null +++ b/landing-page/assets/js/main.js @@ -0,0 +1,140 @@ +// Smooth scroll for navigation links +document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + e.preventDefault(); + const target = document.querySelector(this.getAttribute('href')); + if (target) { + target.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + } + }); +}); + +// Copy code functionality +const copyButtons = document.querySelectorAll('.copy-btn'); +copyButtons.forEach(button => { + button.addEventListener('click', async () => { + const codeId = button.getAttribute('data-code'); + const codeElement = document.getElementById(codeId); + + if (codeElement) { + try { + await navigator.clipboard.writeText(codeElement.textContent); + button.textContent = 'Copied!'; + button.style.background = 'rgba(76, 175, 80, 0.3)'; + + setTimeout(() => { + button.textContent = 'Copy'; + button.style.background = 'transparent'; + }, 2000); + } catch (err) { + console.error('Failed to copy:', err); + button.textContent = 'Failed'; + setTimeout(() => { + button.textContent = 'Copy'; + }, 2000); + } + } + }); +}); + +// Add animation on scroll +const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' +}; + +const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.style.opacity = '1'; + entry.target.style.transform = 'translateY(0)'; + } + }); +}, observerOptions); + +// Observe all cards +document.querySelectorAll('.feature-card, .download-card, .screenshot-card').forEach(card => { + card.style.opacity = '0'; + card.style.transform = 'translateY(20px)'; + card.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; + observer.observe(card); +}); + +// Mobile menu toggle (if needed in future) +const setupMobileMenu = () => { + const nav = document.querySelector('.nav-menu'); + // Could add hamburger menu here if needed +}; + +// Add active state to navigation based on scroll position +const sections = document.querySelectorAll('section[id]'); +const navLinks = document.querySelectorAll('.nav-link'); + +window.addEventListener('scroll', () => { + let current = ''; + sections.forEach(section => { + const sectionTop = section.offsetTop; + const sectionHeight = section.clientHeight; + if (scrollY >= sectionTop - 200) { + current = section.getAttribute('id'); + } + }); + + navLinks.forEach(link => { + link.style.color = ''; + if (link.getAttribute('href') === `#${current}`) { + link.style.color = 'var(--color-primary)'; + } + }); +}); + +// Add loading animation +window.addEventListener('load', () => { + document.body.style.opacity = '0'; + setTimeout(() => { + document.body.style.transition = 'opacity 0.3s ease'; + document.body.style.opacity = '1'; + }, 100); +}); + +// Fetch GitHub repository stats +async function fetchGitHubStats() { + const repo = 'Inokinoki/QEFIEntryManager'; + const starsElement = document.getElementById('github-stars'); + const forksElement = document.getElementById('github-forks'); + + try { + const response = await fetch(`https://api.github.com/repos/${repo}`); + if (!response.ok) throw new Error('API request failed'); + + const data = await response.json(); + + // Format numbers (e.g., 1234 -> 1.2k) + const formatNumber = (num) => { + if (num >= 1000) { + return (num / 1000).toFixed(1) + 'k'; + } + return num.toString(); + }; + + if (starsElement) { + starsElement.textContent = formatNumber(data.stargazers_count); + } + + if (forksElement) { + forksElement.textContent = formatNumber(data.forks_count); + } + } catch (error) { + console.error('Failed to fetch GitHub stats:', error); + // Set default values on error + if (starsElement) starsElement.textContent = '★'; + if (forksElement) forksElement.textContent = '⑂'; + } +} + +// Fetch stats when page loads +fetchGitHubStats(); + diff --git a/landing-page/index.html b/landing-page/index.html new file mode 100644 index 0000000..ca8eed0 --- /dev/null +++ b/landing-page/index.html @@ -0,0 +1,313 @@ + + + + + + QEFI Entry Manager - EFI Boot Entry Manager + + + + + + + +
+ +
+ +
+
+
+
+

+ Manage Your EFI Boot Entries + with Ease +

+

+ A cross-platform GUI application for managing EFI boot entries and partitions. + Change boot order, add new entries, and manage EFI system partitions visually. +

+ +
+ Linux Build + Windows Build + FreeBSD Build +
+ +
+
+
+ +
+
+

Powerful Features

+
+
+
+ + + + +
+

Boot Order Management

+

Change boot order and manage boot entries with an intuitive drag-and-drop interface.

+
+ +
+
+ + + +
+

Quick Boot Selection

+

Temporarily set the next boot entry to quickly reboot to another OS without changing the permanent boot order.

+
+ +
+
+ + + + +
+

Import & Create Entries

+

Add new boot entries from EFI files or import existing ones from your EFI system partition.

+
+ +
+
+ + + + +
+

Partition Management

+

Mount, unmount, and browse EFI system partitions directly from the application.

+
+ +
+
+ + + + +
+

Quick Reboot

+

Set next boot and immediately reboot with a single click for fast OS switching.

+
+ +
+
+ + + + +
+

Entry Management

+

Enable, disable, or delete boot entries. View detailed properties of each entry.

+
+
+
+
+ +
+
+

Screenshots

+
+
+ Boot Entry Management Interface +
Boot Entry Management
+
+
+ Partition Management Interface +
Partition Management
+
+
+ Create Entry from Partition +
Create Entry from Partition
+
+
+ Reboot Confirmation +
Quick Reboot Confirmation
+
+
+
+
+ +
+
+

Downloads

+

Choose your platform and download the pre-built binaries

+ +
+
+
+ + + +
+

Linux

+

AppImage, Debian packages, and AUR

+ +
+ +
+
+ + + +
+

Windows

+

Pre-built executable installer

+ +
+ +
+
+ + + +
+

FreeBSD

+

Native packages available

+ +
+
+ +
+

Requirements

+
    +
  • Linux/FreeBSD: Run with root/sudo privileges
  • +
  • Windows: Run as Administrator (UAC prompt)
  • +
  • Qt5 or Qt6 runtime libraries
  • +
+
+
+
+ +
+
+

Build from Source

+

For older versions or other architectures (e.g., ARM, aarch64)

+
+
+
+ bash + +
+
git clone --recursive https://github.com/Inokinoki/QEFIEntryManager.git
+cd QEFIEntryManager
+mkdir build && cd build
+cmake ..
+make
+
+

Run the executable as root (*nix) or administrator (Windows)

+
+
+
+
+ + + + + +