diff --git a/.prettierrc.mjs b/.prettierrc.mjs index 42d2ed7..a3a1586 100644 --- a/.prettierrc.mjs +++ b/.prettierrc.mjs @@ -1,5 +1,6 @@ /** @type {import("prettier").Config} */ export default { + printWidth: 120, singleQuote: true, quoteProps: 'consistent', tabWidth: 4, diff --git a/README.md b/README.md index d8af7d2..1a18921 100644 --- a/README.md +++ b/README.md @@ -1,47 +1 @@ -# Astro Starter Kit: Minimal - -```sh -bun create astro@latest -- --template minimal -``` - -[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/minimal) -[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/minimal) -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/minimal/devcontainer.json) - -> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! - -## 🚀 Project Structure - -Inside of your Astro project, you'll see the following folders and files: - -```text -/ -├── public/ -├── src/ -│ └── pages/ -│ └── index.astro -└── package.json -``` - -Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. - -There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. - -Any static assets, like images, can be placed in the `public/` directory. - -## 🧞 Commands - -All commands are run from the root of the project, from a terminal: - -| Command | Action | -| :------------------------ | :----------------------------------------------- | -| `bun install` | Installs dependencies | -| `bun dev` | Starts local dev server at `localhost:4321` | -| `bun build` | Build your production site to `./dist/` | -| `bun preview` | Preview your build locally, before deploying | -| `bun astro ...` | Run CLI commands like `astro add`, `astro check` | -| `bun astro -- --help` | Get help using the Astro CLI | - -## 👀 Want to learn more? - -Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). +# Poisson Blog Template diff --git a/package.json b/package.json index 7e9ea41..1ae6bfc 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "version": "0.0.1", "scripts": { "dev": "astro dev", + "start": "astro dev", "build": "astro build", + "build:poisson": "astro build --site 'https://poisson.phc.dm.unipi.it/~ncognome' --base '/~ncognome'", "preview": "astro preview", "astro": "astro" }, diff --git a/src/components/PostCard.astro b/src/components/PostCard.astro new file mode 100644 index 0000000..9612ffb --- /dev/null +++ b/src/components/PostCard.astro @@ -0,0 +1,35 @@ +--- +type Props = { + post: { + title: string + publishDate: string + description: string + url: string + } +} + +const { post } = Astro.props +--- + +
+
+ + {post.title} + +
+
+ { + new Date(post.publishDate) + .toLocaleDateString('it-IT', { + year: 'numeric', + month: 'long', + day: 'numeric', + }) + // to Title Case + .replace(/(\w)(\w*)/g, (match, p1, p2) => p1.toUpperCase() + p2.toLowerCase()) + } +
+
+ {post.description} +
+
diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..bab36d6 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,12 @@ +export type PostFrontmatter = { + title: string + description: string + tags: string[] + + publishDate: string + draft: boolean +} + +export default { + title: 'n.cognome', +} diff --git a/src/config.yaml b/src/config.yaml deleted file mode 100644 index 23e6f97..0000000 --- a/src/config.yaml +++ /dev/null @@ -1 +0,0 @@ -title: Sito di n.cognome \ No newline at end of file diff --git a/src/env.d.ts b/src/env.d.ts deleted file mode 100644 index 6e750db..0000000 --- a/src/env.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare module '@/config.yaml' { - const content: { - title: string - } - - export default content -} diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro index c063998..463cbd7 100644 --- a/src/layouts/Base.astro +++ b/src/layouts/Base.astro @@ -1,6 +1,8 @@ --- import 'katex/dist/katex.min.css' -import config from '@/config.yaml' +import '@/style.css' + +import config from '@/config' --- @@ -26,6 +28,7 @@ import config from '@/config.yaml' }) $s.appendChild($e.firstChild) + $e.remove() }) document.querySelectorAll('.math-display').forEach($e => { @@ -42,6 +45,7 @@ import config from '@/config.yaml' }) $s.appendChild($e.firstChild) + $e.remove() }) }) @@ -49,6 +53,29 @@ import config from '@/config.yaml' {config.title} +
+

+ {config.title} +

+
+ + + + + + + + +
+ diff --git a/src/layouts/Post.astro b/src/layouts/Post.astro index 1c6684a..0257f15 100644 --- a/src/layouts/Post.astro +++ b/src/layouts/Post.astro @@ -1,10 +1,13 @@ --- +import config from '@/config' import Base from './Base.astro' -const { title } = Astro.props +const { frontmatter } = Astro.props --- -

Post: {title}

- +
+

{frontmatter.title}

+ +
diff --git a/src/materiale/dispensa-1.pdf b/src/materiale/dispensa-1.pdf new file mode 100644 index 0000000..3c57e76 Binary files /dev/null and b/src/materiale/dispensa-1.pdf differ diff --git a/src/pages/appunti/index.astro b/src/pages/appunti/index.astro new file mode 100644 index 0000000..2e6323d --- /dev/null +++ b/src/pages/appunti/index.astro @@ -0,0 +1,44 @@ +--- +import Base from '@/layouts/Base.astro' +import config from '@/config' +--- + + +
+

Appunti

+ +
+

Corso 1

+

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod beatae, alias vitae assumenda quia + corporis quos natus laboriosam illo consectetur. Praesentium explicabo vitae assumenda saepe impedit + commodi iusto. Enim harum perspiciatis quae ea nihil iusto saepe cum! Doloribus, ullam dolorum. +

+

+ Scarica +

+
+
+

Corso 2

+

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod beatae, alias vitae assumenda quia + corporis quos natus laboriosam illo consectetur. Praesentium explicabo vitae assumenda saepe impedit + commodi iusto. Enim harum perspiciatis quae ea nihil iusto saepe cum! Doloribus, ullam dolorum. +

+

+ Scarica +

+
+
+

Corso 3

+

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod beatae, alias vitae assumenda quia + corporis quos natus laboriosam illo consectetur. Praesentium explicabo vitae assumenda saepe impedit + commodi iusto. Enim harum perspiciatis quae ea nihil iusto saepe cum! Doloribus, ullam dolorum. +

+

+ Scarica +

+
+
+ diff --git a/src/pages/index.astro b/src/pages/index.astro index a6bf2ba..bc7e5bb 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,7 +1,43 @@ --- -import Base from '../layouts/Base.astro' +import Base from '@/layouts/Base.astro' +import type { MarkdownInstance } from 'astro' +import type { PostFrontmatter } from '@/config' +import config from '@/config' +import PostCard from '@/components/PostCard.astro' + +const posts = import.meta.glob>('./posts/*.md', { eager: true }) --- -

Homepage

+
+
+

Ciao!

+

+ Benvenuto sulla pagina poisson di {config.title}, il mio blog personale. Qui troverai + articoli su vari argomenti, appunti di studio e molto altro. +

+
+

Post Recenti

+
+ { + Object.values(posts) + .filter(post => !post.frontmatter.draft) + .toSorted((a, b) => { + return ( + new Date(b.frontmatter.publishDate).getTime() - + new Date(a.frontmatter.publishDate).getTime() + ) + }) + .slice(0, 3) + .map(post => ( + + )) + } +
+
diff --git a/src/pages/posts/first-post.md b/src/pages/posts/first-post.md index 468f1fc..3d00e06 100644 --- a/src/pages/posts/first-post.md +++ b/src/pages/posts/first-post.md @@ -1,7 +1,7 @@ --- -layout: ../../layouts/Post.astro +layout: '@/layouts/Post.astro' title: This is the first post of my new Astro blog. -pubDate: 2023-12-23 +publishDate: 2025-06-04 description: | Lorem ipsum dolor sit amet consectetur, adipisicing elit. Animi, obcaecati quos. Odit fugiat exercitationem cupiditate adipisci ipsa praesentium @@ -10,20 +10,19 @@ description: | tags: ['tag1', 'tag2', 'tag3', 'tag4'] --- -This is a paragraph. Lorem ipsum dolor sit amet consectetur adipisicing elit. -Tenetur vero esse non molestias eos excepturi, inventore atque cupiditate. Sed -voluptatem quas omnis culpa, et odit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. +Praesent libero $\sum_{i=1}^{n} i^2 = \frac{n(n+1)(2n+1)}{6}$ +Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum +imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue -Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur vero esse non -molestias eos excepturi, inventore atque cupiditate. Sed voluptatem quas omnis -culpa, et odit. +$$ +\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi} +$$ -Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur vero esse non +neque. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales,lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur vero esse non molestias eos excepturi, inventore atque cupiditate. Sed voluptatem quas omnis culpa, et odit. -## Headings - # H1 For example Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur vero esse non @@ -60,19 +59,6 @@ Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur vero esse non molestias eos excepturi, inventore atque cupiditate. Sed voluptatem quas omnis culpa, et odit. -## Latex and Math - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. -Praesent libero $\sum_{i=1}^{n} i^2 = \frac{n(n+1)(2n+1)}{6}$ -Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum -imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue - -$$ -\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi} -$$ - -neque. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, - ## Emphasis Emphasis, aka italics, with _asterisks_ or _underscores_. diff --git a/src/pages/posts/index.astro b/src/pages/posts/index.astro new file mode 100644 index 0000000..1c68a32 --- /dev/null +++ b/src/pages/posts/index.astro @@ -0,0 +1,36 @@ +--- +import Base from '@/layouts/Base.astro' +import type { MarkdownInstance } from 'astro' +import type { PostFrontmatter } from '@/config' +import config from '@/config' +import PostCard from '@/components/PostCard.astro' + +const posts = import.meta.glob>('./*.md', { eager: true }) +--- + + +
+

Archivio Post

+
+ { + Object.values(posts) + .filter(post => !post.frontmatter.draft) + .toSorted((a, b) => { + return ( + new Date(b.frontmatter.publishDate).getTime() - + new Date(a.frontmatter.publishDate).getTime() + ) + }) + .slice(0, 3) + .map(post => ( + + )) + } +
+
+ diff --git a/src/style.css b/src/style.css new file mode 100644 index 0000000..ca2695c --- /dev/null +++ b/src/style.css @@ -0,0 +1,5 @@ +@layer base, typography, components, utilities; + +/* @import url(@/themes/base.css); */ +/* @import url(@/themes/colorful.css); */ +@import url(@/themes/mono.css); diff --git a/src/themes/base.css b/src/themes/base.css new file mode 100644 index 0000000..64d687e --- /dev/null +++ b/src/themes/base.css @@ -0,0 +1,437 @@ +:root { + --heading-base-size: 18px; + --heading-scale-factor: 1.33; +} + +@media screen and (max-width: 768px) { + :root { + --heading-base-size: 16px; + --heading-scale-factor: 1.25; + } +} + +@layer base { + *, + *::before, + *::after { + font-family: inherit; + margin: 0; + box-sizing: border-box; + } + + html, + body { + min-height: 100%; + + font-size: 16px; + line-height: 1.75; + + /* os independent font stack */ + font-family: + -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Inter', 'Open Sans', + 'Helvetica Neue', sans-serif; + } + + body { + background: var(--bg, #fff); + padding: 0; + margin: 0; + } +} + +@layer typography { + body { + color: var(--text-fg, #333); + } + + h1, + h2, + h3, + h4, + h5, + h6 { + line-height: 1; + margin-top: 0.75em; + + @media screen and (max-width: 768px) { + margin-top: 1em; + } + } + + h1 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 5)); + font-weight: 600; + } + h2 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 4)); + font-weight: 600; + } + h3 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 3)); + font-weight: 600; + } + h4 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2)); + font-weight: 600; + } + h5 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 1)); + font-weight: 600; + } + h6 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 0)); + font-weight: 600; + } + + p, + ul, + ol, + blockquote, + li, + pre, + table, + figure { + margin: 1rem 0; + } + + ul, + ol { + padding-left: 1.5rem; + } + + ol { + list-style-type: lower-roman; + } +} + +@layer components { + blockquote { + padding: 0.5rem 1rem; + border-left: var(--blockquote-border, 4px solid #ccc); + background: var(--blockquote-bg, #f9f9f9); + font-style: italic; + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; + } + + a { + color: var(--link-color, #007bff); + text-decoration: none; + + &:hover, + &:focus { + text-decoration: 2px solid underline; + } + } + + pre:not(:has(.katex)), + code { + font-family: 'Courier New', Courier, monospace; + background: var(--code-bg, #f5f5f5) !important; + border-radius: 0.5rem; + font-size: 95%; + } + + pre:not(:has(.katex)) { + padding: 0.5rem; + line-height: 1.35; + } + + header { + width: 100%; + max-width: 60rem; + position: absolute; + top: 1rem; + left: 50%; + transform: translateX(-50%); + + display: grid; + grid-template-columns: auto 1fr auto auto; + align-items: center; + + border: var(--header-border, 1px solid #ccc); + border-radius: var(--header-border-radius, 1rem); + padding: var(--header-padding, 0.5rem); + + > h1 { + justify-self: start; + + display: grid; + place-content: center; + + font-size: 1.5rem; + font-weight: 600; + margin: 0; + + padding: 0 0.5rem; + + > a { + color: inherit; + text-decoration: none; + } + } + + /* Hide hamburger menu elements on desktop */ + .hamburger-toggle { + display: none; + } + + .hamburger-icon { + display: none; + flex-direction: column; + cursor: pointer; + padding: 0.5rem; + gap: 0.25rem; + + span { + width: 1.5rem; + height: 0.125rem; + background-color: var(--text-fg, #333); + transition: all 0.3s ease; + border-radius: 0.125rem; + } + } + + > nav { + justify-self: end; + + display: grid; + grid-auto-flow: column; + gap: 1rem; + + > .nav-item { + display: grid; + + > a { + text-decoration: none; + color: inherit; + font-weight: 500; + border-radius: 0.5rem; + padding: 0.5rem 1rem; + + &:hover, + &:focus { + /* text-decoration: 2px solid underline; */ + background-color: var(--nav-hover-bg-color, #f0f0f0); + } + } + } + } + + /* Responsive header styles */ + @media (max-width: 1024px) and (min-width: 769px) { + max-width: 90%; + margin: 0 auto; + } + + @media (max-width: 768px) { + position: fixed; + top: 0; + left: 0; + right: 0; + transform: none; + max-width: none; + width: 100%; + border-radius: 0; + border: none; + border-bottom: var(--header-border, 1px solid #ccc); + background-color: var(--background-color, #fff); + z-index: 1000; + grid-template-columns: auto 1fr auto; + padding: 1rem; + + > h1 { + font-size: 1.25rem; + padding: 0; + } + + /* Show hamburger icon on mobile */ + .hamburger-icon { + display: flex; + z-index: 1001; + } + + /* Animate hamburger icon when menu is open */ + .hamburger-toggle:checked + .hamburger-icon span:nth-child(1) { + transform: rotate(45deg) translate(0.15rem, 0.375rem); + } + + .hamburger-toggle:checked + .hamburger-icon span:nth-child(2) { + opacity: 0; + } + + .hamburger-toggle:checked + .hamburger-icon span:nth-child(3) { + transform: rotate(-45deg) translate(0.15rem, -0.375rem); + } + + /* Mobile navigation */ + > nav { + position: fixed; + top: 0; + right: -100%; + width: 80%; + max-width: 300px; + height: 100vh; + background-color: var(--background-color, #fff); + border-left: var(--header-border, 1px solid #ccc); + transition: right 0.3s ease; + z-index: 999; + + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: stretch; + gap: 0; + padding-top: 54px; + + > .nav-item { + display: block; + border-bottom: var(--header-border, 1px solid #ccc); + + &:first-child { + border-top: var(--header-border, 1px solid #ccc); + } + + > a { + display: block; + padding: 1rem 1.5rem; + border-radius: 0; + font-size: 1.1rem; + + &:hover, + &:focus { + background-color: var(--nav-hover-bg-color, #f0f0f0); + } + } + } + } + + /* Show navigation when checkbox is checked */ + .hamburger-toggle:checked ~ nav { + right: 0; + } + + /* Overlay when menu is open */ + .hamburger-toggle:checked::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 998; + } + } + + @media (max-width: 480px) { + padding: 0.75rem; + + > h1 { + font-size: 1.1rem; + } + + > nav { + width: 90%; + max-width: none; + } + } + } + + main, + article { + max-width: 52rem; + margin: 9rem auto; + + /* Responsive main/article styles */ + @media (max-width: 1024px) and (min-width: 769px) { + max-width: 90%; + padding: 0 1rem; + } + + @media (max-width: 768px) { + margin-top: 6rem; + padding: 0 1rem; + max-width: none; + } + + @media (max-width: 480px) { + margin-top: 5rem; + padding: 0 0.75rem; + } + } + + .card { + display: grid; + grid-auto-flow: row; + gap: 0.5rem; + + padding: 1rem; + border: var(--header-border, 1px solid #ccc); + border-radius: 0.5rem; + background: var(--card-bg, #fff); + + .title { + font-size: 1.25rem; + font-weight: 600; + } + + .date { + font-size: 0.875rem; + color: var(--text-fg-dimmed, #666); + } + + .description { + font-size: 1rem; + color: var(--text-fg, #333); + } + + &:hover { + background: var(--card-hover-bg, #f0f0f0); + } + + @media (max-width: 480px) { + padding: 0.75rem; + } + } + + .card-list { + display: grid; + grid-auto-flow: row; + gap: 1rem; + margin: 1rem 0; + } + + .jumbotron { + height: 50vh; + display: grid; + place-content: center; + text-align: center; + + p { + max-width: 40ch; + } + + /* Responsive jumbotron */ + @media (max-width: 768px) { + height: 40vh; + padding: 0 1rem; + + h1 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 3)); + } + + h2 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2)); + } + } + + @media (max-width: 480px) { + height: 35vh; + + h1 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2)); + } + } + } +} diff --git a/src/themes/colorful.css b/src/themes/colorful.css new file mode 100644 index 0000000..05957b3 --- /dev/null +++ b/src/themes/colorful.css @@ -0,0 +1,534 @@ +:root { + --heading-base-size: 18px; + --heading-scale-factor: 1.33; + + /* Colorful theme colors */ + --bg: linear-gradient(135deg, #f8f9ff 0%, #fff5f5 50%, #f0fff4 100%); + --text-fg: #2d3748; + --text-fg-dimmed: #4a5568; + --link-color: #3182ce; + --blockquote-border: 4px solid #ed8936; + --blockquote-bg: linear-gradient(135deg, #fff5f0 0%, #fef5e7 100%); + --code-bg: linear-gradient(135deg, #edf2f7 0%, #e2e8f0 100%); + --header-border: 1px solid #cbd5e0; + --header-border-radius: 1rem; + --header-padding: 0.5rem; + --background-color: #ffffff; + --card-bg: linear-gradient(135deg, #ffffff 0%, #f7fafc 100%); + --card-hover-bg: linear-gradient(135deg, #edf2f7 0%, #e2e8f0 100%); +} + +@media screen and (max-width: 768px) { + :root { + --heading-base-size: 16px; + --heading-scale-factor: 1.25; + } +} + +@layer base { + *, + *::before, + *::after { + font-family: inherit; + margin: 0; + box-sizing: border-box; + } + + html, + body { + min-height: 100%; + + font-size: 16px; + line-height: 1.75; + + /* os independent font stack */ + font-family: + -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Inter', 'Open Sans', + 'Helvetica Neue', sans-serif; + } + + body { + background: var(--bg, #fff); + padding: 0; + margin: 0; + } +} + +@layer typography { + body { + color: var(--text-fg, #333); + } + + h1, + h2, + h3, + h4, + h5, + h6 { + line-height: 1; + margin-top: 0.75em; + + @media screen and (max-width: 768px) { + margin-top: 1em; + } + } + + h1 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 5)); + font-weight: 600; + } + h2 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 4)); + font-weight: 600; + } + h3 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 3)); + font-weight: 600; + } + h4 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2)); + font-weight: 600; + } + h5 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 1)); + font-weight: 600; + } + h6 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 0)); + font-weight: 600; + } + + p, + ul, + ol, + blockquote, + li, + pre, + table, + figure { + margin: 1rem 0; + } + + ul, + ol { + padding-left: 1.5rem; + } + + ol { + list-style-type: lower-roman; + } +} + +@layer components { + blockquote { + padding: 0.5rem 1rem; + border-left: var(--blockquote-border, 4px solid #ccc); + background: var(--blockquote-bg, #f9f9f9); + font-style: italic; + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; + box-shadow: 0 2px 4px rgba(237, 137, 54, 0.1); + } + + a { + color: var(--link-color, #007bff); + text-decoration: none; + + &:hover, + &:focus { + text-decoration: 2px solid underline; + color: #2b6cb0; + } + } + + pre:not(:has(.katex)), + code { + font-family: 'Courier New', Courier, monospace; + border-radius: 0.5rem; + font-size: 95%; + } + + pre:not(:has(.katex)) { + padding: 0.5rem; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + border: 1px solid #cbd5e0; + background: var(--code-bg, #f5f5f5) !important; + line-height: 1.35; + } + + header { + width: 100%; + max-width: 60rem; + position: absolute; + top: 1rem; + left: 50%; + transform: translateX(-50%); + + display: grid; + grid-template-columns: auto 1fr auto auto; + align-items: center; + + border: 2px solid transparent; + background: + linear-gradient(135deg, #ffffff 0%, #f7fafc 50%, #edf2f7 100%) padding-box, + linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #f5576c 75%, #4facfe 100%) border-box; + border-radius: var(--header-border-radius, 1rem); + padding: var(--header-padding, 0.5rem); + box-shadow: + 0 8px 25px rgba(102, 126, 234, 0.15), + 0 4px 10px rgba(118, 75, 162, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.5); + + position: relative; + + &::before { + content: ''; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #f5576c 75%, #4facfe 100%); + border-radius: inherit; + z-index: -1; + opacity: 0.8; + } + + > h1 { + justify-self: start; + + display: grid; + place-content: center; + + font-size: 1.5rem; + font-weight: 700; + margin: 0; + + padding: 0.75rem 1.25rem; + + position: relative; + border-radius: 0.75rem; + + > a { + color: inherit; + text-decoration: none; + position: relative; + z-index: 1; + } + } + + /* Hide hamburger menu elements on desktop */ + .hamburger-toggle { + display: none; + } + + .hamburger-icon { + display: none; + flex-direction: column; + cursor: pointer; + padding: 0.75rem; + gap: 0.25rem; + border-radius: 0.5rem; + background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%); + + span { + width: 1.5rem; + height: 0.125rem; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border-radius: 0.125rem; + box-shadow: 0 1px 2px rgba(102, 126, 234, 0.3); + } + } + + > nav { + justify-self: end; + + display: grid; + grid-auto-flow: column; + gap: 0.5rem; + + > .nav-item { + display: grid; + + > a { + padding: 0.5rem 1rem; + border-radius: 0.5rem; + background: linear-gradient(135deg, #e6fffa 0%, #f0fff4 100%); + border: 1px solid #81e6d9; + color: var(--text-fg); + font-weight: 500; + text-decoration: none; + + &:hover, + &:focus { + background: linear-gradient(135deg, #b2f5ea 0%, #c6f6d5 100%); + border-color: #38b2ac; + text-decoration: none; + } + } + } + } + + /* Responsive header styles */ + @media (max-width: 1024px) and (min-width: 769px) { + max-width: 90%; + margin: 0 auto; + } + + @media (max-width: 768px) { + position: fixed; + top: 0; + left: 0; + right: 0; + transform: none; + max-width: none; + width: 100%; + border-radius: 0; + border: none; + border-bottom: 2px solid transparent; + background: + linear-gradient(135deg, #ffffff 0%, #f7fafc 100%) padding-box, + linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%) border-box; + z-index: 1000; + grid-template-columns: auto 1fr auto; + padding: 1rem; + + &::before { + display: none; + } + + > h1 { + font-size: 1.25rem; + padding: 0.5rem 1rem; + + &::before, + &::after { + border-radius: 0.5rem; + } + + &::after { + top: 1px; + left: 1px; + right: 1px; + bottom: 1px; + border-radius: calc(0.5rem - 1px); + } + } + + /* Show hamburger icon on mobile */ + .hamburger-icon { + display: flex; + z-index: 1001; + } + + /* Animate hamburger icon when menu is open */ + .hamburger-toggle:checked + .hamburger-icon span:nth-child(1) { + transform: rotate(45deg) translate(0.15rem, 0.375rem); + } + + .hamburger-toggle:checked + .hamburger-icon span:nth-child(2) { + opacity: 0; + } + + .hamburger-toggle:checked + .hamburger-icon span:nth-child(3) { + transform: rotate(-45deg) translate(0.15rem, -0.375rem); + } + + /* Mobile navigation */ + > nav { + position: fixed; + top: 0; + right: -100%; + width: 80%; + max-width: 300px; + height: 100vh; + background: + linear-gradient(180deg, #ffffff 0%, #f7fafc 50%, #edf2f7 100%), + linear-gradient(135deg, rgba(102, 126, 234, 0.05) 0%, rgba(118, 75, 162, 0.05) 100%); + border-left: 2px solid transparent; + background-clip: padding-box; + z-index: 999; + backdrop-filter: blur(10px); + box-shadow: -4px 0 20px rgba(102, 126, 234, 0.15); + + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: stretch; + gap: 0; + padding-top: 54px; + + > .nav-item { + margin: 0.5rem; + + > a { + display: block; + padding: 1rem 1.5rem; + border-bottom: 1px solid rgba(226, 232, 240, 0.5); + border-radius: 0.75rem; + margin-bottom: 0.5rem; + background: linear-gradient(135deg, rgba(230, 255, 250, 0.3) 0%, rgba(240, 255, 244, 0.3) 100%); + + &:hover, + &:focus { + background: linear-gradient(135deg, #e6fffa 0%, #f0fff4 100%); + transform: translateX(4px); + box-shadow: 0 2px 8px rgba(129, 230, 217, 0.3); + } + } + } + } + + /* Show navigation when checkbox is checked */ + .hamburger-toggle:checked ~ nav { + right: 0; + } + + /* Overlay when menu is open */ + .hamburger-toggle:checked::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 998; + } + } + + @media (max-width: 480px) { + padding: 0.75rem; + + > h1 { + font-size: 1.1rem; + } + + > nav { + width: 90%; + max-width: none; + } + } + } + + main, + article { + max-width: 52rem; + margin: 9rem auto; + + /* Responsive main/article styles */ + @media (max-width: 1024px) and (min-width: 769px) { + max-width: 90%; + padding: 0 1rem; + } + + @media (max-width: 768px) { + margin-top: 6rem; + padding: 0 1rem; + max-width: none; + } + + @media (max-width: 480px) { + margin-top: 5rem; + padding: 0 0.75rem; + } + } + + .card { + display: grid; + grid-auto-flow: row; + gap: 0.5rem; + + padding: 1rem; + border: 1px solid #cbd5e0; + border-radius: 0.5rem; + background: var(--card-bg, #fff); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.1), + 0 1px 2px rgba(0, 0, 0, 0.06); + + .title { + font-size: 1.25rem; + font-weight: 600; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + } + + .date { + font-size: 0.875rem; + color: var(--text-fg-dimmed, #666); + } + + .description { + font-size: 1rem; + color: var(--text-fg, #333); + } + + &:hover { + background: var(--card-hover-bg, #f0f0f0); + box-shadow: + 0 4px 6px rgba(0, 0, 0, 0.07), + 0 2px 4px rgba(0, 0, 0, 0.06); + border-color: #a0aec0; + } + + @media (max-width: 480px) { + padding: 0.75rem; + } + } + + .card-list { + display: grid; + grid-auto-flow: row; + gap: 1rem; + margin: 1rem 0; + } + + .jumbotron { + height: 50vh; + display: grid; + place-content: center; + text-align: center; + background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 25%, #a8edea 50%, #fed6e3 75%, #d299c2 100%); + border-radius: 1rem; + margin: 2rem 0; + + h1, + h2 { + background: linear-gradient(135deg, #2d3748 0%, #4a5568 100%); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + } + + p { + max-width: 40ch; + color: var(--text-fg); + } + + /* Responsive jumbotron */ + @media (max-width: 768px) { + height: 40vh; + padding: 0 1rem; + margin: 1rem; + + h1 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 3)); + } + + h2 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2)); + } + } + + @media (max-width: 480px) { + height: 35vh; + + h1 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2)); + } + } + } +} diff --git a/src/themes/mono.css b/src/themes/mono.css new file mode 100644 index 0000000..4d3def4 --- /dev/null +++ b/src/themes/mono.css @@ -0,0 +1,478 @@ +/* filepath: /home/aziis98/Develop/PHC/theme-poisson-blog/src/themes/mono.css */ + +:root { + --heading-base-size: 18px; + --heading-scale-factor: 1.33; + + /* Minimal monospace theme colors */ + --bg: #fafafa; + --text-fg: #1a1a1a; + --text-fg-dimmed: #666666; + --link-color: #df3131; /* Cornflower Blue */ + --blockquote-border: 3px solid #333333; + --blockquote-bg: #f5f5f5; + --code-bg: #f0f0f0; + --header-border: 1px solid #e0e0e0; + --header-border-radius: 0; + --header-padding: 1rem; + --background-color: #fafafa; + --card-bg: #ffffff; + --card-hover-bg: #f5f5f5; +} + +@media screen and (max-width: 768px) { + :root { + --heading-base-size: 16px; + --heading-scale-factor: 1.25; + } +} + +@layer base { + *, + *::before, + *::after { + font-family: inherit; + margin: 0; + box-sizing: border-box; + } + + html, + body { + min-height: 100%; + + font-size: 16px; + line-height: 1.75; + + /* monospace font stack */ + font-family: + 'SF Mono', Monaco, 'Inconsolata', 'Roboto Mono', 'Source Code Pro', 'Courier New', Courier, monospace; + } + + body { + background: var(--bg, #fff); + padding: 0; + margin: 0; + } +} + +@layer typography { + body { + color: var(--text-fg, #333); + } + + h1, + h2, + h3, + h4, + h5, + h6 { + line-height: 1; + margin-top: 0.75em; + + @media screen and (max-width: 768px) { + margin-top: 1em; + } + } + + h1 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 5)); + font-weight: 600; + } + h2 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 4)); + font-weight: 600; + } + h3 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 3)); + font-weight: 600; + } + h4 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2)); + font-weight: 600; + } + h5 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 1)); + font-weight: 600; + } + h6 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 0)); + font-weight: 600; + } + + p, + ul, + ol, + blockquote, + li, + pre, + table, + figure { + margin: 1rem 0; + } + + ul, + ol { + padding-left: 1.5rem; + } + + ol { + list-style-type: lower-roman; + } +} + +@layer components { + blockquote { + padding: 0.5rem 1rem; + border-left: var(--blockquote-border, 4px solid #ccc); + background: var(--blockquote-bg, #f9f9f9); + font-style: italic; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + margin: 1.5rem 0; + } + + a { + color: var(--link-color, #007bff); + text-decoration: underline; + text-decoration-thickness: 2px; + text-underline-offset: 2px; + + &:hover, + &:focus { + text-decoration-thickness: 3px; + text-decoration-color: var(--link-color); + } + } + + pre:not(:has(.katex)), + code { + font-family: inherit; + background: var(--code-bg, #f5f5f5) !important; + border-radius: 0; + font-size: 95%; + border: 1px solid #e0e0e0; + } + + pre:not(:has(.katex)) { + padding: 0.5rem; + line-height: 1.35; + overflow-x: auto; + } + + header { + width: 100%; + max-width: 60rem; + position: absolute; + top: 1rem; + left: 50%; + transform: translateX(-50%); + + display: grid; + grid-template-columns: auto 1fr auto auto; + align-items: center; + + border: var(--header-border, 1px solid #ccc); + border-radius: var(--header-border-radius, 0); + padding: var(--header-padding, 1rem); + background: var(--background-color, #fafafa); + + > h1 { + justify-self: start; + + display: grid; + place-content: center; + + font-size: 1.5rem; + font-weight: 700; + margin: 0; + padding: 0 0.5rem; + text-transform: uppercase; + letter-spacing: 1px; + + > a { + color: inherit; + text-decoration: none; + } + } + + /* Hide hamburger menu elements on desktop */ + .hamburger-toggle { + display: none; + } + + .hamburger-icon { + display: none; + flex-direction: column; + cursor: pointer; + padding: 0.5rem; + gap: 0.25rem; + + span { + width: 1.5rem; + height: 0.125rem; + background-color: var(--text-fg, #333); + border-radius: 0; + } + } + + > nav { + justify-self: end; + + display: grid; + grid-auto-flow: column; + gap: 2rem; + + > .nav-item { + display: grid; + + > a { + text-decoration: none; + padding: 0.5rem 0; + border-radius: 0; + background: transparent; + border: none; + color: var(--text-fg); + font-weight: 500; + text-transform: uppercase; + font-size: 0.875rem; + letter-spacing: 0.5px; + border-bottom: 2px solid transparent; + + &:hover, + &:focus { + border-bottom-color: var(--text-fg); + text-decoration: none; + } + } + } + } + + /* Responsive header styles */ + @media (max-width: 1024px) and (min-width: 769px) { + max-width: 90%; + margin: 0 auto; + } + + @media (max-width: 768px) { + position: fixed; + top: 0; + left: 0; + right: 0; + transform: none; + max-width: none; + width: 100%; + border-radius: 0; + border: none; + border-bottom: var(--header-border, 1px solid #ccc); + background-color: var(--background-color, #fafafa); + z-index: 1000; + grid-template-columns: auto 1fr auto; + padding: 1rem; + + > h1 { + font-size: 1.25rem; + padding: 0; + } + + /* Show hamburger icon on mobile */ + .hamburger-icon { + display: flex; + z-index: 1001; + } + + /* Animate hamburger icon when menu is open */ + .hamburger-toggle:checked + .hamburger-icon span:nth-child(1) { + transform: rotate(45deg) translate(0.15rem, 0.375rem); + } + + .hamburger-toggle:checked + .hamburger-icon span:nth-child(2) { + opacity: 0; + } + + .hamburger-toggle:checked + .hamburger-icon span:nth-child(3) { + transform: rotate(-45deg) translate(0.15rem, -0.375rem); + } + + /* Mobile navigation */ + > nav { + position: fixed; + top: 0; + right: -100%; + width: 80%; + max-width: 300px; + height: 100vh; + background-color: var(--background-color, #fafafa); + border-left: var(--header-border, 1px solid #ccc); + z-index: 999; + + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: stretch; + gap: 0; + padding-top: 54px; + + > .nav-item { + margin: 0; + + > a { + display: block; + padding: 1rem 1.5rem; + border-bottom: 1px solid #e0e0e0; + border-radius: 0; + + &:hover, + &:focus { + background: var(--card-hover-bg, #f5f5f5); + border-bottom-color: var(--text-fg); + } + } + } + } + + /* Show navigation when checkbox is checked */ + .hamburger-toggle:checked ~ nav { + right: 0; + } + + /* Overlay when menu is open */ + .hamburger-toggle:checked::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 998; + } + } + + @media (max-width: 480px) { + padding: 0.75rem; + + > h1 { + font-size: 1.1rem; + } + + > nav { + width: 90%; + max-width: none; + } + } + } + + main, + article { + max-width: 52rem; + margin: 9rem auto; + + /* Responsive main/article styles */ + @media (max-width: 1024px) and (min-width: 769px) { + max-width: 90%; + padding: 0 1rem; + } + + @media (max-width: 768px) { + margin-top: 6rem; + padding: 0 1rem; + max-width: none; + } + + @media (max-width: 480px) { + margin-top: 5rem; + padding: 0 0.75rem; + } + } + + .card { + display: grid; + grid-auto-flow: row; + gap: 0.5rem; + + padding: 1rem; + border: 1px solid #e0e0e0; + border-radius: 0; + background: var(--card-bg, #fff); + + .title { + font-size: 1.25rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .date { + font-size: 0.875rem; + color: var(--text-fg-dimmed, #666); + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .description { + font-size: 1rem; + color: var(--text-fg, #333); + } + + &:hover { + background: var(--card-hover-bg, #f5f5f5); + border-color: var(--text-fg); + } + + @media (max-width: 480px) { + padding: 0.75rem; + } + } + + .card-list { + display: grid; + grid-auto-flow: row; + gap: 1rem; + margin: 1rem 0; + } + + .jumbotron { + height: 50vh; + display: grid; + place-content: center; + text-align: center; + border: 4px solid var(--text-fg); + margin: 2rem 0; + + h1, + h2 { + text-transform: uppercase; + letter-spacing: 1px; + } + + p { + max-width: 40ch; + text-transform: uppercase; + letter-spacing: 0.5px; + font-size: 1rem; + } + + /* Responsive jumbotron */ + @media (max-width: 768px) { + height: 40vh; + padding: 0 1rem; + margin: 1rem; + + h1 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 3)); + } + + h2 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2)); + } + } + + @media (max-width: 480px) { + height: 35vh; + + h1 { + font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2)); + } + } + } +}