284 lines
6.5 KiB
Vue
Raw Normal View History

<template>
<div class="page">
<section class="card hero glass">
<div>
<p class="eyebrow">Atlas</p>
<h1>Apps</h1>
<p class="lede">
Service shortcuts for Atlas.
</p>
</div>
</section>
<section class="section-grid">
<section v-for="section in sections" :key="section.title" class="card category">
<div class="section-head">
<div>
<h2>{{ section.title }}</h2>
<p class="muted">{{ section.description }}</p>
</div>
</div>
<div v-for="group in section.groups" :key="group.title" class="group">
<div class="group-title">{{ group.title }}</div>
<div class="tiles">
<a
v-for="app in group.apps"
:key="app.name"
class="tile"
:href="app.url"
:target="app.target"
rel="noreferrer"
>
<div class="tile-title">{{ app.name }}</div>
<div class="tile-desc">{{ app.description }}</div>
</a>
</div>
</div>
</section>
</section>
</div>
</template>
<script setup>
const sections = [
{
title: "Cloud",
2026-01-02 12:11:40 -03:00
description: "Your personal cloud hub: files, photos, mail, calendars, and collaborative documents.",
groups: [
{
title: "Nextcloud",
apps: [
{
name: "Cloud",
url: "https://cloud.bstein.dev",
target: "_blank",
2026-01-02 12:11:40 -03:00
description: "Storage, mail, photos, and office docs — the main Atlas hub.",
},
],
},
],
},
{
title: "Security",
2026-01-02 12:11:40 -03:00
description: "Passwords for humans, secrets for infrastructure.",
groups: [
{
title: "Personal",
apps: [
{
name: "Vaultwarden",
url: "https://vault.bstein.dev",
target: "_blank",
description: "Password manager (Bitwarden-compatible).",
},
{
name: "Keycloak",
2026-01-03 17:24:00 -03:00
url: "https://sso.bstein.dev/realms/atlas/account/#/security/signing-in",
target: "_blank",
2026-01-03 17:24:00 -03:00
description: "Account security + MFA (2FA) settings (Keycloak).",
},
],
},
],
},
{
title: "Communications",
2026-01-02 12:11:40 -03:00
description: "Chat rooms, calls, and bots. Element X (mobile) is the recommended client.",
groups: [
{
title: "Chat",
apps: [
{
2026-01-02 12:11:40 -03:00
name: "Element X",
url: "https://live.bstein.dev",
target: "_blank",
2026-01-02 12:11:40 -03:00
description: "Matrix rooms with calls powered by Atlas infra.",
},
{
name: "AI Chat",
url: "/ai/chat",
target: "_self",
description: "Chat with Atlas AI (GPU-accelerated).",
},
],
},
],
},
{
title: "Streaming",
2026-01-02 12:11:40 -03:00
description: "Stream media and publish uploads into your library.",
groups: [
{
title: "Media",
apps: [
{
name: "Jellyfin",
url: "https://stream.bstein.dev",
target: "_blank",
description: "Stream videos to desktop, mobile, and TV.",
},
{
name: "Pegasus",
url: "https://pegasus.bstein.dev",
target: "_blank",
description: "Mobile-friendly upload/publish into Jellyfin.",
},
],
},
],
},
{
title: "Dev",
2026-01-02 12:11:40 -03:00
description: "Build and ship: source control, CI, registry, and GitOps.",
groups: [
{
title: "Dev Stack",
apps: [
{ name: "Gitea", url: "https://scm.bstein.dev", target: "_blank", description: "Git hosting and collaboration." },
{ name: "Jenkins", url: "https://ci.bstein.dev", target: "_blank", description: "CI pipelines and automation." },
{ name: "Harbor", url: "https://registry.bstein.dev", target: "_blank", description: "Artifact registry." },
{ name: "GitOps", url: "https://cd.bstein.dev", target: "_blank", description: "GitOps UI for Flux." },
2026-01-03 17:24:00 -03:00
{ name: "Vault", url: "https://secret.bstein.dev", target: "_blank", description: "Secrets management for infrastructure and apps." },
{ name: "Grafana", url: "https://metrics.bstein.dev", target: "_blank", description: "Dashboards and monitoring." },
2026-01-03 17:24:00 -03:00
],
},
],
},
{
title: "Crypto",
description: "Local infrastructure for crypto workloads.",
groups: [
{
title: "Monero",
apps: [
{
name: "Monero Node",
url: "/monero",
target: "_self",
description: "Faster sync using the Atlas Monero node.",
},
],
},
],
},
];
</script>
<style scoped>
.page {
max-width: 1200px;
margin: 0 auto;
padding: 32px 22px 72px;
}
.section-grid {
display: grid;
gap: 14px;
}
@media (min-width: 980px) {
.section-grid {
grid-template-columns: 1fr 1fr;
}
}
.hero {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 18px;
margin-bottom: 12px;
}
.category {
padding: 18px;
}
.section-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 18px;
margin-bottom: 14px;
min-height: 92px;
}
.group + .group {
margin-top: 14px;
}
.group-title {
font-weight: 700;
color: var(--text-strong);
margin-bottom: 10px;
}
.muted {
margin: 6px 0 0;
color: var(--text-muted);
max-width: 820px;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.tiles {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 12px;
}
.tile {
display: block;
text-decoration: none;
padding: 14px 14px 12px;
border-radius: 14px;
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.02);
transition: border-color 160ms ease, transform 160ms ease;
min-height: 112px;
}
.tile:hover {
border-color: rgba(120, 180, 255, 0.35);
transform: translateY(-1px);
}
.tile-title {
font-weight: 750;
color: var(--text-strong);
}
.tile-desc {
margin-top: 6px;
color: var(--text-muted);
font-size: 14px;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.eyebrow {
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--text-muted);
margin: 0 0 6px;
font-size: 13px;
}
h1 {
margin: 0 0 6px;
font-size: 32px;
}
.lede {
margin: 0;
color: var(--text-muted);
max-width: 640px;
}
</style>