forked from phc/website
Merge branch 'feat-domande-esami'
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"printWidth": 110,
|
||||
"singleQuote": true,
|
||||
"quoteProps": "consistent",
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/** @type {import("prettier").Config} */
|
||||
export default {
|
||||
printWidth: 120,
|
||||
singleQuote: true,
|
||||
quoteProps: 'consistent',
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
semi: false,
|
||||
arrowParens: 'avoid',
|
||||
|
||||
plugins: ['prettier-plugin-astro'],
|
||||
overrides: [
|
||||
{
|
||||
files: '*.astro',
|
||||
options: {
|
||||
parser: 'astro',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: '*.{yml,yaml,json}',
|
||||
options: {
|
||||
tabWidth: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
Vendored
+9
-1
@@ -1,3 +1,11 @@
|
||||
{
|
||||
"npm.packageManager": "bun"
|
||||
"npm.packageManager": "bun",
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"[astro]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[yaml]": {
|
||||
"editor.tabSize": 2,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -18,6 +18,11 @@ export default defineConfig({
|
||||
theme: 'github-light',
|
||||
},
|
||||
},
|
||||
integrations: [preact(), mdx()],
|
||||
integrations: [
|
||||
preact({
|
||||
compat: true,
|
||||
}),
|
||||
mdx(),
|
||||
],
|
||||
output: 'static',
|
||||
})
|
||||
|
||||
@@ -21,12 +21,15 @@
|
||||
"@fontsource/source-sans-pro": "^5.0.8",
|
||||
"@fontsource/space-mono": "^5.0.20",
|
||||
"@phosphor-icons/core": "^2.1.1",
|
||||
"@phosphor-icons/react": "^2.1.7",
|
||||
"@preact/signals": "^1.3.0",
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"astro": "5.1.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"katex": "^0.16.9",
|
||||
"lucide-static": "^0.468.0",
|
||||
"marked": "^15.0.6",
|
||||
"marked-extended-latex": "^1.1.0",
|
||||
"preact": "^10.19.6",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
@@ -37,6 +40,8 @@
|
||||
"jsdom": "^24.1.1",
|
||||
"linkedom": "^0.18.4",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.5.0",
|
||||
"prettier-plugin-astro": "^0.14.1",
|
||||
"rehype-autolink-headings": "^7.1.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"remark-math": "^6.0.0",
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
import { useEffect, useState } from 'preact/hooks'
|
||||
import { Funnel } from '@phosphor-icons/react'
|
||||
import { marked } from 'marked'
|
||||
|
||||
// @ts-ignore
|
||||
import extendedLatex from 'marked-extended-latex'
|
||||
|
||||
marked.use(
|
||||
extendedLatex({
|
||||
lazy: false,
|
||||
render: (formula: string, display: boolean) => {
|
||||
return display ? '$$' + formula + '$$' : '$' + formula + '$'
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
import type { Database } from '@/data/domande-esami.yaml'
|
||||
|
||||
const useRemoteValue = <T,>(url: string): T | null => {
|
||||
const [value, setValue] = useState<T | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(value => setValue(value))
|
||||
.catch(error => console.error(error))
|
||||
}, [url])
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
type Props = {
|
||||
course: string
|
||||
}
|
||||
|
||||
export const DomandeEsamiCourse = ({ course }: Props) => {
|
||||
const database = useRemoteValue<Database>(`/domande-esami/api/${course}.json`)
|
||||
if (!database) {
|
||||
return <>Loading...</>
|
||||
}
|
||||
|
||||
if ('requestIdleCallback' in window) {
|
||||
// @ts-ignore
|
||||
requestIdleCallback(() => window.renderMath())
|
||||
} else {
|
||||
// @ts-ignore
|
||||
setTimeout(() => window.renderMath(), 100)
|
||||
}
|
||||
|
||||
const courseTags = [
|
||||
...new Set(
|
||||
database.questions.filter(question => question.course === course).flatMap(question => question.tags),
|
||||
),
|
||||
]
|
||||
|
||||
const [selectedTag, setSelectedTag] = useState<string | null>(null)
|
||||
|
||||
const filteredQuestions = database.questions
|
||||
.filter(question => question.course === course)
|
||||
.filter(question => (selectedTag ? question.tags.includes(selectedTag) : true))
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="grid-center">
|
||||
<h3>
|
||||
<a href="/domande-esami">Domande Esami</a>
|
||||
</h3>
|
||||
<h1>{database.names[course]}</h1>
|
||||
</div>
|
||||
|
||||
{courseTags.length > 1 && (
|
||||
<div class="card filter">
|
||||
<div class="grid-h">
|
||||
<Funnel />
|
||||
<strong>Filtra Tag</strong>
|
||||
</div>
|
||||
<div class="flex-row-wrap">
|
||||
{!selectedTag
|
||||
? courseTags.map(tag => (
|
||||
<div class="chip clickable" onClick={() => setSelectedTag(tag)}>
|
||||
{tag}
|
||||
</div>
|
||||
))
|
||||
: courseTags.map(tag => (
|
||||
<div
|
||||
class={tag === selectedTag ? 'chip clickable' : 'chip clickable disabled'}
|
||||
onClick={() => setSelectedTag(tag === selectedTag ? null : tag)}
|
||||
>
|
||||
{tag}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div class="wide-card-list" id="questions">
|
||||
{filteredQuestions.length === 0 ? (
|
||||
<div class="grid-center">
|
||||
<em>No questions found</em>
|
||||
</div>
|
||||
) : (
|
||||
filteredQuestions.map(question => (
|
||||
<div class="card">
|
||||
<div
|
||||
class="text"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: marked(question.content, { async: false }),
|
||||
}}
|
||||
/>
|
||||
<div class="metadata">
|
||||
{question.tags.map(tag => (
|
||||
<div class="chip small">{tag}</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
const $debugConsole = document.createElement('div')
|
||||
|
||||
$debugConsole.style.position = 'fixed'
|
||||
$debugConsole.style.bottom = '0'
|
||||
$debugConsole.style.left = '0'
|
||||
$debugConsole.style.width = '100%'
|
||||
$debugConsole.style.height = '25vh'
|
||||
$debugConsole.style.backgroundColor = 'black'
|
||||
$debugConsole.style.color = 'white'
|
||||
$debugConsole.style.overflow = 'auto'
|
||||
$debugConsole.style.padding = '10px'
|
||||
$debugConsole.style.boxSizing = 'border-box'
|
||||
$debugConsole.style.fontFamily = 'monospace'
|
||||
$debugConsole.style.zIndex = '9999'
|
||||
$debugConsole.style.fontSize = '15px'
|
||||
$debugConsole.style.opacity = '0.8'
|
||||
|
||||
document.body.appendChild($debugConsole)
|
||||
|
||||
function logDebugConsole(...args) {
|
||||
$debugConsole.innerHTML += args.join(' ') + '<br>'
|
||||
}
|
||||
|
||||
console.error = logDebugConsole
|
||||
console.warn = logDebugConsole
|
||||
console.log = logDebugConsole
|
||||
console.debug = logDebugConsole
|
||||
@@ -5,6 +5,7 @@ const links = [
|
||||
// { href: '/appunti', text: 'Appunti' },
|
||||
{ href: '/notizie', text: 'Notizie' },
|
||||
{ href: '/guide', text: 'Guide' },
|
||||
{ href: '/domande-esami', text: 'Domande Esami' },
|
||||
{ href: '/storia', text: 'Storia' },
|
||||
// { href: '/login', text: 'Login' },
|
||||
]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Vendored
+23
@@ -19,3 +19,26 @@ declare module '@/data/macchinisti.yaml' {
|
||||
const value: Macchinista[]
|
||||
export default value
|
||||
}
|
||||
|
||||
declare module '@/data/domande-esami.yaml' {
|
||||
export type Question = {
|
||||
course: string
|
||||
content: string
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
export type Group = {
|
||||
id: string
|
||||
name: string
|
||||
items: Array<string>
|
||||
}
|
||||
|
||||
export type Database = {
|
||||
names: Record<string, string>
|
||||
groups: Group[]
|
||||
questions: Question[]
|
||||
}
|
||||
|
||||
const value: Database
|
||||
export default value
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ const { title, description, thumbnail, pageTags } = Astro.props
|
||||
<script>
|
||||
import renderMathInElement from 'katex/contrib/auto-render'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const renderMath = () => {
|
||||
renderMathInElement(document.body, {
|
||||
delimiters: [
|
||||
{ left: '$$', right: '$$', display: true },
|
||||
@@ -54,7 +54,12 @@ const { title, description, thumbnail, pageTags } = Astro.props
|
||||
],
|
||||
throwOnError: false,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => renderMath())
|
||||
|
||||
// @ts-ignore
|
||||
window.renderMath = renderMath
|
||||
</script>
|
||||
|
||||
<script is:inline>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
import type { GetStaticPaths } from 'astro'
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro'
|
||||
import Footer from '@/components/Footer.astro'
|
||||
import Header from '@/components/Header.astro'
|
||||
|
||||
import { marked } from 'marked'
|
||||
|
||||
import database from '@/data/domande-esami.yaml'
|
||||
import PhosphorIcon from '@/components/PhosphorIcon.astro'
|
||||
import { DomandeEsamiCourse } from '@/client/DomandeEsamiCourse'
|
||||
|
||||
export const getStaticPaths = (() => {
|
||||
return Object.keys(database.names).map(course => ({
|
||||
params: { course },
|
||||
}))
|
||||
}) satisfies GetStaticPaths
|
||||
|
||||
const { course } = Astro.params
|
||||
---
|
||||
|
||||
<BaseLayout title="Domande Esami | PHC" pageTags={'domande-esami'}>
|
||||
<Header />
|
||||
<main>
|
||||
<DomandeEsamiCourse client:only="preact" course={course} />
|
||||
</main>
|
||||
<Footer />
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { APIRoute } from 'astro'
|
||||
|
||||
import database from '@/data/domande-esami.yaml'
|
||||
|
||||
export const GET: APIRoute = ({}) => {
|
||||
return new Response(JSON.stringify(database), {
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { APIRoute, GetStaticPaths } from 'astro'
|
||||
|
||||
import database from '@/data/domande-esami.yaml'
|
||||
|
||||
export const getStaticPaths = (() => {
|
||||
return Object.keys(database.names).map(course => ({
|
||||
params: { course },
|
||||
}))
|
||||
}) satisfies GetStaticPaths
|
||||
|
||||
export const GET: APIRoute = ({ params: { course } }) => {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
groups: [],
|
||||
names: Object.fromEntries(Object.entries(database.names).filter(([key]) => key === course)),
|
||||
questions: database.questions.filter(question => question.course === course),
|
||||
}),
|
||||
{
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
import { PhosphorIcon } from '@/client/Icon'
|
||||
import Footer from '@/components/Footer.astro'
|
||||
import Header from '@/components/Header.astro'
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro'
|
||||
|
||||
import database from '@/data/domande-esami.yaml'
|
||||
|
||||
const courseQuestionCounts = Object.fromEntries(
|
||||
database.questions.reduce((acc, question) => {
|
||||
acc.set(question.course, (acc.get(question.course) || 0) + 1)
|
||||
return acc
|
||||
}, new Map()),
|
||||
)
|
||||
---
|
||||
|
||||
<BaseLayout title="Domande Esami | PHC" pageTags={'domande-esami'}>
|
||||
<Header />
|
||||
<main>
|
||||
<h1>Domande Esami</h1>
|
||||
{
|
||||
database.groups.map(group => (
|
||||
<details open>
|
||||
<summary>
|
||||
<h2 id={group.id}>
|
||||
<div class="details-closed">
|
||||
<PhosphorIcon name="caret-down" />
|
||||
</div>
|
||||
<div class="details-openned">
|
||||
<PhosphorIcon name="caret-up" />
|
||||
</div>
|
||||
{group.name}
|
||||
</h2>
|
||||
</summary>
|
||||
<div class="wide-card-list">
|
||||
{group.items
|
||||
.filter(course => courseQuestionCounts[course] > 0)
|
||||
.map(course => (
|
||||
<a href={`/domande-esami/${course}`}>
|
||||
<div class="card">
|
||||
<h2>{database.names[course]}</h2>
|
||||
<div class="text">
|
||||
<p>{courseQuestionCounts[course] || 0} domande</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</details>
|
||||
))
|
||||
}
|
||||
|
||||
<h3>Come Contribuire</h3>
|
||||
<div class="card large">
|
||||
<div class="text">
|
||||
<p>
|
||||
Se hai raccolto delle domande da un orale, puoi inviarcele per email all'indirizzo
|
||||
<a href="mailto:macchinisti@lists.dm.unipi.it"> macchinisti@lists.dm.unipi.it</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<Footer />
|
||||
</BaseLayout>
|
||||
+137
-25
@@ -14,7 +14,7 @@
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
|
||||
display: grid;
|
||||
display: grid inline;
|
||||
place-content: center;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,11 @@
|
||||
place-content: center;
|
||||
|
||||
font-size: 24px;
|
||||
font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 24;
|
||||
font-variation-settings:
|
||||
'FILL' 0,
|
||||
'wght' 300,
|
||||
'GRAD' 0,
|
||||
'opsz' 24;
|
||||
|
||||
max-width: 32px;
|
||||
}
|
||||
@@ -79,29 +83,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
// just to know for reference
|
||||
.fake-masonry {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--columns), 1fr);
|
||||
grid-auto-flow: dense;
|
||||
|
||||
& > * {
|
||||
grid-row: span var(--masonry-height);
|
||||
}
|
||||
}
|
||||
|
||||
.search-results {
|
||||
width: 100%;
|
||||
|
||||
@@ -592,6 +573,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.metadata {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
justify-content: start;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
padding: 0.9rem;
|
||||
|
||||
@@ -609,6 +597,38 @@
|
||||
}
|
||||
}
|
||||
|
||||
.chip {
|
||||
user-select: none;
|
||||
|
||||
display: grid;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
|
||||
color: #111;
|
||||
background: #0004;
|
||||
|
||||
padding: 0 0.25rem;
|
||||
border-radius: 0.25rem;
|
||||
line-height: 1.5;
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
|
||||
&.small {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: #0004;
|
||||
background: #0002;
|
||||
}
|
||||
}
|
||||
|
||||
a:has(> .card) {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
//
|
||||
// Card List
|
||||
//
|
||||
@@ -898,4 +918,96 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wide-card-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(auto, 28rem));
|
||||
gap: 2rem;
|
||||
padding: 2rem;
|
||||
|
||||
width: 100%;
|
||||
|
||||
justify-content: center;
|
||||
// align-items: start;
|
||||
|
||||
.text > * {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr auto;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
padding: 0;
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.filter {
|
||||
min-width: 15rem;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.flex-row-wrap {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.grid-h {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.grid-v {
|
||||
display: grid;
|
||||
justify-items: start;
|
||||
align-content: start;
|
||||
|
||||
grid-auto-flow: row;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.grid-center {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
gap: 0.5rem;
|
||||
grid-auto-flow: row;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// just to know for reference
|
||||
.fake-masonry {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--columns), 1fr);
|
||||
grid-auto-flow: dense;
|
||||
|
||||
& > * {
|
||||
grid-row: span var(--masonry-height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,4 +129,47 @@
|
||||
justify-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
details {
|
||||
width: 100%;
|
||||
|
||||
summary {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
|
||||
list-style: none;
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.details-openned,
|
||||
.details-closed {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
&:not([open]) {
|
||||
.details-openned {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&[open] {
|
||||
summary {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.details-closed {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
summary {
|
||||
place-content: stretch;
|
||||
place-items: stretch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,8 @@ body {
|
||||
font-weight: 500;
|
||||
letter-spacing: 1px;
|
||||
color: #333;
|
||||
|
||||
padding: 0.25rem 1.325rem;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
@@ -208,6 +210,10 @@ body {
|
||||
@media screen and (max-width: $screen-desktop-min) {
|
||||
padding: 3rem 1rem;
|
||||
gap: 3rem;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -437,6 +437,35 @@
|
||||
}
|
||||
}
|
||||
|
||||
.domande-esami {
|
||||
background: hsl(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;
|
||||
|
||||
|
||||
@@ -33,6 +33,18 @@
|
||||
@layer typography {
|
||||
@include geometric-headings;
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text {
|
||||
// text-align: justify;
|
||||
// hyphens: auto;
|
||||
@@ -204,6 +216,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
li + li {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited {
|
||||
color: var(--zone-color, #1e6733);
|
||||
|
||||
Reference in New Issue
Block a user