Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ en vivo. Hace menos que Trello o Jira, y para nosotros esa era la idea.
HTTP plano; se activa solo cuando la app se sirve por HTTPS.
- **Tarjetas con todo**: comentarios, adjuntos con visor de imágenes en la
app, etiquetas, prioridad, vencimiento y feed de actividad por tarjeta.
- **Puntos y recompensas**: completar una tarea da puntos. Karma semanal,
rachas y un catálogo de recompensas reales que definís vosotros. Si lo
ignoras, el tablero funciona exactamente igual.
- **Multiusuario**: roles admin/usuario, idioma por usuario (ES/EN),
contraseñas bcrypt, login con rate-limit y registro de auditoría.
- **PWA instalable**: tema claro/oscuro siguiendo al sistema, service
Expand Down Expand Up @@ -98,6 +101,14 @@ en vivo. Hace menos que Trello o Jira, y para nosotros esa era la idea.
<img alt="Página de ajustes con previews de tema, selector de color de acento, opciones de densidad, tarjeta de perfil, gestor de etiquetas y selector de idioma" src="assets/screenshot-settings-es-light.png" width="800">
</picture>

**Puntos y recompensas:** karma semanal, rachas y premios que definís vosotros**

<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/screenshot-rewards-es-dark.png">
<source media="(prefers-color-scheme: light)" srcset="assets/screenshot-rewards-es-light.png">
<img alt="Panel de puntos y recompensas con el karma semanal de cada uno y su racha, un catálogo de recompensas para canjear y el historial de actividad" src="assets/screenshot-rewards-es-light.png" width="800">
</picture>

## Instalación

Requisitos: Linux (x86_64 o arm64) con systemd, acceso root o sudo.
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ Trello or Jira, and for us that was the point.
plain HTTP; turns itself on once the app is served over HTTPS.
- **Cards with everything**: comments, attachments with an in-app image
viewer, labels, priority, due dates and a per-card activity feed.
- **Points and rewards**: completing a task earns points. A weekly karma
board, streaks and a catalog of real-life rewards you define yourselves.
Ignore it and the board works exactly the same.
- **Multiuser**: admin/user roles, per-user language (ES/EN), bcrypt
passwords, rate-limited login, audit trail.
- **Installable PWA**: light/dark theme following the system, offline
Expand All @@ -93,6 +96,14 @@ Trello or Jira, and for us that was the point.
<img alt="Settings page showing theme previews, accent color swatches, density options, profile card, label manager and language selector" src="assets/screenshot-settings-en-light.png" width="800">
</picture>

**Points and rewards:** weekly karma, streaks and rewards you define**

<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/screenshot-rewards-en-dark.png">
<source media="(prefers-color-scheme: light)" srcset="assets/screenshot-rewards-en-light.png">
<img alt="Points and rewards panel showing each person's weekly karma with their streak, a catalog of redeemable rewards and a recent activity list" src="assets/screenshot-rewards-en-light.png" width="800">
</picture>

## Installation

Requirements: Linux (x86_64 or arm64) with systemd, root or sudo access.
Expand Down
Binary file added assets/screenshot-rewards-en-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshot-rewards-en-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshot-rewards-es-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshot-rewards-es-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion landing/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
function langNow() { return root.lang === 'en' ? 'en' : 'es'; }

/* ---------- Capturas: principal + carrusel, por idioma/tema ---------- */
const SHOT_ORDER = ['board', 'casa', 'viaje', 'trabajo', 'expenses', 'invite', 'settings'];
const SHOT_ORDER = ['board', 'casa', 'viaje', 'trabajo', 'expenses', 'rewards', 'invite', 'settings'];
let shotIndex = 0;
const mainImg = document.getElementById('shotMain');
const capEl = document.getElementById('shotCap');
Expand Down
Binary file added landing/assets/shot-rewards-en-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added landing/assets/shot-rewards-en-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added landing/assets/shot-rewards-es-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added landing/assets/shot-rewards-es-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 7 additions & 2 deletions landing/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
'shot.viaje.cap': 'El viaje a Lisboa, con fechas y responsables',
'shot.trabajo.cap': 'El tablero de Trabajo, para equipos pequeños',
'shot.expenses.cap': 'Gastos compartidos, con su reparto',
'shot.rewards.cap': 'Puntos y recompensas: karma semanal, rachas y premios que canjear',
'shot.invite.cap': 'Invitar sin cuenta: enlace, tu parte y pago',
'shot.settings.cap': 'Ajustes: tema, acento, densidad y etiquetas'
});
Expand All @@ -31,6 +32,7 @@
'shot.viaje.alt': 'Tablero del viaje a Lisboa con la reserva del hotel, los trenes y una lista de restaurantes',
'shot.trabajo.alt': 'Tablero de Trabajo con la presentación del trimestre, una factura y un bug de login',
'shot.expenses.alt': 'Tablero de gastos con la compra del súper, una cena y la factura de la luz, con el reparto de pagos',
'shot.rewards.alt': 'Panel de puntos y recompensas de Deltos: karma semanal de cada uno con su racha, catálogo de recompensas reales para canjear e historial de actividad',
'shot.invite.alt': 'Página pública de invitación de Deltos: saludo a la persona invitada, su parte del gasto y el botón de marcar como pagado',
'shot.settings.alt': 'Ajustes de Deltos: tema claro, oscuro o auto, color de acento, densidad y editor de etiquetas'
});
Expand Down Expand Up @@ -76,23 +78,25 @@
"shot.viaje.cap": "The Lisbon trip, with dates and owners",
"shot.trabajo.cap": "The Work board, for small teams",
"shot.expenses.cap": "Shared expenses, with their splits",
"shot.rewards.cap": "Points and rewards: weekly karma, streaks and prizes to redeem",
"shot.invite.cap": "Invite without an account: link, your share and payment",
"shot.settings.cap": "Settings: theme, accent, density and labels",
"shots.close": "Close",
"feat.eyebrow": "What's in it", "feat.title": "Everything the board can do",
"feat.lede": "Twelve pieces that fit together, including the expense plugin. Not a single filler feature.",
"feat.lede": "Thirteen pieces that fit together, including the expense plugin. Not a single filler feature.",
"f1.t": "Live sync", "f1.p": "Drag a card and everyone sees it instantly, no refresh. All over SSE.",
"f2.t": "Phone alerts", "f2.p": "Web Push with the app closed: assigns and comments reach you.",
"f3.t": "Cards with everything", "f3.p": "Comments, cropped attachments, priority, due dates and activity.",
"f4.t": "Projects and labels", "f4.p": "Each project with its own board and labels to filter.",
"f5.t": "Each one in their language", "f5.p": "Roles, hashed passwords and rate-limited login.",
"f5.t": "Multiuser", "f5.p": "Admin and user roles, per-person language, bcrypt passwords and rate-limited login.",
"f6.t": "Installable PWA", "f6.p": "Installable app, works offline, with light and dark theme.",
"f7.t": "One-click demo", "f7.p": "Sign in password-free into a demo full of sample tasks.",
"f8.t": "Your data, yours", "f8.p": "JSON export, automatic backups and an audit trail.",
"f9.t": "Shared expenses", "f9.p": "Equal or per-person splits, via Bizum, transfer or cash.",
"f10.t": "Invite anyone", "f10.p": "One link: see their share, comment, mark as paid. No signup.",
"f11.t": "Settle up", "f11.p": "One click and the app calculates who owes whom. Done.",
"f12.t": "Drag your cards", "f12.p": "Hold and drag on mobile, or swipe the whole column.",
"f13.t": "Points and rewards", "f13.p": "Complete a task and earn points. Weekly karma, streaks and a catalog of real-life rewards you define yourselves.",
"cmp.eyebrow": "Compare",
"cmp.title": "The category that was missing: a light board for real life",
"cmp.lede": "This is a comparison of task boards, not office suites. Data cross-checked against each project's public sources in August 2026.",
Expand Down Expand Up @@ -157,6 +161,7 @@
"shot.viaje.alt": "Deltos Trip to Lisbon project board with hotel bookings, tickets and a restaurant list",
"shot.trabajo.alt": "Deltos Work project board with the quarterly presentation, an invoice and a login bug",
"shot.expenses.alt": "Deltos expenses board with the supermarket shopping, a dinner and the power bill, with payment splits",
"shot.rewards.alt": "Deltos points and rewards panel: each person's weekly karma with their streak, a catalog of real-life rewards to redeem and a recent activity history",
"shot.invite.alt": "Deltos public invite page: greeting to the invited person, their share of the expense and the mark-as-paid button",
"shot.settings.alt": "Deltos settings: light, dark or auto theme, accent color, density and label editor"
};
Expand Down
14 changes: 9 additions & 5 deletions landing/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<script src="boot.js?v=12"></script>
<link rel="stylesheet" href="styles.194h.css">
<link rel="stylesheet" href="styles.249a.css">
<script type="application/ld+json">
{
"@context": "https://schema.org",
Expand Down Expand Up @@ -314,6 +314,9 @@ <h2 data-i18n="shots.title">La app, por dentro</h2>
<button class="thumb" role="tab" aria-selected="false" data-shot="expenses" aria-label="Gastos compartidos">
<img src="assets/shot-expenses-es-dark.webp" alt="" aria-hidden="true" loading="lazy">
</button>
<button class="thumb" role="tab" aria-selected="false" data-shot="rewards" aria-label="Puntos y recompensas">
<img src="assets/shot-rewards-es-dark.webp" alt="" aria-hidden="true" loading="lazy">
</button>
<button class="thumb" role="tab" aria-selected="false" data-shot="invite" aria-label="Invitar sin cuenta">
<img src="assets/shot-invite-es-dark.webp" alt="" aria-hidden="true" loading="lazy">
</button>
Expand All @@ -330,21 +333,22 @@ <h2 data-i18n="shots.title">La app, por dentro</h2>
<div class="section-head reveal">
<span class="h-eyebrow"><span class="num">03</span><span data-i18n="feat.eyebrow">Qué lleva dentro</span></span>
<h2 data-i18n="feat.title">Todo lo que hace el tablero</h2>
<p class="lede" data-i18n="feat.lede">Doce piezas que encajan entre sí, incluido el plugin de gastos. Ni una función de relleno.</p>
<p class="lede" data-i18n="feat.lede">Trece piezas que encajan entre sí, incluido el plugin de gastos. Ni una función de relleno.</p>
</div>
<div class="feat-grid">
<div class="feat reveal" style="--fc:#34d399"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L4.5 13.5H11L9.5 22 19 10h-6.5z"/></svg></div><h3 data-i18n="f1.t">Sincronización en vivo</h3><p data-i18n="f1.p">Arrastra una tarjeta y todos lo ven al instante, sin recargar. Todo por SSE.</p></div>
<div class="feat reveal d1" style="--fc:#fb7185"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.7 21a2 2 0 0 1-3.4 0"/></svg></div><h3 data-i18n="f2.t">Avisos al móvil</h3><p data-i18n="f2.p">Web Push con la app cerrada: si te asignan algo o comentan, te enteras.</p></div>
<div class="feat reveal d2" style="--fc:#38bdf8"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="3"/><path d="M3 9h18M8 4v5"/></svg></div><h3 data-i18n="f3.t">Tarjetas con todo</h3><p data-i18n="f3.p">Comentarios, adjuntos con recorte, prioridad, fechas límite y actividad.</p></div>
<div class="feat reveal" style="--fc:#a78bfa"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></div><h3 data-i18n="f4.t">Proyectos y etiquetas</h3><p data-i18n="f4.p">Cada proyecto con su tablero y etiquetas para filtrar.</p></div>
<div class="feat reveal d1" style="--fc:#fbbf24"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v2"/><circle cx="10" cy="7" r="4"/><path d="M21 11h-6M21 15h-6"/></svg></div><h3 data-i18n="f5.t">Cada uno en su idioma</h3><p data-i18n="f5.p">Roles, contraseñas hasheadas y login con límite de intentos.</p></div>
<div class="feat reveal d1" style="--fc:#fbbf24"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v2"/><circle cx="10" cy="7" r="4"/><path d="M21 11h-6M21 15h-6"/></svg></div><h3 data-i18n="f5.t">Multiusuario</h3><p data-i18n="f5.p">Roles admin y usuario, idioma por persona, contraseñas bcrypt y login con límite de intentos.</p></div>
<div class="feat reveal d2" style="--fc:#34d399"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="14" rx="2"/><path d="M8 21h8M12 18v3"/></svg></div><h3 data-i18n="f6.t">PWA instalable</h3><p data-i18n="f6.p">App instalable que funciona sin conexión, con tema claro y oscuro.</p></div>
<div class="feat reveal" style="--fc:#38bdf8"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="6 3 20 12 6 21 6 3"/></svg></div><h3 data-i18n="f7.t">Demo con un clic</h3><p data-i18n="f7.p">Entra sin contraseña a una demo llena de tareas de ejemplo.</p></div>
<div class="feat reveal d1" style="--fc:#fb7185"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l8 4v5c0 5-3.5 8-8 9-4.5-1-8-4-8-9V7z"/><path d="M9 12l2 2 4-4"/></svg></div><h3 data-i18n="f8.t">Tus datos, tuyos</h3><p data-i18n="f8.p">Exportación JSON, copias automáticas y registro de auditoría.</p></div>
<div class="feat reveal d2" style="--fc:#fbbf24"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 6v12M15 9.5c0-1.4-1.3-2.5-3-2.5s-3 .9-3 2.2c0 3 6 1.6 6 4.6 0 1.3-1.3 2.2-3 2.2s-3-1.1-3-2.5"/></svg></div><h3 data-i18n="f9.t">Gastos compartidos</h3><p data-i18n="f9.p">Reparto igualitario o por persona, con Bizum, transferencia o efectivo.</p></div>
<div class="feat reveal" style="--fc:#a78bfa"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7"/><path d="M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7"/></svg></div><h3 data-i18n="f10.t">Invita a cualquiera</h3><p data-i18n="f10.p">Un enlace: ve su parte, comenta y marca como pagado. Sin registro.</p></div>
<div class="feat reveal d1" style="--fc:#34d399"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg></div><h3 data-i18n="f11.t">Liquidar cuentas</h3><p data-i18n="f11.p">Un clic y la app calcula quién debe a quién. Listo.</p></div>
<div class="feat reveal d2" style="--fc:#38bdf8"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 9l-5 5M9 9h.01M15 15h.01"/><rect x="3" y="3" width="18" height="18" rx="4"/></svg></div><h3 data-i18n="f12.t">Arrastra tus tarjetas</h3><p data-i18n="f12.p">Mantén y arrastra en el móvil, o desliza la columna entera.</p></div>
<div class="feat reveal" style="--fc:#f472b6"><div class="feat-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9H4.5a2.5 2.5 0 0 1 0-5H6"/><path d="M18 9h1.5a2.5 2.5 0 0 0 0-5H18"/><path d="M4 22h16"/><path d="M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22"/><path d="M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22"/><path d="M18 2H6v7a6 6 0 0 0 12 0V2Z"/></svg></div><h3 data-i18n="f13.t">Puntos y recompensas</h3><p data-i18n="f13.p">Completa una tarea y gana puntos. Karma semanal, rachas y un catálogo de recompensas reales que definís vosotros.</p></div>
</div>
</div>
</section>
Expand Down Expand Up @@ -542,8 +546,8 @@ <h4 data-i18n="foot.c3">Apoya</h4>
<p class="lightbox-caption" id="lightboxCaption"></p>
</div>

<script src="i18n.js?v=13"></script>
<script src="app.js?v=13"></script>
<script src="i18n.js?v=14"></script>
<script src="app.js?v=14"></script>
<script defer src="https://stat.domatix.com/script.js" data-website-id="f1fb2c4e-d967-5a85-b15a-722f30b7ff3b"></script>
</body>
</html>
3 changes: 3 additions & 0 deletions landing/styles.194h.css → landing/styles.249a.css
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@ h2{font-size:clamp(28px,4vw,42px);margin-bottom:16px}

/* features */
.feat-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
/* Si la ultima tarjeta queda sola en la fila (13 = 4x3 + 1), centrarla. */
.feat-grid>.feat:last-child:nth-child(3n+1){grid-column:2}
.feat{
background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
padding:26px;transition:transform .25s,border-color .25s,box-shadow .25s;
Expand Down Expand Up @@ -514,6 +516,7 @@ html.js .reveal.in{opacity:1;transform:none}
.hero-grid{grid-template-columns:1fr;gap:56px}
.hero-sub{max-width:640px}
.feat-grid{grid-template-columns:repeat(2,1fr)}
.feat-grid>.feat:last-child:nth-child(3n+1){grid-column:auto}
.install-grid{grid-template-columns:1fr}
.about-wrap{grid-template-columns:1fr;padding:36px}
.foot-grid{grid-template-columns:1fr 1fr}
Expand Down
3 changes: 3 additions & 0 deletions landing/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@ h2{font-size:clamp(28px,4vw,42px);margin-bottom:16px}

/* features */
.feat-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
/* Si la ultima tarjeta queda sola en la fila (13 = 4x3 + 1), centrarla. */
.feat-grid>.feat:last-child:nth-child(3n+1){grid-column:2}
.feat{
background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
padding:26px;transition:transform .25s,border-color .25s,box-shadow .25s;
Expand Down Expand Up @@ -514,6 +516,7 @@ html.js .reveal.in{opacity:1;transform:none}
.hero-grid{grid-template-columns:1fr;gap:56px}
.hero-sub{max-width:640px}
.feat-grid{grid-template-columns:repeat(2,1fr)}
.feat-grid>.feat:last-child:nth-child(3n+1){grid-column:auto}
.install-grid{grid-template-columns:1fr}
.about-wrap{grid-template-columns:1fr;padding:36px}
.foot-grid{grid-template-columns:1fr 1fr}
Expand Down
Loading