From 049c20a4b2a78643b804ce3d3384c411eb600136 Mon Sep 17 00:00:00 2001 From: Lorenzo Iovino Date: Thu, 8 Jan 2026 17:40:19 +0100 Subject: [PATCH] feat: implement automatic image optimization with Astro Assets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Configure content collections to use image() helper for type-safe image references - Replace all tags with component from astro:assets - Migrate images from /public to /src/assets for automatic optimization - Update blog posts to use relative paths in frontmatter (../../assets/photos/) - Remove unused images and duplicates from /public folder - Update Footer component to use optimized SVG icons - Clean up manifest.json to use favicon.ico instead of deleted photos Performance improvements: - remote.jpg: 1.8MB → 128KB (93% reduction) - me.png: 71KB → 12KB (83% reduction) - Automatic WebP conversion - Tree-shaking: only used images are optimized /public folder reduced from 2.3MB to 32KB (only essential files) Build output: 2.2MB with fully optimized images ready for S3 deployment --- .astro/collections/bio.schema.json | 25 - .astro/collections/blog.schema.json | 76 --- .astro/content-assets.mjs | 1 - .astro/content-modules.mjs | 1 - .astro/content.d.ts | 219 -------- .astro/data-store.json | 1 - .astro/settings.json | 5 - .astro/types.d.ts | 2 - .gitignore | 1 + astro.config.mjs | 5 +- package.json | 2 + pnpm-lock.yaml | 520 +++++++++++++++++- public/manifest.json | 24 +- {public => src/assets}/astro.svg | 0 {public => src/assets}/cat.jpg | Bin {public => src/assets}/cloud.jpg | Bin {public => src/assets}/github.svg | 0 {public => src/assets}/green.jpg | Bin {public => src/assets}/linkedin.svg | 0 {public => src/assets}/photos/dogs.jpg | Bin {public => src/assets}/photos/game-jam.jpg | Bin {public => src/assets}/photos/goliardia.jpg | Bin {public => src/assets}/photos/me-amanda.jpg | Bin {public => src/assets}/photos/me-baby.jpg | Bin {public => src/assets}/photos/me-cc.jpg | Bin .../assets}/photos/me-guitar-17.jpg | Bin {public => src/assets}/photos/me-moverio.jpg | Bin {public => src/assets}/photos/me-wine.jpg | Bin {public => src/assets}/photos/me.png | Bin {public => src/assets}/photos/modica.jpg | Bin {public => src/assets}/photos/pokemon.jpg | Bin {public => src/assets}/photos/remote.jpg | Bin .../assets}/photos/valencia-turia.jpg | Bin {public => src/assets}/photos/wine.jpg | Bin {public => src/assets}/plane.jpg | Bin {public => src/assets}/tailwind.svg | 0 src/components/Footer.astro | 29 +- src/components/Hero.astro | 31 +- src/content/bio/{my-story.md => my-story.mdx} | 43 +- src/content/blog/welcome-to-my-blog.md | 2 +- src/content/config.ts | 4 +- src/layouts/BaseLayout.astro | 4 +- src/pages/bio.astro | 20 +- src/pages/blog.astro | 8 +- src/pages/blog/[slug].astro | 15 +- src/pages/blog/tag/[tag].astro | 8 +- src/pages/index.astro | 5 +- 47 files changed, 632 insertions(+), 419 deletions(-) delete mode 100644 .astro/collections/bio.schema.json delete mode 100644 .astro/collections/blog.schema.json delete mode 100644 .astro/content-assets.mjs delete mode 100644 .astro/content-modules.mjs delete mode 100644 .astro/content.d.ts delete mode 100644 .astro/data-store.json delete mode 100644 .astro/settings.json delete mode 100644 .astro/types.d.ts rename {public => src/assets}/astro.svg (100%) rename {public => src/assets}/cat.jpg (100%) rename {public => src/assets}/cloud.jpg (100%) rename {public => src/assets}/github.svg (100%) rename {public => src/assets}/green.jpg (100%) rename {public => src/assets}/linkedin.svg (100%) rename {public => src/assets}/photos/dogs.jpg (100%) rename {public => src/assets}/photos/game-jam.jpg (100%) rename {public => src/assets}/photos/goliardia.jpg (100%) rename {public => src/assets}/photos/me-amanda.jpg (100%) rename {public => src/assets}/photos/me-baby.jpg (100%) rename {public => src/assets}/photos/me-cc.jpg (100%) rename {public => src/assets}/photos/me-guitar-17.jpg (100%) rename {public => src/assets}/photos/me-moverio.jpg (100%) rename {public => src/assets}/photos/me-wine.jpg (100%) rename {public => src/assets}/photos/me.png (100%) rename {public => src/assets}/photos/modica.jpg (100%) rename {public => src/assets}/photos/pokemon.jpg (100%) rename {public => src/assets}/photos/remote.jpg (100%) rename {public => src/assets}/photos/valencia-turia.jpg (100%) rename {public => src/assets}/photos/wine.jpg (100%) rename {public => src/assets}/plane.jpg (100%) rename {public => src/assets}/tailwind.svg (100%) rename src/content/bio/{my-story.md => my-story.mdx} (71%) diff --git a/.astro/collections/bio.schema.json b/.astro/collections/bio.schema.json deleted file mode 100644 index e5d5eec..0000000 --- a/.astro/collections/bio.schema.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "$ref": "#/definitions/bio", - "definitions": { - "bio": { - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "description": { - "type": "string" - }, - "$schema": { - "type": "string" - } - }, - "required": [ - "title", - "description" - ], - "additionalProperties": false - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" -} \ No newline at end of file diff --git a/.astro/collections/blog.schema.json b/.astro/collections/blog.schema.json deleted file mode 100644 index 1248643..0000000 --- a/.astro/collections/blog.schema.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "$ref": "#/definitions/blog", - "definitions": { - "blog": { - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "description": { - "type": "string" - }, - "pubDate": { - "anyOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "string", - "format": "date" - }, - { - "type": "integer", - "format": "unix-time" - } - ] - }, - "updatedDate": { - "anyOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "string", - "format": "date" - }, - { - "type": "integer", - "format": "unix-time" - } - ] - }, - "heroImage": { - "type": "string" - }, - "author": { - "type": "string", - "default": "Lorenzo Iovino" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "draft": { - "type": "boolean", - "default": false - }, - "$schema": { - "type": "string" - } - }, - "required": [ - "title", - "description", - "pubDate" - ], - "additionalProperties": false - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" -} \ No newline at end of file diff --git a/.astro/content-assets.mjs b/.astro/content-assets.mjs deleted file mode 100644 index 2b8b823..0000000 --- a/.astro/content-assets.mjs +++ /dev/null @@ -1 +0,0 @@ -export default new Map(); \ No newline at end of file diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs deleted file mode 100644 index 2b8b823..0000000 --- a/.astro/content-modules.mjs +++ /dev/null @@ -1 +0,0 @@ -export default new Map(); \ No newline at end of file diff --git a/.astro/content.d.ts b/.astro/content.d.ts deleted file mode 100644 index 7af536f..0000000 --- a/.astro/content.d.ts +++ /dev/null @@ -1,219 +0,0 @@ -declare module 'astro:content' { - export interface RenderResult { - Content: import('astro/runtime/server/index.js').AstroComponentFactory; - headings: import('astro').MarkdownHeading[]; - remarkPluginFrontmatter: Record; - } - interface Render { - '.md': Promise; - } - - export interface RenderedContent { - html: string; - metadata?: { - imagePaths: Array; - [key: string]: unknown; - }; - } -} - -declare module 'astro:content' { - type Flatten = T extends { [K: string]: infer U } ? U : never; - - export type CollectionKey = keyof AnyEntryMap; - export type CollectionEntry = Flatten; - - export type ContentCollectionKey = keyof ContentEntryMap; - export type DataCollectionKey = keyof DataEntryMap; - - type AllValuesOf = T extends any ? T[keyof T] : never; - type ValidContentEntrySlug = AllValuesOf< - ContentEntryMap[C] - >['slug']; - - export type ReferenceDataEntry< - C extends CollectionKey, - E extends keyof DataEntryMap[C] = string, - > = { - collection: C; - id: E; - }; - export type ReferenceContentEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}) = string, - > = { - collection: C; - slug: E; - }; - export type ReferenceLiveEntry = { - collection: C; - id: string; - }; - - /** @deprecated Use `getEntry` instead. */ - export function getEntryBySlug< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - collection: C, - // Note that this has to accept a regular string too, for SSR - entrySlug: E, - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - - /** @deprecated Use `getEntry` instead. */ - export function getDataEntryById( - collection: C, - entryId: E, - ): Promise>; - - export function getCollection>( - collection: C, - filter?: (entry: CollectionEntry) => entry is E, - ): Promise; - export function getCollection( - collection: C, - filter?: (entry: CollectionEntry) => unknown, - ): Promise[]>; - - export function getLiveCollection( - collection: C, - filter?: LiveLoaderCollectionFilterType, - ): Promise< - import('astro').LiveDataCollectionResult, LiveLoaderErrorType> - >; - - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - entry: ReferenceContentEntry, - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >( - entry: ReferenceDataEntry, - ): E extends keyof DataEntryMap[C] - ? Promise - : Promise | undefined>; - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - collection: C, - slug: E, - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >( - collection: C, - id: E, - ): E extends keyof DataEntryMap[C] - ? string extends keyof DataEntryMap[C] - ? Promise | undefined - : Promise - : Promise | undefined>; - export function getLiveEntry( - collection: C, - filter: string | LiveLoaderEntryFilterType, - ): Promise, LiveLoaderErrorType>>; - - /** Resolve an array of entry references from the same collection */ - export function getEntries( - entries: ReferenceContentEntry>[], - ): Promise[]>; - export function getEntries( - entries: ReferenceDataEntry[], - ): Promise[]>; - - export function render( - entry: AnyEntryMap[C][string], - ): Promise; - - export function reference( - collection: C, - ): import('astro/zod').ZodEffects< - import('astro/zod').ZodString, - C extends keyof ContentEntryMap - ? ReferenceContentEntry> - : ReferenceDataEntry - >; - // Allow generic `string` to avoid excessive type errors in the config - // if `dev` is not running to update as you edit. - // Invalid collection names will be caught at build time. - export function reference( - collection: C, - ): import('astro/zod').ZodEffects; - - type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; - type InferEntrySchema = import('astro/zod').infer< - ReturnTypeOrOriginal['schema']> - >; - - type ContentEntryMap = { - - }; - - type DataEntryMap = { - "bio": Record; - rendered?: RenderedContent; - filePath?: string; -}>; -"blog": Record; - rendered?: RenderedContent; - filePath?: string; -}>; - - }; - - type AnyEntryMap = ContentEntryMap & DataEntryMap; - - type ExtractLoaderTypes = T extends import('astro/loaders').LiveLoader< - infer TData, - infer TEntryFilter, - infer TCollectionFilter, - infer TError - > - ? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError } - : { data: never; entryFilter: never; collectionFilter: never; error: never }; - type ExtractDataType = ExtractLoaderTypes['data']; - type ExtractEntryFilterType = ExtractLoaderTypes['entryFilter']; - type ExtractCollectionFilterType = ExtractLoaderTypes['collectionFilter']; - type ExtractErrorType = ExtractLoaderTypes['error']; - - type LiveLoaderDataType = - LiveContentConfig['collections'][C]['schema'] extends undefined - ? ExtractDataType - : import('astro/zod').infer< - Exclude - >; - type LiveLoaderEntryFilterType = - ExtractEntryFilterType; - type LiveLoaderCollectionFilterType = - ExtractCollectionFilterType; - type LiveLoaderErrorType = ExtractErrorType< - LiveContentConfig['collections'][C]['loader'] - >; - - export type ContentConfig = typeof import("../src/content/config.js"); - export type LiveContentConfig = never; -} diff --git a/.astro/data-store.json b/.astro/data-store.json deleted file mode 100644 index 01205f7..0000000 --- a/.astro/data-store.json +++ /dev/null @@ -1 +0,0 @@ -[["Map",1,2,9,10,47,48],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.16.7","content-config-digest","f015b337dbf6db8c","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://lorenzoiovino.com\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":{\"type\":\"shiki\",\"excludeLangs\":[\"math\"]},\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[]},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false,\"svgo\":false},\"legacy\":{\"collections\":false}}","blog",["Map",11,12],"welcome-to-my-blog",{"id":11,"data":13,"body":23,"filePath":24,"digest":25,"rendered":26,"legacyId":46},{"title":14,"description":15,"pubDate":16,"heroImage":17,"author":18,"tags":19,"draft":22},"Welcome to My Blog!","First commit",["Date","2024-01-15T00:00:00.000Z"],"/photos/remote.jpg","Lorenzo Iovino",[20,21],"personal","welcome",false,"Hi, I’m Lorenzo.\n\nI’ve been thinking about writing for a long time, and I finally decided to publish this blog.\nNot to be “a creator” or something like that — just to keep track of what I learn and share it with whoever finds it useful.\n\n## What you will find here\n\nMostly things around software and the life around it:\n\n- software engineering stuff I face in real projects (architecture, scalability, reliability, messy trade-offs)\n- notes about tools / workflows that I actually use\n- remote work life (I work from Sicily, sometimes literally with the sea in front)\n- learning experiments (Rust, infra, random deep dives)\n- and sometimes personal things: family, time, balance, small projects\n\nI don’t have a fixed schedule. I’ll write when I have something real to say.\n\n## Why I’m doing it now\n\nIn the last years I built a lot, broke a lot, fixed a lot.\nI also changed life (moved, family, new priorities). Writing helps me slow down and put things in order.\n\nAlso: many times I solve a problem and then I forget the details after 2 months. This blog is also for future-me.\n\n## If you want to say hi\n\nIf something here is useful (or wrong 😅), feel free to reach out on [LinkedIn](https://www.linkedin.com/in/lorenzoiovino/).\nI’m happy to chat with other engineers, founders, makers, or just curious people.\n\n---\n\nThat’s it. First post done. Now I need to keep going 🙂","src/content/blog/welcome-to-my-blog.md","e981cf7e73fa9073",{"html":27,"metadata":28},"\u003Cp>Hi, I’m Lorenzo.\u003C/p>\n\u003Cp>I’ve been thinking about writing for a long time, and I finally decided to publish this blog.\nNot to be “a creator” or something like that — just to keep track of what I learn and share it with whoever finds it useful.\u003C/p>\n\u003Ch2 id=\"what-you-will-find-here\">What you will find here\u003C/h2>\n\u003Cp>Mostly things around software and the life around it:\u003C/p>\n\u003Cul>\n\u003Cli>software engineering stuff I face in real projects (architecture, scalability, reliability, messy trade-offs)\u003C/li>\n\u003Cli>notes about tools / workflows that I actually use\u003C/li>\n\u003Cli>remote work life (I work from Sicily, sometimes literally with the sea in front)\u003C/li>\n\u003Cli>learning experiments (Rust, infra, random deep dives)\u003C/li>\n\u003Cli>and sometimes personal things: family, time, balance, small projects\u003C/li>\n\u003C/ul>\n\u003Cp>I don’t have a fixed schedule. I’ll write when I have something real to say.\u003C/p>\n\u003Ch2 id=\"why-im-doing-it-now\">Why I’m doing it now\u003C/h2>\n\u003Cp>In the last years I built a lot, broke a lot, fixed a lot.\nI also changed life (moved, family, new priorities). Writing helps me slow down and put things in order.\u003C/p>\n\u003Cp>Also: many times I solve a problem and then I forget the details after 2 months. This blog is also for future-me.\u003C/p>\n\u003Ch2 id=\"if-you-want-to-say-hi\">If you want to say hi\u003C/h2>\n\u003Cp>If something here is useful (or wrong 😅), feel free to reach out on \u003Ca href=\"https://www.linkedin.com/in/lorenzoiovino/\">LinkedIn\u003C/a>.\nI’m happy to chat with other engineers, founders, makers, or just curious people.\u003C/p>\n\u003Chr>\n\u003Cp>That’s it. First post done. Now I need to keep going 🙂\u003C/p>",{"headings":29,"localImagePaths":40,"remoteImagePaths":41,"frontmatter":42,"imagePaths":45},[30,34,37],{"depth":31,"slug":32,"text":33},2,"what-you-will-find-here","What you will find here",{"depth":31,"slug":35,"text":36},"why-im-doing-it-now","Why I’m doing it now",{"depth":31,"slug":38,"text":39},"if-you-want-to-say-hi","If you want to say hi",[],[],{"title":14,"description":15,"pubDate":43,"heroImage":17,"tags":44},["Date","2024-01-15T00:00:00.000Z"],[20,21],[],"welcome-to-my-blog.md","bio",["Map",49,50],"my-story",{"id":49,"data":51,"body":54,"filePath":55,"digest":56,"rendered":57,"legacyId":86},{"title":52,"description":53},"My Story","A journey through code, curiosity, and creativity","## Hello world!\n\nHi! I’m Lorenzo Iovino.\n\nI’m a Software Engineer (that’s my job), but I don’t like to define myself only with a role title. I’m a curious person and I always jump between code, ideas, and side passions.\n\nI was born in December 1988 and since then I’ve been basically chasing two things: understanding how things work, and building things that are useful (or just fun).\n\nThis page is a small recap of my story. Nothing special, just me.\n\n## Childhood Nostalgia\n\n\u003Cdiv class=\"float-right img-medium\">\n \u003Cimg src=\"/photos/me-baby.jpg\" alt=\"Super young software developer with an Apple II\" class=\"float-right img-medium\" />\n \u003Cem class=\"text-sm block mt-2\">Super young software developer with an Apple II\u003C/em>\n\u003C/div>\n\nMy first “wow” moment with computers was very early. I was around 4 years old and I was playing Prince of Persia on an Apple II.\n\nFrom that moment, computers never really left my life. Today they are my work, but also the main thing I enjoy.\n\nI grew up in Ispica, in the south of Sicily. My days were simple: school, videogames, and football with friends. Honestly, it was a good life.\n\nIspica is slow, warm, and beautiful. When I was a kid I didn’t see it that way. I wanted to escape. I was dreaming about big cities, more people, more things happening, more opportunities.\n\n\u003Cdiv class=\"float-left img-medium\">\n \u003Cimg src=\"/photos/pokemon.jpg\" alt=\"Pokemon Yellow and Game Boy Advance\" class=\"float-left img-medium\" />\n \u003Cem class=\"text-sm block mt-2\">Pokemon Yellow and Game Boy Advance\u003C/em>\n\u003C/div>\n\nThen came Pokemon, Nintendo consoles, and long afternoons with friends. And at some point, I started to get curious about what was “behind” games and computers. That curiosity slowly became programming.\n\nWhen I was 15 I discovered rock music and it hit me hard. I bought a guitar and I started learning (very badly at the beginning) but I loved it.\n\n\u003Cdiv class=\"float-right img-medium\">\n \u003Cimg src=\"/photos/me-guitar-17.jpg\" alt=\"My dream guitar Fender stratocaster\" class=\"float-right img-medium\" />\n \u003Cem class=\"text-sm block mt-2\">My dream guitar \"Fender stratocaster\"\u003C/em>\n\u003C/div>\n\nGames + music = I became a classic nerd. I wanted to understand computers, programming languages, and all the “magic” under the hood.\n\nAt 17 I also discovered Magic: The Gathering. It became another obsession for a while. I still play sometimes, just for fun.\n\n## University and Personal Growth\n\nI studied Computer Science at the University of Pisa. It was not a straight path.\n\n\u003Cdiv class=\"float-right img-medium\">\n \u003Cimg src=\"/photos/me-cc.jpg\" alt=\"Me burning out studying\" class=\"float-right img-medium\" />\n \u003Cem class=\"text-sm block mt-2\">Me burning out studying Computability and Complexity exam\u003C/em>\n\u003C/div>\n\nI read a lot (often not the books suggested by professors), I failed exams, I repeated exams, I took online courses, I attended workshops… I was trying to understand what “computer science” really is.\n\nAnd yes, I still have mixed feelings about Computability and Complexity. 😅\n\nIt took me 12 years to finish my Bachelor. Not proud of the timeline, but I’m proud I didn’t quit.\n\nMoving to Pisa was not only about studying. It was also my first real “life outside Sicily” experience, and I needed that.\n\n\u003Cdiv class=\"float-left img-medium\">\n \u003Cimg src=\"/photos/goliardia.jpg\" alt=\"My student hat goliardo\" class=\"float-left img-medium\" />\n \u003Cem class=\"text-sm block mt-2\">My student hat (that's not a hat) \"goliardo\"\u003C/em>\n\u003C/div>\n\nUniversity years for me were also: meeting people, spending time around the city, goliardia culture, wine sommelier course (yes), concerts, small music clubs, and long talks with strangers during aperitivo.\n\nThat period also started my love for traveling. Seeing different cultures in real life changes your brain.\n\n## Embarking on Hackathon Adventures\n\n\u003Cdiv class=\"float-right img-small\">\n \u003Cimg src=\"/photos/me-moverio.jpg\" alt=\"Me wearing moverio smart glasses\" class=\"float-right img-small\" />\n \u003Cem class=\"text-sm block mt-2\">Me wearing moverio smart glasses\u003C/em>\n\u003C/div>\n\nMy first hackathon was organized by [Vargroup](https://www.vargroup.it/).\n\nWe were a random team: nobody knew each other. But in 24 hours we built a Proof of Concept + a business idea for a retail app for furniture.\n\nIt was made for Epson Moverio Smartglass: the idea was to let people “place” furniture in their home in a virtual way.\n\nThat experience made me addicted to hackathons. After that I joined other events like Hackaton Toscana (mobility) and also some game jams. Every time you learn something new, and you also learn a lot about teamwork under pressure.\n\n\u003Cdiv class=\"w-full\">\n \u003Cimg src=\"/photos/game-jam.jpg\" alt=\"Me and the team presenting the game\" class=\"img-hero\" />\n \u003Cem class=\"text-sm block mt-2\">Me and the team presenting the game developed\u003C/em>\n\u003C/div>\n\n*Gameplay of our game \"Oh No My Husband is coming\" developed for GGJ 2015: [Youtube link](https://www.youtube.com/embed/z1Kn6agAujI)*\n\n## Erasmus Project in Valencia\n\n\u003Cdiv class=\"float-right img-large\">\n \u003Cimg src=\"/photos/valencia-turia.jpg\" alt=\"Beautiful sunny day in Valencia\" class=\"float-right img-large\" />\n \u003Cem class=\"text-sm block mt-2\">Beautiful sunny day in Valencia\u003C/em>\n\u003C/div>\n\nA big turning point was my Erasmus in Valencia.\n\nI kept studying Computer Science at Universidad Politecnica, met people from everywhere, and got exposed to different cultures and languages.\n\nThe tech environment there felt different compared to Italy. In that period there was a lot of energy: startups, new ideas, and a strong feeling that people wanted to build things.\n\nValencia also helped me grow as a person. New country, new habits, new friends, new perspective.\n\n## Embracing the Tranquility of Sicily\n\nAt some point I decided to go back to Sicily.\n\nNot as a “I give up” move. More like: I want a different balance.\n\n\u003Cdiv class=\"float-left img-medium\">\n \u003Cimg src=\"/photos/remote.jpg\" alt=\"Working remote watching the sea\" class=\"float-left img-medium\" />\n \u003Cem class=\"text-sm block mt-2\">Working remote watching the sea\u003C/em>\n\u003C/div>\n\nI lived the fast pace, the rush, the always-online mindset. Coming back here was intentional: less noise, more space, more time.\n\nI work remote, and Sicily is perfect for that. Life is slower. Sometimes it’s frustrating, but often it’s exactly what I need.\n\nTime here feels different. You can actually breathe. You can have “nothing special” days, and those days can still feel good.\n\n\u003Cdiv class=\"w-full\">\n \u003Cimg src=\"/photos/dogs.jpg\" alt=\"My wineyard\" class=\"img-hero\" />\n \u003Cem class=\"text-sm block mt-2\">My wineyard\u003C/em>\n\u003C/div>\n\nFamily is a big part of my life here. And I also started a side project with my sister (she’s an agronomist): we planted a small vineyard near the sea and we started producing our own wine.\n\nThat project became [www.netum.it](https://netum.it/). It’s small (1 hectare), limited bottles, but it’s something we built together and I love it.\n\n\u003Cdiv class=\"float-right img-small\">\n \u003Cimg src=\"/photos/wine.jpg\" alt=\"The wine produced Zia Lina\" class=\"float-right img-small\" />\n \u003Cem class=\"text-sm block mt-2\">The wine produced \"Zia Lina\"\u003C/em>\n\u003C/div>\n\nAnd yes: food. Sicily is crazy for food. It’s not even a “food culture”, it’s basically a religion.\n\n*(No food photos here. I’m not a food blogger. But trust me.)*\n\nFor me, living here is a reminder: success is not only about projects and code. It’s also about how you live your days.\n\n\u003Cdiv class=\"w-full\">\n \u003Cimg src=\"/photos/modica.jpg\" alt=\"Modica view from my house\" class=\"img-hero\" />\n \u003Cem class=\"text-sm block mt-2\">Modica view from my house\u003C/em>\n\u003C/div>\n\n## Life at 35\n\nToday I’m a husband (to my wife Amanda) and a dad (to our little Leonardo).\n\nLife changed a lot, in a good way. I still love technology, I still build things, but family gives a different meaning to everything.\n\n\u003Cdiv class=\"w-full\">\n \u003Cimg src=\"/photos/me-amanda.jpg\" alt=\"Me and my wife Amanda\" class=\"img-hero\" />\n \u003Cem class=\"text-sm block mt-2\">Me and my wife Amanda\u003C/em>\n\u003C/div>","src/content/bio/my-story.md","489fea2c99c11bac",{"html":58,"metadata":59},"\u003Ch2 id=\"hello-world\">Hello world!\u003C/h2>\n\u003Cp>Hi! I’m Lorenzo Iovino.\u003C/p>\n\u003Cp>I’m a Software Engineer (that’s my job), but I don’t like to define myself only with a role title. I’m a curious person and I always jump between code, ideas, and side passions.\u003C/p>\n\u003Cp>I was born in December 1988 and since then I’ve been basically chasing two things: understanding how things work, and building things that are useful (or just fun).\u003C/p>\n\u003Cp>This page is a small recap of my story. Nothing special, just me.\u003C/p>\n\u003Ch2 id=\"childhood-nostalgia\">Childhood Nostalgia\u003C/h2>\n\u003Cdiv class=\"float-right img-medium\">\n \u003Cimg src=\"/photos/me-baby.jpg\" alt=\"Super young software developer with an Apple II\" class=\"float-right img-medium\">\n \u003Cem class=\"text-sm block mt-2\">Super young software developer with an Apple II\u003C/em>\n\u003C/div>\n\u003Cp>My first “wow” moment with computers was very early. I was around 4 years old and I was playing Prince of Persia on an Apple II.\u003C/p>\n\u003Cp>From that moment, computers never really left my life. Today they are my work, but also the main thing I enjoy.\u003C/p>\n\u003Cp>I grew up in Ispica, in the south of Sicily. My days were simple: school, videogames, and football with friends. Honestly, it was a good life.\u003C/p>\n\u003Cp>Ispica is slow, warm, and beautiful. When I was a kid I didn’t see it that way. I wanted to escape. I was dreaming about big cities, more people, more things happening, more opportunities.\u003C/p>\n\u003Cdiv class=\"float-left img-medium\">\n \u003Cimg src=\"/photos/pokemon.jpg\" alt=\"Pokemon Yellow and Game Boy Advance\" class=\"float-left img-medium\">\n \u003Cem class=\"text-sm block mt-2\">Pokemon Yellow and Game Boy Advance\u003C/em>\n\u003C/div>\n\u003Cp>Then came Pokemon, Nintendo consoles, and long afternoons with friends. And at some point, I started to get curious about what was “behind” games and computers. That curiosity slowly became programming.\u003C/p>\n\u003Cp>When I was 15 I discovered rock music and it hit me hard. I bought a guitar and I started learning (very badly at the beginning) but I loved it.\u003C/p>\n\u003Cdiv class=\"float-right img-medium\">\n \u003Cimg src=\"/photos/me-guitar-17.jpg\" alt=\"My dream guitar Fender stratocaster\" class=\"float-right img-medium\">\n \u003Cem class=\"text-sm block mt-2\">My dream guitar \"Fender stratocaster\"\u003C/em>\n\u003C/div>\n\u003Cp>Games + music = I became a classic nerd. I wanted to understand computers, programming languages, and all the “magic” under the hood.\u003C/p>\n\u003Cp>At 17 I also discovered Magic: The Gathering. It became another obsession for a while. I still play sometimes, just for fun.\u003C/p>\n\u003Ch2 id=\"university-and-personal-growth\">University and Personal Growth\u003C/h2>\n\u003Cp>I studied Computer Science at the University of Pisa. It was not a straight path.\u003C/p>\n\u003Cdiv class=\"float-right img-medium\">\n \u003Cimg src=\"/photos/me-cc.jpg\" alt=\"Me burning out studying\" class=\"float-right img-medium\">\n \u003Cem class=\"text-sm block mt-2\">Me burning out studying Computability and Complexity exam\u003C/em>\n\u003C/div>\n\u003Cp>I read a lot (often not the books suggested by professors), I failed exams, I repeated exams, I took online courses, I attended workshops… I was trying to understand what “computer science” really is.\u003C/p>\n\u003Cp>And yes, I still have mixed feelings about Computability and Complexity. 😅\u003C/p>\n\u003Cp>It took me 12 years to finish my Bachelor. Not proud of the timeline, but I’m proud I didn’t quit.\u003C/p>\n\u003Cp>Moving to Pisa was not only about studying. It was also my first real “life outside Sicily” experience, and I needed that.\u003C/p>\n\u003Cdiv class=\"float-left img-medium\">\n \u003Cimg src=\"/photos/goliardia.jpg\" alt=\"My student hat goliardo\" class=\"float-left img-medium\">\n \u003Cem class=\"text-sm block mt-2\">My student hat (that's not a hat) \"goliardo\"\u003C/em>\n\u003C/div>\n\u003Cp>University years for me were also: meeting people, spending time around the city, goliardia culture, wine sommelier course (yes), concerts, small music clubs, and long talks with strangers during aperitivo.\u003C/p>\n\u003Cp>That period also started my love for traveling. Seeing different cultures in real life changes your brain.\u003C/p>\n\u003Ch2 id=\"embarking-on-hackathon-adventures\">Embarking on Hackathon Adventures\u003C/h2>\n\u003Cdiv class=\"float-right img-small\">\n \u003Cimg src=\"/photos/me-moverio.jpg\" alt=\"Me wearing moverio smart glasses\" class=\"float-right img-small\">\n \u003Cem class=\"text-sm block mt-2\">Me wearing moverio smart glasses\u003C/em>\n\u003C/div>\n\u003Cp>My first hackathon was organized by \u003Ca href=\"https://www.vargroup.it/\">Vargroup\u003C/a>.\u003C/p>\n\u003Cp>We were a random team: nobody knew each other. But in 24 hours we built a Proof of Concept + a business idea for a retail app for furniture.\u003C/p>\n\u003Cp>It was made for Epson Moverio Smartglass: the idea was to let people “place” furniture in their home in a virtual way.\u003C/p>\n\u003Cp>That experience made me addicted to hackathons. After that I joined other events like Hackaton Toscana (mobility) and also some game jams. Every time you learn something new, and you also learn a lot about teamwork under pressure.\u003C/p>\n\u003Cdiv class=\"w-full\">\n \u003Cimg src=\"/photos/game-jam.jpg\" alt=\"Me and the team presenting the game\" class=\"img-hero\">\n \u003Cem class=\"text-sm block mt-2\">Me and the team presenting the game developed\u003C/em>\n\u003C/div>\n\u003Cp>\u003Cem>Gameplay of our game “Oh No My Husband is coming” developed for GGJ 2015: \u003Ca href=\"https://www.youtube.com/embed/z1Kn6agAujI\">Youtube link\u003C/a>\u003C/em>\u003C/p>\n\u003Ch2 id=\"erasmus-project-in-valencia\">Erasmus Project in Valencia\u003C/h2>\n\u003Cdiv class=\"float-right img-large\">\n \u003Cimg src=\"/photos/valencia-turia.jpg\" alt=\"Beautiful sunny day in Valencia\" class=\"float-right img-large\">\n \u003Cem class=\"text-sm block mt-2\">Beautiful sunny day in Valencia\u003C/em>\n\u003C/div>\n\u003Cp>A big turning point was my Erasmus in Valencia.\u003C/p>\n\u003Cp>I kept studying Computer Science at Universidad Politecnica, met people from everywhere, and got exposed to different cultures and languages.\u003C/p>\n\u003Cp>The tech environment there felt different compared to Italy. In that period there was a lot of energy: startups, new ideas, and a strong feeling that people wanted to build things.\u003C/p>\n\u003Cp>Valencia also helped me grow as a person. New country, new habits, new friends, new perspective.\u003C/p>\n\u003Ch2 id=\"embracing-the-tranquility-of-sicily\">Embracing the Tranquility of Sicily\u003C/h2>\n\u003Cp>At some point I decided to go back to Sicily.\u003C/p>\n\u003Cp>Not as a “I give up” move. More like: I want a different balance.\u003C/p>\n\u003Cdiv class=\"float-left img-medium\">\n \u003Cimg src=\"/photos/remote.jpg\" alt=\"Working remote watching the sea\" class=\"float-left img-medium\">\n \u003Cem class=\"text-sm block mt-2\">Working remote watching the sea\u003C/em>\n\u003C/div>\n\u003Cp>I lived the fast pace, the rush, the always-online mindset. Coming back here was intentional: less noise, more space, more time.\u003C/p>\n\u003Cp>I work remote, and Sicily is perfect for that. Life is slower. Sometimes it’s frustrating, but often it’s exactly what I need.\u003C/p>\n\u003Cp>Time here feels different. You can actually breathe. You can have “nothing special” days, and those days can still feel good.\u003C/p>\n\u003Cdiv class=\"w-full\">\n \u003Cimg src=\"/photos/dogs.jpg\" alt=\"My wineyard\" class=\"img-hero\">\n \u003Cem class=\"text-sm block mt-2\">My wineyard\u003C/em>\n\u003C/div>\n\u003Cp>Family is a big part of my life here. And I also started a side project with my sister (she’s an agronomist): we planted a small vineyard near the sea and we started producing our own wine.\u003C/p>\n\u003Cp>That project became \u003Ca href=\"https://netum.it/\">www.netum.it\u003C/a>. It’s small (1 hectare), limited bottles, but it’s something we built together and I love it.\u003C/p>\n\u003Cdiv class=\"float-right img-small\">\n \u003Cimg src=\"/photos/wine.jpg\" alt=\"The wine produced Zia Lina\" class=\"float-right img-small\">\n \u003Cem class=\"text-sm block mt-2\">The wine produced \"Zia Lina\"\u003C/em>\n\u003C/div>\n\u003Cp>And yes: food. Sicily is crazy for food. It’s not even a “food culture”, it’s basically a religion.\u003C/p>\n\u003Cp>\u003Cem>(No food photos here. I’m not a food blogger. But trust me.)\u003C/em>\u003C/p>\n\u003Cp>For me, living here is a reminder: success is not only about projects and code. It’s also about how you live your days.\u003C/p>\n\u003Cdiv class=\"w-full\">\n \u003Cimg src=\"/photos/modica.jpg\" alt=\"Modica view from my house\" class=\"img-hero\">\n \u003Cem class=\"text-sm block mt-2\">Modica view from my house\u003C/em>\n\u003C/div>\n\u003Ch2 id=\"life-at-35\">Life at 35\u003C/h2>\n\u003Cp>Today I’m a husband (to my wife Amanda) and a dad (to our little Leonardo).\u003C/p>\n\u003Cp>Life changed a lot, in a good way. I still love technology, I still build things, but family gives a different meaning to everything.\u003C/p>\n\u003Cdiv class=\"w-full\">\n \u003Cimg src=\"/photos/me-amanda.jpg\" alt=\"Me and my wife Amanda\" class=\"img-hero\">\n \u003Cem class=\"text-sm block mt-2\">Me and my wife Amanda\u003C/em>\n\u003C/div>",{"headings":60,"localImagePaths":82,"remoteImagePaths":83,"frontmatter":84,"imagePaths":85},[61,64,67,70,73,76,79],{"depth":31,"slug":62,"text":63},"hello-world","Hello world!",{"depth":31,"slug":65,"text":66},"childhood-nostalgia","Childhood Nostalgia",{"depth":31,"slug":68,"text":69},"university-and-personal-growth","University and Personal Growth",{"depth":31,"slug":71,"text":72},"embarking-on-hackathon-adventures","Embarking on Hackathon Adventures",{"depth":31,"slug":74,"text":75},"erasmus-project-in-valencia","Erasmus Project in Valencia",{"depth":31,"slug":77,"text":78},"embracing-the-tranquility-of-sicily","Embracing the Tranquility of Sicily",{"depth":31,"slug":80,"text":81},"life-at-35","Life at 35",[],[],{"title":52,"description":53},[],"my-story.md"] \ No newline at end of file diff --git a/.astro/settings.json b/.astro/settings.json deleted file mode 100644 index 0dc322a..0000000 --- a/.astro/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "_variables": { - "lastUpdateCheck": 1767866746327 - } -} \ No newline at end of file diff --git a/.astro/types.d.ts b/.astro/types.d.ts deleted file mode 100644 index 03d7cc4..0000000 --- a/.astro/types.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0257897..b93b53c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # build output dist/ .output/ +.astro/ # dependencies node_modules/ diff --git a/astro.config.mjs b/astro.config.mjs index f55d10f..22c9775 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,11 +1,12 @@ +import mdx from "@astrojs/mdx"; import sitemap from "@astrojs/sitemap"; import tailwind from "@astrojs/tailwind"; import { defineConfig } from "astro/config"; // https://astro.build/config export default defineConfig({ - integrations: [tailwind(), sitemap()], - site: "https://lorenzoiovino.com", + integrations: [tailwind(), sitemap(), mdx()], + site: "https://www.lorenzoiovino.com", compressHTML: true, build: { inlineStylesheets: "auto", diff --git a/package.json b/package.json index adb10b4..fdc1867 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,10 @@ "type-check": "astro check" }, "dependencies": { + "@astrojs/mdx": "^4.3.13", "@astrojs/tailwind": "^6.0.2", "astro": "^5.16.7", + "sharp": "^0.34.5", "tailwindcss": "^3.4.0" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9c1e959..9102dbc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,18 @@ importers: .: dependencies: + '@astrojs/mdx': + specifier: ^4.3.13 + version: 4.3.13(astro@5.16.7(jiti@1.21.7)(rollup@4.55.1)(typescript@5.9.3)(yaml@2.8.2)) '@astrojs/tailwind': specifier: ^6.0.2 version: 6.0.2(astro@5.16.7(jiti@1.21.7)(rollup@4.55.1)(typescript@5.9.3)(yaml@2.8.2))(tailwindcss@3.4.19(yaml@2.8.2)) astro: specifier: ^5.16.7 version: 5.16.7(jiti@1.21.7)(rollup@4.55.1)(typescript@5.9.3)(yaml@2.8.2) + sharp: + specifier: ^0.34.5 + version: 0.34.5 tailwindcss: specifier: ^3.4.0 version: 3.4.19(yaml@2.8.2) @@ -73,6 +79,12 @@ packages: '@astrojs/markdown-remark@6.3.10': resolution: {integrity: sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A==} + '@astrojs/mdx@4.3.13': + resolution: {integrity: sha512-IHDHVKz0JfKBy3//52JSiyWv089b7GVSChIXLrlUOoTLWowG3wr2/8hkaEgEyd/vysvNQvGk+QhysXpJW5ve6Q==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + peerDependencies: + astro: ^5.0.0 + '@astrojs/prism@3.3.0': resolution: {integrity: sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} @@ -500,6 +512,9 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -673,6 +688,9 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -682,6 +700,9 @@ packages: '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} @@ -694,6 +715,9 @@ packages: '@types/sax@1.2.7': resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -726,6 +750,11 @@ packages: '@vscode/l10n@0.0.18': resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} @@ -781,6 +810,10 @@ packages: array-iterate@2.0.1: resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + astro@5.16.7: resolution: {integrity: sha512-Kfv7FKisFR+THvmojXWtvJGRCvQ4D9przguE9XdeUtS464ned6hvbgmyFDvPzyaNmDtkHGNpPwAQ9tgFcVqp+Q==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} @@ -854,6 +887,9 @@ packages: character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -878,6 +914,9 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1019,6 +1058,12 @@ packages: es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + esbuild@0.25.12: resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} engines: {node: '>=18'} @@ -1032,6 +1077,24 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -1137,9 +1200,15 @@ packages: hast-util-raw@9.1.0: resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + hast-util-to-html@9.0.5: resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + hast-util-to-parse5@8.0.1: resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} @@ -1164,9 +1233,18 @@ packages: import-meta-resolve@4.2.0: resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -1175,6 +1253,9 @@ packages: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + is-docker@3.0.0: resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1192,6 +1273,9 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} @@ -1256,6 +1340,10 @@ packages: magicast@0.5.1: resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==} + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} @@ -1286,6 +1374,18 @@ packages: mdast-util-gfm@3.1.0: resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + mdast-util-phrasing@4.1.0: resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} @@ -1332,12 +1432,30 @@ packages: micromark-extension-gfm@3.0.0: resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + micromark-factory-destination@2.0.1: resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} micromark-factory-label@2.0.1: resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + micromark-factory-space@2.0.1: resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} @@ -1368,6 +1486,9 @@ packages: micromark-util-encode@2.0.1: resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + micromark-util-html-tag-name@2.0.1: resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} @@ -1472,6 +1593,9 @@ packages: package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse-latin@7.0.0: resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} @@ -1602,6 +1726,20 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + regex-recursion@6.0.2: resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} @@ -1617,6 +1755,9 @@ packages: rehype-raw@7.0.0: resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + rehype-stringify@10.0.1: resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} @@ -1626,6 +1767,9 @@ packages: remark-gfm@4.0.1: resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + remark-parse@11.0.0: resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} @@ -1719,6 +1863,10 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -1747,6 +1895,12 @@ packages: strnum@2.1.2: resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + sucrase@3.35.1: resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} @@ -1852,6 +2006,9 @@ packages: unist-util-modify-children@4.0.0: resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + unist-util-position@5.0.0: resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} @@ -2238,6 +2395,25 @@ snapshots: transitivePeerDependencies: - supports-color + '@astrojs/mdx@4.3.13(astro@5.16.7(jiti@1.21.7)(rollup@4.55.1)(typescript@5.9.3)(yaml@2.8.2))': + dependencies: + '@astrojs/markdown-remark': 6.3.10 + '@mdx-js/mdx': 3.1.1 + acorn: 8.15.0 + astro: 5.16.7(jiti@1.21.7)(rollup@4.55.1)(typescript@5.9.3)(yaml@2.8.2) + es-module-lexer: 1.7.0 + estree-util-visit: 2.0.0 + hast-util-to-html: 9.0.5 + piccolore: 0.1.3 + rehype-raw: 7.0.0 + remark-gfm: 4.0.1 + remark-smartypants: 3.0.2 + source-map: 0.7.6 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + '@astrojs/prism@3.3.0': dependencies: prismjs: 1.30.0 @@ -2437,8 +2613,7 @@ snapshots: '@esbuild/win32-x64@0.25.12': optional: true - '@img/colour@1.0.0': - optional: true + '@img/colour@1.0.0': {} '@img/sharp-darwin-arm64@0.34.5': optionalDependencies: @@ -2548,6 +2723,36 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.15.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.15.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -2682,6 +2887,10 @@ snapshots: dependencies: '@types/ms': 2.1.0 + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + '@types/estree@1.0.8': {} '@types/hast@3.0.4': @@ -2692,6 +2901,8 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/mdx@2.0.13': {} + '@types/ms@2.1.0': {} '@types/nlcst@2.0.3': @@ -2704,6 +2915,8 @@ snapshots: dependencies: '@types/node': 17.0.45 + '@types/unist@2.0.11': {} + '@types/unist@3.0.3': {} '@ungap/structured-clone@1.3.0': {} @@ -2758,6 +2971,10 @@ snapshots: '@vscode/l10n@0.0.18': {} + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn@8.15.0: {} ajv-draft-04@1.0.0(ajv@8.17.1): @@ -2800,6 +3017,8 @@ snapshots: array-iterate@2.0.1: {} + astring@1.9.0: {} + astro@5.16.7(jiti@1.21.7)(rollup@4.55.1)(typescript@5.9.3)(yaml@2.8.2): dependencies: '@astrojs/compiler': 2.13.0 @@ -2962,6 +3181,8 @@ snapshots: character-entities@2.0.2: {} + character-reference-invalid@2.0.1: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -2990,6 +3211,8 @@ snapshots: clsx@2.1.1: {} + collapse-white-space@2.1.0: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -3052,8 +3275,7 @@ snapshots: destr@2.0.5: {} - detect-libc@2.1.2: - optional: true + detect-libc@2.1.2: {} deterministic-object-hash@2.0.2: dependencies: @@ -3108,6 +3330,20 @@ snapshots: es-module-lexer@1.7.0: {} + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.15.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + esbuild@0.25.12: optionalDependencies: '@esbuild/aix-ppc64': 0.25.12 @@ -3141,6 +3377,35 @@ snapshots: escape-string-regexp@5.0.0: {} + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -3270,6 +3535,27 @@ snapshots: web-namespaces: 2.0.1 zwitch: 2.0.4 + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + hast-util-to-html@9.0.5: dependencies: '@types/hast': 3.0.4 @@ -3284,6 +3570,26 @@ snapshots: stringify-entities: 4.0.4 zwitch: 2.0.4 + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + hast-util-to-parse5@8.0.1: dependencies: '@types/hast': 3.0.4 @@ -3321,8 +3627,17 @@ snapshots: import-meta-resolve@4.2.0: {} + inline-style-parser@0.2.7: {} + iron-webcrypto@1.2.1: {} + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -3331,6 +3646,8 @@ snapshots: dependencies: hasown: 2.0.2 + is-decimal@2.0.1: {} + is-docker@3.0.0: {} is-extglob@2.1.1: {} @@ -3341,6 +3658,8 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-hexadecimal@2.0.1: {} + is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 @@ -3389,6 +3708,8 @@ snapshots: '@babel/types': 7.28.5 source-map-js: 1.2.1 + markdown-extensions@2.0.0: {} + markdown-table@3.0.4: {} mdast-util-definitions@6.0.0: @@ -3478,6 +3799,55 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + mdast-util-phrasing@4.1.0: dependencies: '@types/mdast': 4.0.4 @@ -3594,6 +3964,57 @@ snapshots: micromark-util-combine-extensions: 2.0.1 micromark-util-types: 2.0.2 + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + micromark-factory-destination@2.0.1: dependencies: micromark-util-character: 2.1.1 @@ -3607,6 +4028,18 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + micromark-factory-space@2.0.1: dependencies: micromark-util-character: 2.1.1 @@ -3659,6 +4092,16 @@ snapshots: micromark-util-encode@2.0.1: {} + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + micromark-util-html-tag-name@2.0.1: {} micromark-util-normalize-identifier@2.0.1: @@ -3778,6 +4221,16 @@ snapshots: package-manager-detector@1.6.0: {} + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.2.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + parse-latin@7.0.0: dependencies: '@types/nlcst': 2.0.3 @@ -3883,6 +4336,35 @@ snapshots: readdirp@4.1.2: {} + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + regex-recursion@6.0.2: dependencies: regex-utilities: 2.3.0 @@ -3905,6 +4387,14 @@ snapshots: hast-util-raw: 9.1.0 vfile: 6.0.3 + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + rehype-stringify@10.0.1: dependencies: '@types/hast': 3.0.4 @@ -3929,6 +4419,13 @@ snapshots: transitivePeerDependencies: - supports-color + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + remark-parse@11.0.0: dependencies: '@types/mdast': 4.0.4 @@ -4075,7 +4572,6 @@ snapshots: '@img/sharp-win32-arm64': 0.34.5 '@img/sharp-win32-ia32': 0.34.5 '@img/sharp-win32-x64': 0.34.5 - optional: true shiki@3.21.0: dependencies: @@ -4101,6 +4597,8 @@ snapshots: source-map-js@1.2.1: {} + source-map@0.7.6: {} + space-separated-tokens@2.0.2: {} stream-replace-string@2.0.0: {} @@ -4132,6 +4630,14 @@ snapshots: strnum@2.1.2: {} + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -4266,6 +4772,10 @@ snapshots: '@types/unist': 3.0.3 array-iterate: 2.0.1 + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-position@5.0.0: dependencies: '@types/unist': 3.0.3 diff --git a/public/manifest.json b/public/manifest.json index 6663095..8d047de 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,7 +1,7 @@ { - "name": "Lorenzo Iovino - Software Developer", + "name": "Lorenzo Iovino - Software Engineer", "short_name": "Lorenzo Iovino", - "description": "Software Developer based in Sicily. Passionate about technology, remote work, and life balance.", + "description": "Software Engineer based in Sicily. Passionate about technology, remote work, and life balance.", "start_url": "/", "display": "standalone", "background_color": "#1e3a8a", @@ -12,18 +12,6 @@ "src": "/favicon.ico", "sizes": "48x48", "type": "image/x-icon" - }, - { - "src": "/photos/me.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "any maskable" - }, - { - "src": "/photos/me.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "any maskable" } ], "categories": ["business", "productivity", "lifestyle"], @@ -38,8 +26,8 @@ "url": "/blog", "icons": [ { - "src": "/photos/me.png", - "sizes": "192x192" + "src": "/favicon.ico", + "sizes": "48x48" } ] }, @@ -50,8 +38,8 @@ "url": "/bio", "icons": [ { - "src": "/photos/me.png", - "sizes": "192x192" + "src": "/favicon.ico", + "sizes": "48x48" } ] } diff --git a/public/astro.svg b/src/assets/astro.svg similarity index 100% rename from public/astro.svg rename to src/assets/astro.svg diff --git a/public/cat.jpg b/src/assets/cat.jpg similarity index 100% rename from public/cat.jpg rename to src/assets/cat.jpg diff --git a/public/cloud.jpg b/src/assets/cloud.jpg similarity index 100% rename from public/cloud.jpg rename to src/assets/cloud.jpg diff --git a/public/github.svg b/src/assets/github.svg similarity index 100% rename from public/github.svg rename to src/assets/github.svg diff --git a/public/green.jpg b/src/assets/green.jpg similarity index 100% rename from public/green.jpg rename to src/assets/green.jpg diff --git a/public/linkedin.svg b/src/assets/linkedin.svg similarity index 100% rename from public/linkedin.svg rename to src/assets/linkedin.svg diff --git a/public/photos/dogs.jpg b/src/assets/photos/dogs.jpg similarity index 100% rename from public/photos/dogs.jpg rename to src/assets/photos/dogs.jpg diff --git a/public/photos/game-jam.jpg b/src/assets/photos/game-jam.jpg similarity index 100% rename from public/photos/game-jam.jpg rename to src/assets/photos/game-jam.jpg diff --git a/public/photos/goliardia.jpg b/src/assets/photos/goliardia.jpg similarity index 100% rename from public/photos/goliardia.jpg rename to src/assets/photos/goliardia.jpg diff --git a/public/photos/me-amanda.jpg b/src/assets/photos/me-amanda.jpg similarity index 100% rename from public/photos/me-amanda.jpg rename to src/assets/photos/me-amanda.jpg diff --git a/public/photos/me-baby.jpg b/src/assets/photos/me-baby.jpg similarity index 100% rename from public/photos/me-baby.jpg rename to src/assets/photos/me-baby.jpg diff --git a/public/photos/me-cc.jpg b/src/assets/photos/me-cc.jpg similarity index 100% rename from public/photos/me-cc.jpg rename to src/assets/photos/me-cc.jpg diff --git a/public/photos/me-guitar-17.jpg b/src/assets/photos/me-guitar-17.jpg similarity index 100% rename from public/photos/me-guitar-17.jpg rename to src/assets/photos/me-guitar-17.jpg diff --git a/public/photos/me-moverio.jpg b/src/assets/photos/me-moverio.jpg similarity index 100% rename from public/photos/me-moverio.jpg rename to src/assets/photos/me-moverio.jpg diff --git a/public/photos/me-wine.jpg b/src/assets/photos/me-wine.jpg similarity index 100% rename from public/photos/me-wine.jpg rename to src/assets/photos/me-wine.jpg diff --git a/public/photos/me.png b/src/assets/photos/me.png similarity index 100% rename from public/photos/me.png rename to src/assets/photos/me.png diff --git a/public/photos/modica.jpg b/src/assets/photos/modica.jpg similarity index 100% rename from public/photos/modica.jpg rename to src/assets/photos/modica.jpg diff --git a/public/photos/pokemon.jpg b/src/assets/photos/pokemon.jpg similarity index 100% rename from public/photos/pokemon.jpg rename to src/assets/photos/pokemon.jpg diff --git a/public/photos/remote.jpg b/src/assets/photos/remote.jpg similarity index 100% rename from public/photos/remote.jpg rename to src/assets/photos/remote.jpg diff --git a/public/photos/valencia-turia.jpg b/src/assets/photos/valencia-turia.jpg similarity index 100% rename from public/photos/valencia-turia.jpg rename to src/assets/photos/valencia-turia.jpg diff --git a/public/photos/wine.jpg b/src/assets/photos/wine.jpg similarity index 100% rename from public/photos/wine.jpg rename to src/assets/photos/wine.jpg diff --git a/public/plane.jpg b/src/assets/plane.jpg similarity index 100% rename from public/plane.jpg rename to src/assets/plane.jpg diff --git a/public/tailwind.svg b/src/assets/tailwind.svg similarity index 100% rename from public/tailwind.svg rename to src/assets/tailwind.svg diff --git a/src/components/Footer.astro b/src/components/Footer.astro index c1ba533..5ead5ee 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -1,5 +1,8 @@ --- - +import { Image } from "astro:assets"; +import astroIcon from "../assets/astro.svg"; +import tailwindIcon from "../assets/tailwind.svg"; +import githubIcon from "../assets/github.svg"; ---
@@ -79,11 +82,11 @@ class="inline-flex items-center hover:text-white transition-all duration-200" title="Astro" > - Astro Logo @@ -94,11 +97,11 @@ class="inline-flex items-center center hover:text-white transition-all duration-200" title="TailwindCSS" > - Tailwind Logo @@ -109,11 +112,11 @@ class="hover:text-white transition-colors duration-200 inline-flex items-center justify-center sm:justify-end gap-2 font-medium" > Check the source code - Github Logo diff --git a/src/components/Hero.astro b/src/components/Hero.astro index 880282f..595b340 100644 --- a/src/components/Hero.astro +++ b/src/components/Hero.astro @@ -1,5 +1,8 @@ --- - +import { Image } from "astro:assets"; +import mePhoto from "../assets/photos/me.png"; +import linkedinIcon from "../assets/linkedin.svg"; +import githubIcon from "../assets/github.svg"; ---
@@ -12,12 +15,14 @@
- Photo of Lorenzo Iovino
@@ -57,12 +62,12 @@ class="group relative p-3 bg-gray-50 hover:bg-secondary/10 rounded-xl transition-all duration-200 transform hover:-translate-y-1" aria-label="LinkedIn" > - LinkedIn @@ -71,12 +76,12 @@ class="group relative p-3 bg-gray-50 hover:bg-secondary/10 rounded-xl transition-all duration-200 transform hover:-translate-y-1" aria-label="GitHub" > - GitHub diff --git a/src/content/bio/my-story.md b/src/content/bio/my-story.mdx similarity index 71% rename from src/content/bio/my-story.md rename to src/content/bio/my-story.mdx index 671c425..1f79cd5 100644 --- a/src/content/bio/my-story.md +++ b/src/content/bio/my-story.mdx @@ -3,6 +3,21 @@ title: "My Story" description: "A journey through code, curiosity, and creativity" --- +import { Image } from 'astro:assets'; +import meBaby from '../../assets/photos/me-baby.jpg'; +import pokemon from '../../assets/photos/pokemon.jpg'; +import meGuitar from '../../assets/photos/me-guitar-17.jpg'; +import meCC from '../../assets/photos/me-cc.jpg'; +import goliardia from '../../assets/photos/goliardia.jpg'; +import meMoverio from '../../assets/photos/me-moverio.jpg'; +import gameJam from '../../assets/photos/game-jam.jpg'; +import valenciaTuria from '../../assets/photos/valencia-turia.jpg'; +import remote from '../../assets/photos/remote.jpg'; +import dogs from '../../assets/photos/dogs.jpg'; +import wine from '../../assets/photos/wine.jpg'; +import modica from '../../assets/photos/modica.jpg'; +import meAmanda from '../../assets/photos/me-amanda.jpg'; + ## Hello world! Hi! I’m Lorenzo Iovino. @@ -16,8 +31,8 @@ This page is a small recap of my story. Nothing special, just me. ## Childhood Nostalgia
- Super young software developer with an Apple II - Super young software developer with an Apple II + Super young geek with an Apple II + Super young software geek with an Apple II
My first “wow” moment with computers was very early. I was around 4 years old and I was playing Prince of Persia on an Apple II. @@ -29,7 +44,7 @@ I grew up in Ispica, in the south of Sicily. My days were simple: school, videog Ispica is slow, warm, and beautiful. When I was a kid I didn’t see it that way. I wanted to escape. I was dreaming about big cities, more people, more things happening, more opportunities.
- Pokemon Yellow and Game Boy Advance + Pokemon Yellow and Game Boy Advance Pokemon Yellow and Game Boy Advance
@@ -38,7 +53,7 @@ Then came Pokemon, Nintendo consoles, and long afternoons with friends. And at s When I was 15 I discovered rock music and it hit me hard. I bought a guitar and I started learning (very badly at the beginning) but I loved it.
- My dream guitar Fender stratocaster + My dream guitar Fender stratocaster My dream guitar "Fender stratocaster"
@@ -51,7 +66,7 @@ At 17 I also discovered Magic: The Gathering. It became another obsession for a I studied Computer Science at the University of Pisa. It was not a straight path.
- Me burning out studying + Me burning out studying Me burning out studying Computability and Complexity exam
@@ -64,7 +79,7 @@ It took me 12 years to finish my Bachelor. Not proud of the timeline, but I’m Moving to Pisa was not only about studying. It was also my first real “life outside Sicily” experience, and I needed that.
- My student hat goliardo + My student hat goliardo My student hat (that's not a hat) "goliardo"
@@ -75,7 +90,7 @@ That period also started my love for traveling. Seeing different cultures in rea ## Embarking on Hackathon Adventures
- Me wearing moverio smart glasses + Me wearing moverio smart glasses Me wearing moverio smart glasses
@@ -88,7 +103,7 @@ It was made for Epson Moverio Smartglass: the idea was to let people “place” That experience made me addicted to hackathons. After that I joined other events like Hackaton Toscana (mobility) and also some game jams. Every time you learn something new, and you also learn a lot about teamwork under pressure.
- Me and the team presenting the game + Me and the team presenting the game Me and the team presenting the game developed
@@ -97,7 +112,7 @@ That experience made me addicted to hackathons. After that I joined other events ## Erasmus Project in Valencia
- Beautiful sunny day in Valencia + Beautiful sunny day in Valencia Beautiful sunny day in Valencia
@@ -116,7 +131,7 @@ At some point I decided to go back to Sicily. Not as a “I give up” move. More like: I want a different balance.
- Working remote watching the sea + Working remote watching the sea Working remote watching the sea
@@ -127,7 +142,7 @@ I work remote, and Sicily is perfect for that. Life is slower. Sometimes it’s Time here feels different. You can actually breathe. You can have “nothing special” days, and those days can still feel good.
- My wineyard + My wineyard My wineyard
@@ -136,7 +151,7 @@ Family is a big part of my life here. And I also started a side project with my That project became [www.netum.it](https://netum.it/). It’s small (1 hectare), limited bottles, but it’s something we built together and I love it.
- The wine produced Zia Lina + The wine produced Zia Lina The wine produced "Zia Lina"
@@ -147,7 +162,7 @@ And yes: food. Sicily is crazy for food. It’s not even a “food culture”, i For me, living here is a reminder: success is not only about projects and code. It’s also about how you live your days.
- Modica view from my house + Modica view from my house Modica view from my house
@@ -158,6 +173,6 @@ Today I’m a husband (to my wife Amanda) and a dad (to our little Leonardo). Life changed a lot, in a good way. I still love technology, I still build things, but family gives a different meaning to everything.
- Me and my wife Amanda + Me and my wife Amanda Me and my wife Amanda
diff --git a/src/content/blog/welcome-to-my-blog.md b/src/content/blog/welcome-to-my-blog.md index 91edd77..ec9d050 100644 --- a/src/content/blog/welcome-to-my-blog.md +++ b/src/content/blog/welcome-to-my-blog.md @@ -2,7 +2,7 @@ title: "Welcome to My Blog!" description: "First commit" pubDate: 2024-01-15 -heroImage: "/photos/remote.jpg" +heroImage: "../../assets/photos/remote.jpg" tags: ["personal", "welcome"] --- diff --git a/src/content/config.ts b/src/content/config.ts index 43bd8cd..25302a9 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -2,12 +2,12 @@ import { defineCollection, z } from "astro:content"; const blog = defineCollection({ type: "content", - schema: z.object({ + schema: ({ image }) => z.object({ title: z.string(), description: z.string(), pubDate: z.coerce.date(), updatedDate: z.coerce.date().optional(), - heroImage: z.string().optional(), + heroImage: image().optional(), author: z.string().default("Lorenzo Iovino"), tags: z.array(z.string()).default([]), draft: z.boolean().default(false), diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 053d82f..919cb75 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -12,7 +12,7 @@ interface Props { const { title, - description = "Lorenzo Iovino - Software Developer based in Sicily. Passionate about technology, remote work, and life balance.", + description = "Lorenzo Iovino - Software Engineer based in Sicily. Passionate about technology, remote work, and life balance.", canonicalUrl, image = "/photos/me.png", type = "website", @@ -21,7 +21,7 @@ const { tags = [], } = Astro.props; -const siteUrl = "https://lorenzoiovino.com"; +const siteUrl = "https://www.lorenzoiovino.com"; const fullImageUrl = image.startsWith("http") ? image : `${siteUrl}${image}`; const fullCanonicalUrl = canonicalUrl || `${siteUrl}${Astro.url.pathname}`; diff --git a/src/pages/bio.astro b/src/pages/bio.astro index 5251173..cb9a736 100644 --- a/src/pages/bio.astro +++ b/src/pages/bio.astro @@ -1,10 +1,13 @@ --- import type { CollectionEntry } from "astro:content"; import { getEntry } from "astro:content"; +import { Image } from "astro:assets"; import Footer from "../components/Footer.astro"; import Navbar from "../components/Navbar.astro"; import BaseLayout from "../layouts/BaseLayout.astro"; import "../styles/prose.css"; +import linkedinIcon from "../assets/linkedin.svg"; +import githubIcon from "../assets/github.svg"; type BioEntry = CollectionEntry<"bio">; @@ -20,7 +23,6 @@ const { Content } = await bioEntry.render();
@@ -56,12 +58,12 @@ const { Content } = await bioEntry.render(); rel="noopener noreferrer" class="inline-flex items-center px-10 py-5 bg-white hover:bg-gray-50 text-gray-700 font-semibold text-lg rounded-xl transition-all duration-200 shadow-lg hover:shadow-xl border-2 border-gray-200 hover:border-gray-300 transform hover:-translate-y-1 hover:scale-105" > - LinkedIn LinkedIn @@ -71,12 +73,12 @@ const { Content } = await bioEntry.render(); rel="noopener noreferrer" class="inline-flex items-center px-10 py-5 bg-white hover:bg-gray-50 text-gray-700 font-semibold text-lg rounded-xl transition-all duration-200 shadow-lg hover:shadow-xl border-2 border-gray-200 hover:border-gray-300 transform hover:-translate-y-1 hover:scale-105" > - GitHub GitHub diff --git a/src/pages/blog.astro b/src/pages/blog.astro index fedfb15..5f5cf77 100644 --- a/src/pages/blog.astro +++ b/src/pages/blog.astro @@ -1,6 +1,7 @@ --- import type { CollectionEntry } from "astro:content"; import { getCollection } from "astro:content"; +import { Image } from "astro:assets"; import Footer from "../components/Footer.astro"; import Navbar from "../components/Navbar.astro"; import BaseLayout from "../layouts/BaseLayout.astro"; @@ -33,7 +34,6 @@ const initialPosts: BlogPost[] = sortedPosts.slice(0, 6);
@@ -115,10 +115,14 @@ const initialPosts: BlogPost[] = sortedPosts.slice(0, 6); {post.data.heroImage && (
- {post.data.title}
diff --git a/src/pages/blog/[slug].astro b/src/pages/blog/[slug].astro index ca6da7c..fff3e6a 100644 --- a/src/pages/blog/[slug].astro +++ b/src/pages/blog/[slug].astro @@ -1,6 +1,7 @@ --- import type { CollectionEntry } from "astro:content"; import { getCollection } from "astro:content"; +import { Image } from "astro:assets"; import BaseLayout from "../../layouts/BaseLayout.astro"; import Navbar from "../../components/Navbar.astro"; import Footer from "../../components/Footer.astro"; @@ -18,13 +19,15 @@ export async function getStaticPaths() { const { entry }: { entry: BlogPost } = Astro.props; const { Content } = await entry.render(); + +// Extract image src for meta tags (Open Graph expects a URL string) +const heroImageSrc = entry.data.heroImage?.src || "/photos/me.png"; ---
- {entry.data.title}
@@ -91,6 +98,8 @@ const { Content } = await entry.render(); src="/photos/me.png" alt="Lorenzo Iovino" class="w-20 h-20 rounded-full object-cover" + width="80" + height="80" />

Lorenzo Iovino

diff --git a/src/pages/blog/tag/[tag].astro b/src/pages/blog/tag/[tag].astro index 8d0ce7f..2f6fec3 100644 --- a/src/pages/blog/tag/[tag].astro +++ b/src/pages/blog/tag/[tag].astro @@ -1,6 +1,7 @@ --- import type { CollectionEntry } from "astro:content"; import { getCollection } from "astro:content"; +import { Image } from "astro:assets"; import Footer from "../../../components/Footer.astro"; import Navbar from "../../../components/Navbar.astro"; import BaseLayout from "../../../layouts/BaseLayout.astro"; @@ -38,7 +39,6 @@ const displayTag: string = tag.charAt(0).toUpperCase() + tag.slice(1);