main
This commit is contained in:
+511
@@ -0,0 +1,511 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Sulfur Launcher</title>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="icon" href="assets/favicon.png" type="image/png">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- SVG Icon Sprite -->
|
||||
<svg class="icon-sprite" aria-hidden="true">
|
||||
<defs>
|
||||
<symbol id="icon-play" viewBox="0 0 24 24"><path d="M7 4.5v15l13-7.5z" fill="currentColor"/></symbol>
|
||||
<symbol id="icon-minimize" viewBox="0 0 24 24"><line x1="5" y1="12" x2="19" y2="12" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></symbol>
|
||||
<symbol id="icon-maximize" viewBox="0 0 24 24"><rect x="5" y="5" width="14" height="14" rx="1.5" fill="none" stroke="currentColor" stroke-width="1.8"/></symbol>
|
||||
<symbol id="icon-restore" viewBox="0 0 24 24"><rect x="4" y="8" width="11" height="11" rx="1.3" fill="none" stroke="currentColor" stroke-width="1.6"/><rect x="9" y="4" width="11" height="11" rx="1.3" fill="none" stroke="currentColor" stroke-width="1.6"/></symbol>
|
||||
<symbol id="icon-close" viewBox="0 0 24 24"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></symbol>
|
||||
<symbol id="icon-category" viewBox="0 0 24 24"><rect x="4" y="4" width="7" height="7" rx="1.3" fill="currentColor"/><rect x="13" y="4" width="7" height="7" rx="1.3" fill="currentColor"/><rect x="4" y="13" width="7" height="7" rx="1.3" fill="currentColor"/><rect x="13" y="13" width="7" height="7" rx="1.3" fill="currentColor"/></symbol>
|
||||
<symbol id="icon-explore" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5" fill="none" stroke="currentColor" stroke-width="1.6"/><path d="M15.2 8.8l-2 4.4-4.4 2 2-4.4z" fill="currentColor"/></symbol>
|
||||
<symbol id="icon-article" viewBox="0 0 24 24"><rect x="5" y="3" width="14" height="18" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"/><line x1="8" y1="8" x2="16" y2="8" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/><line x1="8" y1="12" x2="16" y2="12" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/><line x1="8" y1="16" x2="13" y2="16" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></symbol>
|
||||
<symbol id="icon-bar-chart" viewBox="0 0 24 24"><rect x="4.5" y="13" width="3.4" height="7" rx="0.6" fill="currentColor"/><rect x="10.3" y="8" width="3.4" height="12" rx="0.6" fill="currentColor"/><rect x="16.1" y="4" width="3.4" height="16" rx="0.6" fill="currentColor"/></symbol>
|
||||
<symbol id="icon-settings" viewBox="0 0 24 24"><line x1="4" y1="7" x2="20" y2="7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="9.5" cy="7" r="2.1" fill="currentColor"/><line x1="4" y1="12.5" x2="20" y2="12.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="15" cy="12.5" r="2.1" fill="currentColor"/><line x1="4" y1="18" x2="20" y2="18" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="8" cy="18" r="2.1" fill="currentColor"/></symbol>
|
||||
<symbol id="icon-edit" viewBox="0 0 24 24"><path d="M4 20h4L18.5 9.5a2.1 2.1 0 0 0-3-3L5 17v3z" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round"/><line x1="13.5" y1="7.5" x2="16.5" y2="10.5" stroke="currentColor" stroke-width="1.6"/></symbol>
|
||||
<symbol id="icon-expand-less" viewBox="0 0 24 24"><path d="M6 15l6-6 6 6" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></symbol>
|
||||
<symbol id="icon-hourglass" viewBox="0 0 24 24"><path d="M6 3h12M6 21h12M7 3c0 5 4 6 5 6s5-1 5-6M7 21c0-5 4-6 5-6s5 1 5 6" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></symbol>
|
||||
|
||||
<!-- New Glyphs for Instances, Files, Collections, PWA, Onboarding -->
|
||||
<symbol id="icon-plus" viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="5" y1="12" x2="19" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></symbol>
|
||||
<symbol id="icon-trash" viewBox="0 0 24 24"><path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></symbol>
|
||||
<symbol id="icon-download" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></symbol>
|
||||
<symbol id="icon-upload" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></symbol>
|
||||
<symbol id="icon-file" viewBox="0 0 24 24"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z" fill="none" stroke="currentColor" stroke-width="1.8"/><polyline points="13 2 13 9 20 9" fill="none" stroke="currentColor" stroke-width="1.8"/></symbol>
|
||||
<symbol id="icon-help" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3M12 17h.01" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></symbol>
|
||||
<symbol id="icon-sparkles" viewBox="0 0 24 24"><path d="M12 3l1.912 5.813a2 2 0 0 0 1.275 1.275L21 12l-5.813 1.912a2 2 0 0 0-1.275 1.275L12 21l-1.912-5.813a2 2 0 0 0-1.275-1.275L3 12l5.813-1.912a2 2 0 0 0 1.275-1.275L12 3z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></symbol>
|
||||
<symbol id="icon-app" viewBox="0 0 24 24"><rect x="4" y="4" width="16" height="16" rx="3" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M9 12l2 2 4-4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></symbol>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<!-- Startup Screen -->
|
||||
<div id="startup-screen">
|
||||
<div class="startup-mark">
|
||||
<div class="sulfur-logo-anim">S</div>
|
||||
</div>
|
||||
<h2>S U L F U R</h2>
|
||||
<div class="startup-status" id="startup-status">Loading instances…</div>
|
||||
</div>
|
||||
|
||||
<!-- Title Bar -->
|
||||
<div id="title-bar">
|
||||
<div class="title-text">S U L F U R</div>
|
||||
<div class="window-controls">
|
||||
<button class="win-btn" id="btn-minimize" title="Minimize" aria-label="Minimize">
|
||||
<svg class="icon icon-sm"><use href="#icon-minimize"></use></svg>
|
||||
</button>
|
||||
<button class="win-btn" id="btn-maximize" title="Maximize" aria-label="Maximize">
|
||||
<svg class="icon icon-sm" id="maximize-icon"><use href="#icon-maximize"></use></svg>
|
||||
</button>
|
||||
<button class="win-btn win-btn-close" id="btn-close" title="Close" aria-label="Close">
|
||||
<svg class="icon icon-sm"><use href="#icon-close"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="app-container">
|
||||
<!-- Sidebar / Dock -->
|
||||
<nav id="sidebar">
|
||||
<div class="sidebar-top">
|
||||
<div class="app-icon" title="Sulfur Launcher">S</div>
|
||||
<button class="nav-item active" data-view="play" title="Play">
|
||||
<svg class="icon"><use href="#icon-play"></use></svg>
|
||||
</button>
|
||||
<button class="nav-item" data-view="library" title="Library">
|
||||
<svg class="icon"><use href="#icon-category"></use></svg>
|
||||
</button>
|
||||
<button class="nav-item" data-view="discover" title="Discover">
|
||||
<svg class="icon"><use href="#icon-explore"></use></svg>
|
||||
</button>
|
||||
<button class="nav-item nav-item-add" id="btn-sidebar-add" title="Add Instance">
|
||||
<svg class="icon"><use href="#icon-plus"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="instance-list" id="sidebar-instances">
|
||||
<!-- Injected via JS -->
|
||||
</div>
|
||||
|
||||
<div class="sidebar-bottom">
|
||||
<button class="nav-item" id="btn-onboarding" title="Onboarding & Guide">
|
||||
<svg class="icon"><use href="#icon-help"></use></svg>
|
||||
</button>
|
||||
<button class="nav-item" id="btn-changelog" title="Changelog">
|
||||
<svg class="icon"><use href="#icon-article"></use></svg>
|
||||
</button>
|
||||
<button class="nav-item" id="btn-stats" title="Statistics & Playtime">
|
||||
<svg class="icon"><use href="#icon-bar-chart"></use></svg>
|
||||
</button>
|
||||
<button class="nav-item" id="btn-settings" title="Settings">
|
||||
<svg class="icon"><use href="#icon-settings"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Main Stage -->
|
||||
<main id="main-stage">
|
||||
|
||||
<!-- PLAY VIEW -->
|
||||
<section class="view active" id="view-play">
|
||||
<div id="background-layer"></div>
|
||||
<div class="vignette-overlay"></div>
|
||||
|
||||
<button class="edit-btn" id="btn-edit" title="Edit instance">
|
||||
<svg class="icon"><use href="#icon-edit"></use></svg>
|
||||
</button>
|
||||
|
||||
<div class="bottom-ui">
|
||||
<div class="metadata">
|
||||
<h1 id="instance-title">Loading…</h1>
|
||||
<div class="tags" id="instance-tags"></div>
|
||||
<p id="instance-playtime" class="playtime">Loading data…</p>
|
||||
</div>
|
||||
|
||||
<button id="play-btn">
|
||||
<svg class="icon"><use href="#icon-play"></use></svg> PLAY
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- LIBRARY VIEW -->
|
||||
<section class="view" id="view-library">
|
||||
<div class="view-header">
|
||||
<div>
|
||||
<h2>Library</h2>
|
||||
<p>Every instance you've set up, in one place.</p>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<button class="btn-primary" id="btn-lib-add">
|
||||
<svg class="icon icon-sm"><use href="#icon-plus"></use></svg> Add Instance
|
||||
</button>
|
||||
<button class="btn-ghost-border" id="btn-lib-export">
|
||||
<svg class="icon icon-sm"><use href="#icon-download"></use></svg> Export Collection
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="library-grid" id="library-grid"><!-- Injected via JS --></div>
|
||||
</section>
|
||||
|
||||
<!-- DISCOVER VIEW -->
|
||||
<section class="view" id="view-discover">
|
||||
<div class="view-header">
|
||||
<div>
|
||||
<h2>Discover</h2>
|
||||
<p>Curated Eaglercraft clients and modpacks ready to install.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="discover-catalog" id="discover-catalog">
|
||||
<!-- Injected via JS -->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- Minimized pill -->
|
||||
<button id="minimized-pill" class="hidden">
|
||||
<svg class="icon icon-sm"><use href="#icon-expand-less"></use></svg>
|
||||
Sulfur — click to restore
|
||||
</button>
|
||||
|
||||
<!-- Close confirmation modal -->
|
||||
<div class="modal-overlay" id="modal-close">
|
||||
<div class="modal">
|
||||
<h3>Close Sulfur?</h3>
|
||||
<p>Any active session or unsaved edits will be saved.</p>
|
||||
<div class="modal-actions">
|
||||
<button class="btn-ghost" data-close-modal="modal-close">Cancel</button>
|
||||
<button class="btn-danger" id="confirm-close">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ADD INSTANCE MODAL -->
|
||||
<div class="modal-overlay" id="modal-add-instance">
|
||||
<div class="modal modal-wide">
|
||||
<h3>Add New Instance</h3>
|
||||
<p class="modal-subtitle">Upload a custom HTML client, link a hosted URL, or select from curated collections.</p>
|
||||
|
||||
<!-- Tabs -->
|
||||
<div class="modal-tabs">
|
||||
<button class="modal-tab active" data-tab="tab-add-local">Local HTML File</button>
|
||||
<button class="modal-tab" data-tab="tab-add-hosted">Hosted URL</button>
|
||||
<button class="modal-tab" data-tab="tab-add-collection">Curated Collection</button>
|
||||
<button class="modal-tab" data-tab="tab-add-import">Import JSON</button>
|
||||
</div>
|
||||
|
||||
<!-- Tab 1: Local HTML File -->
|
||||
<div class="tab-content active" id="tab-add-local">
|
||||
<div class="file-drop-zone" id="file-drop-zone">
|
||||
<svg class="icon icon-xl"><use href="#icon-upload"></use></svg>
|
||||
<div class="drop-title" id="drop-filename">Click or Drag & Drop local .html client file here</div>
|
||||
<div class="drop-sub">File will be stored securely in local browser storage</div>
|
||||
<input type="file" id="local-file-input" accept=".html,.htm" class="file-input-hidden">
|
||||
</div>
|
||||
|
||||
<label class="field-label" for="add-local-title">Instance Name</label>
|
||||
<input type="text" id="add-local-title" class="field-input" placeholder="e.g. My Custom Eagler Client" maxlength="40">
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<label class="field-label" for="add-local-version">Version Tag</label>
|
||||
<input type="text" id="add-local-version" class="field-input" placeholder="1.8.8" value="1.8.8" maxlength="15">
|
||||
</div>
|
||||
<div class="form-col">
|
||||
<label class="field-label" for="add-local-tags">Tags <span class="field-hint">(comma separated)</span></label>
|
||||
<input type="text" id="add-local-tags" class="field-input" placeholder="CUSTOM, LOCAL, EAGLER" value="LOCAL, CUSTOM" maxlength="40">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-actions">
|
||||
<button class="btn-ghost" data-close-modal="modal-add-instance">Cancel</button>
|
||||
<button class="btn-primary" id="confirm-add-local">Add Local Instance</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab 2: Hosted URL -->
|
||||
<div class="tab-content" id="tab-add-hosted">
|
||||
<label class="field-label" for="add-hosted-url">Client Launch URL</label>
|
||||
<input type="url" id="add-hosted-url" class="field-input" placeholder="https://example.com/eaglercraft.html">
|
||||
|
||||
<label class="field-label" for="add-hosted-title">Instance Name</label>
|
||||
<input type="text" id="add-hosted-title" class="field-input" placeholder="e.g. Web Client Hosted" maxlength="40">
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<label class="field-label" for="add-hosted-version">Version</label>
|
||||
<input type="text" id="add-hosted-version" class="field-input" placeholder="1.8.8" value="1.8.8" maxlength="15">
|
||||
</div>
|
||||
<div class="form-col">
|
||||
<label class="field-label" for="add-hosted-tags">Tags</label>
|
||||
<input type="text" id="add-hosted-tags" class="field-input" placeholder="HOSTED, ONLINE" value="HOSTED, ONLINE" maxlength="40">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-actions">
|
||||
<button class="btn-ghost" data-close-modal="modal-add-instance">Cancel</button>
|
||||
<button class="btn-primary" id="confirm-add-hosted">Add Hosted Instance</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab 3: Curated Collection -->
|
||||
<div class="tab-content" id="tab-add-collection">
|
||||
<div class="collection-list" id="preset-collection-list">
|
||||
<!-- Injected via JS -->
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button class="btn-ghost" data-close-modal="modal-add-instance">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab 4: Import JSON -->
|
||||
<div class="tab-content" id="tab-add-import">
|
||||
<div class="file-drop-zone" id="json-drop-zone">
|
||||
<svg class="icon icon-xl"><use href="#icon-file"></use></svg>
|
||||
<div class="drop-title" id="json-filename">Select or drop a sulfur-collection.json file</div>
|
||||
<div class="drop-sub">Bulk import multiple instances and settings</div>
|
||||
<input type="file" id="json-file-input" accept=".json" class="file-input-hidden">
|
||||
</div>
|
||||
|
||||
<div id="json-import-preview" class="import-preview hidden">
|
||||
<div class="preview-title" id="preview-collection-name">Collection Preview</div>
|
||||
<div class="preview-count" id="preview-collection-count">0 instances ready to import</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-actions">
|
||||
<button class="btn-ghost" data-close-modal="modal-add-instance">Cancel</button>
|
||||
<button class="btn-primary" id="confirm-import-json" disabled>Import Collection</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit instance modal -->
|
||||
<div class="modal-overlay" id="modal-edit">
|
||||
<div class="modal">
|
||||
<h3>Edit Instance</h3>
|
||||
<label class="field-label" for="edit-title">Instance Name</label>
|
||||
<input type="text" id="edit-title" class="field-input" maxlength="40">
|
||||
|
||||
<label class="field-label" for="edit-tags">Tags <span class="field-hint">comma separated</span></label>
|
||||
<input type="text" id="edit-tags" class="field-input" maxlength="60">
|
||||
|
||||
<label class="field-label" for="edit-launch-file">Launch Target <span class="field-hint">(Path or URL)</span></label>
|
||||
<input type="text" id="edit-launch-file" class="field-input">
|
||||
|
||||
<div class="modal-actions modal-actions-between">
|
||||
<button class="btn-danger-ghost" id="btn-delete-instance" title="Delete instance">
|
||||
<svg class="icon icon-sm"><use href="#icon-trash"></use></svg> Delete
|
||||
</button>
|
||||
<div style="display:flex;gap:8px;">
|
||||
<button class="btn-ghost" data-close-modal="modal-edit">Cancel</button>
|
||||
<button class="btn-primary" id="confirm-edit">Save Changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Confirm Delete Modal -->
|
||||
<div class="modal-overlay" id="modal-confirm-delete">
|
||||
<div class="modal">
|
||||
<h3>Delete Instance?</h3>
|
||||
<p>Are you sure you want to remove <strong id="delete-instance-name">this instance</strong>? This cannot be undone.</p>
|
||||
<div class="modal-actions">
|
||||
<button class="btn-ghost" data-close-modal="modal-confirm-delete">Cancel</button>
|
||||
<button class="btn-danger" id="confirm-delete-action">Delete Instance</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ONBOARDING WIZARD MODAL -->
|
||||
<div class="modal-overlay" id="modal-onboarding">
|
||||
<div class="modal modal-wide onboarding-modal">
|
||||
<div class="onboarding-stepper">
|
||||
<div class="step-indicator active" data-step="1">1</div>
|
||||
<div class="step-line"></div>
|
||||
<div class="step-indicator" data-step="2">2</div>
|
||||
<div class="step-line"></div>
|
||||
<div class="step-indicator" data-step="3">3</div>
|
||||
<div class="step-line"></div>
|
||||
<div class="step-indicator" data-step="4">4</div>
|
||||
</div>
|
||||
|
||||
<!-- Slide 1: Welcome -->
|
||||
<div class="onboarding-slide active" id="onboarding-slide-1">
|
||||
<div class="onboarding-hero">
|
||||
<div class="onboarding-mark">S</div>
|
||||
<h2>Welcome to Sulfur Launcher</h2>
|
||||
<p>The high-performance web client launcher for Eaglercraft. Manage local HTML clients, connect to hosted instances, and track your playtime all in one sleek place.</p>
|
||||
</div>
|
||||
<div class="onboarding-cards">
|
||||
<div class="onboard-card">
|
||||
<svg class="icon"><use href="#icon-file"></use></svg>
|
||||
<h4>Local Client Linking</h4>
|
||||
<p>Link your own custom Eaglercraft HTML files directly without external hosting.</p>
|
||||
</div>
|
||||
<div class="onboard-card">
|
||||
<svg class="icon"><use href="#icon-bar-chart"></use></svg>
|
||||
<h4>Live Playtime Tracking</h4>
|
||||
<p>Automatic session timer records your hours played across every client.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Slide 2: PWA Install -->
|
||||
<div class="onboarding-slide" id="onboarding-slide-2">
|
||||
<div class="onboarding-hero">
|
||||
<svg class="icon icon-xl" style="color:var(--accent);"><use href="#icon-app"></use></svg>
|
||||
<h2>Install as Desktop App (PWA)</h2>
|
||||
<p>Run Sulfur as a standalone desktop application with zero browser navigation UI and instant offline access.</p>
|
||||
</div>
|
||||
|
||||
<div class="pwa-guide-box">
|
||||
<div class="pwa-step">
|
||||
<span class="pwa-badge">Chrome / Edge</span>
|
||||
<span>Click the <strong>Install App</strong> button below or the install icon in your browser URL bar.</span>
|
||||
</div>
|
||||
<div class="pwa-step">
|
||||
<span class="pwa-badge">Safari / iOS</span>
|
||||
<span>Tap <strong>Share</strong> → <strong>Add to Home Screen</strong>.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn-primary btn-full-width" id="pwa-install-trigger">
|
||||
<svg class="icon icon-sm"><use href="#icon-sparkles"></use></svg> Install Sulfur Desktop App Now
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Slide 3: Instances & Collections -->
|
||||
<div class="onboarding-slide" id="onboarding-slide-3">
|
||||
<div class="onboarding-hero">
|
||||
<svg class="icon icon-xl" style="color:var(--accent);"><use href="#icon-category"></use></svg>
|
||||
<h2>Instances & Local Collections</h2>
|
||||
<p>Easily organize and import your client library.</p>
|
||||
</div>
|
||||
<div class="onboarding-cards">
|
||||
<div class="onboard-card">
|
||||
<svg class="icon"><use href="#icon-plus"></use></svg>
|
||||
<h4>Add & Edit Instances</h4>
|
||||
<p>Customize titles, version tags, background artwork, and client launch URLs anytime.</p>
|
||||
</div>
|
||||
<div class="onboard-card">
|
||||
<svg class="icon"><use href="#icon-download"></use></svg>
|
||||
<h4>Import/Export Collections</h4>
|
||||
<p>Share your full setup via <code>sulfur-collection.json</code> format.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Slide 4: Ready -->
|
||||
<div class="onboarding-slide" id="onboarding-slide-4">
|
||||
<div class="onboarding-hero">
|
||||
<div class="onboarding-mark" style="background:var(--success);color:#0a0a0a;">✓</div>
|
||||
<h2>You're All Set!</h2>
|
||||
<p>Your launcher is ready to play. Launch Sulfur Client or add your custom builds.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Controls -->
|
||||
<div class="modal-actions modal-actions-between" style="margin-top:28px;">
|
||||
<button class="btn-ghost" id="onboarding-prev" style="visibility:hidden;">Back</button>
|
||||
<div style="display:flex;gap:10px;">
|
||||
<button class="btn-ghost" id="onboarding-skip">Skip</button>
|
||||
<button class="btn-primary" id="onboarding-next">Next →</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- STATS MODAL -->
|
||||
<div class="modal-overlay" id="modal-stats">
|
||||
<div class="modal modal-wide">
|
||||
<h3>Launcher Statistics & Playtime</h3>
|
||||
<p class="modal-subtitle">Detailed breakdown of your overall gaming activity in Sulfur Launcher.</p>
|
||||
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="stat-total-playtime">0h 0m</div>
|
||||
<div class="stat-label">Total Time Played</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="stat-total-launches">0</div>
|
||||
<div class="stat-label">Total Game Launches</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="stat-most-played">—</div>
|
||||
<div class="stat-label">Most Played Client</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="stat-instance-count">0</div>
|
||||
<div class="stat-label">Installed Instances</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-title-sm">Instance Activity Breakdown</div>
|
||||
<div class="instance-activity-list" id="stats-instance-list">
|
||||
<!-- Injected via JS -->
|
||||
</div>
|
||||
|
||||
<div class="modal-actions">
|
||||
<button class="btn-primary" data-close-modal="modal-stats">Done</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings modal -->
|
||||
<div class="modal-overlay" id="modal-settings">
|
||||
<div class="modal">
|
||||
<h3>Launcher Settings</h3>
|
||||
<div class="setting-row">
|
||||
<div>
|
||||
<div class="setting-title">Reduce Motion</div>
|
||||
<div class="setting-desc">Skip startup radial wipe and transitions</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="setting-reduce-motion">
|
||||
<span class="switch-track"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div>
|
||||
<div class="setting-title">Compact Sidebar</div>
|
||||
<div class="setting-desc">Narrower dock for maximum stage area</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="setting-compact-sidebar">
|
||||
<span class="switch-track"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div>
|
||||
<div class="setting-title">Export Collection</div>
|
||||
<div class="setting-desc">Backup your instances to JSON</div>
|
||||
</div>
|
||||
<button class="btn-ghost-border" id="setting-export-btn">Export JSON</button>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div>
|
||||
<div class="setting-title">Replay Onboarding</div>
|
||||
<div class="setting-desc">View the welcome guide and PWA install steps</div>
|
||||
</div>
|
||||
<button class="btn-ghost-border" id="setting-onboarding-btn">Open Guide</button>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button class="btn-primary" data-close-modal="modal-settings">Done</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="toast-container"></div>
|
||||
|
||||
<script src="js/launcher.js"></script>
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('sw.js').catch(() => {});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user