🔒 Repository is read-only – file editing is disabled.

PaganLinux/pagan-web-v2/templates/main/index.html main

167 linii Raw ← Powrót
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
{% extends "base.html" %}{% block title %}PaganOS Linux – {{ t('hero_title') }} | PaganLinux{% endblock %}
{% block head %}
<style>
 /* ── Strona główna: hero ── */
 .eyebrow{display:inline-flex;align-items:center;gap:0.45rem;padding:0.35rem 1rem;border-radius:99px;background:var(--accent-glow);border:1px solid rgba(63,185,80,0.28);color:var(--accent);font-size:0.8rem;font-weight:700;letter-spacing:0.04em;text-transform:uppercase;margin-bottom:1.1rem}
 .eyebrow.dot{width:8px;height:8px;border-radius:50%;background:var(--accent);animation:pg-pulse 1.4s ease-in-out infinite}
 .hero{padding:3.2rem 1rem 2.6rem}
 .hero h1{font-size:3.4rem}
 .hero-sub{font-size:1.22rem;line-height:1.65;max-width:820px;margin:1.2rem auto 1.6rem;color:var(--text-bright)}
 .hero-stats{display:grid;grid-template-columns:repeat(4,minmax(120px,1fr));gap:0.7rem;max-width:860px;margin:2rem auto 0}
 .hstat{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:0.85rem 0.6rem;text-align:center;transition:var(--transition);animation:pg-fade 0.5s ease both}
 .hstat:hover{border-color:rgba(63,185,80,0.4);transform:translateY(-2px)}
 .hstat.v{font-size:1.6rem;font-weight:800;color:var(--text-bright);line-height:1.1;font-variant-numeric:tabular-nums}
 .hstat.v.ok{color:var(--accent)}.hstat.v.bad{color:var(--red)}
 .hstat.l{font-size:0.68rem;color:var(--muted);text-transform:uppercase;letter-spacing:0.05em;font-weight:700;margin-top:0.25rem}
 @keyframes pg-pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:0.35;transform:scale(1.6)}}

 /* ── Live band ── */
 .live-wrap{border:1px solid var(--border);border-radius:var(--radius);background:linear-gradient(180deg,rgba(255,255,255,0.02),transparent 55%),var(--card);padding:1.1rem 1.3rem;margin:1.5rem 0 0;display:flex;gap:1.4rem;flex-wrap:wrap;align-items:center}
 .live-now{flex:1;min-width:260px}
 .live-now.cur-name{font-size:1.05rem;font-weight:800;color:var(--text-bright);font-family:var(--mono)}
 .live-now.cur-step{color:var(--muted);font-size:0.82rem;margin-top:0.2rem}
 .live-now.idle{color:var(--muted);font-size:0.9rem}
 .pbar{height:8px;background:var(--bg2);border:1px solid var(--border);border-radius:99px;overflow:hidden;margin-top:0.55rem}
 .pbar>div{height:100%;width:0;border-radius:99px;background:linear-gradient(90deg,var(--accent2),var(--accent));box-shadow:0 0 12px rgba(63,185,80,0.6);transition:width 0.8s cubic-bezier(0.3,0.9,0.3,1)}
 .live-facts{display:flex;flex-direction:column;gap:0.35rem;font-size:0.85rem;color:var(--muted);min-width:230px}
 .live-facts.k{display:inline-block;min-width:118px;color:var(--text);font-weight:700}
 .live-facts a{color:var(--link)}

 /* ── Karty sekcji ── */
 .cat-chips{display:flex;gap:0.4rem;flex-wrap:wrap;margin-top:0.9rem}
 .code-snip{margin-top:1rem}
 .big-num{font-size:2.6rem;font-weight:800;color:var(--accent);line-height:1;font-variant-numeric:tabular-nums}
 .section-pad{margin-top:2rem}
 .btn-lg{padding:0.8rem 1.8rem;font-size:0.98rem}
 @media(max-width:768px){.hero h1{font-size:2.3rem}.hero-stats{grid-template-columns:repeat(2,1fr)}.live-facts{min-width:0}}
</style>
{% endblock %}
{% block content %}
<section class="hero">
 <span class="eyebrow"><span class="dot"></span> {{ t('hero_eyebrow') }}</span>
 <img src="/static/pagan-loki-pingwin.svg" alt="Pagan Linux" class="hero-logo">
 <h1>Pagan <span class="accent">Linux</span></h1>
 <p class="hero-sub">{{ t('hero_subtitle') }}</p>
 <div class="hero-actions">
 <a href="/download" class="btn btn-primary btn-lg">⬇ {{ t('download_iso') }}</a>
 <a href="/repo" class="btn btn-lg"> {{ t('browse_repo') }}</a>
 <a href="/docs" class="btn btn-lg"> {{ t('browse_docs') }}</a>
 </div>
 <div class="hero-stats">
 <div class="hstat"><div class="v" id="st-pkg">{{ pkg_count }}</div><div class="l">{{ t('pkg_count') }}</div></div>
 <div class="hstat"><div class="v" id="st-ok">{{ build_status.success }}</div><div class="l">{{ t('ok_count') }}</div></div>
 <div class="hstat"><div class="v" id="st-fail">{{ build_status.failed }}</div><div class="l">{{ t('fail_count') }}</div></div>
 <div class="hstat"><div class="v" id="st-builds">{{ build_status.total_builds }}</div><div class="l">{{ t('build_count') }}</div></div>
 </div>
</section>

<div class="live-wrap">
 <div class="live-now">
 <div style="display:flex;align-items:center;gap:0.5rem;color:var(--muted);font-size:0.75rem;font-weight:700;text-transform:uppercase;letter-spacing:0.06em;margin-bottom:0.35rem">
 <span class="eyebrow" style="margin:0;padding:0.15rem 0.7rem;font-size:0.7rem"> {{ t('live_builds') }}</span>
 </div>
 <div id="cur-box">
 {% if build_status.current_build %}
 {% set cb = build_status.current_build %}
 <div class="cur-name">{{ cb.name }}-{{ cb.version }} <span class="badge badge-info">{{ cb.category }}</span></div>
 <div class="cur-step" id="cur-step">{{ cb.step_text or '' }}</div>
 <div class="pbar"><div id="cur-bar" data-progress="{{ cb.progress or '' }}"></div></div>
 {% else %}
 <div class="idle"> {{ t('no_active_build') }}</div>
 {% endif %}
 </div>
 </div>
 <div class="live-facts">
 <span><span class="k">{{ t('latest_build_lbl') }}:</span> <span id="fx-last">{% if build_status.last_build %}{{ build_status.last_build.name }}-{{ build_status.last_build.version }} {{ '✅' if build_status.last_build.status == 'ok' else '❌' }}{% else %}—{% endif %}</span></span>
 <span><span class="k">{{ t('last_sync_lbl') }}:</span> <span id="fx-sync">{{ build_status.last_sync or '—' }}</span></span>
 <span><a href="{{ section_url('build') }}"> {{ t('build_panel_link') }}</a></span>
 </div>
</div>

<div class="section-title section-pad"><span class="icon"></span> {{ t('why_title') }}</div>
<div class="grid4">
 <div class="feature-card"><div class="icon"></div><h3>{{ t('feat_from_scratch') }}</h3><p>{{ t('feat_from_scratch_desc') }}</p></div>
 <div class="feature-card"><div class="icon"></div><h3>{{ t('feat_pkg_mgr') }}</h3><p>{{ t('feat_pkg_mgr_desc') }}</p></div>
 <div class="feature-card"><div class="icon"></div><h3>{{ t('feat_toolchain') }}</h3><p>{{ t('feat_toolchain_desc') }}</p></div>
 <div class="feature-card"><div class="icon"></div><h3>{{ t('feat_security') }}</h3><p>{{ t('feat_security_desc') }}</p></div>
</div>

<hr class="divider">
<div class="grid2">
 <div class="card">
 <div class="card-header"><h2> {{ t('pkg_repo') }}</h2></div>
 <div style="display:flex;align-items:baseline;gap:0.7rem;flex-wrap:wrap">
 <span class="big-num">{{ pkg_count }}</span>
 <span class="text-muted">{{ t('pkg_repo_desc') }}</span>
 </div>
 {% if pkg_cats %}
 <div class="cat-chips">
 {% for cat, n in pkg_cats.items() %}<span class="chip">{{ cat }} · {{ n }}</span>{% endfor %}
 </div>
 {% endif %}
 <div class="code-snip"><pre><code>pag search firefox
pag install firefox</code></pre></div>
 <div style="margin-top:0.9rem"><a href="/repo" class="btn btn-primary">{{ t('browse_pkgs') }}</a></div>
 </div>
 <div class="card">
 <div class="card-header"><h2>⬇ {{ t('download_iso') }}</h2></div>
 <p class="text-muted">PaganOS udostępniany jest jako gotowe obrazy ISO – wybierz środowisko graficzne, sprawdź sumę kontrolną i uruchom z pendrive'a. Rolling release: raz zainstalowany system aktualizujesz przez <b>pag upgrade</b>.</p>
 <div style="display:flex;gap:0.6rem;flex-wrap:wrap;margin-top:0.4rem">
 <a href="/download" class="btn btn-primary btn-lg">⬇ {{ t('download_iso') }}</a>
 <a href="/docs" class="btn btn-lg"> {{ t('browse_docs') }}</a>
 </div>
 </div>
</div>

<div class="card mt-2">
 <div class="card-header"><h2> {{ t('missing_pkg') }}</h2></div>
 <div style="display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap">
 <p class="text-muted" style="margin:0">{{ t('missing_pkg_desc') }}</p>
 <a href="/submit-recipe" class="btn btn-primary"> {{ t('suggest_pkg') }}</a>
 </div>
</div>

<script>
(function () {
 function setBar() {
 var bar = document.getElementById('cur-bar');
 if (!bar) return;
 var p = parseInt(String(bar.getAttribute('data-progress') || '').replace(/[^\d]/g, ''), 10);
 bar.style.width = (isNaN(p)? 0: Math.min(100, p)) + '%';
 }
 setBar();
 function renderCur(cur) {
 var box = document.getElementById('cur-box');
 if (!box) return;
 if (cur && cur.name) {
 var p = String(cur.progress || '').replace(/[^\d]/g, '');
 box.innerHTML = '<div class="cur-name"></div><div class="cur-step" id="cur-step"></div><div class="pbar"><div id="cur-bar" data-progress="' + cur.progress + '"></div></div>';
 box.querySelector('.cur-name').textContent = cur.name + '-' + (cur.version || '?') + ' ';
 var b = document.createElement('span'); b.className = 'badge badge-info'; b.textContent = cur.category || ''; box.querySelector('.cur-name').appendChild(b);
 box.querySelector('.cur-step').textContent = cur.step_text || '';
 setBar();
 } else {
 box.innerHTML = '<div class="idle"> {{ t('no_active_build') }}</div>';
 }
 }
 function fmtSync(ts) {
 if (!ts) return '—';
 var d = new Date(String(ts).replace(' ', 'T') + (String(ts).includes('Z')? '' : 'Z'));
 if (isNaN(d)) return ts;
 return d.toLocaleString();
 }
 function refresh() {
 fetch('/api/status-live').then(function (r) { return r.json(); }).then(function (d) {
 var ok = document.getElementById('st-ok'), fail = document.getElementById('st-fail'), builds = document.getElementById('st-builds');
 if (ok) ok.textContent = d.ok; if (fail) fail.textContent = d.fail; if (builds) builds.textContent = d.total;
 renderCur(d.current);
 var l = document.getElementById('fx-last');
 if (l && d.last_build) l.textContent = d.last_build.name + '-' + (d.last_build.version || '?') + ' ' + (d.last_build.status === 'ok' ? '✅' : '❌');
 var s = document.getElementById('fx-sync');
 if (s) s.textContent = fmtSync(d.last_sync);
 }).catch(function () {});
 }
 setInterval(refresh, 10000);
})();
</script>
{% endblock %}