This commit is contained in:
2026-04-29 21:10:53 +02:00
commit d073c4e1a5
29 changed files with 9793 additions and 0 deletions

105
Resistere_in_silenzio.md Normal file
View File

@@ -0,0 +1,105 @@
<span id="intro">
## Le protagoniste invisibili della storia:
</span>
Nel corso della storia, e in particolare durante le fasi di forte **crisi** che hanno attanagliato l'umanità, ad emergere sono quasi sempre figure maschili, oscurando **i sacrifici e la dedizione che contraddistinguono molte donne** in tali momenti di emergenza.
Tra gli esempi concreti dello sforzo femminile, vi è il loro impiego massiccio in fabbriche e negli ospedali da campo durante i due conflitti mondiali. In queste fasi, le donne non costituirono solo una figura di supporto logistico ma anche una **garanzia per la continuità della vita civile**; quanto descritto dimostra una rivoluzione silenziosa e impercettibile la quale riuscì gradualmente a **sfaldare le barriere del patriarcato dellepoca**.
Parallelamente agli avvenimenti concreti, anche la letteratura fa emergere forme di resistenza invisibili ma altrettanto profonde, come nel romanzo **La Ciociara** di Alberto Moravia.
I paragrafi che seguono propongono unanalisi storica e letteraria di fatti e testimonianze dellepoca, per far emergere quelli che sono stati i mutamenti nei confronti delle figure femminili, dal silenzio a ruolo cruciale per la storia, donne che, nel mezzo di una **lotta quotidiana per la sopravvivenza**, hanno imparato a “***salvarsi da sole***"
## La Resistenza italiana: un protagonismo femminile dimenticato
### Tra le due guerre:
Con lo scoppio della Prima guerra mondiale, lassenza di molti uomini chiamati a combattere al fronte provocò effetti economici e sociali devastanti in tutta Europa. Le uniche figure rimaste a poter impiegare i posti vacanti di molti contadini e operai furono le donne; continuando a svolgere allo stesso tempo le mansioni domestiche, questo intenso coinvolgimento vede ruoli sempre più di rilievo attribuiti alla donna (dalla gestione delle proprietà agricole alla Croce Rossa per il supporto dei feriti nelle vicinanze dei fronti di guerra).
Lavvento del regime fascista cercò di porre freno allemancipazione femminile avvenuta negli anni precedenti, attuando riforme costituite esplicitamente sulla disuguaglianza fra i sessi. Con la legge del 20 gennaio 1927, il governo fascista **dimezza gli stipendi delle donne**, basandosi sullidea che la donna dovesse essere dipendente economicamente dall'uomo e concentrarsi sulla famiglia.
Inoltre, attraverso **lONMI** (*Opera Nazionale Maternità e Infanzia*) si incentiva la natalità con premi e onorificenze alle “**madri prolifiche**” italiane, in modo tale da distogliere lattenzione dalle **aspirazioni professionali e sociali delle donne**
<span id="rest">
### La Resistenza:
</span>
Tra il 1943 e il 1945, nel pieno della Seconda guerra mondiale, furono decine di **migliaia** le donne italiane, di ogni età e ceto sociale che si esposero ai rischi della guerra, facendo fronte alla piaga del nazifascismo; non solo 'angeli del focolare', ma **parte cruciale per la liberazione dellItalia**, le quali, nel tentativo di portare al successo tale obiettivo comune, divennero vittime di deportazioni, uccisioni e violenze.
A Fronte di ciò il mondo (almeno allepoca) rispose a tali sacrifici **ignorandole** e **sminuendole**, tantè che in troppi casi le donne si rifiutarono di sfilare al fianco dei compagni nelle parate della vittoria, e solo pochissime partigiane ricevettero medaglie e riconoscimenti ufficiali.
Solo verso la fine degli anni 60 emerse la verità sul contributo delle donne durante la Seconda guerra mondiale e della Resistenza italiana: incarnarono **profili materni oltre i confini familiari** (assistendo soldati, prigionieri, ebrei e bambini) dimostrando anche un **forte protagonismo** alla pari di quello maschile.
Ancor prima della nascita della Resistenza, le donne furono protagoniste di scioperi tra il 1943 e 1944, contro lo sfruttamento nei loro confronti negli ambiti lavorativi e la loro riduzione ai compiti esclusivamente domestici della figura femminile, imposta imposte dal regime fascista in Italia.
Nel novembre 1943 nacquero a Milano i **GDD** (*Gruppi di Difesa della Donna*), i quali consistevano in aiuto economico alle famiglie dei deportati e dei combattenti, organizzazione di sabotaggi, attività di propaganda, raccolta di fondi, quindi non una specializzazione fissa per la donna, ma unoccupazione a 360 gradi comprendendo anche il combattere con le armi in pugno.
Come sosteneva **Ada Gobetti** (nome di battaglia *'Ulisse'*), tra i partigiani di **Giustizia e Libertà**, durante la Resistenza “*la donna era presente ovunque*”; infatti, secondo i dati forniti dall**ANPI** (*Associazione nazionale partigiani dItalia*), il numero delle donne che, dopo la guerra, ha presentato domanda ufficiale per il riconoscimento del titolo partigiano si aggirerebbe intorno alle 35.000, un valore considerato sottostimato a confronto di ipotesi moderne che in realtà portano alla luce la partecipazione di **almeno un milione di donne**, andando a comprendere:
- Donne dei **GDD**;
- Chi ha compiuto atti di disobbedienza radicale (come nascondere i ricercati).
Laccettazione di tali figure, dalla parte maschile, non fu facile. Agli albori di tali resistenze, alle donne venivano affidati compiti considerati adatti alla loro “natura”, quindi semplicemente cucinare o prendersi cura dei feriti; compiti più importanti furono legati al ruolo di **staffette** (tra quelli maggiormente riconosciuti), un compito che rompeva con l'immagine tradizionale della donna chiusa in casa. Il termine stesso richiama il passaggio di mano in mano dei messaggi, un lavoro fondamentale che solo a Firenze, per esempio, coinvolse circa 400 donne.
Per queste donne, la guerra portò una libertà di movimento prima impensabile: potevano viaggiare per giorni a piedi, in bicicletta o sui treni, spesso giustificando le assenze con i genitori o i vicini dicendo che andavano in campagna a cercare cibo. Era però un compito pericolosissimo, che richiedeva nervi saldi e il rispetto di **regole rigide per non farsi scoprire**, come:
- **Agire nell'ombra**: non rivelare a nessuno la propria missione e fingere una vita normale in famiglia.
- **Massima allerta**: assicurarsi di non essere seguite e avere sempre una scusa pronta in caso di fermo.
- **Discrezione assoluta**: nascondere il materiale con cura, camminare con disinvoltura e non svelare mai il contenuto di ciò che si consegnava.
Le staffette sapevano bene che un errore poteva costare la prigione, la violenza o la vita, rendendo la loro partecipazione una forma di resistenza coraggiosa e consapevole.
Una volta terminata la guerra, lesperienza della Resistenza e della Liberazione, era divenuta oramai un punto di non ritorno per il paese e anche per i diritti delle donne.
<span id="suf">
### Dalla Resistenza alle urne:
</span>
Questo impegno capillare e rischioso segnò un punto di non ritorno nella storia dell'emancipazione italiana. L'esperienza della Resistenza fu infatti il preludio necessario al riconoscimento del **suffragio universale**: prima ancora del Referendum del 2 giugno, **le donne italiane esercitarono il loro diritto di voto nelle elezioni amministrative della primavera del 1946**, un momento storico che vide un'affluenza massiccia e l'elezione delle prime donne nei consigli comunali.
Quel primo passo portò poi alla storica data del **2 giugno 1946**, quando furono chiamate al voto nazionale per scegliere tra **Monarchia e Repubblica**. Non si trattò di una concessione dall'alto, ma del riconoscimento di un diritto conquistato sul campo: dalle staffette alle 21 'Madri Costituenti', il contributo femminile divenne la base imprescindibile su cui fondare la nuova democrazia repubblicana.
Il 25 giugno 1946 si riunì per la prima volta lAssemblea costituente e ben **21 donne** entrano a far parte di quel gruppo di eletti che potevano sedere ufficialmente nei banchi della politica. Le cosiddette **Madri Costituenti** erano rappresentanti dei diversi partiti presenti nel paese: nove dalla DC, nove dal PCI, due dal PSIUP ed una dal Fronte Liberale Democratico dellUomo qualunque.
Limpatto di queste 21 donne nello scenario politico nazionale fece sì che tutto ciò che fino ad ora era delegato agli uomini, potesse essere portato avanti in prima persona da chi fino a poco prima era senza voce, come la formulazione dell'**Articolo 3** della Costituzione, dove l'aggiunta delle parole **“s*enza distinzione di sesso*”** non fu un semplice dettaglio formale, ma una vittoria politica monumentale. Quelle 21 donne rappresentavano tutte quelle staffette e partigiane che al momento del voto non avevano compiuto la maggiore età ma anche tutte le donne che ora si sentivano sempre più paritarie agli uomini.
<span id="lette">
## Sopravvivere come atto di coraggio: *La Ciociara* di Alberto Moravia
</span>
Se le 21 Madri Costituenti rappresentano il trionfo del protagonismo femminile nelle istituzioni, la letteratura di quegli stessi anni ci offre il ritratto di chi quella rivoluzione la visse non tra i banchi del Parlamento, ma faccia a faccia con la continua lotta per la sopravvivenza. È qui che si inserisce la figura di **Cesira**, protagonista del romanzo ***La Ciociara*** di **Alberto Moravia**.
Mentre la Storia ufficiale celebrava le grandi vittorie e i nuovi diritti, Cesira incarnava quella "***resistenza in silenzio***" tipica di chi non ha ideologie, ma solo la necessità biologica di sopravvivere. La sua storia non parla di politica, ma di una lotta quotidiana per la dignità che è altrettanto fondamentale per comprendere il ruolo della donna in quel periodo.
<span id="tram">
### La trama:
</span>
***La Ciociara* di Alberto Moravia**, pubblicato nel **1957**, racconta la storia di **Cesira**, una contadina ciociara trasferitasi a Roma dopo aver sposato un pizzicagnolo romano, e sua figlia **Rosetta**, un'adolescente timida. La loro vita cambia a causa degli eventi storici.
Quando i nazisti occupano Roma, sono costrette a fuggire nelle montagne della Ciociaria. Lì, cominciano a rendersi conto della malvagità e del male che non avevano mai visto prima. Il ritorno nella loro terra natale è un po' un ritorno alle origini e all'innocenza, nonostante le difficoltà economiche. L'arrivo degli Alleati sembra portare speranza. Ma è proprio allora che accade la cosa più terribile.
In una chiesa abbandonata, davanti a un'immagine della Madonna girata, un gruppo di soldati marocchini, chiamati **goumier**, che sono arrivati con gli inglesi e gli americani per liberare l'Italia, violentano Cesira e Rosetta. **Il male viene da chi avrebbe dovuto aiutarle**. Cesira guarda sua figlia, rassegnata a ciò che è accaduto. Il romanzo finisce con **la distruzione dell'innocenza e della speranza** che sembrava possibile.
La storia parla della guerra e delle persone che ne sono state colpite, e di come certe esperienze possano cambiare profondamente la vita delle persone.
### lo specchio di unItalia violata:
Il Romanzo evidenzia apertamente quali fossero le crudeltà della guerra nei confronti delle protagoniste, frutto non solo della freddezza nazifascista, ma anche dei crimini degli alleati; con la scena dello stupro da parte dei goumier fa riflettere il dramma storico delle cosiddette 'marocchinate': migliaia di donne italiane che, durante la liberazione, subirono stupri di massa da parte delle truppe coloniali francesi. Moravia usa questo trauma per mostrare come **la guerra non faccia distinzioni** tra ***'liberatori'*** e ***'oppressori'*** **quando si tratta di violare il corpo femminile**.
Tali momenti di crisi mettono in luce gli effetti devastanti su chi li vive: attraverso levoluzione morale di Rosetta, la quale ne esce moralmente degradata e privata della sua innocenza originaria, non solo Moravia fa appello a ciò che subirono le donne lottando per la loro sopravvivenza, ma fa anche da simbolo di unItalia, la quale sarà per sempre segnata da tali crimini.
## Dalle macerie alla dignità: l'eredità di una lotta
In definitiva, l'indagine condotta tra le pieghe della storia e i ritratti della letteratura rivela come il silenzio delle donne non sia mai stato sinonimo di assenza, ma una forma di resistenza attiva e resiliente. Se da un lato la storia ufficiale ci consegna limmagine gloriosa delle Madri Costituenti e il traguardo fondamentale del suffragio universale, dall'altro la letteratura di Moravia ci ricorda il prezzo umano e il trauma di chi ha vissuto la guerra sulla propria pelle.
Cesira e Rosetta rappresentano l'altra faccia della medaglia: **quella di unItalia violata che**, nonostante la fine del conflitto, deve fare i conti con ferite invisibili. Tuttavia, è proprio da quel "*salvarsi da sole*" e da quella partecipazione coraggiosa nelle fabbriche, nelle montagne e nelle urne, che è nata lItalia moderna.
Oggi, riconoscere il ruolo delle donne tra il 1943 e il 1946 significa non solo rendere giustizia a un protagonismo a lungo dimenticato, ma anche onorare quel mutamento sociale che ha trasformato la sopravvivenza individuale in una conquista collettiva di dignità e libertà. La "*rivoluzione silenziosa*" di allora rimane ancora oggi la base fondamentale su cui poggiano i nostri valori democratici, ricordandoci che nessun diritto è mai stato una concessione, ma il frutto di una **lotta consapevole per esistere e resistere**.

412
content/css/style.css Normal file
View File

@@ -0,0 +1,412 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--bg-body: #050505;
--bg-header: rgba(10, 10, 10, 0.85);
--bg-footer: #0a0a0a;
--accent: rgb(249, 39, 39);
--text-primary: #ffffff;
--text-secondary: #a0a0a0;
--border: #222222;
--transition: all 0.4s ease;
}
/* --- LOGICA PER FOOTER IN BASSO --- */
html,
body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
/* Impila gli elementi verticalmente */
background-color: var(--bg-body);
font-family: 'Inter', sans-serif;
color: var(--text-primary);
line-height: 1.6;
}
/* Il main occupa tutto lo spazio vuoto spingendo il footer */
main {
flex: 1 0 auto;
background: rgba(15, 15, 15, 0.568);
}
.footer {
flex-shrink: 0;
/* Impedisce al footer di restringersi */
}
/* ---------------------------------- */
a {
text-decoration: none;
color: inherit;
transition: var(--transition);
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 25px;
}
/* --- HEADER --- */
.header {
position: fixed;
top: 0;
width: 100%;
z-index: 1000;
background: var(--bg-header);
backdrop-filter: blur(15px);
border-bottom: 1px solid var(--border);
padding: 18px 0;
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 1.4rem;
font-weight: 800;
letter-spacing: -0.5px;
text-transform: uppercase;
}
.logo span {
color: var(--accent);
}
.nav-menu {
display: flex;
list-style: none;
gap: 35px;
}
.nav-link {
font-size: 0.85rem;
font-weight: 500;
color: var(--text-secondary);
letter-spacing: 1px;
text-transform: uppercase;
}
.nav-link:hover {
color: var(--accent);
}
.cta-btn {
background: var(--accent);
padding: 10px 22px;
border-radius: 2px;
font-weight: 700;
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 1px;
}
.cta-btn:hover {
filter: brightness(1.2);
box-shadow: 0 0 20px rgba(188, 0, 0, 0.4);
}
/* --- CONTENUTO --- */
.hero {
min-height: 60vh;
/* Altezza minima per il contenuto */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.hero h1 {
font-size: clamp(3rem, 10vw, 5rem);
font-weight: 900;
line-height: 1;
margin-bottom: 20px;
}
/* --- FOOTER --- */
.footer {
background: var(--bg-footer);
border-top: 1px solid var(--border);
padding: 80px 0 30px;
}
.footer-grid {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
gap: 50px;
margin-bottom: 60px;
}
.footer-brand h2 {
color: var(--accent);
margin-bottom: 20px;
font-size: 1.5rem;
}
.footer-brand p {
color: var(--text-secondary);
max-width: 400px;
font-size: 0.95rem;
}
.footer-title {
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 2px;
color: #fff;
margin-bottom: 25px;
display: block;
}
.footer-list {
list-style: none;
}
.footer-list li {
margin-bottom: 12px;
}
.footer-list a {
color: var(--text-secondary);
font-size: 0.9rem;
}
.footer-list a:hover {
color: var(--accent);
padding-left: 8px;
}
.footer-bottom {
border-top: 1px solid var(--border);
padding-top: 30px;
display: flex;
justify-content: space-between;
align-items: center;
color: #444;
font-size: 0.8rem;
}
@media (max-width: 768px) {
.nav-menu,
.cta-btn {
display: none;
}
.footer-grid {
grid-template-columns: 1fr;
gap: 40px;
}
.footer-bottom {
flex-direction: column;
gap: 15px;
text-align: center;
}
}
.iframe-background {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
border: none;
z-index: -2;
pointer-events: none;
transform: scale(1.5);
transform-origin: center;
}
.title-conteiner {
position: relative;
width: 100%;
max-height: 500px;
overflow: hidden;
}
.title-conteiner img {
width: 100%;
height: 500px;
display: block;
object-fit: cover;
}
.title-on-img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.664);
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 20px;
box-sizing: border-box;
}
.title-on-img h1, .title-on-img h2, .title-on-img p {
max-width: 850px;
}
.title-on-img h1 {
font-family: 'Playfair Display', serif;
font-size: 3rem;
color: #c02626;
margin-bottom: 5px;
text-transform: uppercase;
letter-spacing: 2px;
}
.title-on-img h2 {
font-family: 'Playfair Display', serif;
font-style: italic;
font-size: 1.5rem;
color: #e9ecef;
font-weight: 400;
margin-bottom: 20px;
}
.title-on-img p {
font-family: 'Montserrat', sans-serif;
font-size: 1.1rem;
color: #f8f9fa;
line-height: 1.6;
max-width: 700px;
}
.footer-logo {
width: 70px;
}
@media (max-width: 768px) {
.title-on-img h1 { font-size: 2rem; }
.title-on-img h2 { font-size: 1.1rem; }
.title-on-img p { font-size: 0.95rem; }
}
@media (max-width: 768px) {
.title-conteiner img {
height: 400px;
}
.title-on-img {
padding: 15px;
}
.title-on-img h1 {
font-size: 1.8rem;
margin-bottom: 10px;
}
.title-on-img h2 {
font-size: 1.2rem;
line-height: 1.3;
}
.title-on-img p {
font-size: 0.9rem;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
.markdown-body {
font-family: 'Inter', sans-serif;
line-height: 1.8;
color: #e0e0e0;
max-width: 850px;
margin: 0 auto;
padding: 40px 20px;
background-color: transparent;
}
.markdown-body h2 {
font-size: 2rem;
font-weight: 700;
color: rgb(249, 39, 39);
border-bottom: 1px solid #333;
padding-bottom: 0.5rem;
margin-top: 2.5rem;
margin-bottom: 1rem;
letter-spacing: -0.01em;
}
.markdown-body h3 {
font-size: 1.5rem;
font-weight: 600;
color: #f8f9fa;
margin-top: 2rem;
margin-bottom: 0.8rem;
}
.markdown-body p {
font-size: 1.15rem;
margin-bottom: 1.5rem;
color: #bdbdbd;
font-weight: 300;
}
.markdown-body strong {
color: #ffffff;
font-weight: 600;
letter-spacing: 0.02em;
}
@media (max-width: 768px) {
.markdown-body {
padding: 20px 15px;
}
.markdown-body h2 {
font-size: 1.5rem;
margin-top: 1.8rem;
line-height: 1.2;
}
.markdown-body h3 {
font-size: 1.25rem;
margin-top: 1.5rem;
}
.markdown-body p {
font-size: 1rem;
line-height: 1.6;
text-align: left;
color: #d1d1d1;
}
.markdown-body strong {
font-weight: 700;
}
}

1995
content/php/Parsedown.php Normal file

File diff suppressed because it is too large Load Diff

52
content/php/markDown.php Normal file
View File

@@ -0,0 +1,52 @@
<?php
require_once "Parsedown.php";
/**
* Converte Markdown in HTML da sorgente locale o remota.
*
* @param string $localPath Percorso del file sul server
* @param string $remoteUrl URL del file .md
* @return string HTML generato
*/
function getMarkdownContent($localPath, $remoteUrl)
{
clearstatcache();
$markdown = false;
// Definiamo il percorso assoluto completo
$fullLocalPath = $localPath;
// 1. Tentativo Locale (Corretto)
if (file_exists($fullLocalPath)) {
$markdown = file_get_contents($fullLocalPath);
}
// 2. Fallback Remoto
if ($markdown === false) {
$ch = curl_init($remoteUrl);
// Sostituisci la parte del cURL con questa logica di "cache busting"
$timestamp = time();
$separator = (strpos($remoteUrl, '?') !== false) ? '&' : '?';
$urlWithNoCache = $remoteUrl . $separator . "t=" . $timestamp;
curl_setopt($ch, CURLOPT_URL, $urlWithNoCache);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$markdown = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($markdown === false || $httpCode !== 200) {
return "<p>Errore: Impossibile recuperare il contenuto ($httpCode).</p>";
}
}
$Parsedown = new Parsedown();
// Importante: Rimuove eventuali spazi bianchi superflui all'inizio/fine
return '<div class="markdown-body">' . $Parsedown->text(trim($markdown)) . '</div>';
}
?>

BIN
img/woman-hair.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
img/women-smovement.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

100
index.php Normal file
View File

@@ -0,0 +1,100 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Resistere in Silenzio</title>
<link rel="icon" href="img/woman-hair.png" type="image/png">
<link rel="stylesheet" href="content/css/style.css">
</head>
<body>
<?php
$env = getenv('APP_ENV') ?: 'prod';
// Definisce l'URL in base all'ambiente e alla pagina
if ($env === 'local') {
$nextUrl = "http://localhost:3000/plasma";
} else {
$nextUrl = "/next/out/plasma.html";
}
?>
<iframe src="<?= $nextUrl ?>" class="iframe-background" title="Floating Lines"></iframe>
<div class="div-content"></div>
<header class="header">
<div class="container header-content">
<div class="logo">Resistere<span>.</span>in<span>.</span>Silenzio</div>
<nav>
<ul class="nav-menu">
<li><a href="#intro" class="nav-link">Introduzione</a></li>
<li><a href="#rest" class="nav-link">Resistenza</a></li>
<li><a href="#suf" class="nav-link">Suffragio</a></li>
<li><a href="#lette" class="nav-link">La Ciociara</a></li>
</ul>
</nav>
</div>
</header>
<main>
<div class="title-conteiner">
<img src="img/women-smovement.webp">
<div class="title-on-img">
<h1>Resistere in Silenzio</h1>
<h2>Il ruolo nascosto ma fondamentale delle donne tra storia e letteratura</h2>
<p>Un archivio digitale dedicato alle storie sommerse delle donne che hanno forgiato il proprio destino.
Figure silenziose che hanno trovato in sé la forza di resistere e liberarsi. Perché la libertà
è una radice antica che va difesa, ogni giorno.</p>
</div>
</div>
<div>
<?php
include "content/php/markDown.php";
$fileLocale = __DIR__ . "/Resistere_in_silenzio.md";
$urlRemoto = "test/Resistere_in_silenzio.md";
echo getMarkdownContent($fileLocale, $urlRemoto);
?>
</div>
</main>
<footer class="footer">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<h2>Resistere in Silenzio</h2>
<p>Un archivio digitale dedicato alle storie sommerse delle donne che hanno forgiato il proprio
destino. Figure silenziose che hanno trovato in sé la forza di resistere e liberarsi. Perché la
libertà è una radice antica che va difesa, ogni giorno.</p>
</div>
<div>
<span class="footer-title">Approfondimenti</span>
<ul class="footer-list">
<li><a href="#suf">Le 21 Costituenti</a></li>
<li><a href="#rest">Gruppi di Difesa</a></li>
<li><a href="#tram">La Ciociara: Trama</a></li>
</ul>
</div>
<div>
<img src="img/woman-hair.png" alt="Logo" class="footer-logo">
</div>
</div>
<div class="footer-bottom">
<p>&copy; 2026 - Realizzzato da Muccari Luigi. Tutti i diritti riservati.</p>
</div>
</div>
</footer>
</body>
</html>

41
my-app/.gitignore vendored Normal file
View File

@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

5
my-app/AGENTS.md Normal file
View File

@@ -0,0 +1,5 @@
<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->

1
my-app/CLAUDE.md Normal file
View File

@@ -0,0 +1 @@
@AGENTS.md

36
my-app/README.md Normal file
View File

@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.

BIN
my-app/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

26
my-app/app/globals.css Normal file
View File

@@ -0,0 +1,26 @@
@import "tailwindcss";
:root {
--background: #ffffff;
--foreground: #171717;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}

33
my-app/app/layout.tsx Normal file
View File

@@ -0,0 +1,33 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html
lang="en"
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
>
<body className="min-h-full flex flex-col">{children}</body>
</html>
);
}

14
my-app/app/page.tsx Normal file
View File

@@ -0,0 +1,14 @@
"use client";
export default function Home() {
return (
<main className="min-h-screen w-full bg-black">
{/*
Pagina Home vuota.
I componenti sono ora raggiungibili separatamente su:
/terminal
/text
*/}
</main>
);
}

View File

@@ -0,0 +1,37 @@
"use client";
import dynamic from "next/dynamic";
// 1. Definiamo l'interfaccia delle props
interface PlasmaProps {
color?: string;
speed?: number;
direction?: "forward" | "backward";
scale?: number;
opacity?: number;
mouseInteractive?: boolean;
}
// 2. Passiamo l'interfaccia al generic di dynamic
const PlasmaCanvas = dynamic<PlasmaProps>(
() => import("../../src/components/Plasma"),
{
ssr: false,
loading: () => <div style={{ background: "black", width: "100vw", height: "100vh" }} />,
}
);
export default function PlasmaPage() {
return (
<div style={{ width: "100%", height: "600px", position: "relative" }}>
<PlasmaCanvas
color="#5f0000"
speed={0.6}
direction="forward"
scale={1.1}
opacity={0.8}
mouseInteractive={true}
/>
</div>
);
}

18
my-app/eslint.config.mjs Normal file
View File

@@ -0,0 +1,18 @@
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
const eslintConfig = defineConfig([
...nextVitals,
...nextTs,
// Override default ignores of eslint-config-next.
globalIgnores([
// Default ignores of eslint-config-next:
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
]),
]);
export default eslintConfig;

7
my-app/next.config.ts Normal file
View File

@@ -0,0 +1,7 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
};
export default nextConfig;

6592
my-app/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

27
my-app/package.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
},
"dependencies": {
"next": "16.2.4",
"ogl": "^1.0.11",
"react": "19.2.4",
"react-dom": "19.2.4"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.2.4",
"tailwindcss": "^4",
"typescript": "^5"
}
}

View File

@@ -0,0 +1,7 @@
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
};
export default config;

1
my-app/public/file.svg Normal file
View File

@@ -0,0 +1 @@
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 391 B

1
my-app/public/globe.svg Normal file
View File

@@ -0,0 +1 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

1
my-app/public/next.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

1
my-app/public/vercel.svg Normal file
View File

@@ -0,0 +1 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 128 B

1
my-app/public/window.svg Normal file
View File

@@ -0,0 +1 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>

After

Width:  |  Height:  |  Size: 385 B

View File

@@ -0,0 +1,6 @@
.plasma-container {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}

View File

@@ -0,0 +1,240 @@
import { useEffect, useRef } from 'react';
import { Renderer, Program, Mesh, Triangle } from 'ogl';
import './Plasma.css';
const hexToRgb = hex => {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
if (!result) return [1, 0.5, 0.2];
return [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255];
};
const vertex = `#version 300 es
precision highp float;
in vec2 position;
in vec2 uv;
out vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4(position, 0.0, 1.0);
}
`;
const fragment = `#version 300 es
precision highp float;
uniform vec2 iResolution;
uniform float iTime;
uniform vec3 uCustomColor;
uniform float uUseCustomColor;
uniform float uSpeed;
uniform float uDirection;
uniform float uScale;
uniform float uOpacity;
uniform vec2 uMouse;
uniform float uMouseInteractive;
out vec4 fragColor;
void mainImage(out vec4 o, vec2 C) {
vec2 center = iResolution.xy * 0.5;
C = (C - center) / uScale + center;
vec2 mouseOffset = (uMouse - center) * 0.0002;
C += mouseOffset * length(C - center) * step(0.5, uMouseInteractive);
float i, d, z, T = iTime * uSpeed * uDirection;
vec3 O, p, S;
for (vec2 r = iResolution.xy, Q; ++i < 60.; O += o.w/d*o.xyz) {
p = z*normalize(vec3(C-.5*r,r.y));
p.z -= 4.;
S = p;
d = p.y-T;
p.x += .4*(1.+p.y)*sin(d + p.x*0.1)*cos(.34*d + p.x*0.05);
Q = p.xz *= mat2(cos(p.y+vec4(0,11,33,0)-T));
z+= d = abs(sqrt(length(Q*Q)) - .25*(5.+S.y))/3.+8e-4;
o = 1.+sin(S.y+p.z*.5+S.z-length(S-p)+vec4(2,1,0,8));
}
o.xyz = tanh(O/1e4);
}
bool finite1(float x){ return !(isnan(x) || isinf(x)); }
vec3 sanitize(vec3 c){
return vec3(
finite1(c.r) ? c.r : 0.0,
finite1(c.g) ? c.g : 0.0,
finite1(c.b) ? c.b : 0.0
);
}
void main() {
vec4 o = vec4(0.0);
mainImage(o, gl_FragCoord.xy);
vec3 rgb = sanitize(o.rgb);
float intensity = (rgb.r + rgb.g + rgb.b) / 3.0;
vec3 customColor = intensity * uCustomColor;
vec3 finalColor = mix(rgb, customColor, step(0.5, uUseCustomColor));
float alpha = length(rgb) * uOpacity;
fragColor = vec4(finalColor, alpha);
}`;
export const Plasma = ({
color = '#ffffff',
speed = 1,
direction = 'forward',
scale = 1,
opacity = 1,
mouseInteractive = true
}) => {
const containerRef = useRef(null);
const mousePos = useRef({ x: 0, y: 0 });
useEffect(() => {
if (!containerRef.current) return;
const containerEl = containerRef.current;
const useCustomColor = color ? 1.0 : 0.0;
const customColorRgb = color ? hexToRgb(color) : [1, 1, 1];
const directionMultiplier = direction === 'reverse' ? -1.0 : 1.0;
let renderer;
try {
renderer = new Renderer({
webgl: 2,
alpha: true,
antialias: false,
dpr: Math.min(window.devicePixelRatio || 1, 2)
});
} catch {
return;
}
const gl = renderer.gl;
if (!gl) return;
const canvas = gl.canvas;
canvas.style.display = 'block';
canvas.style.width = '100%';
canvas.style.height = '100%';
containerEl.appendChild(canvas);
const geometry = new Triangle(gl);
const program = new Program(gl, {
vertex: vertex,
fragment: fragment,
uniforms: {
iTime: { value: 0 },
iResolution: { value: new Float32Array([1, 1]) },
uCustomColor: { value: new Float32Array(customColorRgb) },
uUseCustomColor: { value: useCustomColor },
uSpeed: { value: speed * 0.4 },
uDirection: { value: directionMultiplier },
uScale: { value: scale },
uOpacity: { value: opacity },
uMouse: { value: new Float32Array([0, 0]) },
uMouseInteractive: { value: mouseInteractive ? 1.0 : 0.0 }
}
});
const mesh = new Mesh(gl, { geometry, program });
const handleMouseMove = e => {
if (!mouseInteractive) return;
const rect = containerEl.getBoundingClientRect();
mousePos.current.x = e.clientX - rect.left;
mousePos.current.y = e.clientY - rect.top;
const mouseUniform = program.uniforms.uMouse.value;
mouseUniform[0] = mousePos.current.x;
mouseUniform[1] = mousePos.current.y;
};
if (mouseInteractive) {
containerEl.addEventListener('mousemove', handleMouseMove);
}
const setSize = () => {
const rect = containerEl.getBoundingClientRect();
const width = Math.max(1, Math.floor(rect.width));
const height = Math.max(1, Math.floor(rect.height));
renderer.setSize(width, height);
const res = program.uniforms.iResolution.value;
res[0] = gl.drawingBufferWidth;
res[1] = gl.drawingBufferHeight;
};
const ro = new ResizeObserver(setSize);
ro.observe(containerEl);
setSize();
let raf = 0;
let contextLost = false;
let isVisible = true;
const t0 = performance.now();
const loop = t => {
if (contextLost || !isVisible) return;
let timeValue = (t - t0) * 0.001;
if (direction === 'pingpong') {
const pingpongDuration = 10;
const segmentTime = timeValue % pingpongDuration;
const isForward = Math.floor(timeValue / pingpongDuration) % 2 === 0;
const u = segmentTime / pingpongDuration;
const smooth = u * u * (3 - 2 * u);
const pingpongTime = isForward ? smooth * pingpongDuration : (1 - smooth) * pingpongDuration;
program.uniforms.uDirection.value = 1.0;
program.uniforms.iTime.value = pingpongTime;
} else {
program.uniforms.iTime.value = timeValue;
}
renderer.render({ scene: mesh });
raf = requestAnimationFrame(loop);
};
const handleContextLost = (e) => {
e.preventDefault();
contextLost = true;
cancelAnimationFrame(raf);
};
const handleContextRestored = () => {
contextLost = false;
if (isVisible) {
cancelAnimationFrame(raf);
raf = requestAnimationFrame(loop);
}
};
canvas.addEventListener('webglcontextlost', handleContextLost);
canvas.addEventListener('webglcontextrestored', handleContextRestored);
const io = new IntersectionObserver(([entry]) => {
const wasVisible = isVisible;
isVisible = entry.isIntersecting;
if (isVisible && !wasVisible && !contextLost) {
cancelAnimationFrame(raf);
raf = requestAnimationFrame(loop);
}
}, { threshold: 0 });
io.observe(containerEl);
raf = requestAnimationFrame(loop);
return () => {
cancelAnimationFrame(raf);
ro.disconnect();
io.disconnect();
canvas.removeEventListener('webglcontextlost', handleContextLost);
canvas.removeEventListener('webglcontextrestored', handleContextRestored);
if (mouseInteractive && containerEl) {
containerEl.removeEventListener('mousemove', handleMouseMove);
}
try {
containerEl?.removeChild(canvas);
} catch {}
};
}, [color, speed, direction, scale, opacity, mouseInteractive]);
return <div ref={containerRef} className="plasma-container" />;
};
export default Plasma;

34
my-app/tsconfig.json Normal file
View File

@@ -0,0 +1,34 @@
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts",
"**/*.mts"
],
"exclude": ["node_modules"]
}