longevity: layout e stile del gestionale — barra laterale, tabelle, bottone d'azione

Variante "gestionale" di Longevity.astro (finora dichiarata e non implementata):
barra laterale sul modello di StressIndex.astro, con le voci Clienti, Nuovo cliente
e un link "Il mio referto". CSS nuovo in longevity.css, solo classi lg-* e solo i
colori già ammessi (nessun colore letterale nuovo: il bianco del testo sul bottone
pieno riusa var(--lg-surface), non un #fff aggiuntivo).

Refs #2
This commit is contained in:
2026-09-26 13:05:32 +00:00
parent 95ffa08197
commit 8ee2c8a2b4
2 changed files with 128 additions and 12 deletions
+51 -12
View File
@@ -5,8 +5,8 @@
// dentro) qui i pubblici sono due, e uno non è staff: il cliente entra tre o quattro
// volte l'anno a leggere il proprio referto, non gli serve l'arredamento di uno
// strumento di lavoro. Il layout prevede due forme:
// - "referto": una colonna che scorre, senza navigazione (questo task)
// - "gestionale": barra laterale come Stress Index (arriva col piano del gestionale)
// - "referto": una colonna che scorre, senza navigazione (il cliente)
// - "gestionale": barra laterale sul modello di StressIndex.astro (il trainer, Unità 2b #2)
import '@fontsource/montserrat/400.css';
import '@fontsource/montserrat/500.css';
import '@fontsource/montserrat/600.css';
@@ -19,10 +19,18 @@ interface Props {
title: string;
/** Voci di percorso mostrate nell'intestazione, dopo "Longevity". */
crumbs?: string[];
/** "referto" (colonna centrata, senza navigazione) o "gestionale" (barra laterale, non ancora implementata). */
/** "referto" (colonna centrata, senza navigazione) o "gestionale" (barra laterale, per il trainer). */
variante?: 'referto' | 'gestionale';
}
const { title, crumbs = [], variante = 'referto' } = Astro.props;
const path = Astro.url.pathname;
// Le voci della barra laterale del gestionale: nasce con due pagine, non le sette di
// Stress Index — un elenco più lungo arriverà con gli sviluppi futuri (#3, #7, #8).
const NAV_GESTIONALE = [
{ href: '/longevity/gestionale', label: 'Clienti' },
{ href: '/longevity/gestionale/nuovo', label: 'Nuovo cliente' },
];
---
<!doctype html>
<html lang="it">
@@ -34,14 +42,45 @@ const { title, crumbs = [], variante = 'referto' } = Astro.props;
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
</head>
<body class="lg" data-variante={variante}>
<div class="lg-shell">
<header class="lg-top">
<p class="lg-top__crumbs">
<strong>Longevity</strong>
{crumbs.map((c) => <span> / {c}</span>)}
</p>
</header>
<main class="lg-main"><slot /></main>
</div>
{variante === 'gestionale' ? (
<>
<input type="checkbox" id="lg-menu" class="lg-menu-toggle" hidden />
<label for="lg-menu" class="lg-menu-btn" aria-label="Apri il menu">☰ Menu</label>
<aside class="lg-side">
<a class="lg-brand" href="/longevity/gestionale">
<span class="eyebrow">InsanityLab</span>
Longevity
</a>
<a class="lg-home" href="/piattaforme">Piattaforme</a>
<nav class="lg-nav">
{NAV_GESTIONALE.map((item) => (
<a href={item.href} class:list={['lg-nav__link', { 'is-active': path === item.href }]}>
{item.label}
</a>
))}
<a class="lg-nav__link lg-nav__link--referto" href="/longevity/io">Il mio referto</a>
</nav>
</aside>
<div class="lg-body">
<header class="lg-top">
<p class="lg-top__crumbs">
<strong>Longevity</strong>
{crumbs.map((c) => <span> / {c}</span>)}
</p>
</header>
<main class="lg-main"><slot /></main>
</div>
</>
) : (
<div class="lg-shell">
<header class="lg-top">
<p class="lg-top__crumbs">
<strong>Longevity</strong>
{crumbs.map((c) => <span> / {c}</span>)}
</p>
</header>
<main class="lg-main"><slot /></main>
</div>
)}
</body>
</html>
+77
View File
@@ -116,6 +116,10 @@
.lg-field { display: flex; flex-direction: column; gap: 6px; font-size: .92rem; }
.lg-field > span { color: var(--c-heading); font-weight: 500; }
.lg-field input[type="number"],
.lg-field input[type="text"],
.lg-field input[type="date"],
.lg-field input[type="email"],
.lg-field input[type="tel"],
.lg-field textarea {
border: 1px solid var(--lg-line); padding: 9px 11px; font: inherit; background: var(--lg-surface);
}
@@ -135,6 +139,79 @@
}
.lg-form__nav button:disabled { opacity: .35; cursor: not-allowed; }
.lg-form__nav button:last-child:not(:only-child) { background: var(--c-accent); border-color: var(--c-accent); color: #fff; }
/* Il link "Annulla" accanto al bottone di invio (nuovo.astro, checkup.astro): stesso rigo,
peso visivo minore — non compete con l'azione che porta avanti il modulo. */
.lg-form__nav a { align-self: center; font-size: .85rem; color: var(--c-text-light); text-decoration: none; }
.lg-form__nav a:hover { color: var(--c-heading); }
/* --- il gestionale del trainer (Unità 2b, #2): barra laterale sul modello di
StressIndex.astro, ma nella palette di Longevity — niente sfondo scuro con colori
letterali, solo i token già ammessi qui. --- */
.lg[data-variante="gestionale"] { justify-content: flex-start; align-items: flex-start; }
.lg-side {
width: 240px; flex: 0 0 240px; height: 100vh; position: sticky; top: 0; overflow-y: auto;
background: var(--c-bg-alt); border-right: 1px solid var(--lg-line);
padding: 28px 20px 40px; display: flex; flex-direction: column;
}
.lg-brand {
display: block; font-family: var(--font-heading); font-size: 1.15rem; font-weight: 600;
letter-spacing: .06em; text-transform: uppercase; color: var(--c-heading); text-decoration: none; line-height: 1.15;
}
.lg-brand .eyebrow { display: block; font-size: .68rem; letter-spacing: .18em; color: var(--c-accent); margin-bottom: 5px; }
.lg-home {
display: inline-block; margin: 16px 0 22px; font-family: var(--font-heading); font-size: .66rem;
font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--c-text-light);
text-decoration: none; border-bottom: 1px solid transparent;
}
.lg-home:hover { color: var(--c-heading); border-bottom-color: var(--c-accent); }
.lg-nav { display: flex; flex-direction: column; gap: 2px; border-top: 1px solid var(--lg-line); padding-top: 16px; }
.lg-nav__link {
padding: 9px 12px; text-decoration: none; font-family: var(--font-heading); font-size: .72rem;
font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--c-text-light);
border-left: 3px solid transparent;
}
.lg-nav__link:hover { color: var(--c-heading); background: var(--c-bg); }
.lg-nav__link.is-active { color: var(--c-heading); background: var(--lg-surface); border-left-color: var(--c-accent); }
.lg-nav__link--referto { margin-top: 16px; border-top: 1px dashed var(--lg-tratteggio); padding-top: 16px; }
.lg-body { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 100vh; }
/* intestazione di pagina con un'azione a destra (es. "Nuovo cliente", "Nuovo check-up") */
.lg-head--azioni { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
/* bottone pieno per un link che porta a un'azione (non un <button> di form) */
.lg-btn {
display: inline-block; font-family: var(--font-heading); font-size: .76rem; font-weight: 600;
letter-spacing: .06em; text-transform: uppercase; padding: 10px 20px; border: 1px solid var(--c-accent);
background: var(--c-accent); color: var(--lg-surface); text-decoration: none;
}
.lg-btn:hover { background: var(--c-accent-dark); border-color: var(--c-accent-dark); }
/* tabelle del gestionale: elenco clienti, sessioni, misure fuori range */
.lg-table { width: 100%; border-collapse: collapse; font-size: .88rem; }
.lg-table th, .lg-table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--lg-line); }
.lg-table th {
font-family: var(--font-heading); font-size: .7rem; font-weight: 600; letter-spacing: .08em;
text-transform: uppercase; color: var(--c-text-light);
}
.lg-table tbody tr:hover { background: var(--c-bg-alt); }
.lg-table a { color: var(--c-heading); font-weight: 600; text-decoration: none; }
.lg-table a:hover { color: var(--c-accent-dark); }
.lg-menu-btn { display: none; }
@media (max-width: 900px) {
.lg[data-variante="gestionale"] { display: block; }
.lg-menu-btn {
display: block; position: sticky; top: 0; z-index: 20; cursor: pointer;
background: var(--lg-surface); color: var(--c-heading); border-bottom: 1px solid var(--lg-line);
font-family: var(--font-heading); font-size: .7rem; font-weight: 600; letter-spacing: .16em;
text-transform: uppercase; padding: 14px 20px;
}
.lg-side { display: none; width: auto; flex: none; height: auto; position: static; }
.lg-menu-toggle:checked ~ .lg-side { display: flex; }
}
@media (max-width: 640px) {
.lg-top, .lg-main { padding-left: 20px; padding-right: 20px; }