Up to Bloom v0.23

This commit is contained in:
Esteban
2026-07-04 23:18:28 +02:00
parent d58f2195f5
commit 487fdb9f75
13 changed files with 211 additions and 1 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ APP_KEY=
APP_DEBUG=false
APP_URL=http://localhost:7081
APP_LOCALE=fr
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=fr_FR
+7
View File
@@ -27,6 +27,13 @@ return [
'feature_reader_text' => 'BloomFeed ruft die Originalseite ab, extrahiert den Hauptinhalt und zeigt ihn sauber an — Schluss mit zehn offenen Tabs.',
'feature_home_title' => 'Bei dir, für dich',
'feature_home_text' => 'Eine BloomFeed-Instanz = ein Besitzer. Keine öffentlichen Registrierungen standardmäßig, kein Tracking, dein Server, deine Daten.',
'screenshots_title' => 'So siehts aus',
'screenshots_lede' => 'Ein kurzer Blick auf das Dashboard, den integrierten Reader, den Feed-Katalog und den Benachrichtigungsbildschirm.',
'screenshot_dashboard' => 'Dashboard',
'screenshot_dark' => 'Dunkelmodus',
'screenshot_reader' => 'Integrierter Reader',
'screenshot_catalog' => 'Feed-Katalog mit einem Klick',
'screenshot_notifiers' => 'Discord- und Webhook-Benachrichtigungen',
// Authentifizierung
'login_title' => 'Anmelden',
+7
View File
@@ -27,6 +27,13 @@ return [
'feature_reader_text' => 'BloomFeed fetches the source page, extracts the main content and displays it cleanly — no more juggling ten tabs.',
'feature_home_title' => 'Your home, your rules',
'feature_home_text' => 'One BloomFeed instance = one owner. No public sign-ups by default, no tracking, your server, your data.',
'screenshots_title' => 'See it in action',
'screenshots_lede' => 'A quick look at the dashboard, the built-in reader, the feed catalog and the notifiers screen.',
'screenshot_dashboard' => 'Dashboard',
'screenshot_dark' => 'Dark mode',
'screenshot_reader' => 'Built-in reader',
'screenshot_catalog' => 'One-click feed catalog',
'screenshot_notifiers' => 'Discord & webhook notifiers',
// Authentication
'login_title' => 'Log in',
+7
View File
@@ -27,6 +27,13 @@ return [
'feature_reader_text' => 'BloomFeed recupera la página original, extrae el contenido principal y lo muestra limpiamente — se acabó abrir diez pestañas.',
'feature_home_title' => 'En tu casa, para ti',
'feature_home_text' => 'Una instancia de BloomFeed = un propietario. Sin registros públicos por defecto, sin rastreo, tu servidor, tus datos.',
'screenshots_title' => 'En imágenes',
'screenshots_lede' => 'Un vistazo rápido al panel, al lector integrado, al catálogo de fuentes y a la pantalla de notificadores.',
'screenshot_dashboard' => 'Panel',
'screenshot_dark' => 'Modo oscuro',
'screenshot_reader' => 'Lector integrado',
'screenshot_catalog' => 'Catálogo de fuentes en un clic',
'screenshot_notifiers' => 'Notificadores de Discord y webhook',
// Autenticación
'login_title' => 'Iniciar sesión',
+7
View File
@@ -27,6 +27,13 @@ return [
'feature_reader_text' => "BloomFeed récupère la page source, en extrait le contenu principal et l'affiche proprement — plus besoin d'ouvrir dix onglets.",
'feature_home_title' => 'Chez vous, pour vous',
'feature_home_text' => "Une instance BloomFeed = un propriétaire. Pas d'inscriptions publiques par défaut, pas de tracking, votre serveur, vos données.",
'screenshots_title' => 'En images',
'screenshots_lede' => 'Un aperçu rapide du tableau de bord, du lecteur intégré, du catalogue de flux et de l’écran des notifieurs.',
'screenshot_dashboard' => 'Tableau de bord',
'screenshot_dark' => 'Mode sombre',
'screenshot_reader' => 'Lecteur intégré',
'screenshot_catalog' => 'Catalogue de flux en un clic',
'screenshot_notifiers' => 'Notifieurs Discord et webhook',
// Authentification
'login_title' => 'Connexion',
+93
View File
@@ -382,6 +382,99 @@ h1, h2, h3 {
margin: 0;
}
/* ---------- Screenshots (landing page) ---------- */
.screenshots-section {
max-width: 980px;
margin: 0 auto;
padding: 0 var(--space-5) var(--space-8);
}
.screenshots-header {
text-align: center;
margin-bottom: var(--space-6);
}
.screenshots-header h2 {
font-size: var(--font-2xl);
margin-bottom: var(--space-2);
}
.screenshots-header p {
color: var(--text-muted);
font-size: var(--font-md);
max-width: 620px;
margin: 0 auto;
}
.screenshot-gallery {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-4);
animation: fade-up 600ms var(--ease-out) both;
}
.screenshot-main {
width: 100%;
aspect-ratio: 16 / 10;
border-radius: var(--radius-lg);
overflow: hidden;
border: 1px solid var(--border);
box-shadow: var(--shadow-lg);
background: var(--surface);
}
.screenshot-main img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.screenshot-thumbs {
display: flex;
justify-content: center;
gap: var(--space-2);
flex-wrap: wrap;
}
.screenshot-thumb {
width: 84px;
height: 56px;
padding: 0;
border-radius: var(--radius-sm);
overflow: hidden;
border: 2px solid var(--border);
background: none;
cursor: pointer;
opacity: 0.55;
transition: opacity var(--t-fast), border-color var(--t-fast), transform var(--t-fast);
}
.screenshot-thumb img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.screenshot-thumb:hover {
opacity: 0.85;
transform: translateY(-2px);
}
.screenshot-thumb.active {
opacity: 1;
border-color: var(--accent);
}
.screenshot-caption {
color: var(--text-muted);
font-size: var(--font-sm);
margin: 0;
}
/* ---------- Page docs / self-hosting ---------- */
.docs-list {
Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

+51
View File
@@ -0,0 +1,51 @@
(function () {
var AUTOPLAY_DELAY = 4500;
document.addEventListener('DOMContentLoaded', function () {
var thumbs = document.querySelectorAll('.screenshot-thumb');
var mainImg = document.getElementById('screenshotMainImg');
var caption = document.getElementById('screenshotCaption');
if (!thumbs.length || !mainImg) {
return;
}
var index = 0;
var autoplay = null;
function activate(i) {
thumbs.forEach(function (thumb) { thumb.classList.remove('active'); });
thumbs[i].classList.add('active');
mainImg.src = thumbs[i].getAttribute('data-img');
if (caption) {
caption.textContent = thumbs[i].getAttribute('data-caption');
}
index = i;
}
function startAutoplay() {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
return;
}
autoplay = setInterval(function () {
activate((index + 1) % thumbs.length);
}, AUTOPLAY_DELAY);
}
function resetAutoplay() {
if (autoplay) {
clearInterval(autoplay);
}
startAutoplay();
}
thumbs.forEach(function (thumb, i) {
thumb.addEventListener('click', function () {
activate(i);
resetAutoplay();
});
});
startAutoplay();
});
})();
+38
View File
@@ -33,5 +33,43 @@
<h3>{{ __('app.feature_home_title') }}</h3>
<p>{{ __('app.feature_home_text') }}</p>
</div>
<div class="feature-card">
<div class="feature-icon">🔔</div>
<h3>{{ __('app.notifiers') }}</h3>
<p>{{ __('app.notifiers_lede') }}</p>
</div>
</section>
<section class="screenshots-section">
<div class="screenshots-header">
<h2>{{ __('app.screenshots_title') }}</h2>
<p>{{ __('app.screenshots_lede') }}</p>
</div>
@php
$screenshots = [
['file' => 'dashboard-light.png', 'caption' => __('app.screenshot_dashboard')],
['file' => 'dashboard-dark.png', 'caption' => __('app.screenshot_dark')],
['file' => 'reader-light.png', 'caption' => __('app.screenshot_reader')],
['file' => 'catalog-light.png', 'caption' => __('app.screenshot_catalog')],
['file' => 'notifiers-light.png', 'caption' => __('app.screenshot_notifiers')],
];
@endphp
<div class="screenshot-gallery">
<div class="screenshot-main">
<img id="screenshotMainImg" src="{{ asset('images/screenshots/' . $screenshots[0]['file']) }}" alt="{{ $screenshots[0]['caption'] }}">
</div>
<div class="screenshot-thumbs">
@foreach ($screenshots as $index => $shot)
<button type="button" class="screenshot-thumb {{ $index === 0 ? 'active' : '' }}" data-img="{{ asset('images/screenshots/' . $shot['file']) }}" data-caption="{{ $shot['caption'] }}">
<img src="{{ asset('images/screenshots/' . $shot['file']) }}" alt="{{ $shot['caption'] }}" loading="lazy">
</button>
@endforeach
</div>
<p class="screenshot-caption" id="screenshotCaption">{{ $screenshots[0]['caption'] }}</p>
</div>
</section>
<script src="{{ asset('js/screenshot-gallery.js') }}" defer></script>
@endsection