First commit. claude tried

This commit is contained in:
2026-04-10 10:44:49 +03:00
parent e8338576d7
commit 7931ddb528
13 changed files with 654 additions and 16 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,5 @@
# build output
dist/
# dist/
# generated types
.astro/

View File

@@ -1,5 +1,11 @@
// @ts-check
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';
// https://astro.build/config
export default defineConfig({});
export default defineConfig({
vite: {
plugins: [tailwindcss()]
}
});

View File

@@ -5,7 +5,9 @@
"": {
"name": "elzasainargift",
"dependencies": {
"@tailwindcss/vite": "^4.2.2",
"astro": "^6.1.5",
"tailwindcss": "^4.2.2",
},
},
},
@@ -138,8 +140,16 @@
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
"@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="],
"@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="],
@@ -210,6 +220,36 @@
"@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
"@tailwindcss/node": ["@tailwindcss/node@4.2.2", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.2.2" } }, "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA=="],
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.2.2", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.2.2", "@tailwindcss/oxide-darwin-arm64": "4.2.2", "@tailwindcss/oxide-darwin-x64": "4.2.2", "@tailwindcss/oxide-freebsd-x64": "4.2.2", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2", "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2", "@tailwindcss/oxide-linux-arm64-musl": "4.2.2", "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", "@tailwindcss/oxide-linux-x64-musl": "4.2.2", "@tailwindcss/oxide-wasm32-wasi": "4.2.2", "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2", "@tailwindcss/oxide-win32-x64-msvc": "4.2.2" } }, "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg=="],
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.2.2", "", { "os": "android", "cpu": "arm64" }, "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg=="],
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.2.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg=="],
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.2.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw=="],
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.2.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ=="],
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2", "", { "os": "linux", "cpu": "arm" }, "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ=="],
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw=="],
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag=="],
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg=="],
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ=="],
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.2.2", "", { "dependencies": { "@emnapi/core": "^1.8.1", "@emnapi/runtime": "^1.8.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.1", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q=="],
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.2.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ=="],
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.2.2", "", { "os": "win32", "cpu": "x64" }, "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA=="],
"@tailwindcss/vite": ["@tailwindcss/vite@4.2.2", "", { "dependencies": { "@tailwindcss/node": "4.2.2", "@tailwindcss/oxide": "4.2.2", "tailwindcss": "4.2.2" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w=="],
"@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "*" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
@@ -306,6 +346,8 @@
"dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="],
"enhanced-resolve": ["enhanced-resolve@5.20.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA=="],
"entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
"es-module-lexer": ["es-module-lexer@2.0.0", "", {}, "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw=="],
@@ -338,6 +380,8 @@
"github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
"h3": ["h3@1.15.11", "", { "dependencies": { "cookie-es": "^1.2.3", "crossws": "^0.3.5", "defu": "^6.1.6", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.4", "radix3": "^1.1.2", "ufo": "^1.6.3", "uncrypto": "^0.1.3" } }, "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg=="],
"hast-util-from-html": ["hast-util-from-html@2.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.1.0", "hast-util-from-parse5": "^8.0.0", "parse5": "^7.0.0", "vfile": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw=="],
@@ -376,8 +420,34 @@
"is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="],
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
"js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
"lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
"longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="],
"lru-cache": ["lru-cache@11.3.3", "", {}, "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ=="],
@@ -582,6 +652,10 @@
"svgo": ["svgo@4.0.1", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.5.0" }, "bin": "./bin/svgo.js" }, "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w=="],
"tailwindcss": ["tailwindcss@4.2.2", "", {}, "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q=="],
"tapable": ["tapable@2.3.2", "", {}, "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA=="],
"tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="],
"tinyclip": ["tinyclip@0.1.12", "", {}, "sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA=="],
@@ -652,6 +726,18 @@
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" }, "bundled": true }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="],
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" }, "bundled": true }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="],
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
"csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="],

File diff suppressed because one or more lines are too long

BIN
dist/favicon.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

9
dist/favicon.svg vendored Normal file
View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

After

Width:  |  Height:  |  Size: 749 B

6
dist/index.html vendored Normal file
View File

@@ -0,0 +1,6 @@
<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>A gift for Anna &amp; Tomas</title><link rel="stylesheet" href="/_astro/index@_@astro.CqUEaQKA.css"></head> <body> <div class="bg-shapes" aria-hidden="true"> <span></span> <span></span> <span></span> </div> <main class="page"> <header class="header"> <p class="header-eyebrow">July 19, 2025</p> <h1 class="header-names">Anna &amp; Tomas</h1> <div class="header-divider"> <hr> <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"> <path d="M12 21.593c-5.63-5.539-11-10.297-11-14.402 0-3.791 3.068-5.191 5.281-5.191 1.312 0 4.151.501 5.719 4.457 1.59-3.968 4.464-4.447 5.726-4.447 2.54 0 5.274 1.621 5.274 5.181 0 4.069-5.136 8.625-11 14.402z"></path> </svg> <hr> </div> <p class="header-message">
A small gift from Marta, with all my love for your
new beginning.
</p> </header> <section aria-labelledby="codes-heading"> <div class="section-header"> <h2 id="codes-heading" class="section-title"> ZARA Home </h2> <a href="https://www.zarahome.com" target="_blank" rel="noopener noreferrer" class="section-link">
Visit store
</a> </div> <div class="codes-list"> <div class="gift-card" style="animation-delay: 0ms"> <div> <p class="gift-card-label">Gift code 1</p> <p class="gift-card-code">GIFT-A1B2-C3D4</p> </div> <button class="copy-btn" data-code="GIFT-A1B2-C3D4" aria-label="Copy code GIFT-A1B2-C3D4">Copy</button> </div> <script type="module">document.querySelectorAll(".copy-btn").forEach(e=>{e.addEventListener("click",async()=>{const t=e.dataset.code??"";try{await navigator.clipboard.writeText(t),e.textContent="Copied",e.classList.add("copied"),setTimeout(()=>{e.textContent="Copy",e.classList.remove("copied")},2e3)}catch{e.textContent="Error",setTimeout(()=>{e.textContent="Copy"},2e3)}})});</script><div class="gift-card" style="animation-delay: 80ms"> <div> <p class="gift-card-label">Gift code 2</p> <p class="gift-card-code">GIFT-E5F6-G7H8</p> </div> <button class="copy-btn" data-code="GIFT-E5F6-G7H8" aria-label="Copy code GIFT-E5F6-G7H8">Copy</button> </div> <div class="gift-card" style="animation-delay: 160ms"> <div> <p class="gift-card-label">Gift code 3</p> <p class="gift-card-code">GIFT-I9J0-K1L2</p> </div> <button class="copy-btn" data-code="GIFT-I9J0-K1L2" aria-label="Copy code GIFT-I9J0-K1L2">Copy</button> </div> </div> </section> <div class="or-divider" aria-hidden="true"> <hr><span>or</span><hr> </div> <section class="payment-card" aria-labelledby="payment-heading"> <h2 id="payment-heading" class="payment-title"> A little extra, with love </h2> <p class="payment-desc">If you&#39;d prefer something personal, here&#39;s a direct contribution.</p> <a href="https://revolut.me/example" target="_blank" rel="noopener noreferrer" class="payment-btn"> Send via Revolut </a> </section> <footer class="footer"> <p class="footer-sign">With love, Marta</p> </footer> </main> </body></html>

View File

@@ -12,6 +12,8 @@
"astro": "astro"
},
"dependencies": {
"astro": "^6.1.5"
"@tailwindcss/vite": "^4.2.2",
"astro": "^6.1.5",
"tailwindcss": "^4.2.2"
}
}

View File

@@ -0,0 +1,39 @@
---
interface Props {
code: string;
index: number;
}
const { code, index } = Astro.props;
---
<div class="gift-card" style={`animation-delay: ${index * 80}ms`}>
<div>
<p class="gift-card-label">Gift code {index + 1}</p>
<p class="gift-card-code">{code}</p>
</div>
<button class="copy-btn" data-code={code} aria-label={`Copy code ${code}`}
>Copy</button
>
</div>
<script>
document.querySelectorAll<HTMLButtonElement>(".copy-btn").forEach((btn) => {
btn.addEventListener("click", async () => {
const code = btn.dataset.code ?? "";
try {
await navigator.clipboard.writeText(code);
btn.textContent = "Copied";
btn.classList.add("copied");
setTimeout(() => {
btn.textContent = "Copy";
btn.classList.remove("copied");
}, 2000);
} catch {
btn.textContent = "Error";
setTimeout(() => {
btn.textContent = "Copy";
}, 2000);
}
});
});
</script>

22
src/data/gifts.json Normal file
View File

@@ -0,0 +1,22 @@
{
"couple": {
"names": "Anna & Tomas",
"date": "July 19, 2025",
"from": "Marta"
},
"store": {
"name": "ZARA Home",
"url": "https://www.zarahome.com",
"codes": [
{ "id": 1, "code": "GIFT-A1B2-C3D4" },
{ "id": 2, "code": "GIFT-E5F6-G7H8" },
{ "id": 3, "code": "GIFT-I9J0-K1L2" }
]
},
"payment": {
"label": "A little extra, with love",
"description": "If you'd prefer something personal, here's a direct contribution.",
"url": "https://revolut.me/example",
"buttonText": "Send via Revolut"
}
}

1
src/env.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference path="../.astro/types.d.ts" />

View File

@@ -1,17 +1,99 @@
---
import GiftCard from "../components/GiftCard.astro";
import gifts from "../data/gifts.json";
import "../styles/global.css";
const { couple, store, payment } = gifts;
---
---
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
</body>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>A gift for {couple.names}</title>
</head>
<body>
<div class="bg-shapes" aria-hidden="true">
<span></span>
<span></span>
<span></span>
</div>
<main class="page">
<header class="header">
<p class="header-eyebrow">{couple.date}</p>
<h1 class="header-names">{couple.names}</h1>
<div class="header-divider">
<hr />
<svg
width="14"
height="14"
viewBox="0 0 24 24"
fill="currentColor"
aria-hidden="true"
>
<path
d="M12 21.593c-5.63-5.539-11-10.297-11-14.402 0-3.791 3.068-5.191 5.281-5.191 1.312 0 4.151.501 5.719 4.457 1.59-3.968 4.464-4.447 5.726-4.447 2.54 0 5.274 1.621 5.274 5.181 0 4.069-5.136 8.625-11 14.402z"
></path>
</svg>
<hr />
</div>
<p class="header-message">
A small gift from {couple.from}, with all my love for your
new beginning.
</p>
</header>
<section aria-labelledby="codes-heading">
<div class="section-header">
<h2 id="codes-heading" class="section-title">
{store.name}
</h2>
<a
href={store.url}
target="_blank"
rel="noopener noreferrer"
class="section-link"
>
Visit store
</a>
</div>
<div class="codes-list">
{
store.codes.map((item, i) => (
<GiftCard code={item.code} index={i} />
))
}
</div>
</section>
<div class="or-divider" aria-hidden="true">
<hr /><span>or</span><hr />
</div>
<section class="payment-card" aria-labelledby="payment-heading">
<h2 id="payment-heading" class="payment-title">
{payment.label}
</h2>
<p class="payment-desc">{payment.description}</p>
<a
href={payment.url}
target="_blank"
rel="noopener noreferrer"
class="payment-btn"
>
{payment.buttonText}
</a>
</section>
<footer class="footer">
<p class="footer-sign">With love, {couple.from}</p>
</footer>
</main>
</body>
</html>

384
src/styles/global.css Normal file
View File

@@ -0,0 +1,384 @@
@import url("https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;1,400;1,500&family=Dancing+Script:wght@600&family=Jost:wght@300;400;500&display=swap");
@import "tailwindcss";
/* ── Reset & base ───────────────────────────────────────── */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
scroll-behavior: smooth;
}
body {
min-height: 100svh;
background-color: #faf6f1;
color: #3a2e2b;
font-family: "Jost", sans-serif;
font-weight: 300;
-webkit-font-smoothing: antialiased;
}
/* ── Grain overlay ──────────────────────────────────────── */
body::before {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
z-index: 100;
opacity: 0.04;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
background-size: 128px;
}
/* ── Background shapes ──────────────────────────────────── */
.bg-shapes {
position: fixed;
inset: 0;
overflow: hidden;
pointer-events: none;
}
.bg-shapes span {
position: absolute;
border-radius: 50% 0 50% 0;
opacity: 0.15;
}
.bg-shapes span:nth-child(1) {
width: 360px;
height: 360px;
background: #e8c4b8;
top: -100px;
right: -120px;
transform: rotate(20deg);
}
.bg-shapes span:nth-child(2) {
width: 280px;
height: 280px;
background: #8fa89e;
bottom: -80px;
left: -90px;
transform: rotate(-15deg);
border-radius: 0 50% 0 50%;
}
.bg-shapes span:nth-child(3) {
width: 160px;
height: 160px;
background: #c9857a;
top: 42%;
left: 62%;
transform: rotate(35deg);
opacity: 0.08;
}
/* ── Layout ─────────────────────────────────────────────── */
.page {
position: relative;
z-index: 1;
max-width: 420px;
margin: 0 auto;
padding: 56px 20px 72px;
}
/* ── Header ─────────────────────────────────────────────── */
.header {
text-align: center;
margin-bottom: 48px;
animation: fade-in 0.8s ease both;
}
.header-eyebrow {
font-family: "Jost", sans-serif;
font-size: 11px;
font-weight: 400;
letter-spacing: 0.22em;
text-transform: uppercase;
color: #8fa89e;
margin-bottom: 14px;
}
.header-names {
font-family: "Dancing Script", cursive;
font-size: 52px;
color: #7d4f47;
line-height: 1.15;
}
.header-divider {
display: flex;
align-items: center;
gap: 12px;
margin: 18px 0;
}
.header-divider hr {
flex: 1;
border: none;
border-top: 1px solid #e8c4b8;
}
.header-divider svg {
color: #c9857a;
flex-shrink: 0;
}
.header-message {
font-family: "Cormorant Garamond", serif;
font-size: 16px;
font-style: italic;
line-height: 1.7;
color: rgba(58, 46, 43, 0.65);
max-width: 340px;
margin: 0 auto;
}
/* ── Section heading row ────────────────────────────────── */
.section-header {
display: flex;
align-items: baseline;
justify-content: space-between;
margin-bottom: 16px;
animation: fade-up 0.7s 0.15s ease both;
}
.section-title {
font-family: "Cormorant Garamond", serif;
font-size: 20px;
font-weight: 600;
color: #3a2e2b;
}
.section-link {
font-family: "Jost", sans-serif;
font-size: 11px;
font-weight: 400;
letter-spacing: 0.2em;
text-transform: uppercase;
color: #8fa89e;
text-decoration: none;
transition: color 0.2s;
}
.section-link:hover {
color: #c9857a;
}
/* ── Gift cards list ────────────────────────────────────── */
.codes-list {
display: flex;
flex-direction: column;
gap: 12px;
margin-bottom: 32px;
}
/* ── Single gift card ───────────────────────────────────── */
.gift-card {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
background: rgba(255, 255, 255, 0.6);
border: 1px solid rgba(232, 196, 184, 0.6);
border-radius: 16px;
padding: 16px 20px;
box-shadow: 0 1px 4px rgba(58, 46, 43, 0.06);
backdrop-filter: blur(6px);
transition: box-shadow 0.3s;
animation: fade-up 0.5s ease both;
}
.gift-card:hover {
box-shadow: 0 4px 16px rgba(58, 46, 43, 0.1);
}
.gift-card::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 32px;
background: rgba(201, 133, 122, 0.5);
border-radius: 0 2px 2px 0;
}
.gift-card-label {
font-family: "Jost", sans-serif;
font-size: 10px;
font-weight: 400;
letter-spacing: 0.22em;
text-transform: uppercase;
color: #8fa89e;
margin-bottom: 4px;
}
.gift-card-code {
font-family: "Cormorant Garamond", serif;
font-size: 18px;
font-weight: 600;
letter-spacing: 0.05em;
color: #3a2e2b;
}
/* ── Copy button ────────────────────────────────────────── */
.copy-btn {
flex-shrink: 0;
font-family: "Jost", sans-serif;
font-size: 11px;
font-weight: 500;
letter-spacing: 0.2em;
text-transform: uppercase;
color: #7d4f47;
background: #faf6f1;
border: 1px solid #e8c4b8;
border-radius: 12px;
padding: 8px 16px;
cursor: pointer;
transition:
background 0.2s,
border-color 0.2s,
color 0.2s,
transform 0.1s;
}
.copy-btn:hover {
background: rgba(232, 196, 184, 0.4);
border-color: #c9857a;
color: #c9857a;
}
.copy-btn:active {
transform: scale(0.95);
}
.copy-btn.copied {
background: rgba(143, 168, 158, 0.12);
border-color: #8fa89e;
color: #8fa89e;
}
/* ── Or divider ─────────────────────────────────────────── */
.or-divider {
display: flex;
align-items: center;
gap: 14px;
margin: 8px 0 28px;
animation: fade-up 0.7s 0.28s ease both;
}
.or-divider hr {
flex: 1;
border: none;
border-top: 1px solid rgba(232, 196, 184, 0.5);
}
.or-divider span {
font-family: "Jost", sans-serif;
font-size: 10px;
font-weight: 400;
letter-spacing: 0.22em;
text-transform: uppercase;
color: #e8c4b8;
}
/* ── Payment card ───────────────────────────────────────── */
.payment-card {
background: rgba(255, 255, 255, 0.5);
border: 1px solid rgba(232, 196, 184, 0.6);
border-radius: 16px;
padding: 28px 24px;
text-align: center;
box-shadow: 0 1px 4px rgba(58, 46, 43, 0.06);
backdrop-filter: blur(6px);
animation: fade-up 0.7s 0.32s ease both;
}
.payment-title {
font-family: "Cormorant Garamond", serif;
font-size: 20px;
font-weight: 600;
color: #3a2e2b;
margin-bottom: 6px;
}
.payment-desc {
font-family: "Cormorant Garamond", serif;
font-size: 15px;
font-style: italic;
color: rgba(58, 46, 43, 0.6);
margin-bottom: 22px;
line-height: 1.6;
}
.payment-btn {
display: inline-block;
font-family: "Jost", sans-serif;
font-size: 13px;
font-weight: 500;
letter-spacing: 0.2em;
text-transform: uppercase;
color: #fff;
background: #c9857a;
border: none;
border-radius: 12px;
padding: 14px 32px;
text-decoration: none;
box-shadow: 0 2px 8px rgba(201, 133, 122, 0.35);
transition:
background 0.2s,
box-shadow 0.2s,
transform 0.1s;
cursor: pointer;
}
.payment-btn:hover {
background: #7d4f47;
box-shadow: 0 4px 16px rgba(125, 79, 71, 0.3);
}
.payment-btn:active {
transform: scale(0.96);
}
/* ── Footer ─────────────────────────────────────────────── */
.footer {
margin-top: 56px;
text-align: center;
animation: fade-in 1s 0.5s ease both;
}
.footer-sign {
font-family: "Dancing Script", cursive;
font-size: 28px;
color: rgba(201, 133, 122, 0.65);
}
/* ── Animations ─────────────────────────────────────────── */
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fade-up {
from {
opacity: 0;
transform: translateY(14px);
}
to {
opacity: 1;
transform: translateY(0);
}
}