Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83431a0373 | ||
|
|
bf9709c689 | ||
|
|
4cbfc828c0 | ||
|
|
8fddadb098 | ||
|
|
6e615d6874 | ||
|
|
54d95b9c59 | ||
|
|
21260f1a85 | ||
|
|
10bcde22bf | ||
|
|
7c9d1e3fcc | ||
|
|
e355a29ae9 | ||
|
|
22c8357282 | ||
|
|
3308e10981 | ||
|
|
176bad6d51 | ||
|
|
f7076759e1 | ||
|
|
5eb8e3fc85 | ||
|
|
85a144b6d0 | ||
|
|
f99a7389be | ||
|
|
ff966c31a8 | ||
|
|
e5821067b1 | ||
|
|
655a4c5b22 | ||
|
|
40673661cf | ||
|
|
969e8bea35 | ||
|
|
d409e83ccb | ||
|
|
abd12dd2f3 | ||
|
|
cc77ec90cc | ||
|
|
b8eb2eb7bf | ||
|
|
18f6df7c4d | ||
|
|
d2a866cb0f | ||
|
|
b3251906d5 | ||
|
|
55d0dc8345 | ||
|
|
74ed415980 | ||
|
|
cc12c4fc18 | ||
|
|
eb667f7f04 | ||
|
|
575a37accc | ||
|
|
bbad670baa | ||
|
|
4c19ffdd9f | ||
|
|
15c2b44fcf | ||
|
|
34597fe9f8 | ||
|
|
4780133019 | ||
|
|
55352af0f2 | ||
|
|
b595169e3b | ||
|
|
d75ccecdf2 | ||
|
|
a694817c28 | ||
|
|
a2125bdab7 | ||
|
|
ddca56e868 | ||
|
|
da7f526cb0 | ||
|
|
370f8204a0 |
@@ -7,15 +7,19 @@
|
||||
|
||||
kind: pipeline
|
||||
name: default
|
||||
type: docker
|
||||
|
||||
steps:
|
||||
- name: deploy
|
||||
image: node:latest
|
||||
image: node:22-alpine
|
||||
volumes:
|
||||
- name: host-website-dist
|
||||
path: /mnt/website
|
||||
commands:
|
||||
- npm install
|
||||
- uname -a
|
||||
- node -v
|
||||
- npm ci
|
||||
- node -e 'import Sharp from "sharp"; console.log(Sharp)'
|
||||
- npm run build
|
||||
- cp -rT ./dist /mnt/website
|
||||
|
||||
@@ -32,8 +36,8 @@ trigger:
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: exec # this job is executed on the host machine
|
||||
name: caddy-permissions
|
||||
type: exec # this job is executed on the host machine
|
||||
|
||||
depends_on:
|
||||
- default
|
||||
|
||||
@@ -2,6 +2,7 @@ import { defineConfig } from 'astro/config'
|
||||
import preact from '@astrojs/preact'
|
||||
|
||||
import mdx from '@astrojs/mdx'
|
||||
import remarkMath from 'remark-math'
|
||||
|
||||
import yaml from '@rollup/plugin-yaml'
|
||||
|
||||
@@ -14,6 +15,7 @@ export default defineConfig({
|
||||
port: 3000,
|
||||
},
|
||||
markdown: {
|
||||
remarkPlugins: [remarkMath],
|
||||
shikiConfig: {
|
||||
theme: 'github-light',
|
||||
},
|
||||
@@ -22,7 +24,9 @@ export default defineConfig({
|
||||
preact({
|
||||
compat: true,
|
||||
}),
|
||||
mdx(),
|
||||
mdx({
|
||||
remarkPlugins: [remarkMath],
|
||||
}),
|
||||
],
|
||||
output: 'static',
|
||||
})
|
||||
|
||||
@@ -11,41 +11,44 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.4",
|
||||
"@astrojs/node": "9.0.0",
|
||||
"@astrojs/preact": "4.0.0",
|
||||
"@fontsource-variable/material-symbols-outlined": "^5.1.1",
|
||||
"@fontsource/iosevka": "^5.0.11",
|
||||
"@fontsource/mononoki": "^5.0.11",
|
||||
"@fontsource/open-sans": "^5.0.24",
|
||||
"@fontsource/source-code-pro": "^5.0.16",
|
||||
"@fontsource/source-sans-pro": "^5.0.8",
|
||||
"@fontsource/space-mono": "^5.0.20",
|
||||
"@astrojs/node": "^9.4.3",
|
||||
"@astrojs/preact": "^4.1.1",
|
||||
"@fontsource-variable/material-symbols-outlined": "^5.2.21",
|
||||
"@fontsource/iosevka": "^5.2.5",
|
||||
"@fontsource/mononoki": "^5.2.5",
|
||||
"@fontsource/open-sans": "^5.2.6",
|
||||
"@fontsource/source-code-pro": "^5.2.6",
|
||||
"@fontsource/source-sans-pro": "^5.2.5",
|
||||
"@fontsource/space-mono": "^5.2.8",
|
||||
"@phosphor-icons/core": "^2.1.1",
|
||||
"@phosphor-icons/react": "^2.1.7",
|
||||
"@preact/signals": "^1.3.0",
|
||||
"@phosphor-icons/react": "^2.1.10",
|
||||
"@preact/signals": "^1.3.2",
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"astro": "5.1.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"katex": "^0.16.9",
|
||||
"astro": "^5.13.7",
|
||||
"fuse.js": "^7.1.0",
|
||||
"katex": "^0.16.22",
|
||||
"lucide-static": "^0.468.0",
|
||||
"marked": "^15.0.6",
|
||||
"preact": "^10.19.6",
|
||||
"typescript": "^5.3.3"
|
||||
"marked": "^15.0.12",
|
||||
"node-addon-api": "^8.5.0",
|
||||
"node-gyp": "^11.4.2",
|
||||
"preact": "^10.27.2",
|
||||
"sharp": "^0.34.3",
|
||||
"typescript": "^5.9.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/mdx": "4.0.2",
|
||||
"@astrojs/mdx": "^4.3.5",
|
||||
"@rollup/plugin-yaml": "^4.1.2",
|
||||
"@types/katex": "^0.16.7",
|
||||
"jsdom": "^24.1.1",
|
||||
"linkedom": "^0.18.4",
|
||||
"jsdom": "^24.1.3",
|
||||
"linkedom": "^0.18.12",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.5.0",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-plugin-astro": "^0.14.1",
|
||||
"rehype-autolink-headings": "^7.1.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"remark-math": "^6.0.0",
|
||||
"remark-toc": "^9.0.0",
|
||||
"sass": "^1.71.1",
|
||||
"tsx": "^4.7.1"
|
||||
"sass": "^1.92.1",
|
||||
"tsx": "^4.20.5"
|
||||
}
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 877 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 77 KiB |
@@ -41,7 +41,13 @@ export const ComboBox = ({
|
||||
<PhosphorIcon name="caret-down" />
|
||||
</div>
|
||||
{open && (
|
||||
<div class={clsx('dropdown', cloak && 'invisible')} ref={el => el && setItemWidth(el.offsetWidth)}>
|
||||
<div
|
||||
class={clsx('dropdown', cloak && 'invisible')}
|
||||
ref={el => {
|
||||
if (!el) return
|
||||
setItemWidth(el.offsetWidth)
|
||||
}}
|
||||
>
|
||||
{Object.keys(children).map(key => (
|
||||
<div
|
||||
class="option"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from 'preact/hooks'
|
||||
import { Funnel } from '@phosphor-icons/react'
|
||||
import { FunnelIcon } from '@phosphor-icons/react'
|
||||
import { marked } from 'marked'
|
||||
|
||||
import extendedLatex from '@/client/lib/marked-latex'
|
||||
@@ -70,7 +70,7 @@ export const DomandeEsamiCourse = ({ course }: Props) => {
|
||||
{courseTags.length > 1 && (
|
||||
<div class="card filter">
|
||||
<div class="grid-h">
|
||||
<Funnel />
|
||||
<FunnelIcon />
|
||||
<strong>Filtra Tag</strong>
|
||||
</div>
|
||||
<div class="flex-row-wrap">
|
||||
|
||||
@@ -0,0 +1,765 @@
|
||||
import { useState, useEffect } from 'preact/hooks'
|
||||
|
||||
// Tipi per la gestione dei dati
|
||||
type TipoStudente = 'triennale' | 'magistrale'
|
||||
|
||||
interface Corso {
|
||||
nome: string
|
||||
anno: '1' | '2' | '3' | 'M' | 'istituzioni'
|
||||
cfu: number
|
||||
passFailOnly?: boolean // Per materie senza voto (pass/fail)
|
||||
}
|
||||
|
||||
interface CorsoSelezionato {
|
||||
id: string
|
||||
nome: string
|
||||
cfu: number
|
||||
voto: number | null
|
||||
lode: boolean
|
||||
passFailOnly?: boolean // Per materie senza voto (pass/fail)
|
||||
}
|
||||
|
||||
interface CorsoCustom {
|
||||
nome: string
|
||||
cfu: number
|
||||
}
|
||||
|
||||
// Dati dei corsi aggiornati dalla tabella ufficiale
|
||||
const CORSI_DISPONIBILI: Corso[] = [
|
||||
// Primo Anno
|
||||
{ nome: 'Analisi matematica 1', anno: '1', cfu: 15 },
|
||||
{ nome: 'Aritmetica', anno: '1', cfu: 9 },
|
||||
{ nome: 'Fisica I con laboratorio', anno: '1', cfu: 9 },
|
||||
{ nome: 'Fondamenti di programmazione con laboratorio', anno: '1', cfu: 9 },
|
||||
{ nome: 'Geometria 1', anno: '1', cfu: 15 },
|
||||
{ nome: 'Laboratorio di introduzione alla matematica computazionale', anno: '1', cfu: 6, passFailOnly: true },
|
||||
{ nome: 'Laboratorio di comunicazione mediante calcolatore', anno: '1', cfu: 3, passFailOnly: true },
|
||||
|
||||
// Secondo Anno
|
||||
{ nome: 'Algebra 1', anno: '2', cfu: 6 },
|
||||
{ nome: 'Algoritmi e strutture dati', anno: '2', cfu: 6 },
|
||||
{ nome: 'Analisi matematica 2', anno: '2', cfu: 12 },
|
||||
{ nome: 'Analisi numerica con laboratorio', anno: '2', cfu: 9 },
|
||||
{ nome: 'Elementi di probabilità e statistica', anno: '2', cfu: 6 },
|
||||
{ nome: 'Geometria 2', anno: '2', cfu: 12 },
|
||||
{ nome: 'Inglese scientifico', anno: '2', cfu: 6, passFailOnly: true },
|
||||
{ nome: 'Laboratorio didattico di matematica computazionale', anno: '2', cfu: 3, passFailOnly: true },
|
||||
|
||||
// Terzo Anno
|
||||
{ nome: 'Algebra 2', anno: '3', cfu: 6 },
|
||||
{ nome: 'Analisi matematica 3', anno: '3', cfu: 6 },
|
||||
{ nome: 'Analisi reale', anno: '3', cfu: 6 },
|
||||
{ nome: 'Calcolo scientifico', anno: '3', cfu: 6 },
|
||||
{ nome: 'Elementi di analisi complessa', anno: '3', cfu: 6 },
|
||||
{ nome: 'Elementi di calcolo delle variazioni', anno: '3', cfu: 6 },
|
||||
{ nome: 'Elementi di geometria algebrica', anno: '3', cfu: 6 },
|
||||
{ nome: 'Elementi di meccanica celeste', anno: '3', cfu: 6 },
|
||||
{ nome: 'Elementi di teoria degli insiemi', anno: '3', cfu: 6 },
|
||||
{ nome: 'Elementi di teoria delle rappresentazioni', anno: '3', cfu: 6 },
|
||||
{ nome: 'Elementi di topologia algebrica', anno: '3', cfu: 6 },
|
||||
{ nome: 'Equazioni alle derivate parziali', anno: '3', cfu: 6 },
|
||||
{ nome: 'Fisica II', anno: '3', cfu: 9 },
|
||||
{ nome: 'Fisica III', anno: '3', cfu: 6 },
|
||||
{ nome: 'Geometria e topologia differenziale', anno: '3', cfu: 6 },
|
||||
{ nome: 'Gruppi e rappresentazioni', anno: '3', cfu: 6 },
|
||||
{ nome: 'Laboratorio computazionale', anno: '3', cfu: 6, passFailOnly: true },
|
||||
{ nome: 'Laboratorio sperimentale di matematica computazionale', anno: '3', cfu: 6, passFailOnly: true },
|
||||
{ nome: 'Linguaggi di programmazione con laboratorio', anno: '3', cfu: 9 },
|
||||
{ nome: 'Logica matematica', anno: '3', cfu: 6 },
|
||||
{ nome: 'Matematiche elementari da un punto di vista superiore: aritmetica', anno: '3', cfu: 6 },
|
||||
{ nome: 'Matematiche elementari da un punto di vista superiore: geometria', anno: '3', cfu: 6 },
|
||||
{ nome: 'Meccanica razionale', anno: '3', cfu: 6 },
|
||||
{ nome: 'Metodi numerici per equazioni differenziali ordinarie', anno: '3', cfu: 6 },
|
||||
{ nome: 'Metodi topologici in analisi globale', anno: '3', cfu: 6 },
|
||||
{ nome: 'Ottimizzazione non lineare', anno: '3', cfu: 6 },
|
||||
{ nome: 'Probabilità', anno: '3', cfu: 6 },
|
||||
{ nome: 'Ricerca operativa', anno: '3', cfu: 6 },
|
||||
{ nome: 'Sistemi dinamici', anno: '3', cfu: 6 },
|
||||
{ nome: 'Spazi di Sobolev', anno: '3', cfu: 6 },
|
||||
{ nome: 'Statistica matematica', anno: '3', cfu: 6 },
|
||||
{ nome: 'Storia della matematica', anno: '3', cfu: 6 },
|
||||
{ nome: 'Teoria algebrica dei numeri 1', anno: '3', cfu: 6 },
|
||||
{ nome: 'Teoria dei campi e teoria di Galois', anno: '3', cfu: 6 },
|
||||
{ nome: 'Teoria dei numeri elementare', anno: '3', cfu: 6 },
|
||||
{ nome: 'Teoria della misura', anno: '3', cfu: 6 },
|
||||
|
||||
// Istituzioni (Magistrale)
|
||||
{ nome: 'Istituzioni di algebra', anno: 'istituzioni', cfu: 11 },
|
||||
{ nome: 'Istituzioni di analisi matematica', anno: 'istituzioni', cfu: 11 },
|
||||
{ nome: 'Istituzioni di analisi numerica', anno: 'istituzioni', cfu: 11 },
|
||||
{ nome: 'Istituzioni di didattica della matematica', anno: 'istituzioni', cfu: 11 },
|
||||
{ nome: 'Istituzioni di fisica matematica', anno: 'istituzioni', cfu: 11 },
|
||||
{ nome: 'Istituzioni di geometria', anno: 'istituzioni', cfu: 11 },
|
||||
{ nome: 'Istituzioni di probabilità', anno: 'istituzioni', cfu: 11 },
|
||||
|
||||
// Materie a scelta (Magistrale)
|
||||
{ nome: '4-varietà', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Algebra superiore A', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Algebre e gruppi di Lie', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi armonica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi complessa A', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi complessa B', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi convessa', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi dei dati', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi non standard', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi reale', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi su spazi gaussiani', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi superiore', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi superiore A', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Analisi superiore B', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Aspetti matematici nella computazione quantistica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Calcolo delle variazioni B', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Calcolo della variazioni A', anno: 'M', cfu: 6 }, // Variante nome
|
||||
{ nome: 'Combinatoria algebrica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Complementi di analisi funzionale', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Complementi di meccanica razionale', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Crittografia post-quantistica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Curve ellittiche', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Determinazione orbitale', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Didattica della matematica e nuove tecnologie', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Dinamica del sistema solare', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Dinamica iperbolica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Dinamica olomorfa', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Elementi di calcolo in gruppi omogenei', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Equazioni della fluidodinamica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Equazioni differenziali stocastiche e applicazioni', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Equazioni ellittiche', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Finanza matematica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Fisica matematica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Forme modulari', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria algebrica B', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria algebrica C', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria algebrica complessa', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria algebrica D', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria algebrica E', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria algebrica F', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria algebrica G', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria e analisi complessa', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria differenziale complessa', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria iperbolica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Geometria riemanniana', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Gruppi algebrici lineari', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Gruppi di Coxeter', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Gruppi di Galois e gruppi fondamentali', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Meccanica celeste', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Meccanica spaziale', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Meccanica superiore', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Metodi di analisi armonica in analisi non lineare', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Metodi di approssimazione', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Metodi matematici della crittografia', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Metodi matematici della meccanica quantistica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Metodi numerici per catene di Markov', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Metodi numerici per equazioni alle derivate parziali', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Metodi numerici per il calcolo tensoriale', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Metodi numerici per il controllo ottimo', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Metodi numerici per la grafica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Metodi numerici per problemi inversi', anno: 'M', cfu: 6 },
|
||||
{ nome: "Metodi probabilistici per l'algebra lineare numerica", anno: 'M', cfu: 6 },
|
||||
{ nome: 'Modelli matematici in biomedicina e fisica matematica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Origini e sviluppo delle matematiche moderne', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Probabilità superiore', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Problemi e metodi della ricerca in didattica della matematica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Problemi e metodi in storia della matematica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Sistemi dinamici aleatori', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Statistica superiore', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Storia della matematica antica e della sua tradizione', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Superfici di Riemann e curve algebriche', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Tecnologie per la didattica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria algebrica dei numeri 2', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria analitica dei numeri A', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria dei giochi', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria dei modelli', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria dei nodi A', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria degli insiemi', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria degli insiemi A', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria degli insiemi B', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria delle categorie', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria delle rappresentazioni A', anno: 'M', cfu: 6 },
|
||||
{ nome: "Teoria e metodi dell'ottimizzazione", anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria ergodica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Teoria geometrica della misura', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Topologia algebrica', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Topologia algebrica A', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Topologia algebrica B', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Topologia differenziale', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Topologia e geometria in bassa dimensione', anno: 'M', cfu: 6 },
|
||||
{ nome: 'Ultrafiltri e metodi non-standard', anno: 'M', cfu: 6 },
|
||||
]
|
||||
|
||||
export function MediaPesataApp() {
|
||||
// Funzioni per localStorage
|
||||
const loadFromStorage = () => {
|
||||
try {
|
||||
const savedData = localStorage.getItem('media-pesata-data')
|
||||
if (savedData) {
|
||||
const parsed = JSON.parse(savedData)
|
||||
return {
|
||||
tipoStudente: parsed.tipoStudente || 'triennale',
|
||||
corsiSelezionati: parsed.corsiSelezionati || [],
|
||||
sezioniAperte: parsed.sezioniAperte || {},
|
||||
mostraRisultati: parsed.mostraRisultati || false,
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Errore nel caricamento dei dati salvati:', error)
|
||||
}
|
||||
return {
|
||||
tipoStudente: 'triennale' as TipoStudente,
|
||||
corsiSelezionati: [],
|
||||
sezioniAperte: {},
|
||||
mostraRisultati: false,
|
||||
}
|
||||
}
|
||||
|
||||
const saveToStorage = (data: any) => {
|
||||
try {
|
||||
localStorage.setItem('media-pesata-data', JSON.stringify(data))
|
||||
} catch (error) {
|
||||
console.warn('Errore nel salvataggio dei dati:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Inizializzazione con dati salvati
|
||||
// const initialData = loadFromStorage()
|
||||
const [tipoStudente, setTipoStudente] = useState<TipoStudente>('triennale')
|
||||
const [corsiSelezionati, setCorsiSelezionati] = useState<CorsoSelezionato[]>([])
|
||||
const [showCustomForm, setShowCustomForm] = useState(false)
|
||||
const [customCorso, setCustomCorso] = useState<CorsoCustom>({ nome: '', cfu: 0 })
|
||||
const [sezioniAperte, setSezioniAperte] = useState<Record<string, boolean>>({})
|
||||
const [mostraRisultati, setMostraRisultati] = useState(false)
|
||||
|
||||
// Load data from localStorage on mount
|
||||
useEffect(() => {
|
||||
const initialData = loadFromStorage()
|
||||
setTipoStudente(initialData.tipoStudente)
|
||||
setCorsiSelezionati(initialData.corsiSelezionati)
|
||||
setSezioniAperte(initialData.sezioniAperte)
|
||||
setMostraRisultati(initialData.mostraRisultati)
|
||||
}, [])
|
||||
|
||||
// Salva automaticamente quando cambiano i dati importanti
|
||||
useEffect(() => {
|
||||
const dataToSave = {
|
||||
tipoStudente,
|
||||
corsiSelezionati,
|
||||
sezioniAperte,
|
||||
mostraRisultati,
|
||||
}
|
||||
saveToStorage(dataToSave)
|
||||
}, [tipoStudente, corsiSelezionati, sezioniAperte, mostraRisultati])
|
||||
|
||||
const toggleSezione = (nomeSezione: string) => {
|
||||
setSezioniAperte(prev => ({
|
||||
...prev,
|
||||
[nomeSezione]: !prev[nomeSezione],
|
||||
}))
|
||||
}
|
||||
|
||||
const calcolaMedia = () => {
|
||||
const corsiConVoto = corsiSelezionati.filter(corso => corso.voto !== null && !corso.passFailOnly)
|
||||
if (corsiConVoto.length === 0) {
|
||||
alert('Inserisci almeno un voto per calcolare la media!')
|
||||
return
|
||||
}
|
||||
setMostraRisultati(true)
|
||||
}
|
||||
|
||||
// Funzioni per la gestione dei corsi
|
||||
const aggiungiCorso = (corso: Corso) => {
|
||||
// Controlla se la materia esiste già
|
||||
const materiaEsiste = corsiSelezionati.some(c => c.nome.toLowerCase() === corso.nome.toLowerCase())
|
||||
if (materiaEsiste) {
|
||||
alert('Questa materia è già stata aggiunta')
|
||||
return
|
||||
}
|
||||
|
||||
// Controllo per magistrali: massimo 3 istituzioni
|
||||
if (tipoStudente === 'magistrale' && corso.anno === 'istituzioni') {
|
||||
const istituzioniAttuali = corsiSelezionati.filter(c => c.nome.toLowerCase().includes('istituzioni')).length
|
||||
if (istituzioniAttuali >= 3) {
|
||||
alert('Puoi selezionare al massimo 3 istituzioni per la magistrale')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const id = Date.now().toString()
|
||||
const nuovoCorso: CorsoSelezionato = {
|
||||
id,
|
||||
nome: corso.nome,
|
||||
cfu: corso.cfu,
|
||||
voto: null,
|
||||
lode: false,
|
||||
passFailOnly: corso.passFailOnly,
|
||||
}
|
||||
setCorsiSelezionati([...corsiSelezionati, nuovoCorso])
|
||||
}
|
||||
|
||||
const aggiungiCorsoCustom = () => {
|
||||
// Validazioni
|
||||
if (!customCorso.nome.trim()) {
|
||||
alert('Il nome della materia non può essere vuoto')
|
||||
return
|
||||
}
|
||||
if (customCorso.cfu <= 0 || customCorso.cfu > 30) {
|
||||
alert('I CFU devono essere tra 1 e 30')
|
||||
return
|
||||
}
|
||||
if (!Number.isInteger(customCorso.cfu)) {
|
||||
alert('I CFU devono essere un numero intero')
|
||||
return
|
||||
}
|
||||
|
||||
// Controlla se la materia esiste già
|
||||
const materiaEsiste = corsiSelezionati.some(
|
||||
corso => corso.nome.toLowerCase().trim() === customCorso.nome.toLowerCase().trim(),
|
||||
)
|
||||
if (materiaEsiste) {
|
||||
alert('Questa materia è già stata aggiunta')
|
||||
return
|
||||
}
|
||||
|
||||
const id = Date.now().toString()
|
||||
const nuovoCorso: CorsoSelezionato = {
|
||||
id,
|
||||
nome: customCorso.nome.trim(),
|
||||
cfu: customCorso.cfu,
|
||||
voto: null,
|
||||
lode: false,
|
||||
}
|
||||
setCorsiSelezionati([...corsiSelezionati, nuovoCorso])
|
||||
setCustomCorso({ nome: '', cfu: 0 })
|
||||
setShowCustomForm(false)
|
||||
}
|
||||
|
||||
const rimuoviCorso = (id: string) => {
|
||||
setCorsiSelezionati(corsiSelezionati.filter(corso => corso.id !== id))
|
||||
}
|
||||
|
||||
const aggiornaVoto = (id: string, voto: number | null) => {
|
||||
// Validazione voto: deve essere tra 18 e 30 e intero
|
||||
if (voto !== null && (voto < 18 || voto > 30 || !Number.isInteger(voto))) {
|
||||
return // Ignora valori non validi
|
||||
}
|
||||
|
||||
setCorsiSelezionati(
|
||||
corsiSelezionati.map(corso =>
|
||||
corso.id === id ? { ...corso, voto, lode: voto !== 30 ? false : corso.lode } : corso,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
const aggiornaLode = (id: string, lode: boolean) => {
|
||||
setCorsiSelezionati(corsiSelezionati.map(corso => (corso.id === id ? { ...corso, lode } : corso)))
|
||||
}
|
||||
|
||||
const resetTutto = () => {
|
||||
if (corsiSelezionati.length > 0) {
|
||||
if (confirm('Sei sicuro di voler cancellare tutte le materie selezionate?')) {
|
||||
setCorsiSelezionati([])
|
||||
setCustomCorso({ nome: '', cfu: 0 })
|
||||
setShowCustomForm(false)
|
||||
setSezioniAperte({})
|
||||
setMostraRisultati(false)
|
||||
// Pulisce anche il localStorage
|
||||
try {
|
||||
localStorage.removeItem('media-pesata-data')
|
||||
} catch (error) {
|
||||
console.warn('Errore nella pulizia del localStorage:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calcoli della media pesata
|
||||
const calcolaMediaPesata = () => {
|
||||
// Escludi le materie pass/fail dal calcolo
|
||||
const corsiConVoto = corsiSelezionati.filter(corso => corso.voto !== null && !corso.passFailOnly)
|
||||
if (corsiConVoto.length === 0) {
|
||||
return {
|
||||
mediaPesata: 0,
|
||||
votoAmmissione: 0,
|
||||
massimoVotoLaurea: 0,
|
||||
conLode: false,
|
||||
bonusLodi: 0,
|
||||
errore: 'Nessun voto inserito per il calcolo della media',
|
||||
}
|
||||
}
|
||||
|
||||
// Calcola CFU totali con voto
|
||||
const cfuTotaliConVoto = corsiConVoto.reduce((sum, corso) => sum + corso.cfu, 0)
|
||||
const cfuDaEscludere = tipoStudente === 'triennale' ? 15 : 9
|
||||
|
||||
// Se i CFU sono insufficienti per l'esclusione, avvisa l'utente
|
||||
if (cfuTotaliConVoto < cfuDaEscludere) {
|
||||
return {
|
||||
mediaPesata: 0,
|
||||
votoAmmissione: 0,
|
||||
massimoVotoLaurea: 0,
|
||||
conLode: false,
|
||||
bonusLodi: 0,
|
||||
errore: `Hai inserito solo ${cfuTotaliConVoto} CFU con voto. Servono almeno ${cfuDaEscludere} CFU per applicare le regole di esclusione.`,
|
||||
}
|
||||
}
|
||||
|
||||
// Ordina per voto crescente
|
||||
const corsiOrdinati = [...corsiConVoto].sort((a, b) => a.voto! - b.voto!)
|
||||
|
||||
let cfuEsclusi = 0
|
||||
const corsiValidi: CorsoSelezionato[] = []
|
||||
|
||||
for (const corso of corsiOrdinati) {
|
||||
if (cfuEsclusi < cfuDaEscludere) {
|
||||
const cfuRimanentiDaEscludere = cfuDaEscludere - cfuEsclusi
|
||||
if (corso.cfu <= cfuRimanentiDaEscludere) {
|
||||
// Escludi tutto il corso
|
||||
cfuEsclusi += corso.cfu
|
||||
} else {
|
||||
// Escludi solo una parte del corso
|
||||
const cfuValidi = corso.cfu - cfuRimanentiDaEscludere
|
||||
corsiValidi.push({ ...corso, cfu: cfuValidi })
|
||||
cfuEsclusi = cfuDaEscludere
|
||||
}
|
||||
} else {
|
||||
corsiValidi.push(corso)
|
||||
}
|
||||
}
|
||||
|
||||
// Calcola media pesata
|
||||
const sommaPesata = corsiValidi.reduce((sum, corso) => sum + corso.voto! * corso.cfu, 0)
|
||||
const sommaCfu = corsiValidi.reduce((sum, corso) => sum + corso.cfu, 0)
|
||||
|
||||
const mediaPesata = sommaCfu > 0 ? sommaPesata / sommaCfu : 0
|
||||
|
||||
// Calcola bonus lodi
|
||||
const bonusLodi = corsiConVoto.reduce((bonus, corso) => {
|
||||
if (corso.lode) {
|
||||
return bonus + (corso.cfu > 6 ? 0.5 : 0.25)
|
||||
}
|
||||
return bonus
|
||||
}, 0)
|
||||
|
||||
// Cap del bonus lodi basato sul tipo di studente
|
||||
const capBonusLodi = tipoStudente === 'triennale' ? 1.5 : 2
|
||||
const bonusLodiFinal = Math.min(bonusLodi, capBonusLodi)
|
||||
|
||||
// Voto di ammissione alla laurea (media pesata * 11/3)
|
||||
const votoAmmissione = (mediaPesata * 11) / 3
|
||||
|
||||
// Voto di ammissione finale = voto ammissione + bonus lodi
|
||||
const votoAmmissioneFinale = votoAmmissione + bonusLodiFinal
|
||||
|
||||
// Massimo voto di laurea possibile = voto ammissione + 10 (cappato a 110)
|
||||
const massimoVotoLaurea = Math.min(votoAmmissioneFinale + 10, 110)
|
||||
const conLode = massimoVotoLaurea === 110
|
||||
|
||||
return {
|
||||
mediaPesata: Math.round(mediaPesata * 100) / 100,
|
||||
votoAmmissione: Math.round(votoAmmissioneFinale * 100) / 100,
|
||||
massimoVotoLaurea: Math.round(massimoVotoLaurea * 100) / 100,
|
||||
conLode,
|
||||
bonusLodi: Math.round(bonusLodiFinal * 100) / 100,
|
||||
errore: null,
|
||||
}
|
||||
}
|
||||
|
||||
// Filtra corsi disponibili in base al tipo di studente
|
||||
const getCorsiDisponibili = () => {
|
||||
if (tipoStudente === 'triennale') {
|
||||
return CORSI_DISPONIBILI.filter(corso => corso.anno !== 'istituzioni')
|
||||
} else {
|
||||
return CORSI_DISPONIBILI.filter(
|
||||
corso => corso.anno === 'istituzioni' || corso.anno === '3' || corso.anno === 'M',
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Raggruppa corsi per categoria
|
||||
const raggruppaCorsi = () => {
|
||||
const corsi = getCorsiDisponibili()
|
||||
const gruppi: Record<string, Corso[]> = {}
|
||||
|
||||
if (tipoStudente === 'triennale') {
|
||||
gruppi['Primo Anno'] = corsi.filter(c => c.anno === '1')
|
||||
gruppi['Secondo Anno'] = corsi.filter(c => c.anno === '2')
|
||||
gruppi['Terzo Anno'] = corsi.filter(c => c.anno === '3')
|
||||
gruppi['Materie a Scelta'] = corsi.filter(c => c.anno === 'M')
|
||||
} else {
|
||||
// Per magistrali: prima le istituzioni, poi tutto il resto come "Materie a Scelta"
|
||||
gruppi['Istituzioni'] = corsi.filter(c => c.anno === 'istituzioni')
|
||||
gruppi['Materie a Scelta'] = corsi.filter(c => c.anno === '3' || c.anno === 'M')
|
||||
}
|
||||
|
||||
return gruppi
|
||||
}
|
||||
|
||||
const cambiaTipoStudente = (nuovoTipo: TipoStudente) => {
|
||||
setTipoStudente(nuovoTipo)
|
||||
}
|
||||
|
||||
const gruppiCorsi = raggruppaCorsi()
|
||||
const risultati = calcolaMediaPesata()
|
||||
const totaleCfu = corsiSelezionati.reduce((sum, corso) => sum + corso.cfu, 0)
|
||||
const maxCfu = tipoStudente === 'triennale' ? 171 : 93 // 180 − 9 e 120 − 27 per la tesi
|
||||
const cfuError = totaleCfu > maxCfu
|
||||
|
||||
return (
|
||||
<div class="media-pesata-app">
|
||||
{/* Selezione tipo studente */}
|
||||
<div class="card student-type-switcher wide">
|
||||
<div class="grid-center">
|
||||
<h2>Corso di Laurea</h2>
|
||||
<div class="compound-button">
|
||||
<button
|
||||
class={tipoStudente === 'triennale' ? 'active' : ''}
|
||||
onClick={() => cambiaTipoStudente('triennale')}
|
||||
>
|
||||
Triennale
|
||||
</button>
|
||||
<button
|
||||
class={tipoStudente === 'magistrale' ? 'active' : ''}
|
||||
onClick={() => cambiaTipoStudente('magistrale')}
|
||||
>
|
||||
Magistrale
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Counter CFU */}
|
||||
<div class={`cfu-counter wide ${cfuError ? 'error' : ''}`}>
|
||||
<h3>
|
||||
CFU Totali: {totaleCfu}/{maxCfu}
|
||||
{tipoStudente === 'triennale' ? ' (+9 tesi)' : ' (+27 tesi)'}
|
||||
</h3>
|
||||
{cfuError && <p class="error-text">⚠️ Hai superato il limite di CFU consentiti!</p>}
|
||||
</div>
|
||||
|
||||
{/* Sezione selezione corsi */}
|
||||
<div class="card">
|
||||
<div class="title">
|
||||
<h2>Seleziona Materie</h2>
|
||||
</div>
|
||||
|
||||
{Object.entries(gruppiCorsi).map(([categoria, corsi]) => (
|
||||
<div key={categoria} class="course-category">
|
||||
<button onClick={() => toggleSezione(categoria)}>
|
||||
<div class="h-flex">
|
||||
{categoria}
|
||||
<div class="spacer"></div>
|
||||
<span class={`toggle-icon ${sezioniAperte[categoria] ? 'expanded' : ''}`}>▶</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{sezioniAperte[categoria] && (
|
||||
<div class="course-grid">
|
||||
{corsi.map((corso, index) => (
|
||||
<button
|
||||
key={index}
|
||||
class="course-button"
|
||||
onClick={() => aggiungiCorso(corso)}
|
||||
disabled={corsiSelezionati.some(c => c.nome === corso.nome)}
|
||||
>
|
||||
<span class="course-name">{corso.nome}</span>
|
||||
<span class="course-cfu">{corso.cfu} CFU</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Form per materia custom */}
|
||||
<div class="custom-course">
|
||||
<h3>Materia Personalizzata</h3>
|
||||
{!showCustomForm ? (
|
||||
<button onClick={() => setShowCustomForm(true)}>+ Aggiungi Materia Personalizzata</button>
|
||||
) : (
|
||||
<div class="custom-form">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Nome materia"
|
||||
value={customCorso.nome}
|
||||
onChange={e =>
|
||||
setCustomCorso({ ...customCorso, nome: (e.target as HTMLInputElement).value })
|
||||
}
|
||||
/>
|
||||
<input
|
||||
type="number"
|
||||
placeholder="CFU"
|
||||
min="1"
|
||||
max="30"
|
||||
step="1"
|
||||
value={customCorso.cfu || ''}
|
||||
onChange={e =>
|
||||
setCustomCorso({
|
||||
...customCorso,
|
||||
cfu: parseInt((e.target as HTMLInputElement).value) || 0,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<button onClick={aggiungiCorsoCustom}>Aggiungi</button>
|
||||
<button onClick={() => setShowCustomForm(false)}>Annulla</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sezione lista corsi selezionati */}
|
||||
<div class="card">
|
||||
<div class="h-flex">
|
||||
<div class="title">
|
||||
<h2>Materie Selezionate</h2>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
{corsiSelezionati.length > 0 && <button onClick={resetTutto}>🗑️ Cancella Tutto</button>}
|
||||
</div>
|
||||
|
||||
{corsiSelezionati.length === 0 ? (
|
||||
<p>Nessuna materia selezionata</p>
|
||||
) : (
|
||||
<div class="courses-list">
|
||||
{corsiSelezionati.map(corso => (
|
||||
<div key={corso.id} class="course-item">
|
||||
<span class="course-name">{corso.nome}</span>
|
||||
<span class="course-cfu">{corso.cfu} CFU</span>
|
||||
|
||||
{!corso.passFailOnly && (
|
||||
<div class="course-grade tall">
|
||||
<input
|
||||
type="number"
|
||||
placeholder="Voto"
|
||||
min="18"
|
||||
max="30"
|
||||
step="1"
|
||||
value={corso.voto || ''}
|
||||
onChange={e =>
|
||||
aggiornaVoto(
|
||||
corso.id,
|
||||
parseInt((e.target as HTMLInputElement).value) || null,
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
<label class={`lode-checkbox ${corso.voto !== 30 ? 'disabled' : ''}`}>
|
||||
<input
|
||||
class="star"
|
||||
type="checkbox"
|
||||
checked={corso.lode}
|
||||
disabled={corso.voto !== 30}
|
||||
onChange={e =>
|
||||
aggiornaLode(corso.id, (e.target as HTMLInputElement).checked)
|
||||
}
|
||||
/>
|
||||
Lode
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div class="actions tall">
|
||||
<button
|
||||
class="icon remove-btn"
|
||||
onClick={() => rimuoviCorso(corso.id)}
|
||||
title="Rimuovi materia"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Pulsante Calcola */}
|
||||
{corsiSelezionati.length > 0 && (
|
||||
<div class="calculate-section wide">
|
||||
<button onClick={calcolaMedia}>🧮 Calcola Media e Voto di Laurea</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Risultati */}
|
||||
{risultati && mostraRisultati && (
|
||||
<div class="results wide">
|
||||
<h2>Risultati</h2>
|
||||
{risultati.errore ? (
|
||||
<div class="error-message">
|
||||
<p>⚠️ {risultati.errore}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div class="results-grid">
|
||||
<div class="result-item">
|
||||
<span class="label">Media Pesata:</span>
|
||||
<span class="value">{risultati.mediaPesata}</span>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<span class="label">Bonus Lodi:</span>
|
||||
<span class="value">+{risultati.bonusLodi}</span>
|
||||
</div>
|
||||
<div class="result-item highlight">
|
||||
<span class="label">Voto di Ammissione:</span>
|
||||
<span class="value">{risultati.votoAmmissione}</span>
|
||||
</div>
|
||||
<div class="result-item highlight">
|
||||
<span class="label">Massimo Voto Di Laurea Possibile:</span>
|
||||
<span class="value">
|
||||
{risultati.massimoVotoLaurea}
|
||||
{risultati.conLode && <span class="lode-badge">(+lode)</span>}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Nota informativa */}
|
||||
<div class="card wide">
|
||||
<h3>📋 Come viene calcolata la media</h3>
|
||||
<div class="info-content">
|
||||
<h4>Regole di esclusione CFU:</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Triennale:</strong> I 15 CFU con i voti più bassi vengono esclusi dalla media
|
||||
</li>
|
||||
<li>
|
||||
<strong>Magistrale:</strong> I 9 CFU con i voti più bassi vengono esclusi dalla media
|
||||
</li>
|
||||
<li>Se un corso ha più CFU di quelli da escludere, viene diviso proporzionalmente</li>
|
||||
</ul>
|
||||
|
||||
<h4>Calcolo del voto finale:</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Media pesata:</strong> Somma dei (voto × CFU) diviso per i CFU totali
|
||||
</li>
|
||||
<li>
|
||||
<strong>Bonus lodi:</strong> +0.5 per lodi in materie > 6 CFU, +0.25 per lodi in materie
|
||||
≤ 6 CFU (max +1.5 per triennale, max +2 per magistrale)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Voto di laurea:</strong> (Voto finale × 11) ÷ 3
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Note:</h4>
|
||||
<ul>
|
||||
<li>
|
||||
Le materie <strong>Pass/Fail</strong> non contribuiscono al calcolo della media
|
||||
</li>
|
||||
<li>Il voto finale è limitato a 30</li>
|
||||
<li>Per i magistrali: massimo 3 istituzioni selezionabili</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Funzione per inizializzare l'app
|
||||
// export function initMediaPesataApp() {
|
||||
// const container = document.getElementById('media-pesata-app')
|
||||
// if (container) {
|
||||
// render(<MediaPesataApp />, container)
|
||||
// }
|
||||
// }
|
||||
|
||||
// export default MediaPesataApp
|
||||
@@ -9,7 +9,7 @@ const extBlock = options => ({
|
||||
start(src) {
|
||||
return src.match(/\$\$[^\$]/)?.index ?? -1
|
||||
},
|
||||
tokenizer(src, tokens) {
|
||||
tokenizer(src, _tokens) {
|
||||
const match = /^\$\$([^\$]+)\$\$/.exec(src)
|
||||
return match ? { type: 'latex-block', raw: match[0], formula: match[1] } : undefined
|
||||
},
|
||||
@@ -25,7 +25,7 @@ const extInline = options => ({
|
||||
start(src) {
|
||||
return src.match(/\$[^\$]/)?.index ?? -1
|
||||
},
|
||||
tokenizer(src, tokens) {
|
||||
tokenizer(src, _tokens) {
|
||||
const match = /^\$([^\$]+)\$/.exec(src)
|
||||
return match ? { type: 'latex', raw: match[0], formula: match[1] } : undefined
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@ const links = [
|
||||
{ href: '/notizie', text: 'Notizie' },
|
||||
{ href: '/guide', text: 'Guide' },
|
||||
{ href: '/domande-esami', text: 'Domande Orali' },
|
||||
{ href: '/media-pesata', text: 'Calcolo Media' }, // Beta testing - solo URL diretto
|
||||
{ href: '/storia', text: 'Storia' },
|
||||
// { href: '/login', text: 'Login' },
|
||||
]
|
||||
|
||||
@@ -17,7 +17,7 @@ const { href, imgSrc, style, title } = Astro.props
|
||||
{imgSrc ? <img src={imgSrc} alt={'logo for ' + title.toLowerCase()} /> : <div class="box" />}
|
||||
</div>
|
||||
<div class="title">{title}</div>
|
||||
<div class="description">
|
||||
<div class="description text">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,17 +32,17 @@ const guidesCollection = defineCollection({
|
||||
})
|
||||
|
||||
// Per ora sono su un sito a parte ma prima o poi verranno migrati qui
|
||||
const seminariettiCollection = defineCollection({
|
||||
type: 'content',
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
author: z.string(),
|
||||
publishDate: z.date(),
|
||||
eventDate: z.date(),
|
||||
tags: z.array(z.string()),
|
||||
}),
|
||||
})
|
||||
// const seminariettiCollection = defineCollection({
|
||||
// type: 'content',
|
||||
// schema: z.object({
|
||||
// title: z.string(),
|
||||
// description: z.string(),
|
||||
// author: z.string(),
|
||||
// publishDate: z.date(),
|
||||
// eventDate: z.date(),
|
||||
// tags: z.array(z.string()),
|
||||
// }),
|
||||
// })
|
||||
|
||||
const metaCollection = defineCollection({
|
||||
type: 'content',
|
||||
@@ -53,6 +53,6 @@ const metaCollection = defineCollection({
|
||||
export const collections = {
|
||||
news: newsCollection,
|
||||
guides: guidesCollection,
|
||||
seminarietti: seminariettiCollection,
|
||||
// seminarietti: seminariettiCollection,
|
||||
meta: metaCollection,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
id: stampare-via-ssh
|
||||
title: Stampare via SSH
|
||||
description: Istruzioni per stampare in dipartimento da remoto, tramite SSH 🖨
|
||||
author: Antonio De Lucreziis, Francesco Minnocci
|
||||
tags: [linux, ssh, stampanti]
|
||||
---
|
||||
|
||||
Per stampare in dipartimento non bisogna per forza usare i computer dei laboratori, possiamo che stampare direttamente da remoto tramite SSH. Vediamo come fare!
|
||||
|
||||
Se non l'avete mai fatto per prima cosa bisogna poter accedere da remoto ad una macchina chiamata "login", il cui indirizzo è `login.dm.unipi.it`. Per fare l'accesso possiamo usare il seguente comando con l'account di Ateneo (non quello Poisson!)
|
||||
|
||||
```bash shell
|
||||
ssh USERNAME_ATENEO@login.dm.unipi.it
|
||||
```
|
||||
|
||||
Una volta connessi possiamo stampare utilizzando il comando `lpr` seguito dal nome del file che vogliamo stampare. Prima però serve trasferire il file che vogliamo stampare sulla macchina "login". Per fare ciò possiamo usare il comando `scp`: per prima cosa usciamo dalla macchina "login" (premere `Ctrl+D` oppure scrivendo `exit`), andiamo nella cartella dove si trova il file che vogliamo stampare e poi eseguiamo il comando:
|
||||
|
||||
```bash shell
|
||||
scp NOME_FILE.pdf USERNAME_ATENEO@login.dm.unipi.it:~/Documents
|
||||
```
|
||||
|
||||
Dove `NOME_FILE.pdf` è il nome del file che vogliamo stampare e `Documents` è un esempio di cartella dove vogliamo trasferirlo. Una volta trasferito il file possiamo rifare ssh su "login" e stampare il file con il comando:
|
||||
|
||||
```bash shell
|
||||
lpr Documents/NOME_FILE.pdf
|
||||
```
|
||||
|
||||
Alternativamente possiamo stampare direttamente il file senza trasferirlo con il comando:
|
||||
|
||||
```bash shell
|
||||
cat NOME_FILE.pdf | ssh USERNAME_ATENEO@login.dm.unipi.it lpr OPZIONI... -
|
||||
```
|
||||
|
||||
Qui, `[OPZIONI...]` sono le opzioni che possiamo passare a `lpr` (vedi sotto). L'ultimo trattino "`-`" è molto importante e indica che il file da stampare è quello in standard input. Più precisamente, `cat NOME_FILE.pdf` invia il contenuto del file `NOME_FILE.pdf` allo standard output e `|` lo ridireziona a input di `ssh`, che a sua volta lo passa a `lpr` via rete.
|
||||
|
||||
## Opzioni di `lpr`
|
||||
|
||||
Il comando `lpr` accetta alcune opzioni che possono essere utili:
|
||||
|
||||
- `-P` seguito dal nome della stampante: permette di specificare la stampante su cui stampare, le stampanti disponibili in dipartimento sono
|
||||
- `cdc4` che è la stampante di default e si trova in Aula 4
|
||||
|
||||
- `cdclf` che si trova al piano terra nel corridoio dopo l'Aula 4
|
||||
|
||||
- `cdc3` che si trova in Aula 3 (è un po' vecchia ma di solito funziona)
|
||||
|
||||
- `-#` seguito dal numero di copie: permette di specificare il numero di copie da stampare. In realtà questa opzione non funziona per vari motivi arcani e se uno passa `-#N` per stampare $N$ copie, la stampante stampa $N^2$ copie. (Questo ha scaturito una serie di ragionamenti sul modo ottimo di decomporre $N$ come somma di quadrati [con tanto di sito di comodo](https://shortest-sum-of-squares.netlify.app/)...)
|
||||
|
||||
- `-o sides=two-sided-long-edge`: permette di stampare **fronte-retro** (che dovrebbe essere già il default)
|
||||
|
||||
- `-o sides=two-sided-short-edge`: permette di stampare fronte-retro con "la rilegatura" delle pagine sul lato corto
|
||||
|
||||
- `-o sides=one-sided`: permette di stampare _solo fronte_, comodo per stampare i meme di laurea
|
||||
|
||||
- `-o fit-to-page`: permette di ridimensionare il documento per farlo entrare in un foglio (è buona prassi passare sempre questa opzione)
|
||||
|
||||
- `-o media=a4`: permette di specificare il formato del foglio, di default è A4 quindi non dovrebbere servire
|
||||
|
||||
## Altre comodità
|
||||
|
||||
Stampare da remoto porta anche altre comodità, ad esempio possiamo interrompere un file che abbiamo mandato in stampa per sbaglio con il comando (sempre tutti comandi da eseguire su "login")
|
||||
|
||||
```bash shell
|
||||
cancel -a
|
||||
```
|
||||
|
||||
> Attenzione, il comando sopra cancella tutta la propria coda di stampa, non solo l'ultimo lavoro inviato.
|
||||
|
||||
Alternativamente possiamo vedere lo stato della coda di stampa con il comando
|
||||
|
||||
```bash shell
|
||||
lpq -a
|
||||
```
|
||||
|
||||
e cancellare un lavoro con uno specifico ID con
|
||||
|
||||
```bash shell
|
||||
cancel ID
|
||||
```
|
||||
@@ -52,7 +52,7 @@ Le card possono essere di dimensioni diverse. Questa è una card grande.
|
||||
</div>
|
||||
```
|
||||
|
||||
### Low Level: Mixin SCSS
|
||||
### ~~Low Level: Mixin SCSS~~ Old CSS Mixin
|
||||
|
||||
Non dovrebbe essere mai necessario usarlo direttamente ma l'effetto di ombra delle card è ottenuto con questo mixin SCSS (che si trova in `src/styles/mixins.scss`).
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: Calcola la tua media ed il voto di laurea con il nuovissimo calcolatore del PHC!
|
||||
description: È ora disponibile uno strumento per calcolare la propria media pesata e il voto di ammissione alla laurea secondo le regole del dipartimento.
|
||||
publishDate: 2025-06-26
|
||||
---
|
||||
|
||||
# Calcola la tua media ed il voto di laurea con il nuovissimo calcolatore del PHC!
|
||||
|
||||
È ora disponibile nella sezione "Calcolo Media" del sito uno strumento per calcolare la propria media pesata e il voto di ammissione alla laurea secondo le regole ufficiali del dipartimento.
|
||||
|
||||
<p align="center">
|
||||
<a href="https://phc.dm.unipi.it/media-pesata/">phc.dm.unipi.it/media-pesata/</a>
|
||||
</p>
|
||||
|
||||
Il calcolatore applica automaticamente le regole di esclusione previste dal regolamento:
|
||||
|
||||
- **Triennale**: vengono esclusi i 15 CFU con i voti più bassi
|
||||
- **Magistrale**: vengono esclusi i 9 CFU con i voti più bassi
|
||||
|
||||
Il sistema calcola anche il bonus per le lodi, che vale +0.5 punti per ogni materia superiore a 6 CFU e +0.25 punti per materie da 6 CFU o meno, con un tetto massimo di +1.5 punti per la triennale e +2 punti per la magistrale.
|
||||
|
||||
Se dovessero esserci bug scriveteci un'email a <a href="mailto:macchinisti@lists.dm.unipi.it">macchinisti@lists.dm.unipi.it</a>!
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: Esplora i meme dell'aula studenti online!
|
||||
description: |
|
||||
Gli storici meme sono stati staccati per i lavori, ma non disperare: li potrai vedere su una nuova pagina.
|
||||
publishDate: 2025-06-26
|
||||
---
|
||||
|
||||
# Esplora i meme dell'aula studenti online!
|
||||
|
||||
Visti gli imminenti lavori che occuperanno l'aula studenti, ad inizio Settembre tutti i meme sulle pareti sono stati staccati e riposti temporaneamente in PHC; qui sotto trovate alcuni timelapse della giornata:
|
||||
|
||||
<div class="grid-h-split">
|
||||
<video controls>
|
||||
<source src="https://static.phc.dm.unipi.it/timelapse-nord.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
<video controls>
|
||||
<source src="https://static.phc.dm.unipi.it/timelapse-sud.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
<video controls>
|
||||
<source src="https://static.phc.dm.unipi.it/timelapse-termosifone.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
</div>
|
||||
|
||||
Per questo motivo, li abbiamo scansionati ed abbiamo creato una bacheca per poter contemplare i meme dovunque voi siate 🧳
|
||||
|
||||
Eccovi dunque il link alla pagina, buon divertimento:
|
||||
|
||||

|
||||
|
||||
<p align="center">
|
||||
<a href="https://meme.phc.dm.unipi.it">meme.phc.dm.unipi.it</a>
|
||||
</p>
|
||||
|
||||
## Coming Soon
|
||||
|
||||
Prima o poi faremo anche una mappa interattiva della stanza, basata sul seguente modello 3D ricostruito con tecniche di fotogrammetria:
|
||||
|
||||
<video controls>
|
||||
<source src="https://static.phc.dm.unipi.it/3d-scan-preview.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
|
||||
> Disclaimer: Se volessi rimuovere una tua immagine da questa pagina, scrivici pure a <a href="mailto:macchinisti@lists.dm.unipi.it">macchinisti@lists.dm.unipi.it</a> e ce ne occuperemo.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: Non avete attivato la 2FA entro il primo dicembre? Ecco come recuperare l'accesso
|
||||
description: |
|
||||
Se non avete attivato l'autenticazione a due fattori entro il primo dicembre, siete bloccati fuori dall'account Unipi. La procedura di recupero passa dal supporto tecnico.
|
||||
publishDate: 2025-12-05
|
||||
---
|
||||
|
||||
# Non avete attivato la 2FA entro il primo dicembre? Ecco come recuperare l'accesso
|
||||
|
||||
Se siamo rimasti fuori dal nostro account Unipi perché non abbiamo attivato l'autenticazione a due fattori entro il primo dicembre, il percorso di recupero è piuttosto lineare.
|
||||
|
||||
Il primo passo è mandare una mail a
|
||||
|
||||
> <a href="mailto:help.polo2@ticket.unipi.it">help.polo2@ticket.unipi.it</a>
|
||||
|
||||
usando un indirizzo email personale (quello di ateneo è bloccato). Nel messaggio dobbiamo specificare chiaramente il problema e includere il nostro indirizzo email d'ateneo.
|
||||
|
||||
Dopo aver inviato la richiesta, tocca aspettare. Il supporto tecnico resetta manualmente lo status 2FA e ci manda una conferma. A quel punto possiamo procedere con l'attivazione seguendo le istruzioni ufficiali:
|
||||
|
||||
> https://it.unipi.it/configurazioni/mfa/autenticazione-a-piu-fattori-mfa-microsoft-365/
|
||||
|
||||
**Nota tecnica:** L'app Microsoft Authenticator non è obbligatoria! Qualsiasi autenticatore compatibile con [TOTP](https://en.wikipedia.org/wiki/Time-based_one-time_password) va bene: Google Authenticator, Bitwarden, Authy e altre alternative funzionano perfettamente. L'unica differenza è che l'app Microsoft Authenticator permette di ricevere notifiche l'accesso che consente di fare login con meno click.
|
||||
|
||||
Per utilizzare una di queste altre app (invece di Microsoft Authenticator), seguire questi step nella creazione del metodo di autenticazione:
|
||||
|
||||
1. Selezionare **"Microsoft Authenticator"**
|
||||
|
||||

|
||||
|
||||
2. Selezionare **"Configura un'app di autenticazione diversa"**
|
||||
|
||||

|
||||
|
||||
3. A questo punto il procedimento cambia in base all'app. In generale verrà richiesto di scannerizzare un QR code e di verificare il corretto funzionamento inserendo la TOTP (codice a 6 cifre)
|
||||
@@ -19,6 +19,7 @@ names:
|
||||
analisi-armonica: Analisi Armonica
|
||||
elementi-di-analisi-complessa: Elementi di Analisi Complessa
|
||||
eti: Elementi di Teoria degli Insiemi
|
||||
teoria-dei-nodi: Teoria dei Nodi
|
||||
|
||||
groups:
|
||||
- id: triennale-anno-1
|
||||
@@ -58,6 +59,7 @@ groups:
|
||||
- analisi-armonica
|
||||
- elementi-di-analisi-complessa
|
||||
- eti
|
||||
- teoria-dei-nodi
|
||||
|
||||
questions:
|
||||
- course: geometria-2
|
||||
@@ -747,7 +749,7 @@ questions:
|
||||
- course: aritmetica
|
||||
content: |
|
||||
Quanti sono i polinomi irriducibili di grado $n$ su $\mathbb{F}_p$? (Hint: può essere utile provare prima il caso dei polinomi di secondo grado. Hint: in alternativa si possono contare i polinomi riducibili.)
|
||||
Hint: Altrimenti dimostrate che
|
||||
Hint: Altrimenti dimostrate che
|
||||
$$\prod_{\mathclap{\substack{p(x) \text{irriducibile} \\ \deg(p(x)) | n}}} p(x) = x^{p^n} - x.$$
|
||||
tags:
|
||||
- 2015
|
||||
@@ -1059,7 +1061,7 @@ questions:
|
||||
|
||||
- course: ricerca-operativa
|
||||
content: |
|
||||
Dato il problema $\max (x_1 + 2x_2)$ soggetto ai vincoli:
|
||||
Dato il problema $\max (x_1 + 2x_2)$ soggetto ai vincoli:
|
||||
$$
|
||||
\begin{cases}
|
||||
x_2 \leq 4 \\
|
||||
@@ -1115,6 +1117,400 @@ questions:
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
# Raccolta di Istituzioni di Geometria da Valeria
|
||||
|
||||
# Raccolta di Istituzioni di Geometria da Fra
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Intorno tubolare, esistenza
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Gruppi di Lie, esiste un unico sottogruppo connesso con data sottoalgebra
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Frobenius
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Invarianza omotopica di de Rham
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Mayer-Vietoris
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Cartan-Hadamard
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Lemma di Gauss
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Whitney
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Localmente euclideo se e solo se R=0
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Mayer-Vietoris a supporto compatto
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Orientabilità di RP^n e CP^n
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Lemma di Poincaré (dimostrare anche che mappe omotope inducono stesso pullback sulla coomologia), brevissimo accenno al caso a supporto compatto (nessuna dimostrazione)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Cos'è il trasporto parallelo (tutti i dettagli di buona definizione a partire dalla definizione di campo parallelo)? Se metto una metrica cosa succede? (Statement delle condizioni equivalenti di compatibilità senza dimostrazione)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Dimostra che l'algebra di Lie associata ad un gruppo di Lie è un'algebra di Lie in senso astratto (voleva giusto sentirsi dire che il bracket di campi invarianti a sinistra è invariante a sinistra senza dimostrazione)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Teorema di corrispondenza algebre di lie
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Quando gli spazi proiettivi reali sono orientabili
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Esistenza dell'intorno tubolare (senza dimostrazione degli "esercizi")
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Dualità di Poincaré 2
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Definizione di connessione metrica e condizioni equivalenti (solo enunciato)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Hopf-Rinow
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Isotopia Ambiente
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Differenziale Esterno
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Stokes
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Raddrizzamento simultaneo
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Definizione di fibrato tangente
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Definizione di intorno tubolare e esistenza
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Teorema di Frobenius
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Piatto se e solo se localmente isometrico
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Quando lo spazio proiettivo reale è orientabile? E quello complesso?
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Isotopia e isotopia ambiente
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Differenziale k-forme
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Corrispondenza tra sottogruppi di lie connessi e sottoalgebre di lie
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Torsione di una connessione
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Dualità di poincarè (perché la mappa DP passa in coomologia?)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Parlare dell'algebra di Lie associata a un Gruppo di Lie
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Enunciato di Frobenius, e perché una distribuzione è integrabile sse è loc. costante
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Poincaré Dualità
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Conseguenze (Betti numeri, specchiabilità)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Distribuzioni, esempi di distribuzioni che (non) sono embeddings
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Trasporto parallelo e geodetiche
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Esempio di varietà non geodeticamente completa, si può avere compatto? (Hopf rinow)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Esistenza di forma volume per varietà orientate e di struttura riemanniana sui fibrati
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Definizione di foliazione
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Localmente euclidea sse piatto
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Teorema di Stokes
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Teorema di Hopf-Rinow
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Orientabilità di CP^n
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Definizione di forma volume ed esistenza
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Stokes (dim.)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
isotopia e isotopia ambiente (def. + teo.)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
tensore Riemann (def.)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
teo. sottoalgebre di Lie
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
esistenza metrica Lorentziana e Riemanniana
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
derivata di k-forme
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
lemma Poincaré e teo. sull'omotopia
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Cos'è l'algebra di Lie (molto veloce)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Cos'è la connessione di Levi Civita ed elencare le forme equivalenti di "compatibilità con la metrica"
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Definire la torsione e fare i conti per mostrare che è un tensore
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Teorema di Whitney (caso compatto e caso generale).
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
M ammette struttura lorentziana orientabile temporalmente sse pettinabile.
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Teorema su sottoalgebre di Lie
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
geodetiche (praticamente solo quale è l'equazione e perché ha senso fare la nabla di un campo su una curva)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Frobenius, enunciato e dimostrazione (dando per scontate le def.equivalenti di foliazione)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
Whitney (entrambi)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
content: |
|
||||
quando il proiettivo è orientabile (ed enunciato del teorema da cui segue)
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
# Raccolta di Istituzioni di Geometria da Fra
|
||||
|
||||
- course: istituzioni-di-geometria
|
||||
@@ -2116,7 +2512,7 @@ questions:
|
||||
|
||||
- course: geometria-e-topologia-differenziale
|
||||
content: |
|
||||
Spazio tangente a $S^n$ (dimostrando che il tangente a $f^{-1}(y) = \ker(df_x)$)
|
||||
Spazio tangente a $S^n$ (dimostrando che il tangente a $f^{-1}(y) = \ker(df_x)$)
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
@@ -2129,25 +2525,25 @@ questions:
|
||||
- course: geometria-e-topologia-differenziale
|
||||
content: |
|
||||
Che cos'è un'orientazione su una varietà?
|
||||
Se la varietà è connessa e orientabile, mostrare che esistono esattamente 2 orientazioni
|
||||
Se la varietà è connessa e orientabile, mostrare che esistono esattamente 2 orientazioni
|
||||
(se non connessa, ce n'è una per ogni componente)
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
- course: geometria-e-topologia-differenziale
|
||||
content: |
|
||||
Per quale motivo è lecito parlare di orientazione "naturale"
|
||||
Per quale motivo è lecito parlare di orientazione "naturale"
|
||||
(nel senso di cosa è permesso e cosa no)?
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
- course: geometria-e-topologia-differenziale
|
||||
content: |
|
||||
Per un diffeomorfismo da una varietà connessa su se stessa,
|
||||
o ne rispetta l'orientazione, o la "flippa".
|
||||
Mostrare (idee) che esiste tale $f$ che "flippa"
|
||||
Per un diffeomorfismo da una varietà connessa su se stessa,
|
||||
o ne rispetta l'orientazione, o la "flippa".
|
||||
Mostrare (idee) che esiste tale $f$ che "flippa"
|
||||
(ad esempio considerare un $f_0 : x \mapsto -x$ che flippa la sfera in $\mathbb{R}^n$
|
||||
e analogamente si può fare per altre varietà in punto,
|
||||
e analogamente si può fare per altre varietà in punto,
|
||||
allora viene flippata sempre)
|
||||
tags:
|
||||
- 2023
|
||||
@@ -2236,3 +2632,104 @@ questions:
|
||||
e illustrare la formula di Gauss
|
||||
tags:
|
||||
- 2023
|
||||
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Definizione di superficie di Seifert e sue proprietà locali.
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Teorema di Seifert, enunciato e dimostrazione.
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Definizione del genere di un nodo (tramite superficie di Seifert).
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Proprietà del genere di un nodo: genere del nodo banale ($g(U)=0$), additività rispetto alla somma connessa ($g(K_1 \# K_2) = g(K_1) + g(K_2)$).
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Relazione tra caratteristica di Eulero di una superficie di Seifert e il genere del nodo.
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Genere del nodo immagine speculare $m(K)$.
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Minimalità del genere di un nodo (genere di una superficie di Seifert minima).
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Struttura del complementare di una superficie di Seifert $S$ in $\mathbb{R}^3$.
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Numero di allacciamento
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Verifica che $\text{lk}$ è un invariante
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Interpretazione omologica di $\text{lk}$.
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Classi di omotopia vs isotopia
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Due curve semplici chiuse sul toro sono isotope $\Leftrightarrow$ solo la stessa classe a meno del segno in $H_1(S^1 \times S^1)$
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
$L = \alpha \cup \beta$, $\text{lk}(L) = \#(\alpha \cap G) = \#(\beta \cap F)$
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Forma di Seifert
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Modulo di Alexander
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Struttura di $H_1(X_\infty)$
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
$H_1(X_\infty)$ è presentato da $tA - A^T$.
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Differenza tra superfici di Seifert: S-equivalenza e invarianza per mosse di Reidemeister.
|
||||
tags:
|
||||
- 2025
|
||||
- course: teoria-dei-nodi
|
||||
content: |
|
||||
Relazioni tra le matrici di Seifert.
|
||||
tags:
|
||||
- 2025
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
|
||||
- fullName: Francesco Baldino
|
||||
entranceDate: 2022
|
||||
description: Bla bla Star Wars
|
||||
description: |
|
||||
Appassionato di Star Wars, NixOS e lunghe camminate in montagna. Pokemon preferito: Latias.
|
||||
social:
|
||||
github: https://github.com/Fran314
|
||||
website: https://poisson.phc.dm.unipi.it/~baldino
|
||||
|
||||
@@ -9,20 +9,17 @@ import '@fontsource/iosevka/latin.css'
|
||||
|
||||
import '@fontsource-variable/material-symbols-outlined/full.css'
|
||||
|
||||
import '../styles/main.scss'
|
||||
import '@/styles/main.css'
|
||||
|
||||
type Props = {
|
||||
title?: string
|
||||
description?: string
|
||||
thumbnail?: string
|
||||
|
||||
/** Tags for the page, used for styling */
|
||||
pageTags?: string | string[]
|
||||
}
|
||||
|
||||
import phcIcon from '../assets/icon.png'
|
||||
|
||||
const { title, description, thumbnail, pageTags } = Astro.props
|
||||
const { title, description, thumbnail } = Astro.props
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
@@ -75,9 +72,14 @@ const { title, description, thumbnail, pageTags } = Astro.props
|
||||
src="//analytics.phc.dm.unipi.it/count.js"
|
||||
data-goatcounter="https://analytics.phc.dm.unipi.it/count"></script>
|
||||
|
||||
<style is:inline>
|
||||
/* Workaround Astro CSS loading order, this forces the layering upfront */
|
||||
@layer base, typography, component, page, utility;
|
||||
</style>
|
||||
|
||||
<title>{title ?? 'PHC'}</title>
|
||||
</head>
|
||||
<body class:list={typeof pageTags === 'string' ? [pageTags] : pageTags}>
|
||||
<body>
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/appunti.css'
|
||||
|
||||
import PageLayout from '@layouts/PageLayout.astro'
|
||||
|
||||
import { AppuntiList, AppuntiCard } from '@client/Appunti'
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/domande-esami.css'
|
||||
|
||||
import type { GetStaticPaths } from 'astro'
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro'
|
||||
import Footer from '@/components/Footer.astro'
|
||||
@@ -16,7 +18,7 @@ export const getStaticPaths = (() => {
|
||||
const { course } = Astro.params
|
||||
---
|
||||
|
||||
<BaseLayout title="Domande Orali | PHC" pageTags={'domande-esami'}>
|
||||
<BaseLayout title="Domande Orali | PHC">
|
||||
<Header />
|
||||
<main>
|
||||
<DomandeEsamiCourse client:only="preact" course={course} />
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/domande-esami.css'
|
||||
|
||||
import { PhosphorIcon } from '@/client/Icon'
|
||||
import Footer from '@/components/Footer.astro'
|
||||
import Header from '@/components/Header.astro'
|
||||
@@ -14,7 +16,7 @@ const courseQuestionCounts = Object.fromEntries(
|
||||
)
|
||||
---
|
||||
|
||||
<BaseLayout title="Domande Orali | PHC" pageTags={'domande-esami'}>
|
||||
<BaseLayout title="Domande Orali | PHC">
|
||||
<Header />
|
||||
<main>
|
||||
<h1>Domande Orali</h1>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/guide-item.css'
|
||||
|
||||
import { getCollection } from 'astro:content'
|
||||
|
||||
import ArticleLayout from '@/layouts/ArticleLayout.astro'
|
||||
@@ -16,11 +18,9 @@ const { entry } = Astro.props
|
||||
const { Content } = await entry.render()
|
||||
---
|
||||
|
||||
<ArticleLayout
|
||||
{...entry.data}
|
||||
title={entry.data.title + ' | Guide | PHC'}
|
||||
pageTags={['guida', entry.data.id, entry.data.series && 'series']}
|
||||
>
|
||||
<ArticleLayout {...entry.data} title={entry.data.title + ' | Guide | PHC'}>
|
||||
<!-- pageTags={['guida', entry.data.id, entry.data.series && 'series']} -->
|
||||
|
||||
<h1>{entry.data.title}</h1>
|
||||
|
||||
{entry.data.series && <div class="series">Serie: {entry.data.series}</div>}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/guide-list.css'
|
||||
|
||||
import { getCollection } from 'astro:content'
|
||||
|
||||
import PageLayout from '@layouts/PageLayout.astro'
|
||||
@@ -6,7 +8,7 @@ import PageLayout from '@layouts/PageLayout.astro'
|
||||
const guides = await getCollection('guides')
|
||||
---
|
||||
|
||||
<PageLayout title="Guide | PHC" pageTags="guide">
|
||||
<PageLayout title="Guide | PHC">
|
||||
<h1>
|
||||
<a href="/guide">Guide</a>
|
||||
</h1>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/guide-list.css'
|
||||
|
||||
import { getCollection } from 'astro:content'
|
||||
import type { CollectionEntry } from 'astro:content'
|
||||
import PageLayout from '@/layouts/PageLayout.astro'
|
||||
@@ -33,7 +35,7 @@ interface Props {
|
||||
const { tag, guides } = Astro.props
|
||||
---
|
||||
|
||||
<PageLayout title={`#${tag} | Guide | PHC`} pageTags="guide tag">
|
||||
<PageLayout title={`#${tag} | Guide | PHC`}>
|
||||
<h1><a href="/guide">Guide</a> > <a href={`/guide/tags/${tag}`}>#{tag}</a></h1>
|
||||
<div class="card-list">
|
||||
{
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/homepage.css'
|
||||
|
||||
import { getCollection } from 'astro:content'
|
||||
import PageLayout from '@/layouts/PageLayout.astro'
|
||||
import { Content as WhatPhcContent, frontmatter as whatsPhcFrontmatter } from '@/content/meta/whats-phc.md'
|
||||
@@ -9,7 +11,11 @@ import Card from '@/components/Card.astro'
|
||||
|
||||
const news = await getCollection('news')
|
||||
|
||||
const galleryCollage = await Astro.glob('@/assets/gallery/*.jpg')
|
||||
// const galleryCollage = await Astro.glob('@/assets/gallery/*.jpg')
|
||||
|
||||
const galleryCollage: { default: ImageMetadata }[] = Object.values(
|
||||
import.meta.glob('@/assets/gallery/*.jpg', { eager: true }),
|
||||
)
|
||||
---
|
||||
|
||||
<PageLayout title="PHC" pageTags="homepage">
|
||||
@@ -45,21 +51,23 @@ const galleryCollage = await Astro.glob('@/assets/gallery/*.jpg')
|
||||
|
||||
<div class="card-list">
|
||||
{
|
||||
news.toReversed().map(newsItem => (
|
||||
<Card>
|
||||
<a href={`/notizie/${newsItem.slug}`} class="title">
|
||||
{newsItem.data.title}
|
||||
</a>
|
||||
<div class="text small dimmed">
|
||||
{new Date(newsItem.data.publishDate).toLocaleDateString('it-IT', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</div>
|
||||
<div class="text">{newsItem.data.description}</div>
|
||||
</Card>
|
||||
))
|
||||
news
|
||||
.sort((s, t) => -s.id.localeCompare(t.id))
|
||||
.map(newsItem => (
|
||||
<Card>
|
||||
<a href={`/notizie/${newsItem.slug}`} class="title">
|
||||
{newsItem.data.title}
|
||||
</a>
|
||||
<div class="text small dimmed">
|
||||
{new Date(newsItem.data.publishDate).toLocaleDateString('it-IT', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</div>
|
||||
<div class="text">{newsItem.data.description}</div>
|
||||
</Card>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -92,9 +100,9 @@ const galleryCollage = await Astro.glob('@/assets/gallery/*.jpg')
|
||||
</ProjectCard> -->
|
||||
<ProjectCard
|
||||
title="Orario"
|
||||
href="https://lab.phc.dm.unipi.it/orario/"
|
||||
href="https://orario.phc.dm.unipi.it/"
|
||||
style="--card-bg: #75ca75; --masonry-height: 1;"
|
||||
imgSrc="https://lab.phc.dm.unipi.it/orario/icon.png"
|
||||
imgSrc="https://orario.phc.dm.unipi.it/icon.png"
|
||||
>
|
||||
<p>
|
||||
Questo sito permette di visualizzare il proprio orario delle lezioni, con informazioni sui docenti e
|
||||
@@ -103,9 +111,9 @@ const galleryCollage = await Astro.glob('@/assets/gallery/*.jpg')
|
||||
</ProjectCard>
|
||||
<ProjectCard
|
||||
title="Problemi"
|
||||
href="https://lab.phc.dm.unipi.it/problemi/"
|
||||
href="https://problemi.phc.dm.unipi.it/"
|
||||
style="--card-bg: #aa88c0; --masonry-height: 2;"
|
||||
imgSrc="https://lab.phc.dm.unipi.it/problemi/favicon/android-chrome-512x512.png"
|
||||
imgSrc="https://problemi.phc.dm.unipi.it/favicon/android-chrome-512x512.png"
|
||||
>
|
||||
<p>Bacheca di problemi di Matematica da risolvere, inviandone le soluzioni in LaTeX.</p>
|
||||
<p>Di sera, puoi leggere i problemi sullo schermo del Dipartimento in atrio.</p>
|
||||
@@ -114,7 +122,7 @@ const galleryCollage = await Astro.glob('@/assets/gallery/*.jpg')
|
||||
title='Cluster "Steffè"'
|
||||
href="http://steffe.cs.dm.unipi.it/"
|
||||
style="--masonry-height: 2;"
|
||||
imgSrc="https://steffe.lb.cs.dm.unipi.it/assets/img/logo.png"
|
||||
imgSrc="/images/steffe-logo.png"
|
||||
>
|
||||
<p>
|
||||
Cluster progettato ed assemblato durante il progetto speciale per la didattica "Calcolo Parallelo
|
||||
@@ -144,7 +152,7 @@ const galleryCollage = await Astro.glob('@/assets/gallery/*.jpg')
|
||||
title="GGWP"
|
||||
href="https://ggwp.phc.dm.unipi.it/"
|
||||
style="--card-bg: rgb(255, 157, 65); --masonry-height: 2;"
|
||||
imgSrc="https://ggwp.phc.dm.unipi.it/ggwp-icon.png"
|
||||
imgSrc="/images/ggwp-icon.png"
|
||||
>
|
||||
<p>
|
||||
Sito per il tabellone del GGWP, utilizzato durante la gara di Novembre 2024 dagli organizzatori per
|
||||
@@ -155,7 +163,7 @@ const galleryCollage = await Astro.glob('@/assets/gallery/*.jpg')
|
||||
title="Chat"
|
||||
href="https://chat.phc.dm.unipi.it/"
|
||||
style="--card-bg: #383838; --card-fg: #ddd; --masonry-height: 1;"
|
||||
imgSrc="https://chat.phc.dm.unipi.it/favicon.png"
|
||||
imgSrc="/images/chat-favicon.png"
|
||||
>
|
||||
<p>Istanza di Open-WebUI, una chat stile ChatGPT con alcuni LLM self-hostati dal PHC.</p>
|
||||
</ProjectCard>
|
||||
@@ -196,14 +204,16 @@ const galleryCollage = await Astro.glob('@/assets/gallery/*.jpg')
|
||||
{
|
||||
galleryCollage.map((module, i) => {
|
||||
const src = module.default.src
|
||||
const filename = src.split('/').at(-1).split('?').at(0).split('.').at(0)
|
||||
const filename = src.split('/').at(-1)?.split('?').at(0)?.split('.').at(0)
|
||||
|
||||
if (!filename) return null
|
||||
|
||||
const [rows, cols] = filename.includes('@')
|
||||
? filename
|
||||
? (filename
|
||||
.split('@')
|
||||
.at(-1)
|
||||
.split('x')
|
||||
.map((s: string) => parseInt(s))
|
||||
?.split('x')
|
||||
.map((s: string) => parseInt(s)) ?? [1, 1])
|
||||
: [1, 1]
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/macchinisti.css'
|
||||
|
||||
import BaseLayout from '../layouts/BaseLayout.astro'
|
||||
import Header from '../components/Header.astro'
|
||||
import Footer from '../components/Footer.astro'
|
||||
@@ -26,7 +28,7 @@ const getMacchinistaPicture = (fullName: string) => {
|
||||
}
|
||||
---
|
||||
|
||||
<BaseLayout title="Macchinisti | PHC" pageTags={'macchinisti'}>
|
||||
<BaseLayout title="Macchinisti | PHC">
|
||||
<Header />
|
||||
<main>
|
||||
<div class="card large" style={{ '--card-base': '#e1766b' }}>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
import '@/styles/pages/media-pesata.css'
|
||||
import PageLayout from '../layouts/PageLayout.astro'
|
||||
|
||||
import { MediaPesataApp } from '@/client/MediaPesataApp'
|
||||
---
|
||||
|
||||
<PageLayout
|
||||
title="Voto Laurea"
|
||||
description="Calcola la tua media pesata e il voto di laurea seguendo le regole del dipartimento"
|
||||
>
|
||||
<div class="media-pesata-container">
|
||||
<h1>Calcolo Media e Voto di Laurea</h1>
|
||||
<p>
|
||||
Calcola la tua media pesata e il voto con cui ti siederai alla discussione di laurea, seguendo le regole del
|
||||
dipartimento di Matematica.
|
||||
</p>
|
||||
|
||||
<MediaPesataApp client:load />
|
||||
</div>
|
||||
</PageLayout>
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/meta-design.css'
|
||||
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro'
|
||||
|
||||
import Header from '../../components/Header.astro'
|
||||
@@ -11,7 +13,7 @@ import { Content, getHeadings } from '../../content/meta/design.mdx'
|
||||
const headings = getHeadings()
|
||||
---
|
||||
|
||||
<BaseLayout {...Astro.props} pageTags="design">
|
||||
<BaseLayout {...Astro.props}>
|
||||
<Header />
|
||||
<aside>
|
||||
<nav>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/news-item.css'
|
||||
|
||||
import { getCollection } from 'astro:content'
|
||||
|
||||
import ArticleLayout from '../../layouts/ArticleLayout.astro'
|
||||
@@ -15,6 +17,6 @@ const { entry } = Astro.props
|
||||
const { Content } = await entry.render()
|
||||
---
|
||||
|
||||
<ArticleLayout {...entry.data} title={entry.data.title + ' | Notizie | PHC'} pageTags={['notizia']}>
|
||||
<ArticleLayout {...entry.data} title={entry.data.title + ' | Notizie | PHC'}>
|
||||
<Content />
|
||||
</ArticleLayout>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/news-list.css'
|
||||
|
||||
import { getCollection } from 'astro:content'
|
||||
|
||||
import PageLayout from '@layouts/PageLayout.astro'
|
||||
@@ -6,25 +8,27 @@ import PageLayout from '@layouts/PageLayout.astro'
|
||||
const news = await getCollection('news')
|
||||
---
|
||||
|
||||
<PageLayout title="Notizie | PHC" pageTags="notizie">
|
||||
<PageLayout title="Notizie | PHC">
|
||||
<h1><a href="/notizie">Notizie</a></h1>
|
||||
<div class="card-list">
|
||||
{
|
||||
news.toReversed().map(newsItem => (
|
||||
<div class="card">
|
||||
<a href={`/notizie/${newsItem.slug}`} class="title">
|
||||
{newsItem.data.title}
|
||||
</a>
|
||||
<div class="text small dimmed">
|
||||
{new Date(newsItem.data.publishDate).toLocaleDateString('it-IT', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
news
|
||||
.sort((s, t) => -s.id.localeCompare(t.id))
|
||||
.map(newsItem => (
|
||||
<div class="card">
|
||||
<a href={`/notizie/${newsItem.slug}`} class="title">
|
||||
{newsItem.data.title}
|
||||
</a>
|
||||
<div class="text small dimmed">
|
||||
{new Date(newsItem.data.publishDate).toLocaleDateString('it-IT', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</div>
|
||||
<div class="text">{newsItem.data.description}</div>
|
||||
</div>
|
||||
<div class="text">{newsItem.data.description}</div>
|
||||
</div>
|
||||
))
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</PageLayout>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import '@/styles/pages/storia.css'
|
||||
|
||||
import BaseLayout from '../layouts/BaseLayout.astro'
|
||||
|
||||
import Header from '../components/Header.astro'
|
||||
@@ -10,7 +12,7 @@ import imgCluster from '@/assets/gallery/001-cluster-fra-luca@4x3.jpg'
|
||||
import WebSite from '@/assets/gallery/005-website-development@3x4.jpg'
|
||||
---
|
||||
|
||||
<BaseLayout title="Storia | PHC" pageTags={'storia'}>
|
||||
<BaseLayout title="Storia | PHC">
|
||||
<Header />
|
||||
<main>
|
||||
<div class="card large" style={{ '--card-base': '#ffd3a0' }}>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
---
|
||||
import '@/styles/pages/utenti.css'
|
||||
|
||||
import PageLayout from '../layouts/PageLayout.astro'
|
||||
|
||||
import { UtentiPage } from '../client/UtentiPage.tsx'
|
||||
---
|
||||
|
||||
<PageLayout title="Utenti | PHC" pageTags="utenti">
|
||||
<PageLayout title="Utenti | PHC">
|
||||
<h1>Utenti</h1>
|
||||
<UtentiPage client:load />
|
||||
</PageLayout>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
@mixin neo-brutalist-card($size: 3px, $offset: $size + 1, $shadow: true, $hoverable: false) {
|
||||
/* This file is here for historical reasons but is not used anymore */
|
||||
|
||||
/* @mixin neo-brutalist-card($size: 3px, $offset: $size + 1, $shadow: true, $hoverable: false) {
|
||||
border: $size solid #222;
|
||||
border-radius: $size * 2;
|
||||
|
||||
@@ -14,4 +16,4 @@
|
||||
box-shadow: $offset + 1 $offset + 1 0 0 #222;
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
@@ -0,0 +1,27 @@
|
||||
/* This file is here for historical reasons but is not used anymore */
|
||||
|
||||
@layer page {
|
||||
/*
|
||||
.login {
|
||||
background: #ddfaff;
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
max-width: 80ch;
|
||||
padding: 3rem 0;
|
||||
|
||||
gap: 3rem;
|
||||
|
||||
h3 {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
// $news-bg: #fffbeb;
|
||||
// $news-accent-bg: #f8e8b1;
|
||||
/*
|
||||
$news-bg: #fffbeb;
|
||||
$news-accent-bg: #f8e8b1;
|
||||
*/
|
||||
|
||||
@import './mixins.scss';
|
||||
/* @TODO: SCSS conversion - @import becomes more complex */
|
||||
/* @import './mixins.scss'; */
|
||||
|
||||
@layer component {
|
||||
//
|
||||
// Components - for complex parts of the UI like search bars or compound buttons
|
||||
//
|
||||
/*
|
||||
/* Components - for complex parts of the UI like search bars or compound buttons
|
||||
*/
|
||||
|
||||
.phosphor-icon {
|
||||
box-sizing: content-box;
|
||||
@@ -52,7 +55,13 @@
|
||||
width: 100%;
|
||||
height: 2.5rem;
|
||||
|
||||
@include neo-brutalist-card;
|
||||
/* @TODO: SCSS conversion - mixin */
|
||||
/* @include neo-brutalist-card; */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 4px 4px 0 0 #222;
|
||||
|
||||
background: #fff;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
@@ -60,8 +69,6 @@
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
background: #fff;
|
||||
|
||||
&:hover,
|
||||
&:hover input[type='text'] {
|
||||
background: #f8f8f8;
|
||||
@@ -105,7 +112,11 @@
|
||||
|
||||
background: #fff;
|
||||
|
||||
@include neo-brutalist-card;
|
||||
/* @TODO: SCSS conversion - mixin */
|
||||
/* @include neo-brutalist-card; */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 4px 4px 0 0 #222;
|
||||
|
||||
a {
|
||||
display: contents;
|
||||
@@ -161,7 +172,16 @@
|
||||
aspect-ratio: 10 / 14;
|
||||
background: #d0d0d0;
|
||||
|
||||
@include neo-brutalist-card($hoverable: true);
|
||||
/* @TODO: SCSS conversion - mixin */
|
||||
/* @include neo-brutalist-card($hoverable: true); */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
transition: all 64ms linear;
|
||||
|
||||
&:hover {
|
||||
transform: translate(-1px, -1px);
|
||||
box-shadow: 4px 4px 0 0 #222;
|
||||
}
|
||||
}
|
||||
|
||||
& > .thumbnail + * {
|
||||
@@ -195,7 +215,11 @@
|
||||
background: var(--card-bg, var(--project-card-bg));
|
||||
color: #000e;
|
||||
|
||||
@include neo-brutalist-card($size: 3px, $offset: 9px);
|
||||
/* @TODO: SCSS conversion - mixin */
|
||||
/* @include neo-brutalist-card($size: 3px, $offset: 9px); */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 9px 9px 0 0 #222;
|
||||
|
||||
row-gap: 0.5rem;
|
||||
padding: 1rem;
|
||||
@@ -219,109 +243,109 @@
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
|
||||
// .news-item {
|
||||
// background: $news-bg;
|
||||
// color: #111;
|
||||
/* .news-item {
|
||||
background: $news-bg;
|
||||
color: #111;
|
||||
|
||||
// @include neo-brutalist-card($size: 3px, $offset: 9px);
|
||||
@include neo-brutalist-card($size: 3px, $offset: 9px);
|
||||
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
// width: 22rem;
|
||||
// max-height: 27rem;
|
||||
width: 22rem;
|
||||
max-height: 27rem;
|
||||
|
||||
// overflow: hidden;
|
||||
overflow: hidden;
|
||||
|
||||
// ::-webkit-scrollbar {
|
||||
// width: 10px;
|
||||
// }
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
// ::-webkit-scrollbar-thumb {
|
||||
// background-color: #c67e14;
|
||||
// border: 2px solid #222;
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #c67e14;
|
||||
border: 2px solid #222;
|
||||
|
||||
// &:hover {
|
||||
// background-color: #e69419;
|
||||
// }
|
||||
// }
|
||||
&:hover {
|
||||
background-color: #e69419;
|
||||
}
|
||||
}
|
||||
|
||||
// a {
|
||||
// font-weight: 600;
|
||||
// text-decoration: none;
|
||||
// color: #c67e14;
|
||||
a {
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
color: #c67e14;
|
||||
|
||||
// &:hover {
|
||||
// text-decoration: underline solid 2px;
|
||||
// }
|
||||
// }
|
||||
&:hover {
|
||||
text-decoration: underline solid 2px;
|
||||
}
|
||||
}
|
||||
|
||||
// & > .title {
|
||||
// padding: 1rem;
|
||||
// background: $news-accent-bg;
|
||||
// line-height: 1;
|
||||
// font-size: 26px;
|
||||
// }
|
||||
& > .title {
|
||||
padding: 1rem;
|
||||
background: $news-accent-bg;
|
||||
line-height: 1;
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
// a.title {
|
||||
// color: #83530c;
|
||||
// }
|
||||
a.title {
|
||||
color: #83530c;
|
||||
}
|
||||
|
||||
// & > .abstract {
|
||||
// flex-grow: 1;
|
||||
& > .abstract {
|
||||
flex-grow: 1;
|
||||
|
||||
// padding: 1rem;
|
||||
padding: 1rem;
|
||||
|
||||
// overflow-y: auto;
|
||||
overflow-y: auto;
|
||||
|
||||
// @extend .text;
|
||||
// }
|
||||
@extend .text;
|
||||
}
|
||||
|
||||
// & > .content {
|
||||
// display: flex;
|
||||
// padding: 1rem;
|
||||
// flex-direction: column;
|
||||
// gap: 0.5rem;
|
||||
& > .content {
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
|
||||
// background: #fff8da;
|
||||
background: #fff8da;
|
||||
|
||||
// & > .continue {
|
||||
// padding: 1rem;
|
||||
& > .continue {
|
||||
padding: 1rem;
|
||||
|
||||
// display: grid;
|
||||
// align-items: end;
|
||||
// justify-content: end;
|
||||
// }
|
||||
display: grid;
|
||||
align-items: end;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
// & > .description {
|
||||
// font-size: 16px;
|
||||
// line-height: 1.5;
|
||||
& > .description {
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
|
||||
// flex-grow: 1;
|
||||
// }
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
// & > .tags {
|
||||
// display: flex;
|
||||
// gap: 0.5rem;
|
||||
// flex-wrap: wrap;
|
||||
// font-size: 14px;
|
||||
// color: #555;
|
||||
// }
|
||||
& > .tags {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
// & > .date {
|
||||
// font-size: 14px;
|
||||
// font-style: italic;
|
||||
// font-weight: 600;
|
||||
// color: #0008;
|
||||
// }
|
||||
& > .date {
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
color: #0008;
|
||||
}
|
||||
|
||||
// & > .author {
|
||||
// font-weight: 600;
|
||||
// font-size: 15px;
|
||||
// color: #555;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
& > .author {
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
}
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
.timeline {
|
||||
@@ -334,7 +358,7 @@
|
||||
max-width: 120ch;
|
||||
grid-template-columns: 1fr var(--timeline-track-size) 1fr;
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
--timeline-track-size: 3rem;
|
||||
grid-template-columns: var(--timeline-track-size) 1fr;
|
||||
}
|
||||
@@ -348,7 +372,7 @@
|
||||
grid-template-columns: auto;
|
||||
padding: 2rem 1rem;
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 1rem 1rem 1rem 0;
|
||||
}
|
||||
|
||||
@@ -364,7 +388,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// timeline vertical line
|
||||
/* timeline vertical line */
|
||||
&::before {
|
||||
content: '';
|
||||
|
||||
@@ -386,7 +410,7 @@
|
||||
bottom: 50%;
|
||||
}
|
||||
|
||||
// timeline circle
|
||||
/* timeline circle */
|
||||
&::after {
|
||||
content: '';
|
||||
|
||||
@@ -406,7 +430,7 @@
|
||||
grid-column: 1 / span 1;
|
||||
}
|
||||
|
||||
@media screen and (min-width: $screen-desktop-min) {
|
||||
@media screen and (min-width: 1024px) {
|
||||
&:nth-child(odd)::before {
|
||||
grid-column: 2 / span 1;
|
||||
}
|
||||
@@ -425,7 +449,11 @@
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
@include neo-brutalist-card;
|
||||
/* @TODO: SCSS conversion - mixin */
|
||||
/* @include neo-brutalist-card; */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 3px 3px 0 0 #222;
|
||||
|
||||
max-width: 15rem;
|
||||
position: absolute;
|
||||
@@ -435,8 +463,12 @@
|
||||
border-top: none;
|
||||
border-radius: 0 0 0.5rem 0.5rem;
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@include neo-brutalist-card;
|
||||
@media screen and (max-width: 1024px) {
|
||||
/* @TODO: SCSS conversion - mixin */
|
||||
/* @include neo-brutalist-card; */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 3px 3px 0 0 #222;
|
||||
|
||||
position: static;
|
||||
transform: none;
|
||||
@@ -444,7 +476,7 @@
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: $screen-desktop-min) {
|
||||
@media screen and (min-width: 1024px) {
|
||||
&:nth-child(odd) {
|
||||
grid-column: 1 / span 2;
|
||||
grid-template-columns: 1fr var(--timeline-track-size);
|
||||
@@ -475,7 +507,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
grid-column: 1 / span 2;
|
||||
|
||||
grid-template-columns: var(--timeline-track-size) 1fr;
|
||||
@@ -487,9 +519,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Cards
|
||||
//
|
||||
/*
|
||||
/* Cards
|
||||
*/
|
||||
|
||||
.card {
|
||||
display: grid;
|
||||
@@ -499,17 +531,25 @@
|
||||
background: var(--card-base-internal);
|
||||
color: color-mix(in srgb, var(--card-base-internal), #000 80%);
|
||||
|
||||
@include neo-brutalist-card($size: 3px, $offset: 9px);
|
||||
/* @TODO: SCSS conversion - mixin */
|
||||
/* @include neo-brutalist-card($size: 3px, $offset: 9px); */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 9px 9px 0 0 #222;
|
||||
|
||||
row-gap: 0.5rem;
|
||||
padding: 1rem;
|
||||
|
||||
// Variants
|
||||
/* Variants */
|
||||
|
||||
&.large {
|
||||
padding: 2rem;
|
||||
|
||||
@include neo-brutalist-card($size: 4px, $offset: 8px);
|
||||
/* @TODO: SCSS conversion - mixin */
|
||||
/* @include neo-brutalist-card($size: 4px, $offset: 8px); */
|
||||
border: 4px solid #222;
|
||||
border-radius: 8px;
|
||||
box-shadow: 8px 8px 0 0 #222;
|
||||
|
||||
row-gap: 1rem;
|
||||
|
||||
@@ -523,7 +563,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Child Items
|
||||
/* Child Items */
|
||||
|
||||
& > .title {
|
||||
color: color-mix(in srgb, var(--card-base-internal), #000 75%);
|
||||
@@ -580,7 +620,7 @@
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 0.9rem;
|
||||
|
||||
&.large {
|
||||
@@ -629,9 +669,9 @@
|
||||
display: contents;
|
||||
}
|
||||
|
||||
//
|
||||
// Card List
|
||||
//
|
||||
/*
|
||||
/* Card List
|
||||
*/
|
||||
|
||||
.card-list {
|
||||
display: grid;
|
||||
@@ -663,7 +703,7 @@
|
||||
|
||||
gap: 1rem;
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
& > .search {
|
||||
@@ -673,44 +713,44 @@
|
||||
}
|
||||
|
||||
/* .filter-select {
|
||||
width: 100%;
|
||||
height: 2.5rem;
|
||||
width: 100%;
|
||||
height: 2.5rem;
|
||||
|
||||
@include neo-brutalist-card;
|
||||
@include neo-brutalist-card;
|
||||
|
||||
display: grid;
|
||||
align-items: center;
|
||||
grid-auto-flow: column;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
grid-auto-flow: column;
|
||||
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
|
||||
--filter-bg-color-hover: color-mix(in srgb, var(--filter-bg-color, #ddd), #000 10%);
|
||||
--filter-bg-color-hover: color-mix(in srgb, var(--filter-bg-color, #ddd), #000 10%);
|
||||
|
||||
background: var(--filter-bg-color, #ddd);
|
||||
background: var(--filter-bg-color, #ddd);
|
||||
|
||||
&:hover,
|
||||
&:hover select {
|
||||
background: var(--filter-bg-color-hover);
|
||||
}
|
||||
&:hover,
|
||||
&:hover select {
|
||||
background: var(--filter-bg-color-hover);
|
||||
}
|
||||
|
||||
.material-symbols-outlined {
|
||||
padding: 0 0.35rem;
|
||||
}
|
||||
.material-symbols-outlined {
|
||||
padding: 0 0.35rem;
|
||||
}
|
||||
|
||||
select {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
height: 100%;
|
||||
appearance: none;
|
||||
select {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
height: 100%;
|
||||
appearance: none;
|
||||
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
|
||||
padding: 0;
|
||||
padding: 0;
|
||||
|
||||
background: var(--filter-bg-color, #ddd);
|
||||
}
|
||||
} */
|
||||
background: var(--filter-bg-color, #ddd);
|
||||
}
|
||||
} */
|
||||
|
||||
.combobox {
|
||||
width: 100%;
|
||||
@@ -718,7 +758,10 @@
|
||||
position: relative;
|
||||
padding: 0 0.25rem 0 0.25rem;
|
||||
|
||||
@include neo-brutalist-card;
|
||||
/* @TODO: SCSS conversion - mixin */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 4px 4px 0 0 #222;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
@@ -753,7 +796,10 @@
|
||||
top: calc(100% + 8px);
|
||||
left: -3px;
|
||||
|
||||
@include neo-brutalist-card;
|
||||
/* @TODO: SCSS conversion - mixin */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
/* box-shadow: 3px 3px 0 0 #222; */
|
||||
|
||||
background: #fff;
|
||||
|
||||
@@ -770,7 +816,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
.dropdown {
|
||||
left: 3px;
|
||||
right: 3px;
|
||||
@@ -781,10 +827,10 @@
|
||||
}
|
||||
|
||||
.gallery-collage {
|
||||
// display: flex;
|
||||
// flex-wrap: wrap;
|
||||
/* display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
// width: 64rem;
|
||||
width: 64rem; */
|
||||
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
@@ -799,9 +845,9 @@
|
||||
gap: 1rem;
|
||||
|
||||
place-content: center;
|
||||
// align-items: center;
|
||||
/* align-items: center; */
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
grid-template-columns: auto;
|
||||
grid-template-rows: auto;
|
||||
grid-auto-rows: auto;
|
||||
@@ -818,7 +864,7 @@
|
||||
grid-column: span var(--cols, 1);
|
||||
grid-row: span var(--rows, 1);
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
max-width: 100%;
|
||||
|
||||
grid-column: span 1;
|
||||
@@ -837,7 +883,7 @@
|
||||
|
||||
object-fit: cover;
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
max-height: none;
|
||||
|
||||
width: 25rem;
|
||||
@@ -878,7 +924,7 @@
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
|
||||
// gold badge
|
||||
/* gold badge */
|
||||
background: #ffdb12;
|
||||
color: #725306;
|
||||
|
||||
@@ -928,7 +974,7 @@
|
||||
width: 100%;
|
||||
|
||||
justify-content: center;
|
||||
// align-items: start;
|
||||
/* align-items: start; */
|
||||
|
||||
.text > * {
|
||||
max-width: none;
|
||||
@@ -939,7 +985,7 @@
|
||||
grid-template-rows: 1fr auto;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
padding: 0;
|
||||
@@ -996,11 +1042,25 @@
|
||||
grid-auto-flow: row;
|
||||
}
|
||||
|
||||
.grid-h-split {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
gap: 1rem;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: 1fr;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
grid-auto-flow: row;
|
||||
grid-auto-columns: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// just to know for reference
|
||||
/* just to know for reference */
|
||||
.fake-masonry {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--columns), 1fr);
|
||||
@@ -1,10 +1,10 @@
|
||||
@import './mixins.scss';
|
||||
/* @import './mixins.scss'; */
|
||||
|
||||
//
|
||||
// Controls - for things like buttons, input, select
|
||||
//
|
||||
/*
|
||||
Controls - for things like buttons, input, select
|
||||
*/
|
||||
|
||||
@layer common {
|
||||
@layer base {
|
||||
button,
|
||||
.button,
|
||||
[role='button'] {
|
||||
@@ -12,7 +12,10 @@
|
||||
|
||||
background: #fff;
|
||||
|
||||
@include neo-brutalist-card;
|
||||
/* @include neo-brutalist-card; */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 4px 4px 0 0 #222;
|
||||
|
||||
transition: all 64ms linear;
|
||||
|
||||
@@ -35,7 +38,7 @@
|
||||
text-decoration: none;
|
||||
color: #222;
|
||||
|
||||
font-family: var(--font-secondary);
|
||||
font-family: var(--font-secondary); /* TODO: check if this is a global variable and replace */
|
||||
font-weight: 600;
|
||||
|
||||
cursor: pointer;
|
||||
@@ -72,9 +75,12 @@
|
||||
input[type='text'],
|
||||
input[type='password'] {
|
||||
width: 100%;
|
||||
height: 2.5rem;
|
||||
min-height: 1.75rem;
|
||||
|
||||
@include neo-brutalist-card;
|
||||
/* @include neo-brutalist-card; */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 4px 4px 0 0 #222;
|
||||
|
||||
padding: 0 0.25rem;
|
||||
|
||||
@@ -83,6 +89,95 @@
|
||||
}
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
|
||||
width: calc(1.5rem + 1px);
|
||||
height: calc(1.5rem + 1px);
|
||||
|
||||
background: #fff;
|
||||
border: 3px solid #222;
|
||||
border-radius: 4px;
|
||||
box-shadow: 3px 3px 0 0 #222;
|
||||
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
transition: all 64ms linear;
|
||||
|
||||
&:hover {
|
||||
transform: translate(-1px, -1px);
|
||||
box-shadow: 4px 4px 0 0 #222;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translate(1px, 1px);
|
||||
box-shadow: 2px 2px 0 0 #222;
|
||||
}
|
||||
|
||||
&:checked {
|
||||
background: #1e6733;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
width: 0.8rem;
|
||||
height: 0.8rem;
|
||||
background: #1e6733;
|
||||
|
||||
clip-path: polygon(10% 55%, 35% 75%, 85% 25%, 90% 35%, 40% 95%, 5% 60%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #2b8b47;
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: #eee;
|
||||
border-color: #888;
|
||||
box-shadow: 3px 3px 0 0 #888;
|
||||
cursor: not-allowed;
|
||||
|
||||
&:hover {
|
||||
transform: none;
|
||||
box-shadow: 3px 3px 0 0 #888;
|
||||
}
|
||||
|
||||
&:checked {
|
||||
background: #aaa;
|
||||
|
||||
&::after {
|
||||
background: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.star {
|
||||
&:checked::after {
|
||||
background: rgb(255, 197, 49);
|
||||
clip-path: polygon(
|
||||
50% 0%,
|
||||
61% 35%,
|
||||
98% 35%,
|
||||
68% 57%,
|
||||
79% 91%,
|
||||
50% 70%,
|
||||
21% 91%,
|
||||
32% 57%,
|
||||
2% 35%,
|
||||
39% 35%
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
form {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
@@ -92,7 +187,10 @@
|
||||
|
||||
min-width: 40ch;
|
||||
|
||||
@include neo-brutalist-card($size: 3px, $offset: 9px);
|
||||
/* @include neo-brutalist-card($size: 3px, $offset: 9px); */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 9px 9px 0 0 #222;
|
||||
|
||||
button,
|
||||
.button,
|
||||
@@ -165,7 +263,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@media screen and (max-width: 1024px) {
|
||||
/* TODO: check if this is a global variable and replace */
|
||||
summary {
|
||||
place-content: stretch;
|
||||
place-items: stretch;
|
||||
@@ -0,0 +1,371 @@
|
||||
@layer base, typography, component, page, utility;
|
||||
|
||||
@import url(./controls.css);
|
||||
@import url(./components.css);
|
||||
@import url(./typography.css);
|
||||
|
||||
/* $screen-desktop-min: 1024px; */
|
||||
/* @TODO: SCSS conversion - @import becomes more complex */
|
||||
/* @import './mixins.scss'; */
|
||||
/* @import './typography.scss'; */
|
||||
|
||||
:root {
|
||||
--palette-black: #222;
|
||||
--border-large: 4px solid var(--palette-black);
|
||||
|
||||
--header-bg: #fff;
|
||||
|
||||
--footer-bg: #444;
|
||||
--footer-fg: #fdfdfd;
|
||||
|
||||
--homepage-principal-bg: #ecffe3;
|
||||
--homepage-whatsphc-bg: #e4c5ff;
|
||||
--homepage-news-bg: #c2a8eb;
|
||||
--homepage-projects-bg: #f5f2cc;
|
||||
--homepage-macchinisti-bg: #888;
|
||||
|
||||
--project-card-bg: #a2d4f3;
|
||||
|
||||
--font-primary: 'Open Sans', sans-serif;
|
||||
--font-display: 'Iosevka', monospace;
|
||||
--font-mono: 'Source Code Pro', monospace;
|
||||
--font-secondary: 'Source Sans Pro', sans-serif;
|
||||
}
|
||||
|
||||
:root {
|
||||
--guide-base: #a2d4f3;
|
||||
|
||||
--guide-darkest: color-mix(in srgb, var(--guide-base), #000 75%);
|
||||
--guide-darker: color-mix(in srgb, var(--guide-base), #000 50%);
|
||||
--guide-dark: color-mix(in srgb, var(--guide-base), #000 25%);
|
||||
|
||||
--guide-light: color-mix(in srgb, var(--guide-base), #fff 25%);
|
||||
--guide-lighter: color-mix(in srgb, var(--guide-base), #fff 50%);
|
||||
--guide-lightest: color-mix(in srgb, var(--guide-base), #fff 75%);
|
||||
|
||||
--news-base: #f8e8b1;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
min-height: 100%;
|
||||
margin: 0;
|
||||
|
||||
font-family: var(--font-primary);
|
||||
font-size: 18px;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
/*
|
||||
html {
|
||||
scroll-snap-type: y mandatory;
|
||||
scroll-padding-top: 4rem;
|
||||
}
|
||||
*/
|
||||
|
||||
img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
body {
|
||||
/*
|
||||
for the header spacing
|
||||
padding-top: 6rem;
|
||||
*/
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
|
||||
header {
|
||||
z-index: 10;
|
||||
|
||||
height: 6rem;
|
||||
border-bottom: var(--border-large);
|
||||
background: var(--header-bg);
|
||||
|
||||
grid-column: 1 / -1;
|
||||
|
||||
top: 0;
|
||||
position: sticky;
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.logo {
|
||||
padding-left: 1rem;
|
||||
|
||||
img {
|
||||
height: 3.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
|
||||
padding: 0 1.5rem;
|
||||
|
||||
a {
|
||||
font-family: var(--font-display);
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 1px;
|
||||
color: #333;
|
||||
|
||||
padding: 0.25rem 1.325rem;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.side-menu {
|
||||
position: fixed;
|
||||
|
||||
/*
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 3rem;
|
||||
*/
|
||||
|
||||
top: 5rem;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
background: #f0f0f0;
|
||||
|
||||
display: grid;
|
||||
/*
|
||||
grid-template-rows: auto 1fr;
|
||||
*/
|
||||
grid-template-rows: 1fr;
|
||||
|
||||
gap: 1.5rem;
|
||||
padding: 1.5rem;
|
||||
|
||||
justify-content: center;
|
||||
|
||||
/*
|
||||
& > :first-child {
|
||||
justify-self: end;
|
||||
}
|
||||
*/
|
||||
|
||||
.links {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
align-content: start;
|
||||
|
||||
width: calc(100vw - 3rem);
|
||||
max-width: 100%;
|
||||
|
||||
gap: 1.5rem;
|
||||
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#header-menu-toggle {
|
||||
display: none;
|
||||
|
||||
&:not(:checked) ~ .side-menu {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:has(#header-menu-toggle:checked) #header-menu-toggle-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:has(#header-menu-toggle:not(:checked)) #header-menu-toggle-close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
height: 5rem;
|
||||
padding: 0 0.5rem;
|
||||
|
||||
.logo {
|
||||
padding-left: 0;
|
||||
|
||||
img {
|
||||
height: 3rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
width: 100%;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
z-index: 10;
|
||||
padding: 1rem 0;
|
||||
--paragraph-margin: 0.5rem;
|
||||
--zone-color: #aaa;
|
||||
|
||||
min-height: 6rem;
|
||||
border-top: var(--border-large);
|
||||
background: var(--footer-bg);
|
||||
color: var(--footer-fg);
|
||||
|
||||
display: grid;
|
||||
place-content: center;
|
||||
|
||||
font-family: var(--font-secondary);
|
||||
font-size: 18px;
|
||||
|
||||
scroll-snap-align: end;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
min-height: 5rem;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track:vertical {
|
||||
background-color: #f0f0f0;
|
||||
border-left: 2px solid #222;
|
||||
border-top: 2px solid #222;
|
||||
border-bottom: 2px solid #222;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track:horizontal {
|
||||
background-color: #f0f0f0;
|
||||
border-top: 2px solid #222;
|
||||
border-left: 2px solid #222;
|
||||
border-right: 2px solid #222;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #1e6733;
|
||||
border: 2px solid #222;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #2b8b47;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: #f0f0f0;
|
||||
/* border-left: 2px solid #222; */
|
||||
/* border-top: 2px solid #222; */
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: #0002;
|
||||
}
|
||||
|
||||
body:has(#header-menu-toggle:checked) {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Typography
|
||||
*/
|
||||
|
||||
/* @TODO: SCSS conversion - @import becomes more complex */
|
||||
/* @import './controls.scss'; */
|
||||
/* @import './components.scss'; */
|
||||
|
||||
/*
|
||||
Custom Page Styles
|
||||
*/
|
||||
|
||||
/* @TODO: SCSS conversion - @import becomes more complex */
|
||||
/* @import './pages.scss'; */
|
||||
|
||||
@layer utility {
|
||||
.hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
.grid-center {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.h-flex {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.v-flex {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.h-flex,
|
||||
.v-flex {
|
||||
place-self: stretch;
|
||||
align-items: center;
|
||||
|
||||
> * {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
> .spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1024px) {
|
||||
.mobile-only {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
.desktop-only {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,315 +0,0 @@
|
||||
$screen-desktop-min: 1024px;
|
||||
|
||||
:root {
|
||||
--palette-black: #222;
|
||||
--border-large: 4px solid var(--palette-black);
|
||||
|
||||
--header-bg: #fff;
|
||||
|
||||
--footer-bg: #444;
|
||||
--footer-fg: #fdfdfd;
|
||||
|
||||
--homepage-principal-bg: #ecffe3;
|
||||
--homepage-whatsphc-bg: #e4c5ff;
|
||||
--homepage-news-bg: #c2a8eb;
|
||||
--homepage-projects-bg: #f5f2cc;
|
||||
--homepage-macchinisti-bg: #888;
|
||||
|
||||
--project-card-bg: #a2d4f3;
|
||||
|
||||
--font-primary: 'Open Sans', sans-serif;
|
||||
--font-display: 'Iosevka', monospace;
|
||||
--font-mono: 'Source Code Pro', monospace;
|
||||
--font-secondary: 'Source Sans Pro', sans-serif;
|
||||
}
|
||||
|
||||
@layer common, typography, component, page;
|
||||
|
||||
@import './mixins.scss';
|
||||
@import './typography.scss';
|
||||
|
||||
@layer common {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
min-height: 100%;
|
||||
margin: 0;
|
||||
|
||||
font-family: var(--font-primary);
|
||||
font-size: 18px;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
// html {
|
||||
// scroll-snap-type: y mandatory;
|
||||
// scroll-padding-top: 4rem;
|
||||
// }
|
||||
|
||||
img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Typography
|
||||
//
|
||||
|
||||
@import './controls.scss';
|
||||
@import './components.scss';
|
||||
|
||||
//
|
||||
// Custom Page Styles
|
||||
//
|
||||
|
||||
body {
|
||||
// for the header spacing
|
||||
// padding-top: 6rem;
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
|
||||
header {
|
||||
z-index: 10;
|
||||
|
||||
height: 6rem;
|
||||
border-bottom: var(--border-large);
|
||||
background: var(--header-bg);
|
||||
|
||||
grid-column: 1 / -1;
|
||||
|
||||
top: 0;
|
||||
position: sticky;
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.logo {
|
||||
padding-left: 1rem;
|
||||
|
||||
img {
|
||||
height: 3.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
|
||||
padding: 0 1.5rem;
|
||||
|
||||
a {
|
||||
font-family: var(--font-display);
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 1px;
|
||||
color: #333;
|
||||
|
||||
padding: 0.25rem 1.325rem;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.side-menu {
|
||||
position: fixed;
|
||||
|
||||
// top: 0;
|
||||
// right: 0;
|
||||
// bottom: 0;
|
||||
// left: 3rem;
|
||||
|
||||
top: 5rem;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
background: #f0f0f0;
|
||||
|
||||
display: grid;
|
||||
// grid-template-rows: auto 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
|
||||
gap: 1.5rem;
|
||||
padding: 1.5rem;
|
||||
|
||||
justify-content: center;
|
||||
|
||||
// & > :first-child {
|
||||
// justify-self: end;
|
||||
// }
|
||||
|
||||
.links {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
align-content: start;
|
||||
|
||||
width: calc(100vw - 3rem);
|
||||
max-width: 100%;
|
||||
|
||||
gap: 1.5rem;
|
||||
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#header-menu-toggle {
|
||||
display: none;
|
||||
|
||||
&:not(:checked) ~ .side-menu {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:has(#header-menu-toggle:checked) #header-menu-toggle-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:has(#header-menu-toggle:not(:checked)) #header-menu-toggle-close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
height: 5rem;
|
||||
padding: 0 0.5rem;
|
||||
|
||||
.logo {
|
||||
padding-left: 0;
|
||||
|
||||
img {
|
||||
height: 3rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
width: 100%;
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
z-index: 10;
|
||||
padding: 1rem 0;
|
||||
--paragraph-margin: 0.5rem;
|
||||
--zone-color: #aaa;
|
||||
|
||||
min-height: 6rem;
|
||||
border-top: var(--border-large);
|
||||
background: var(--footer-bg);
|
||||
color: var(--footer-fg);
|
||||
|
||||
display: grid;
|
||||
place-content: center;
|
||||
|
||||
font-family: var(--font-secondary);
|
||||
font-size: 18px;
|
||||
|
||||
scroll-snap-align: end;
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
min-height: 5rem;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@import './pages.scss';
|
||||
|
||||
//
|
||||
// Misc
|
||||
//
|
||||
|
||||
::-webkit-scrollbar-track:vertical {
|
||||
background-color: #f0f0f0;
|
||||
border-left: 2px solid #222;
|
||||
border-top: 2px solid #222;
|
||||
border-bottom: 2px solid #222;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track:horizontal {
|
||||
background-color: #f0f0f0;
|
||||
border-top: 2px solid #222;
|
||||
border-left: 2px solid #222;
|
||||
border-right: 2px solid #222;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #1e6733;
|
||||
border: 2px solid #222;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #2b8b47;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: #f0f0f0;
|
||||
// border-left: 2px solid #222;
|
||||
// border-top: 2px solid #222;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: #0002;
|
||||
}
|
||||
|
||||
body:has(#header-menu-toggle:checked) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
//
|
||||
// Utility Classes
|
||||
//
|
||||
|
||||
.hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
@media screen and (min-width: $screen-desktop-min) {
|
||||
.mobile-only {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
.desktop-only {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@@ -1,879 +0,0 @@
|
||||
:root {
|
||||
--guide-base: #a2d4f3;
|
||||
|
||||
--guide-darkest: color-mix(in srgb, var(--guide-base), #000 75%);
|
||||
--guide-darker: color-mix(in srgb, var(--guide-base), #000 50%);
|
||||
--guide-dark: color-mix(in srgb, var(--guide-base), #000 25%);
|
||||
|
||||
--guide-light: color-mix(in srgb, var(--guide-base), #fff 25%);
|
||||
--guide-lighter: color-mix(in srgb, var(--guide-base), #fff 50%);
|
||||
--guide-lightest: color-mix(in srgb, var(--guide-base), #fff 75%);
|
||||
|
||||
--news-base: #f8e8b1;
|
||||
}
|
||||
|
||||
@layer page {
|
||||
.homepage {
|
||||
header:has(#header-menu-toggle:not(:checked)) .logo {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
section {
|
||||
position: relative;
|
||||
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 6rem);
|
||||
|
||||
&:last-of-type {
|
||||
min-height: calc(100vh - 10rem);
|
||||
}
|
||||
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
// align-items: center;
|
||||
& {
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
justify-items: center;
|
||||
align-content: start;
|
||||
|
||||
gap: 2rem;
|
||||
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
& > .title {
|
||||
font-size: 48px;
|
||||
padding-top: 4rem;
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
padding-top: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.zig-zag {
|
||||
z-index: 5;
|
||||
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
|
||||
&:first-child {
|
||||
bottom: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
section.principal {
|
||||
z-index: 2;
|
||||
|
||||
min-height: calc(100vh - 7rem);
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
align-items: center;
|
||||
place-content: center;
|
||||
|
||||
gap: 4rem;
|
||||
|
||||
padding: 3rem 2rem 6rem;
|
||||
|
||||
background: var(--homepage-principal-bg);
|
||||
|
||||
position: relative;
|
||||
|
||||
.circuit-layer {
|
||||
pointer-events: none;
|
||||
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
& > .logo {
|
||||
z-index: 2;
|
||||
|
||||
width: 32rem;
|
||||
|
||||
position: relative;
|
||||
|
||||
user-select: none;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
// filter: drop-shadow(6px 6px 0 var(--palette-black))
|
||||
// drop-shadow(4px 0 0 var(--palette-black)) drop-shadow(0 4px 0 var(--palette-black))
|
||||
// drop-shadow(-4px 0 0 var(--palette-black)) drop-shadow(0 -4px 0 var(--palette-black));
|
||||
}
|
||||
|
||||
max-width: calc(100vw - 3rem);
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
}
|
||||
}
|
||||
|
||||
& > .whats-phc {
|
||||
z-index: 2;
|
||||
background: #e4c5ff;
|
||||
|
||||
--zone-color: color-mix(in lab, #e4c5ff, #000 75%);
|
||||
|
||||
max-width: 37rem;
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline 2px solid;
|
||||
|
||||
&:hover {
|
||||
--zone-color: color-mix(in lab, #e4c5ff, #000 60%);
|
||||
}
|
||||
}
|
||||
|
||||
span.highlighted {
|
||||
background: color-mix(in lab, #e4c5ff, #000 10%);
|
||||
cursor: default;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.125rem 0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section.news {
|
||||
--card-base: color-mix(in lab, var(--news-base), #fff 25%);
|
||||
--zone-color: color-mix(in lab, var(--news-base), #000 50%);
|
||||
|
||||
background: var(--homepage-news-bg);
|
||||
|
||||
gap: 3rem;
|
||||
|
||||
padding-bottom: 6rem;
|
||||
|
||||
& > .news-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 3rem;
|
||||
|
||||
align-items: flex-start;
|
||||
|
||||
padding: 0 3rem;
|
||||
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
[role='button'] {
|
||||
padding: 0.5rem 2rem;
|
||||
|
||||
&.primary {
|
||||
background: #ffdd6e;
|
||||
color: #000d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section.projects {
|
||||
background: var(--homepage-projects-bg);
|
||||
|
||||
padding-bottom: 6rem;
|
||||
|
||||
.project-list {
|
||||
// width: calc(20rem * 3 + 1.5rem * 2 + 6rem * 2);
|
||||
// max-width: calc(100vw - 2rem); // HACK: capire come si propagano le width per bene
|
||||
|
||||
max-width: calc(20rem * 3 + 1.5rem * 2 + 1rem * 2);
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
|
||||
grid-auto-flow: dense;
|
||||
|
||||
gap: 1.5rem;
|
||||
padding: 0 1rem;
|
||||
|
||||
& > * {
|
||||
grid-row: span var(--masonry-height);
|
||||
}
|
||||
|
||||
.project {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
// background: #fcddff;
|
||||
// background: #ffa89c;
|
||||
background: var(--card-bg, var(--project-card-bg));
|
||||
color: var(--card-fg, #000e);
|
||||
|
||||
@include neo-brutalist-card($size: 3px, $offset: 9px);
|
||||
|
||||
padding: 1rem;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-template-rows: auto 1fr;
|
||||
|
||||
gap: 0.25rem 1rem;
|
||||
|
||||
transition: all 128ms ease-out;
|
||||
|
||||
.title {
|
||||
font-size: 32px;
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
grid-row: span 2;
|
||||
// place-self: center;
|
||||
|
||||
.box {
|
||||
background: #0003;
|
||||
border: 3px solid #0006;
|
||||
border-radius: 6px;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
img {
|
||||
object-fit: cover;
|
||||
width: 4rem;
|
||||
}
|
||||
|
||||
// &.auto {
|
||||
// img {
|
||||
// width: auto;
|
||||
// height: auto;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 16px;
|
||||
@extend .text;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: translate(0, -4px);
|
||||
box-shadow: 9px 13px 0 0 #222;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
padding: 0 1rem;
|
||||
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
.project {
|
||||
padding: 0.8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section.wanna-be-macchinista {
|
||||
background: var(--homepage-macchinisti-bg);
|
||||
color: #fdfdfd;
|
||||
|
||||
padding-bottom: 6rem;
|
||||
|
||||
.card {
|
||||
max-width: 40rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
@extend .text;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
& > main {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
section.principal {
|
||||
padding: 3rem 0 6rem;
|
||||
|
||||
.whats-phc {
|
||||
padding: 1.5rem;
|
||||
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
#mobile-whats-phc-read-more {
|
||||
&:checked ~ .text {
|
||||
max-height: 7lh;
|
||||
overflow: hidden;
|
||||
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 3lh;
|
||||
|
||||
background: linear-gradient(to bottom, transparent, #e4c5ff);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:checked) ~ * .button span:nth-child(1) {
|
||||
display: none;
|
||||
}
|
||||
&:checked ~ * .button span:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section.news {
|
||||
& > .news-list {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
section.projects {
|
||||
.project-list {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
section.wanna-be-macchinista {
|
||||
.content {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
section {
|
||||
padding: 1rem 1rem 4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.utenti {
|
||||
background: #ffffe4;
|
||||
|
||||
--filter-bg-color: #ffd270;
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 5rem 0;
|
||||
|
||||
gap: 5rem;
|
||||
|
||||
max-width: 80ch;
|
||||
|
||||
.search-result {
|
||||
background: #ffeabc;
|
||||
}
|
||||
|
||||
button {
|
||||
background: #ffd270;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.appunti {
|
||||
main {
|
||||
background: #e8e8e8;
|
||||
|
||||
justify-self: center;
|
||||
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
|
||||
justify-items: center;
|
||||
|
||||
padding: 3rem;
|
||||
|
||||
gap: 3rem;
|
||||
|
||||
width: 100%;
|
||||
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
width: 100%;
|
||||
height: 80vh;
|
||||
|
||||
background: linear-gradient(to bottom, transparent, #e8e8e8);
|
||||
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.search {
|
||||
max-width: 80ch;
|
||||
}
|
||||
|
||||
.appunti-scrollable {
|
||||
justify-self: stretch;
|
||||
|
||||
&.center {
|
||||
justify-self: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.domande-esami {
|
||||
background: hsl(180, 100%, 95%);
|
||||
--card-base: hsl(180, 100%, 85%);
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 4rem 0;
|
||||
|
||||
gap: 2rem;
|
||||
|
||||
.search {
|
||||
max-width: 80ch;
|
||||
}
|
||||
|
||||
button {
|
||||
background: hsl(180, 100%, 72%);
|
||||
}
|
||||
|
||||
.card a {
|
||||
color: color-mix(in srgb, var(--card-base-internal), #000 80%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// .login {
|
||||
// background: #ddfaff;
|
||||
|
||||
// main {
|
||||
// justify-self: center;
|
||||
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
// align-items: center;
|
||||
|
||||
// max-width: 80ch;
|
||||
// padding: 3rem 0;
|
||||
|
||||
// gap: 3rem;
|
||||
|
||||
// h3 {
|
||||
// font-size: 28px;
|
||||
// font-weight: 600;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
//
|
||||
// Notizie
|
||||
//
|
||||
|
||||
.notizie,
|
||||
.notizia {
|
||||
--card-base: color-mix(in lab, var(--news-base), #fff 25%);
|
||||
--zone-color: color-mix(in lab, var(--news-base), #000 75%);
|
||||
background: color-mix(in lab, var(--news-base), #fff 90%);
|
||||
}
|
||||
|
||||
.notizie {
|
||||
h1 > a {
|
||||
&:hover {
|
||||
text-decoration: underline 3px solid;
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 5rem;
|
||||
gap: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.notizia {
|
||||
main {
|
||||
--card-base: color-mix(in lab, var(--news-base), #fff 25%);
|
||||
|
||||
max-width: calc(46rem + 2rem * 2);
|
||||
justify-self: center;
|
||||
padding: 3rem 2rem 2rem;
|
||||
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 6rem;
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
max-width: none;
|
||||
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Guide
|
||||
//
|
||||
|
||||
.guide,
|
||||
.guida {
|
||||
--card-base: color-mix(in lab, var(--guide-base), #fff 25%);
|
||||
--zone-color: color-mix(in lab, var(--guide-base), #000 75%);
|
||||
background: color-mix(in lab, var(--guide-base), #fff 90%);
|
||||
}
|
||||
|
||||
.guide {
|
||||
h1 > a {
|
||||
&:hover {
|
||||
text-decoration: underline 3px solid;
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 5rem;
|
||||
gap: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.guida {
|
||||
main {
|
||||
--card-base: color-mix(in lab, var(--guide-base), #fff 50%);
|
||||
|
||||
max-width: calc(46rem + 2rem * 2);
|
||||
justify-self: center;
|
||||
padding: 3rem 2rem 2rem;
|
||||
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 6rem;
|
||||
|
||||
position: relative;
|
||||
|
||||
.metadata {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: calc(100% + 2rem);
|
||||
width: 15rem;
|
||||
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
gap: 1rem;
|
||||
|
||||
justify-items: start;
|
||||
|
||||
.metadata-item {
|
||||
background: var(--card-base);
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: auto auto;
|
||||
justify-items: start;
|
||||
gap: 0.25rem;
|
||||
|
||||
padding: 0.75rem 1rem;
|
||||
|
||||
@include neo-brutalist-card($size: 3px);
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
max-width: none;
|
||||
|
||||
margin: 0 auto;
|
||||
|
||||
.metadata {
|
||||
position: static;
|
||||
padding: 0;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
|
||||
--card-base: color-mix(in lab, var(--guide-base), #fff 30%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tag {
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 5rem 0;
|
||||
gap: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.storia {
|
||||
--card-base: #e4c5ff;
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 5rem 0;
|
||||
gap: 3rem;
|
||||
|
||||
// background horizontal linear gradient that is black in the center
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
#ffe4c544 0%,
|
||||
// #ffe4c599 25%,
|
||||
#ffe4c5ff 50%,
|
||||
// #ffe4c599 75%,
|
||||
#ffe4c544 100%
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
.macchinisti {
|
||||
main {
|
||||
justify-self: center;
|
||||
background: linear-gradient(to top, #d5fbff, #ffd9d5);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 4.5rem 3rem;
|
||||
gap: 4.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Meta
|
||||
//
|
||||
|
||||
.design {
|
||||
grid-template-columns: minmax(15rem, 2fr) 10fr;
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
aside {
|
||||
margin: 1rem;
|
||||
padding: 1rem;
|
||||
|
||||
@include neo-brutalist-card();
|
||||
|
||||
background: #f0f0f0;
|
||||
|
||||
align-self: start;
|
||||
position: sticky;
|
||||
top: 7rem;
|
||||
height: calc(100dvh - 8rem - 6rem);
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
|
||||
li {
|
||||
padding-left: calc((var(--depth) - 1) * 1rem);
|
||||
|
||||
display: flex;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
|
||||
transform: translate(-0.25rem, 0);
|
||||
|
||||
padding: 0.125rem 0.25rem;
|
||||
border-radius: 0.125rem;
|
||||
|
||||
color: #444;
|
||||
|
||||
&:hover {
|
||||
background: #00000018;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
@media screen and (min-width: $screen-desktop-min) {
|
||||
padding: 3rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
pre[data-language='astro'] {
|
||||
--code-bg: #fff7ef;
|
||||
|
||||
width: 100%;
|
||||
max-width: 46rem;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 2rem auto;
|
||||
|
||||
border: 2px dashed #ddd;
|
||||
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
&.large {
|
||||
min-width: calc(100% - 4rem);
|
||||
}
|
||||
|
||||
&:not(.large) {
|
||||
& > .content {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
& > .content {
|
||||
padding: 2rem;
|
||||
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
// label in the top left corner
|
||||
&::before {
|
||||
content: 'Preview';
|
||||
position: absolute;
|
||||
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
|
||||
padding: 0.125rem 0.5rem;
|
||||
|
||||
background: #eee;
|
||||
color: #000;
|
||||
|
||||
font-family: var(--font-display);
|
||||
font-size: 14px;
|
||||
|
||||
border-radius: 0.25rem;
|
||||
|
||||
z-index: -1;
|
||||
|
||||
transform: translate(-2px, -4px);
|
||||
|
||||
opacity: 0;
|
||||
transition: opacity 64ms ease-in;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: #bbb;
|
||||
|
||||
&::before {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.palette {
|
||||
margin: 2rem auto;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
|
||||
gap: 1rem;
|
||||
|
||||
place-content: center;
|
||||
|
||||
& > .color {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-radius: 0.25rem;
|
||||
|
||||
border: 2px solid #000;
|
||||
box-shadow: 4px 4px 0 0 #000;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
& > .region {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
border: 2px solid #fff;
|
||||
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
& > .label {
|
||||
display: grid;
|
||||
align-content: center;
|
||||
|
||||
font-family: 'JetBrains Mono', var(--font-mono);
|
||||
font-size: 16px;
|
||||
|
||||
user-select: all;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
@layer page {
|
||||
main {
|
||||
background: #e8e8e8;
|
||||
|
||||
justify-self: center;
|
||||
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
|
||||
justify-items: center;
|
||||
|
||||
padding: 3rem;
|
||||
|
||||
gap: 3rem;
|
||||
|
||||
width: 100%;
|
||||
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
width: 100%;
|
||||
height: 80vh;
|
||||
|
||||
background: linear-gradient(to bottom, transparent, #e8e8e8);
|
||||
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.search {
|
||||
max-width: 80ch;
|
||||
}
|
||||
|
||||
.appunti-scrollable {
|
||||
justify-self: stretch;
|
||||
|
||||
&.center {
|
||||
justify-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
overflow: clip;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
:root {
|
||||
--card-base: hsl(180, 100%, 85%);
|
||||
}
|
||||
|
||||
@layer page {
|
||||
body {
|
||||
background: hsl(180, 100%, 95%);
|
||||
}
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 4rem 0;
|
||||
|
||||
gap: 2rem;
|
||||
|
||||
.search {
|
||||
max-width: 80ch;
|
||||
}
|
||||
|
||||
button {
|
||||
background: hsl(180, 100%, 72%);
|
||||
}
|
||||
|
||||
.card a {
|
||||
color: color-mix(in srgb, var(--card-base-internal), #000 80%);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
@layer page {
|
||||
body {
|
||||
--card-base: color-mix(in lab, var(--guide-base), #fff 25%);
|
||||
--zone-color: color-mix(in lab, var(--guide-base), #000 75%);
|
||||
background: color-mix(in lab, var(--guide-base), #fff 90%);
|
||||
}
|
||||
|
||||
main {
|
||||
--card-base: color-mix(in lab, var(--guide-base), #fff 50%);
|
||||
|
||||
max-width: calc(46rem + 2rem * 2);
|
||||
justify-self: center;
|
||||
padding: 3rem 2rem 2rem;
|
||||
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 6rem;
|
||||
|
||||
position: relative;
|
||||
|
||||
.metadata {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: calc(100% + 2rem);
|
||||
width: 15rem;
|
||||
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
gap: 1rem;
|
||||
|
||||
justify-items: start;
|
||||
|
||||
.metadata-item {
|
||||
background: var(--card-base);
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: auto auto;
|
||||
justify-items: start;
|
||||
gap: 0.25rem;
|
||||
|
||||
padding: 0.75rem 1rem;
|
||||
|
||||
/* @include neo-brutalist-card($size: 3px); */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 3px 3px 0 0 #222;
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
max-width: none;
|
||||
|
||||
margin: 0 auto;
|
||||
padding: 3rem 1rem 2rem;
|
||||
|
||||
.metadata {
|
||||
position: static;
|
||||
padding: 0;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
|
||||
--card-base: color-mix(in lab, var(--guide-base), #fff 30%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
@layer page {
|
||||
body {
|
||||
--card-base: color-mix(in lab, var(--guide-base), #fff 25%);
|
||||
--zone-color: color-mix(in lab, var(--guide-base), #000 75%);
|
||||
background: color-mix(in lab, var(--guide-base), #fff 90%);
|
||||
}
|
||||
|
||||
h1 > a {
|
||||
&:hover {
|
||||
text-decoration: underline 3px solid;
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 5rem 2.5rem;
|
||||
gap: 5rem;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
grid-template-rows: auto 1fr auto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
@layer page {
|
||||
header:has(#header-menu-toggle:not(:checked)) .logo {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
section {
|
||||
position: relative;
|
||||
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 6rem);
|
||||
|
||||
&:last-of-type {
|
||||
min-height: calc(100vh - 10rem);
|
||||
}
|
||||
|
||||
& {
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
justify-items: center;
|
||||
align-content: start;
|
||||
|
||||
gap: 2rem;
|
||||
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
& > .title {
|
||||
font-size: 48px;
|
||||
padding-top: 4rem;
|
||||
|
||||
@media screen and (max-width: /* $screen-desktop-min */ 1024px) {
|
||||
padding-top: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.zig-zag {
|
||||
z-index: 5;
|
||||
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
|
||||
&:first-child {
|
||||
bottom: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
section.principal {
|
||||
z-index: 2;
|
||||
|
||||
min-height: calc(100vh - 7rem);
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
align-items: center;
|
||||
place-content: center;
|
||||
|
||||
gap: 4rem;
|
||||
|
||||
padding: 3rem 2rem 6rem;
|
||||
|
||||
background: var(--homepage-principal-bg);
|
||||
|
||||
position: relative;
|
||||
|
||||
.circuit-layer {
|
||||
pointer-events: none;
|
||||
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
& > .logo {
|
||||
z-index: 2;
|
||||
|
||||
width: 32rem;
|
||||
|
||||
position: relative;
|
||||
|
||||
user-select: none;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
/* filter: drop-shadow(6px 6px 0 var(--palette-black))
|
||||
drop-shadow(4px 0 0 var(--palette-black)) drop-shadow(0 4px 0 var(--palette-black))
|
||||
drop-shadow(-4px 0 0 var(--palette-black)) drop-shadow(0 -4px 0 var(--palette-black)); */
|
||||
}
|
||||
|
||||
max-width: calc(100vw - 3rem);
|
||||
@media screen and (max-width: /* $screen-desktop-min */ 1024px) {
|
||||
}
|
||||
}
|
||||
|
||||
& > .whats-phc {
|
||||
z-index: 2;
|
||||
background: #e4c5ff;
|
||||
|
||||
--zone-color: color-mix(in lab, #e4c5ff, #000 75%);
|
||||
|
||||
max-width: 37rem;
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline 2px solid;
|
||||
|
||||
&:hover {
|
||||
--zone-color: color-mix(in lab, #e4c5ff, #000 60%);
|
||||
}
|
||||
}
|
||||
|
||||
span.highlighted {
|
||||
background: color-mix(in lab, #e4c5ff, #000 10%);
|
||||
cursor: default;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.125rem 0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section.news {
|
||||
--card-base: color-mix(in lab, var(--news-base), #fff 25%);
|
||||
--zone-color: color-mix(in lab, var(--news-base), #000 50%);
|
||||
|
||||
background: var(--homepage-news-bg);
|
||||
|
||||
gap: 3rem;
|
||||
|
||||
padding-bottom: 6rem;
|
||||
|
||||
& > .news-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 3rem;
|
||||
|
||||
align-items: flex-start;
|
||||
|
||||
padding: 0 3rem;
|
||||
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
[role='button'] {
|
||||
padding: 0.5rem 2rem;
|
||||
|
||||
&.primary {
|
||||
background: #ffdd6e;
|
||||
color: #000d;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
grid-template-rows: auto auto 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
section.projects {
|
||||
background: var(--homepage-projects-bg);
|
||||
|
||||
padding-bottom: 6rem;
|
||||
|
||||
.project-list {
|
||||
/* width: calc(20rem * 3 + 1.5rem * 2 + 6rem * 2);
|
||||
max-width: calc(100vw - 2rem); */ /* HACK: capire come si propagano le width per bene */
|
||||
|
||||
max-width: calc(20rem * 3 + 1.5rem * 2 + 1rem * 2);
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
|
||||
grid-auto-flow: dense;
|
||||
|
||||
gap: 1.5rem;
|
||||
padding: 0 1rem;
|
||||
|
||||
& > * {
|
||||
grid-row: span var(--masonry-height);
|
||||
}
|
||||
|
||||
.project {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
/* background: #fcddff;
|
||||
background: #ffa89c; */
|
||||
background: var(--card-bg, var(--project-card-bg));
|
||||
color: var(--card-fg, #000e);
|
||||
|
||||
/* @include neo-brutalist-card($size: 3px, $offset: 9px); */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 9px 9px 0 0 #222;
|
||||
|
||||
padding: 1rem;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-template-rows: auto 1fr;
|
||||
|
||||
gap: 0.25rem 1rem;
|
||||
|
||||
transition: all 128ms ease-out;
|
||||
|
||||
.title {
|
||||
font-size: 32px;
|
||||
|
||||
@media screen and (max-width: /* $screen-desktop-min */ 1024px) {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
grid-row: span 2;
|
||||
/* place-self: center; */
|
||||
|
||||
.box {
|
||||
background: #0003;
|
||||
border: 3px solid #0006;
|
||||
border-radius: 6px;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
img {
|
||||
object-fit: cover;
|
||||
width: 4rem;
|
||||
}
|
||||
|
||||
/* &.auto {
|
||||
img {
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: translate(0, -4px);
|
||||
box-shadow: 9px 13px 0 0 #222;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: /* $screen-desktop-min */ 1024px) {
|
||||
padding: 0 1rem;
|
||||
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
.project {
|
||||
padding: 0.8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section.wanna-be-macchinista {
|
||||
background: var(--homepage-macchinisti-bg);
|
||||
color: #fdfdfd;
|
||||
|
||||
padding-bottom: 6rem;
|
||||
|
||||
.card {
|
||||
max-width: 40rem;
|
||||
}
|
||||
|
||||
/* .content {
|
||||
/* @extend .text;
|
||||
/* Placeholder: Assuming .text is a class with common text styles, you might want to define those styles directly here or in a separate CSS rule.
|
||||
} */
|
||||
}
|
||||
|
||||
@media screen and (max-width: /* $screen-desktop-min */ 1024px) {
|
||||
main {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
section.principal {
|
||||
padding: 3rem 0 6rem;
|
||||
|
||||
.whats-phc {
|
||||
padding: 1.5rem;
|
||||
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
#mobile-whats-phc-read-more {
|
||||
&:checked ~ .text {
|
||||
max-height: 7lh;
|
||||
overflow: hidden;
|
||||
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 3lh;
|
||||
|
||||
background: linear-gradient(to bottom, transparent, #e4c5ff);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:checked) ~ * .button span:nth-child(1) {
|
||||
display: none;
|
||||
}
|
||||
&:checked ~ * .button span:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section.news {
|
||||
& > .news-list {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
section.projects {
|
||||
.project-list {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
section.wanna-be-macchinista {
|
||||
.content {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
section {
|
||||
padding: 1rem 1rem 4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
@layer page {
|
||||
main {
|
||||
justify-self: center;
|
||||
background: linear-gradient(to top, #d5fbff, #ffd9d5);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 4.5rem 3rem;
|
||||
gap: 4.5rem;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
@layer page {
|
||||
body {
|
||||
grid-template-columns: minmax(15rem, 2fr) 10fr;
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
aside {
|
||||
margin: 1rem;
|
||||
padding: 1rem;
|
||||
|
||||
/* @include neo-brutalist-card(); */
|
||||
border: 3px solid #222;
|
||||
border-radius: 6px;
|
||||
box-shadow: 3px 3px 0 0 #222;
|
||||
|
||||
background: #f0f0f0;
|
||||
|
||||
align-self: start;
|
||||
position: sticky;
|
||||
top: 7rem;
|
||||
height: calc(100dvh - 8rem - 6rem);
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
|
||||
li {
|
||||
padding-left: calc((var(--depth) - 1) * 1rem);
|
||||
|
||||
display: flex;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
|
||||
transform: translate(-0.25rem, 0);
|
||||
|
||||
padding: 0.125rem 0.25rem;
|
||||
border-radius: 0.125rem;
|
||||
|
||||
color: #444;
|
||||
|
||||
&:hover {
|
||||
background: #00000018;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
@media screen and (min-width: /* $screen-desktop-min */ 1024px) {
|
||||
padding: 3rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
pre[data-language='astro'] {
|
||||
--code-bg: #fff7ef;
|
||||
|
||||
width: 100%;
|
||||
max-width: 46rem;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 2rem auto;
|
||||
|
||||
border: 2px dashed #ddd;
|
||||
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
&.large {
|
||||
min-width: calc(100% - 4rem);
|
||||
}
|
||||
|
||||
&:not(.large) {
|
||||
& > .content {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
& > .content {
|
||||
padding: 2rem;
|
||||
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* label in the top left corner */
|
||||
&::before {
|
||||
content: 'Preview';
|
||||
position: absolute;
|
||||
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
|
||||
padding: 0.125rem 0.5rem;
|
||||
|
||||
background: #eee;
|
||||
color: #000;
|
||||
|
||||
font-family: var(--font-display);
|
||||
font-size: 14px;
|
||||
|
||||
border-radius: 0.25rem;
|
||||
|
||||
z-index: -1;
|
||||
|
||||
transform: translate(-2px, -4px);
|
||||
|
||||
opacity: 0;
|
||||
transition: opacity 64ms ease-in;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: #bbb;
|
||||
|
||||
&::before {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.palette {
|
||||
margin: 2rem auto;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
|
||||
gap: 1rem;
|
||||
|
||||
place-content: center;
|
||||
|
||||
& > .color {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-radius: 0.25rem;
|
||||
|
||||
border: 2px solid #000;
|
||||
box-shadow: 4px 4px 0 0 #000;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
& > .region {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
border: 2px solid #fff;
|
||||
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
& > .label {
|
||||
display: grid;
|
||||
align-content: center;
|
||||
|
||||
font-family: 'JetBrains Mono', var(--font-mono);
|
||||
font-size: 16px;
|
||||
|
||||
user-select: all;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
@layer page {
|
||||
:root {
|
||||
--card-base: color-mix(in lab, var(--news-base), #fff 25%);
|
||||
--zone-color: color-mix(in lab, var(--news-base), #000 75%);
|
||||
}
|
||||
|
||||
body {
|
||||
background: color-mix(in lab, var(--news-base), #fff 90%);
|
||||
}
|
||||
|
||||
main {
|
||||
max-width: calc(46rem + 2rem * 2);
|
||||
justify-self: center;
|
||||
padding: 3rem 2rem 2rem;
|
||||
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 6rem;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
max-width: none;
|
||||
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
@layer page {
|
||||
:root {
|
||||
--card-base: color-mix(in lab, var(--news-base), #fff 25%);
|
||||
--zone-color: color-mix(in lab, var(--news-base), #000 75%);
|
||||
}
|
||||
|
||||
body {
|
||||
background: color-mix(in lab, var(--news-base), #fff 90%);
|
||||
}
|
||||
|
||||
h1 > a {
|
||||
&:hover {
|
||||
text-decoration: underline 3px solid;
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 5rem;
|
||||
gap: 5rem;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
grid-template-rows: auto auto 1fr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
:root {
|
||||
--card-base: #e4c5ff;
|
||||
}
|
||||
|
||||
@layer page {
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 5rem 0;
|
||||
gap: 3rem;
|
||||
|
||||
/* background horizontal linear gradient that is black in the center */
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
#ffe4c544 0%,
|
||||
/* #ffe4c599 25%, */ #ffe4c5ff 50%,
|
||||
/* #ffe4c599 75%, */ #ffe4c544 100%
|
||||
);
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
:root {
|
||||
--filter-bg-color: #ffd270;
|
||||
}
|
||||
|
||||
@layer page {
|
||||
body {
|
||||
background: #ffffe4;
|
||||
}
|
||||
|
||||
main {
|
||||
justify-self: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 5rem 0;
|
||||
|
||||
gap: 5rem;
|
||||
|
||||
max-width: 80ch;
|
||||
|
||||
.search-result {
|
||||
background: #ffeabc;
|
||||
}
|
||||
|
||||
button {
|
||||
background: #ffd270;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,8 @@
|
||||
@function pow($number, $exponent) {
|
||||
$value: 1;
|
||||
|
||||
@if $exponent > 0 {
|
||||
@for $i from 1 through $exponent {
|
||||
$value: $value * $number;
|
||||
}
|
||||
}
|
||||
|
||||
@return $value;
|
||||
}
|
||||
|
||||
@mixin geometric-headings {
|
||||
$base-font-size: 16px;
|
||||
$heading-scale: 1.25;
|
||||
|
||||
@for $i from 1 through 5 {
|
||||
$factor: pow($heading-scale, 5 - $i);
|
||||
|
||||
h#{$i} {
|
||||
font-size: $base-font-size * $factor;
|
||||
font-family: var(--font-display);
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
// p + h#{$i} {
|
||||
// margin-top: 0.75rem * $factor;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@layer typography {
|
||||
@include geometric-headings;
|
||||
:root {
|
||||
--heading-base-size: 16px;
|
||||
--heading-factor: 1.25;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
@@ -45,9 +16,48 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-factor), 4));
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-factor), 3));
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-factor), 2));
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-factor), 1));
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-factor), 0));
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.text {
|
||||
// text-align: justify;
|
||||
// hyphens: auto;
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
/* text-align: justify;
|
||||
hyphens: auto; */
|
||||
|
||||
&.center {
|
||||
text-align: center;
|
||||
@@ -64,8 +74,8 @@
|
||||
pre,
|
||||
code {
|
||||
background: color-mix(in lab, var(--card-base-internal, #ededed), #fff 35%) !important;
|
||||
// background: color-mix(in lab, var(--zone-color), #fff 75%) !important;
|
||||
// background: var(--code-bg, #00000022) !important;
|
||||
/* background: color-mix(in lab, var(--zone-color), #fff 75%) !important;
|
||||
background: var(--code-bg, #00000022) !important; */
|
||||
|
||||
font-family: var(--font-mono);
|
||||
font-weight: 400;
|
||||
@@ -77,12 +87,16 @@
|
||||
padding: 0.125rem 0.3rem;
|
||||
}
|
||||
|
||||
p > code {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 2rem auto;
|
||||
|
||||
padding: 0.5rem 1rem;
|
||||
|
||||
// width: 100%;
|
||||
/* width: 100%; */
|
||||
max-width: 80ch;
|
||||
|
||||
width: fit-content;
|
||||
@@ -97,11 +111,6 @@
|
||||
code {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
width: calc(100vw - 2rem);
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
@@ -109,26 +118,26 @@
|
||||
margin: var(--paragraph-margin, 1rem) auto;
|
||||
}
|
||||
|
||||
// p + p {
|
||||
// margin-top: 1rem;
|
||||
// }
|
||||
/* p + p {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
// h1 + p,
|
||||
// h2 + p,
|
||||
// h3 + p,
|
||||
// h4 + p {
|
||||
// margin-top: 1rem;
|
||||
// }
|
||||
h1 + p,
|
||||
h2 + p,
|
||||
h3 + p,
|
||||
h4 + p {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
// p:has(+ h1, + h2, + h3, + h4) {
|
||||
// margin-bottom: 1rem;
|
||||
// }
|
||||
p:has(+ h1, + h2, + h3, + h4) {
|
||||
margin-bottom: 1rem;
|
||||
} */
|
||||
|
||||
p[align='center'] {
|
||||
margin: 1.5rem 0;
|
||||
|
||||
a {
|
||||
// background: color-mix(in hsl, var(--card-base-internal, #ededed), #fff 20%);
|
||||
/* background: color-mix(in hsl, var(--card-base-internal, #ededed), #fff 20%); */
|
||||
background: hsl(from var(--card-base-internal, #ededed) h calc(s + 10) calc(l - 10));
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
@@ -137,14 +146,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
img,
|
||||
video {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
|
||||
width: 50ch;
|
||||
max-width: 100%;
|
||||
|
||||
@include neo-brutalist-card(2px);
|
||||
border: 2px solid #333;
|
||||
border-radius: 0.25rem;
|
||||
box-shadow: 0.25rem 0.25rem 0 0 #333;
|
||||
background: #000;
|
||||
|
||||
&.fill {
|
||||
width: 100%;
|
||||
@@ -161,6 +174,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
video {
|
||||
margin: 1rem auto;
|
||||
}
|
||||
|
||||
p:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
@@ -177,7 +194,22 @@
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@include geometric-headings;
|
||||
/* @include geometric-headings; */
|
||||
/* Inlined geometric-headings mixin */
|
||||
/* @for $i from 1 through 5 {
|
||||
$factor: pow($heading-scale, 5 - $i);
|
||||
|
||||
h#{$i} {
|
||||
font-size: $base-font-size * $factor;
|
||||
font-family: var(--font-display);
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
/* p + h#{$i} {
|
||||
margin-top: 0.75rem * $factor;
|
||||
}
|
||||
} */
|
||||
|
||||
h1 {
|
||||
margin-bottom: 2rem;
|
||||
@@ -191,7 +223,7 @@
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
|
||||
// HACK: Trick to fix anchor links with sticky header
|
||||
/* HACK: Trick to fix anchor links with sticky header */
|
||||
padding-top: 7rem;
|
||||
margin-top: -6.5rem;
|
||||
}
|
||||
@@ -250,9 +282,17 @@
|
||||
border-top: 2px solid #0003;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
& > * {
|
||||
margin: 0 0.75rem;
|
||||
@media screen and (max-width: 1024px) {
|
||||
max-width: calc(100vw - 2rem);
|
||||
|
||||
pre {
|
||||
margin: 1rem 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
hr {
|
||||
max-width: none;
|
||||
margin: 3rem auto;
|
||||
}
|
||||
}
|
||||
}
|
||||