Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4757c3e0a9 | ||
|
|
7c36f87149 | ||
|
|
84caa87951 | ||
|
|
6330a13d92 | ||
|
|
2d0d34c4ff | ||
|
|
af4f3d35f0 | ||
|
|
9684ff98ea | ||
|
|
5feab1ba69 | ||
|
|
0a2df372d5 |
+6
-1
@@ -18,6 +18,11 @@ export default defineConfig({
|
||||
theme: 'github-light',
|
||||
},
|
||||
},
|
||||
integrations: [preact(), mdx()],
|
||||
integrations: [
|
||||
preact({
|
||||
compat: true,
|
||||
}),
|
||||
mdx(),
|
||||
],
|
||||
output: 'static',
|
||||
})
|
||||
|
||||
@@ -21,12 +21,14 @@
|
||||
"@fontsource/source-sans-pro": "^5.0.8",
|
||||
"@fontsource/space-mono": "^5.0.20",
|
||||
"@phosphor-icons/core": "^2.1.1",
|
||||
"@phosphor-icons/react": "^2.1.7",
|
||||
"@preact/signals": "^1.3.0",
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"astro": "5.1.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"katex": "^0.16.9",
|
||||
"lucide-static": "^0.468.0",
|
||||
"marked": "^15.0.6",
|
||||
"preact": "^10.19.6",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 645 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 113 KiB |
@@ -0,0 +1,116 @@
|
||||
import { useEffect, useState } from 'preact/hooks'
|
||||
import { Funnel } from '@phosphor-icons/react'
|
||||
import { marked } from 'marked'
|
||||
|
||||
import type { Database } from '@/data/domande-esami.yaml'
|
||||
|
||||
const useRemoteValue = <T,>(url: string): T | null => {
|
||||
const [value, setValue] = useState<T | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(value => setValue(value))
|
||||
}, [url])
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
type Props = {
|
||||
course: string
|
||||
}
|
||||
|
||||
export const DomandeEsamiCourse = ({ course }: Props) => {
|
||||
const database = useRemoteValue<Database>(`/domande-esami/api/${course}.json`)
|
||||
if (!database) {
|
||||
return <>Loading...</>
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
requestIdleCallback(() => window.renderMath())
|
||||
|
||||
console.log(database)
|
||||
|
||||
const courseTags = [
|
||||
...new Set(
|
||||
database.questions
|
||||
.filter(question => question.course === course)
|
||||
.flatMap(question => question.tags)
|
||||
),
|
||||
]
|
||||
|
||||
const [selectedTags, setSelectedTags] = useState<string[]>([])
|
||||
|
||||
const filteredQuestions = database.questions
|
||||
.filter(question => question.course === course)
|
||||
.filter(
|
||||
question => selectedTags.length === 0 || selectedTags.every(tag => question.tags.includes(tag))
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="grid-center">
|
||||
<h3>
|
||||
<a href="/domande-esami">Domande Esami</a>
|
||||
</h3>
|
||||
<h1>{database.names[course]}</h1>
|
||||
</div>
|
||||
|
||||
<div class="card filter">
|
||||
<div class="grid-h">
|
||||
<Funnel />
|
||||
<strong>Filtra Tag</strong>
|
||||
</div>
|
||||
<div class="flex-row-wrap">
|
||||
{selectedTags.length === 0
|
||||
? courseTags.map(tag => (
|
||||
<div class="chip clickable" onClick={() => setSelectedTags([tag])}>
|
||||
{tag}
|
||||
</div>
|
||||
))
|
||||
: courseTags.map(tag => (
|
||||
<div
|
||||
class={
|
||||
selectedTags.includes(tag)
|
||||
? 'chip clickable'
|
||||
: 'chip clickable disabled'
|
||||
}
|
||||
onClick={() =>
|
||||
setSelectedTags(
|
||||
selectedTags.includes(tag)
|
||||
? selectedTags.filter(t => t !== tag)
|
||||
: [...selectedTags, tag]
|
||||
)
|
||||
}
|
||||
>
|
||||
{tag}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div class="wide-card-list" id="questions">
|
||||
{filteredQuestions.length === 0 ? (
|
||||
<div class="grid-center">
|
||||
<em>No questions found</em>
|
||||
</div>
|
||||
) : (
|
||||
filteredQuestions.map(question => (
|
||||
<div class="card">
|
||||
<div
|
||||
class="text"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: marked(question.content, { async: false }),
|
||||
}}
|
||||
/>
|
||||
<div class="metadata">
|
||||
{question.tags.map(tag => (
|
||||
<div class="chip small">{tag}</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: Incidente del 2-7 Gennaio 2025
|
||||
description: Riassunto dell'incidente che ha portato al guasto del server Poisson e delle azioni intraprese per ripristinare i servizi.
|
||||
publishDate: 2025-01-07
|
||||
---
|
||||
|
||||
# Incidente 2-7 Gennaio 2025
|
||||
|
||||
In questi giorni il server fisico principale del PHC, **Poisson**, non è stato operativo. Di conseguenza, i servizi ospitati direttamente su Poisson, come le pagine web degli utenti, l'accesso SSH e Gitea, sono rimasti offline. Al contrario, altri servizi web del PHC che non sono hostati su Poisson non hanno subito interruzioni. La buona notizia è che tutti i dati sono stati recuperati con successo e che l'infrastruttura è tornata pienamente operativa senza ulteriori complicazioni.
|
||||
|
||||
## Cosa è successo?
|
||||
|
||||
Sospettiamo che la causa principale dell'incidente sia stata una serie di brusche accensioni e spegnimenti, che hanno portato al guasto della scheda madre di Poisson. Il server non riusciva più ad avviarsi, neanche accedendo al BIOS, rendendo evidente che il problema era di natura hardware.
|
||||
|
||||
### Diagnosi e sostituzione
|
||||
|
||||
La mattina del 7 Gennaio, grazie alla disponibilità del dipartimento, abbiamo trovato una scheda madre di recupero, simile a quella originale ma meno potente. Questa è stata installata immediatamente, permettendo di riportare Poisson in funzione. Dal punto di vista software non è cambiato nulla: l'architettura della CPU è rimasta invariata, sebbene con meno core e la metà della RAM. Gli Hard Disks e una delle schede di rete sono stati riutilizzati senza problemi.
|
||||
|
||||
In un futuro prossimo si prevede di aggiornare la scheda madre con una più potente, per garantire le prestazioni di Poisson. Preghiamo per ora quindi di evitare di eseguire operazioni troppo pesanti sul server.
|
||||
|
||||
Tutto è stato rimontato nel consueto case bianco che ospita Poisson. Anche se ora è operativo, il server potrebbe essere considerato una nuova incarnazione, sollevando una riflessione interessante: **Poisson è ancora lo stesso server?** Proprio come nel paradosso della nave di Teseo, molti componenti di Poisson sono stati sostituiti nel corso degli anni. Dal 1992, pezzi come HDD, CPU, RAM e schede madri sono stati aggiornati per mantenere il server al passo con i tempi, mentre i dati e le funzionalità sono rimasti intatti.
|
||||
|
||||

|
||||
|
||||
## Ritorno alla normalità
|
||||
|
||||
Grazie all’intervento, i servizi principali sono tornati online. Gli utenti possono nuovamente accedere alle proprie pagine web, utilizzare SSH e lavorare su Gitea senza alcuna modifica ai dati o alle configurazioni precedenti.
|
||||
|
||||
Per chi avesse riscontrato difficoltà nell'accesso, invitiamo a contattare i macchinisti per ricevere supporto.
|
||||
|
||||
> Be a System Administrator, they said. It will be fun, they said 🤦♂️
|
||||
@@ -0,0 +1,201 @@
|
||||
names:
|
||||
aritmetica: Aritmetica
|
||||
geometria-1: Geometria 1
|
||||
analisi-1: Analisi 1
|
||||
algebra-1: Algebra 1
|
||||
geometria-2: Geometria 2
|
||||
analisi-2: Analisi 2
|
||||
algebra-2: Algebra 2
|
||||
analisi-3: Analisi 3
|
||||
ricerca-operativa: Ricerca Operativa
|
||||
fisica-3: Fisica 3
|
||||
meccanica-razionale: Meccanica Razionale
|
||||
istituzioni-di-geometria: Istituzioni di Geometria
|
||||
istituzioni-di-analisi: Istituzioni di Analisi
|
||||
istituzioni-di-algebra: Istituzioni di Algebra
|
||||
istituzioni-di-fisica: Istituzioni di Fisica
|
||||
istituzioni-di-probabilità: Istituzioni di Probabilità
|
||||
geometria-e-topologia-differenziale: Geometria e Topologia Differenziale
|
||||
analisi-armonica: Analisi Armonica
|
||||
elementi-di-analisi-complessa: Elementi di Analisi Complessa
|
||||
|
||||
groups:
|
||||
- id: triennale-anno-1
|
||||
name: I Anno Triennale
|
||||
items:
|
||||
- aritmetica
|
||||
- geometria-1
|
||||
- analisi-1
|
||||
- algebra-1
|
||||
|
||||
- id: triennale-anno-2
|
||||
name: II Anno Triennale
|
||||
items:
|
||||
- geometria-2
|
||||
- analisi-2
|
||||
- algebra-1
|
||||
|
||||
- id: triennale-anno-3
|
||||
name: III Anno Triennale
|
||||
items:
|
||||
- ricerca-operativa
|
||||
- fisica-3
|
||||
- meccanica-razionale
|
||||
|
||||
- id: istituzioni
|
||||
name: Istituzioni
|
||||
items:
|
||||
- istituzioni-di-geometria
|
||||
- istituzioni-di-analisi
|
||||
- istituzioni-di-algebra
|
||||
- istituzioni-di-fisica
|
||||
- istituzioni-di-probabilità
|
||||
|
||||
- id: other
|
||||
name: Esami a scelta
|
||||
items:
|
||||
- geometria-e-topologia-differenziale
|
||||
- analisi-armonica
|
||||
- elementi-di-analisi-complessa
|
||||
|
||||
questions:
|
||||
- course: geometria-1
|
||||
content: |
|
||||
Dimostrare il teorema spettrale reale
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: gtd
|
||||
content: |
|
||||
Calcolare la curvatura gaussiana di una sfera di raggio $r$
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: geometria-1
|
||||
content: |
|
||||
Dimostrare che _l'area_ di un cerchio è $A = \pi r^2$
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
- course: algebra-1
|
||||
content: |
|
||||
Dimostrare il teorema di Sylow
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: algebra-1
|
||||
content: |
|
||||
Dimostrare che ogni sottogruppo di un gruppo ciclico è ciclico
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
- course: analisi-1
|
||||
content: |
|
||||
Dimostrare il teorema di Weierstrass
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: analisi-1
|
||||
content: |
|
||||
Dimostrare che se $f$ è continua su $[a,b]$, allora $f$ è limitata
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
- course: analisi-2
|
||||
content: |
|
||||
Dimostrare il teorema di Stokes
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: analisi-2
|
||||
content: |
|
||||
Dimostrare il teorema di Green
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
- course: analisi-3
|
||||
content: |
|
||||
Dimostrare il teorema di Cauchy
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: analisi-3
|
||||
content: |
|
||||
Dimostrare il teorema di Liouville
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
- course: algebra-2
|
||||
content: |
|
||||
Dimostrare il teorema di struttura per i gruppi abeliani finiti
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: algebra-2
|
||||
content: |
|
||||
Dimostrare il teorema di struttura per i gruppi finiti
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
- course: ricerca-operativa
|
||||
content: |
|
||||
Dimostrare il teorema di dualità per i problemi di programmazione lineare
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: geometria-topologia-differenziale
|
||||
content: |
|
||||
Dimostrare il teorema di Poincaré-Hopf
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: analisi-armonica
|
||||
content: |
|
||||
Dimostrare il teorema di Hahn-Banach
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: analisi-complessa
|
||||
content: |
|
||||
Dimostrare il teorema di Morera
|
||||
tags:
|
||||
- 2024
|
||||
|
||||
- course: analisi-complessa
|
||||
content: |
|
||||
Dimostrare il teorema degli zeri di Weierstrass
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
- course: analisi-complessa
|
||||
content: |
|
||||
Dimostrare il teorema della mappa aperta
|
||||
tags:
|
||||
- 2022
|
||||
|
||||
- course: analisi-complessa
|
||||
content: |
|
||||
Dimostrare il teorema della mappa aperta
|
||||
tags:
|
||||
- 2021
|
||||
|
||||
- course: geometria-2
|
||||
content: |
|
||||
Dimostrare il teorema di Van Kampen
|
||||
tags:
|
||||
- 2024
|
||||
- Frigerio
|
||||
|
||||
- course: geometria-2
|
||||
content: |
|
||||
Definizione di gruppo fondamentale
|
||||
tags:
|
||||
- 2023
|
||||
- Frigerio
|
||||
|
||||
- course: geometria-2
|
||||
content: |
|
||||
Dimostrare il teorema Cauchy
|
||||
tags:
|
||||
- 2022
|
||||
- Abate
|
||||
@@ -32,11 +32,41 @@
|
||||
|
||||
- fullName: Illya Serdyuk
|
||||
entranceDate: 2020
|
||||
description: Bla bla Void Linux
|
||||
social:
|
||||
github: https://github.com/Kratacoa
|
||||
|
||||
- fullName: Francesco Manicastri
|
||||
entranceDate: 2022
|
||||
exitDate: 2024
|
||||
description: Bla bla Keenan Crane
|
||||
# Vecchi Macchinisti
|
||||
|
||||
# - fullName: Francesco Manicastri
|
||||
# entranceDate: 2022
|
||||
# exitDate: 2024
|
||||
# description: Bla bla Keenan Crane
|
||||
|
||||
- fullName: Cristiano Cricci
|
||||
entranceDate: 2010
|
||||
exitDate: 2019
|
||||
social:
|
||||
website: https://poisson.phc.dm.unipi.it/~cricci/
|
||||
|
||||
- fullName: Tommaso Biannucci
|
||||
entranceDate: 2019
|
||||
exitDate: 2022
|
||||
social:
|
||||
github: https://gitlab.com/churli
|
||||
website: https://churli.gitlab.io/
|
||||
|
||||
- fullName: Letizia D'Achille
|
||||
entranceDate: 2018
|
||||
exitDate: 2022
|
||||
description: Appassionata di crittografia, teoria dei codici e matematica computazionale.
|
||||
social:
|
||||
github: https://github.com/letizia-dachille
|
||||
website: https://letizia-dachille.github.io/
|
||||
linkedin: https://www.linkedin.com/in/letizia-dachille/
|
||||
|
||||
- fullName: Emiliano Rago
|
||||
entranceDate: 2000
|
||||
exitDate: 2006
|
||||
description: Traviato da Linux in età troppo giovane ha difficoltà ad usare il mouse ma ama gli shortcuts con una decina di tasti.
|
||||
social:
|
||||
linkedin: https://www.linkedin.com/in/emiliano-rago-1a8018109/
|
||||
|
||||
Vendored
+23
@@ -15,3 +15,26 @@ declare module '@/data/macchinisti.yaml' {
|
||||
const value: Macchinista[]
|
||||
export default value
|
||||
}
|
||||
|
||||
declare module '@/data/domande-esami.yaml' {
|
||||
export type Question = {
|
||||
course: string
|
||||
content: string
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
export type Group = {
|
||||
id: string
|
||||
name: string
|
||||
items: Array<string>
|
||||
}
|
||||
|
||||
export type Database = {
|
||||
names: Record<string, string>
|
||||
groups: Group[]
|
||||
questions: Question[]
|
||||
}
|
||||
|
||||
const value: Database
|
||||
export default value
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ const { title, description, thumbnail, pageTags } = Astro.props
|
||||
<script>
|
||||
import renderMathInElement from 'katex/contrib/auto-render'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const renderMath = () => {
|
||||
renderMathInElement(document.body, {
|
||||
delimiters: [
|
||||
{ left: '$$', right: '$$', display: true },
|
||||
@@ -54,7 +54,12 @@ const { title, description, thumbnail, pageTags } = Astro.props
|
||||
],
|
||||
throwOnError: false,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => renderMath())
|
||||
|
||||
// @ts-ignore
|
||||
window.renderMath = renderMath
|
||||
</script>
|
||||
|
||||
<script is:inline>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
import type { GetStaticPaths } from 'astro'
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro'
|
||||
import Footer from '@/components/Footer.astro'
|
||||
import Header from '@/components/Header.astro'
|
||||
|
||||
import { marked } from 'marked'
|
||||
|
||||
import database from '@/data/domande-esami.yaml'
|
||||
import PhosphorIcon from '@/components/PhosphorIcon.astro'
|
||||
import { DomandeEsamiCourse } from '@/client/DomandeEsamiCourse'
|
||||
|
||||
export const getStaticPaths = (() => {
|
||||
return Object.keys(database.names).map(course => ({
|
||||
params: { course },
|
||||
}))
|
||||
}) satisfies GetStaticPaths
|
||||
|
||||
const { course } = Astro.params
|
||||
---
|
||||
|
||||
<BaseLayout title="Domande Esami | PHC" pageTags={'domande-esami'}>
|
||||
<Header />
|
||||
<main>
|
||||
<DomandeEsamiCourse client:load course={course} />
|
||||
</main>
|
||||
<Footer />
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { APIRoute } from 'astro'
|
||||
|
||||
import database from '@/data/domande-esami.yaml'
|
||||
|
||||
export const GET: APIRoute = ({}) => {
|
||||
return new Response(JSON.stringify(database), {
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { APIRoute, GetStaticPaths } from 'astro'
|
||||
|
||||
import database from '@/data/domande-esami.yaml'
|
||||
|
||||
export const getStaticPaths = (() => {
|
||||
return Object.keys(database.names).map(course => ({
|
||||
params: { course },
|
||||
}))
|
||||
}) satisfies GetStaticPaths
|
||||
|
||||
export const GET: APIRoute = ({ params: { course } }) => {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
groups: [],
|
||||
names: Object.fromEntries(Object.entries(database.names).filter(([key]) => key === course)),
|
||||
questions: database.questions.filter(question => question.course === course),
|
||||
}),
|
||||
{
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
import { PhosphorIcon } from '@/client/Icon'
|
||||
import Footer from '@/components/Footer.astro'
|
||||
import Header from '@/components/Header.astro'
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro'
|
||||
|
||||
import database from '@/data/domande-esami.yaml'
|
||||
|
||||
const courseQuestionCounts = Object.fromEntries(
|
||||
database.questions.reduce((acc, question) => {
|
||||
acc.set(question.course, (acc.get(question.course) || 0) + 1)
|
||||
return acc
|
||||
}, new Map())
|
||||
)
|
||||
---
|
||||
|
||||
<BaseLayout title="Domande Esami | PHC" pageTags={'domande-esami'}>
|
||||
<Header />
|
||||
<main>
|
||||
<h1>Domande Esami</h1>
|
||||
{
|
||||
database.groups.map(group => (
|
||||
<details open>
|
||||
<summary>
|
||||
<h2 id={group.id}>
|
||||
<div class="details-closed">
|
||||
<PhosphorIcon name="caret-down" />
|
||||
</div>
|
||||
<div class="details-openned">
|
||||
<PhosphorIcon name="caret-up" />
|
||||
</div>
|
||||
{group.name}
|
||||
</h2>
|
||||
</summary>
|
||||
<div class="wide-card-list">
|
||||
{group.items.map(course => (
|
||||
<a href={`/domande-esami/${course}`}>
|
||||
<div class="card">
|
||||
<h2>{database.names[course]}</h2>
|
||||
<div class="text">
|
||||
<p>{courseQuestionCounts[course] || 0} domande</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</details>
|
||||
))
|
||||
}
|
||||
|
||||
<h3>Come Contribuire</h3>
|
||||
<div class="card large">
|
||||
<div class="text">
|
||||
<p>Se hai raccolte di domande da condividere, puoi...</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<Footer />
|
||||
</BaseLayout>
|
||||
@@ -10,7 +10,7 @@ const news = await getCollection('news')
|
||||
<h1><a href="/notizie">Notizie</a></h1>
|
||||
<div class="card-list">
|
||||
{
|
||||
news.map(newsItem => (
|
||||
news.toReversed().map(newsItem => (
|
||||
<div class="card">
|
||||
<a href={`/notizie/${newsItem.slug}`} class="title">
|
||||
{newsItem.data.title}
|
||||
|
||||
+125
-24
@@ -14,7 +14,7 @@
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
|
||||
display: grid;
|
||||
display: grid inline;
|
||||
place-content: center;
|
||||
}
|
||||
|
||||
@@ -79,29 +79,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
// just to know for reference
|
||||
.fake-masonry {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--columns), 1fr);
|
||||
grid-auto-flow: dense;
|
||||
|
||||
& > * {
|
||||
grid-row: span var(--masonry-height);
|
||||
}
|
||||
}
|
||||
|
||||
.search-results {
|
||||
width: 100%;
|
||||
|
||||
@@ -592,6 +569,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.metadata {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
justify-content: start;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
padding: 0.9rem;
|
||||
|
||||
@@ -609,6 +593,37 @@
|
||||
}
|
||||
}
|
||||
|
||||
.chip {
|
||||
user-select: none;
|
||||
|
||||
display: grid;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
|
||||
background: #0003;
|
||||
|
||||
padding: 0 0.25rem;
|
||||
border-radius: 0.25rem;
|
||||
line-height: 1.5;
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
|
||||
&.small {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: #0005;
|
||||
background: #0002;
|
||||
}
|
||||
}
|
||||
|
||||
a:has(> .card) {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
//
|
||||
// Card List
|
||||
//
|
||||
@@ -875,4 +890,90 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wide-card-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(auto, 30rem));
|
||||
gap: 2rem;
|
||||
padding: 2rem;
|
||||
|
||||
width: 100%;
|
||||
|
||||
justify-content: center;
|
||||
|
||||
.text > * {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
padding: 0;
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.filter {
|
||||
min-width: 15rem;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.flex-row-wrap {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.grid-h {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.grid-v {
|
||||
display: grid;
|
||||
justify-items: start;
|
||||
align-content: start;
|
||||
|
||||
grid-auto-flow: row;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.grid-center {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
gap: 0.5rem;
|
||||
grid-auto-flow: row;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// just to know for reference
|
||||
.fake-masonry {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--columns), 1fr);
|
||||
grid-auto-flow: dense;
|
||||
|
||||
& > * {
|
||||
grid-row: span var(--masonry-height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,4 +129,47 @@
|
||||
justify-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
details {
|
||||
width: 100%;
|
||||
|
||||
summary {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
|
||||
list-style: none;
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.details-openned,
|
||||
.details-closed {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
&:not([open]) {
|
||||
.details-openned {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&[open] {
|
||||
summary {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.details-closed {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
summary {
|
||||
place-content: stretch;
|
||||
place-items: stretch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,6 +208,10 @@ body {
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -437,6 +437,35 @@
|
||||
}
|
||||
}
|
||||
|
||||
.domande-esami {
|
||||
background: hsl(45, 100%, 95%);
|
||||
--card-base: hsl(45, 100%, 80%);
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 4rem 0;
|
||||
|
||||
gap: 2rem;
|
||||
|
||||
.search {
|
||||
max-width: 80ch;
|
||||
}
|
||||
|
||||
button {
|
||||
background: hsl(45, 100%, 72%);
|
||||
}
|
||||
|
||||
.card a {
|
||||
color: color-mix(in srgb, var(--card-base-internal), #000 80%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// .login {
|
||||
// background: #ddfaff;
|
||||
|
||||
|
||||
@@ -33,6 +33,18 @@
|
||||
@layer typography {
|
||||
@include geometric-headings;
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text {
|
||||
// text-align: justify;
|
||||
// hyphens: auto;
|
||||
@@ -129,6 +141,9 @@
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
|
||||
width: 50ch;
|
||||
max-width: 100%;
|
||||
|
||||
@include neo-brutalist-card(2px);
|
||||
|
||||
&.fill {
|
||||
@@ -201,6 +216,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
li + li {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited {
|
||||
color: var(--zone-color, #1e6733);
|
||||
|
||||
Reference in New Issue
Block a user