update colors and slight layout changes

This commit is contained in:
Daniel Bulant 2025-07-08 22:46:16 +02:00
parent a0c424db77
commit 4b653cf32e
No known key found for this signature in database
29 changed files with 372 additions and 326 deletions

View file

@ -1,6 +1,7 @@
{
"name": "design",
"version": "0.0.1",
"public": false,
"scripts": {
"dev": "vite dev",
"build": "vite build",
@ -10,7 +11,7 @@
"devDependencies": {
"@dimforge/rapier3d-compat": "^0.10.0",
"@sveltejs/adapter-static": "2.0.1",
"@sveltejs/kit": "1.9.3",
"@sveltejs/kit": "1.30.4",
"@theatre/core": "^0.5.1",
"@theatre/studio": "^0.5.1",
"@threlte/core": "^5.0.9",
@ -19,8 +20,8 @@
"@threlte/rapier": "^0.5.0",
"@threlte/theatre": "^0.0.2",
"@types/three": "^0.147.1",
"mdsvex": "0.10.5",
"svelte": "3.55.1",
"mdsvexrs": "^0.1.1",
"svelte": "4.2.20",
"svelte-sequential-preprocessor": "^0.0.7",
"three": "^0.148.0",
"vite-plugin-windicss": "^1.8.10"

View file

@ -83,10 +83,10 @@ importers:
version: 0.10.0
'@sveltejs/adapter-static':
specifier: 2.0.1
version: 2.0.1(@sveltejs/kit@1.9.3)
version: 2.0.1(@sveltejs/kit@1.30.4(svelte@4.2.20)(vite@4.1.4))
'@sveltejs/kit':
specifier: 1.9.3
version: 1.9.3(svelte@3.55.1)(vite@4.1.4)
specifier: 1.30.4
version: 1.30.4(svelte@4.2.20)(vite@4.1.4)
'@theatre/core':
specifier: ^0.5.1
version: 0.5.1
@ -111,12 +111,12 @@ importers:
'@types/three':
specifier: ^0.147.1
version: 0.147.1
mdsvex:
specifier: 0.10.5
version: 0.10.5(svelte@3.55.1)
mdsvexrs:
specifier: ^0.1.1
version: 0.1.2
svelte:
specifier: 3.55.1
version: 3.55.1
specifier: 4.2.20
version: 4.2.20
svelte-sequential-preprocessor:
specifier: ^0.0.7
version: 0.0.7
@ -129,6 +129,10 @@ importers:
packages:
'@ampproject/remapping@2.3.0':
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
'@antfu/utils@0.7.2':
resolution: {integrity: sha512-vy9fM3pIxZmX07dL+VX1aZe7ynZ+YyB0jY+jE6r3hOK6GNY2t6W8rzpFC4tgpbXUYABkFQwgJq2XYXlxbXAI0g==}
@ -280,9 +284,26 @@ packages:
cpu: [x64]
os: [win32]
'@fastify/busboy@2.1.1':
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
engines: {node: '>=14'}
'@jridgewell/gen-mapping@0.3.12':
resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==}
'@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
'@jridgewell/sourcemap-codec@1.4.14':
resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
'@jridgewell/sourcemap-codec@1.5.4':
resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==}
'@jridgewell/trace-mapping@0.3.29':
resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==}
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@ -323,22 +344,30 @@ packages:
peerDependencies:
'@sveltejs/kit': ^1.5.0
'@sveltejs/kit@1.9.3':
resolution: {integrity: sha512-rh9FbGfS8w328JZSZmG/ahabBbE50TisHvfz4sVNU3IM3AOhgUAv3EhAJ2dij9R8uARbDHRTY8jOQbIPjcKBZQ==}
'@sveltejs/kit@1.30.4':
resolution: {integrity: sha512-JSQIQT6XvdchCRQEm7BABxPC56WP5RYVONAi+09S8tmzeP43fBsRlr95bFmsTQM2RHBldfgQk+jgdnsKI75daA==}
engines: {node: ^16.14 || >=18}
hasBin: true
peerDependencies:
svelte: ^3.54.0
svelte: ^3.54.0 || ^4.0.0-next.0 || ^5.0.0-next.0
vite: ^4.0.0
'@sveltejs/pancake@0.0.18':
resolution: {integrity: sha512-vnpKn+sHE0yvw/6x4juF9EoDS8iYC5JNIVtRgclA37rfxdnIpvbVxStiZ5/gWncjERN4jtSpTAplS1zCARCBXA==}
'@sveltejs/vite-plugin-svelte@2.0.3':
resolution: {integrity: sha512-o+cguBFdwIGtRbNkYOyqTM7KvRUffxh5bfK4oJsWKG2obu+v/cbpT03tJrGl58C7tRXo/aEC0/axN5FVHBj0nA==}
'@sveltejs/vite-plugin-svelte-inspector@1.0.4':
resolution: {integrity: sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==}
engines: {node: ^14.18.0 || >= 16}
peerDependencies:
svelte: ^3.54.0
'@sveltejs/vite-plugin-svelte': ^2.2.0
svelte: ^3.54.0 || ^4.0.0
vite: ^4.0.0
'@sveltejs/vite-plugin-svelte@2.5.3':
resolution: {integrity: sha512-erhNtXxE5/6xGZz/M9eXsmI7Pxa6MS7jyTy06zN3Ck++ldrppOnOlJwHHTsMC7DHDQdgUp4NAc4cDNQ9eGdB/w==}
engines: {node: ^14.18.0 || >= 16}
peerDependencies:
svelte: ^3.54.0 || ^4.0.0 || ^5.0.0-next.0
vite: ^4.0.0
'@theatre/core@0.5.1':
@ -377,6 +406,9 @@ packages:
'@types/debug@4.1.7':
resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==}
'@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
'@types/hast@2.3.4':
resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==}
@ -416,6 +448,11 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
acorn@8.15.0:
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
engines: {node: '>=0.4.0'}
hasBin: true
acorn@8.8.2:
resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==}
engines: {node: '>=0.4.0'}
@ -428,6 +465,10 @@ packages:
ansi-sequence-parser@1.1.0:
resolution: {integrity: sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==}
aria-query@5.3.2:
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
engines: {node: '>= 0.4'}
assert@2.0.0:
resolution: {integrity: sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==}
@ -438,6 +479,10 @@ packages:
resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
engines: {node: '>= 0.4'}
axobject-query@4.1.0:
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
engines: {node: '>= 0.4'}
bail@2.0.2:
resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
@ -457,10 +502,6 @@ packages:
browser-process-hrtime@1.0.0:
resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==}
busboy@1.6.0:
resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
engines: {node: '>=10.16.0'}
call-bind@1.0.2:
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
@ -470,6 +511,9 @@ packages:
character-entities@2.0.2:
resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
code-red@1.0.4:
resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==}
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@ -491,6 +535,10 @@ packages:
css-selector-parser@1.4.1:
resolution: {integrity: sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==}
css-tree@2.3.1:
resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
cssom@0.3.8:
resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==}
@ -527,6 +575,10 @@ packages:
resolution: {integrity: sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==}
engines: {node: '>=0.10.0'}
deepmerge@4.3.1:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
define-properties@1.2.0:
resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
engines: {node: '>= 0.4'}
@ -539,8 +591,8 @@ packages:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
devalue@4.3.0:
resolution: {integrity: sha512-n94yQo4LI3w7erwf84mhRUkUJfhLoCZiLyoOZ/QFsDbcWNZePrLwbQpvZBUG2TNxwV3VjCKPxkiiQA6pe3TrTA==}
devalue@4.3.3:
resolution: {integrity: sha512-UH8EL6H2ifcY8TbD2QsxwCC/pr5xSwPvv85LrLXVihmHVC3T3YqTCIwnR5ak0yO1KYqlxrPVOA/JVZJYPy2ATg==}
diff@5.1.0:
resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==}
@ -607,6 +659,9 @@ packages:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
@ -782,6 +837,9 @@ packages:
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
is-reference@3.0.3:
resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==}
is-typed-array@1.1.10:
resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==}
engines: {node: '>= 0.4'}
@ -827,6 +885,9 @@ packages:
resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==}
engines: {node: '>= 0.8.0'}
locate-character@3.0.0:
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
lodash-es@4.17.21:
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
@ -841,13 +902,8 @@ packages:
resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==}
engines: {node: '>=12'}
magic-string@0.29.0:
resolution: {integrity: sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q==}
engines: {node: '>=12'}
magic-string@0.30.0:
resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==}
engines: {node: '>=12'}
magic-string@0.30.17:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
markdown-table@3.0.3:
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
@ -896,10 +952,14 @@ packages:
mdast-util-to-string@3.1.1:
resolution: {integrity: sha512-tGvhT94e+cVnQt8JWE9/b3cUQZWS732TJxXHktvP+BYo62PpYD53Ls/6cC60rW21dW+txxiM4zMdc6abASvZKA==}
mdsvex@0.10.5:
resolution: {integrity: sha512-/B23WZn5Vjrjh7Qp2YsOXLkU9YFm59IEylKNXC10o05ZaCP4LNv32tGXKP6aEssss6hk/LdISJuneELHFIS2pQ==}
peerDependencies:
svelte: 3.x
mdn-data@2.0.30:
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
mdsvexrs-wasm@0.1.0:
resolution: {integrity: sha512-ts6nW2hPLTQV91xz/yBwZkpq6r3X4JGjrOA90APhXMLt0pPVUq7yVrQqgh7earOoBUN1QVq2H3r1OeBOm8vP7g==}
mdsvexrs@0.1.2:
resolution: {integrity: sha512-6pi7b1Fj1RE5BUyVAPUW7pLJ1l+CgtGCecYH0lsBvHVJvuyXqYN2a/+utZNkBkGJYGcR3/H6axE3M43OSnY5wg==}
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
@ -1007,11 +1067,6 @@ packages:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
mime@3.0.0:
resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==}
engines: {node: '>=10.0.0'}
hasBin: true
mri@1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
engines: {node: '>=4'}
@ -1065,6 +1120,9 @@ packages:
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
periscopic@3.1.0:
resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
picocolors@1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
@ -1080,13 +1138,6 @@ packages:
resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==}
engines: {node: '>= 0.8.0'}
prism-svelte@0.4.7:
resolution: {integrity: sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==}
prismjs@1.29.0:
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
engines: {node: '>=6'}
promise-polyfill@8.3.0:
resolution: {integrity: sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==}
@ -1174,8 +1225,8 @@ packages:
resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==}
engines: {node: '>=10'}
set-cookie-parser@2.5.1:
resolution: {integrity: sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ==}
set-cookie-parser@2.7.1:
resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
shiki@0.14.1:
resolution: {integrity: sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==}
@ -1198,19 +1249,15 @@ packages:
stackframe@0.3.1:
resolution: {integrity: sha512-XmoiF4T5nuWEp2x2w92WdGjdHGY/cZa6LIbRsDRQR/Xlk4uW0PAUlH1zJYVffocwKpCdwyuypIp25xsSXEtZHw==}
streamsearch@1.1.0:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'}
supports-preserve-symlinks-flag@1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
svelte-hmr@0.15.1:
resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==}
svelte-hmr@0.15.3:
resolution: {integrity: sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==}
engines: {node: ^12.20 || ^14.13.1 || >= 16}
peerDependencies:
svelte: '>=3.19.0'
svelte: ^3.19.0 || ^4.0.0
svelte-sequential-preprocessor@0.0.7:
resolution: {integrity: sha512-xk974Ny77eiC8xpFPCVNopCfCW4ElWWlvWIv+c7psbjjb4UVRyhR8IJfwOuwnY5S3nduBOYoalY4eigB9YyqHA==}
@ -1220,6 +1267,10 @@ packages:
resolution: {integrity: sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ==}
engines: {node: '>= 8'}
svelte@4.2.20:
resolution: {integrity: sha512-eeEgGc2DtiUil5ANdtd8vPwt9AgaMdnuUFnPft9F5oMvU/FHu5IHFic+p1dR/UOB7XU2mX2yHW+NcTch4DCh5Q==}
engines: {node: '>=16'}
symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
@ -1280,9 +1331,9 @@ packages:
resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==}
engines: {node: '>= 0.8.0'}
undici@5.20.0:
resolution: {integrity: sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g==}
engines: {node: '>=12.18'}
undici@5.29.0:
resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==}
engines: {node: '>=14.0'}
unified@10.1.2:
resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==}
@ -1305,9 +1356,6 @@ packages:
unist-util-position@4.0.4:
resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==}
unist-util-stringify-position@2.0.3:
resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==}
unist-util-stringify-position@3.0.3:
resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==}
@ -1348,9 +1396,6 @@ packages:
engines: {node: '>=8'}
hasBin: true
vfile-message@2.0.4:
resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==}
vfile-message@3.1.4:
resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==}
@ -1482,6 +1527,11 @@ packages:
snapshots:
'@ampproject/remapping@2.3.0':
dependencies:
'@jridgewell/gen-mapping': 0.3.12
'@jridgewell/trace-mapping': 0.3.29
'@antfu/utils@0.7.2': {}
'@atomiks/mdx-pretty-code@0.1.0(shiki@0.14.1)':
@ -1574,8 +1624,24 @@ snapshots:
'@esbuild/win32-x64@0.16.17':
optional: true
'@fastify/busboy@2.1.1': {}
'@jridgewell/gen-mapping@0.3.12':
dependencies:
'@jridgewell/sourcemap-codec': 1.5.4
'@jridgewell/trace-mapping': 0.3.29
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/sourcemap-codec@1.4.14': {}
'@jridgewell/sourcemap-codec@1.5.4': {}
'@jridgewell/trace-mapping@0.3.29':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.4
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@ -1617,26 +1683,26 @@ snapshots:
'@sentry/types': 7.40.0
tslib: 1.14.1
'@sveltejs/adapter-static@2.0.1(@sveltejs/kit@1.9.3)':
'@sveltejs/adapter-static@2.0.1(@sveltejs/kit@1.30.4(svelte@4.2.20)(vite@4.1.4))':
dependencies:
'@sveltejs/kit': 1.9.3(svelte@3.55.1)(vite@4.1.4)
'@sveltejs/kit': 1.30.4(svelte@4.2.20)(vite@4.1.4)
'@sveltejs/kit@1.9.3(svelte@3.55.1)(vite@4.1.4)':
'@sveltejs/kit@1.30.4(svelte@4.2.20)(vite@4.1.4)':
dependencies:
'@sveltejs/vite-plugin-svelte': 2.0.3(svelte@3.55.1)(vite@4.1.4)
'@sveltejs/vite-plugin-svelte': 2.5.3(svelte@4.2.20)(vite@4.1.4)
'@types/cookie': 0.5.1
cookie: 0.5.0
devalue: 4.3.0
devalue: 4.3.3
esm-env: 1.0.0
kleur: 4.1.5
magic-string: 0.30.0
mime: 3.0.0
magic-string: 0.30.17
mrmime: 1.0.1
sade: 1.8.1
set-cookie-parser: 2.5.1
set-cookie-parser: 2.7.1
sirv: 2.0.2
svelte: 3.55.1
svelte: 4.2.20
tiny-glob: 0.2.9
undici: 5.20.0
undici: 5.29.0
vite: 4.1.4
transitivePeerDependencies:
- supports-color
@ -1645,14 +1711,24 @@ snapshots:
dependencies:
yootils: 0.0.16
'@sveltejs/vite-plugin-svelte@2.0.3(svelte@3.55.1)(vite@4.1.4)':
'@sveltejs/vite-plugin-svelte-inspector@1.0.4(@sveltejs/vite-plugin-svelte@2.5.3(svelte@4.2.20)(vite@4.1.4))(svelte@4.2.20)(vite@4.1.4)':
dependencies:
'@sveltejs/vite-plugin-svelte': 2.5.3(svelte@4.2.20)(vite@4.1.4)
debug: 4.3.4
deepmerge: 4.3.0
svelte: 4.2.20
vite: 4.1.4
transitivePeerDependencies:
- supports-color
'@sveltejs/vite-plugin-svelte@2.5.3(svelte@4.2.20)(vite@4.1.4)':
dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 1.0.4(@sveltejs/vite-plugin-svelte@2.5.3(svelte@4.2.20)(vite@4.1.4))(svelte@4.2.20)(vite@4.1.4)
debug: 4.3.4
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.29.0
svelte: 3.55.1
svelte-hmr: 0.15.1(svelte@3.55.1)
magic-string: 0.30.17
svelte: 4.2.20
svelte-hmr: 0.15.3(svelte@4.2.20)
vite: 4.1.4
vitefu: 0.2.4(vite@4.1.4)
transitivePeerDependencies:
@ -1693,6 +1769,8 @@ snapshots:
dependencies:
'@types/ms': 0.7.31
'@types/estree@1.0.8': {}
'@types/hast@2.3.4':
dependencies:
'@types/unist': 2.0.6
@ -1742,6 +1820,8 @@ snapshots:
acorn@7.4.1: {}
acorn@8.15.0: {}
acorn@8.8.2: {}
agent-base@6.0.2:
@ -1752,6 +1832,8 @@ snapshots:
ansi-sequence-parser@1.1.0: {}
aria-query@5.3.2: {}
assert@2.0.0:
dependencies:
es6-object-assign: 1.1.0
@ -1763,6 +1845,8 @@ snapshots:
available-typed-arrays@1.0.5: {}
axobject-query@4.1.0: {}
bail@2.0.2: {}
bcp-47-match@1.0.3: {}
@ -1779,10 +1863,6 @@ snapshots:
browser-process-hrtime@1.0.0: {}
busboy@1.6.0:
dependencies:
streamsearch: 1.1.0
call-bind@1.0.2:
dependencies:
function-bind: 1.1.1
@ -1792,6 +1872,14 @@ snapshots:
character-entities@2.0.2: {}
code-red@1.0.4:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.4
'@types/estree': 1.0.8
acorn: 8.15.0
estree-walker: 3.0.3
periscopic: 3.1.0
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
@ -1806,6 +1894,11 @@ snapshots:
css-selector-parser@1.4.1: {}
css-tree@2.3.1:
dependencies:
mdn-data: 2.0.30
source-map-js: 1.0.2
cssom@0.3.8: {}
cssom@0.5.0: {}
@ -1834,6 +1927,8 @@ snapshots:
deepmerge@4.3.0: {}
deepmerge@4.3.1: {}
define-properties@1.2.0:
dependencies:
has-property-descriptors: 1.0.0
@ -1843,7 +1938,7 @@ snapshots:
dequal@2.0.3: {}
devalue@4.3.0: {}
devalue@4.3.3: {}
diff@5.1.0: {}
@ -1923,6 +2018,10 @@ snapshots:
estraverse@5.3.0: {}
estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.8
esutils@2.0.3: {}
extend@3.0.2: {}
@ -2112,6 +2211,10 @@ snapshots:
is-potential-custom-element-name@1.0.1: {}
is-reference@3.0.3:
dependencies:
'@types/estree': 1.0.8
is-typed-array@1.1.10:
dependencies:
available-typed-arrays: 1.0.5
@ -2185,6 +2288,8 @@ snapshots:
prelude-ls: 1.1.2
type-check: 0.3.2
locate-character@3.0.0: {}
lodash-es@4.17.21: {}
longest-streak@3.1.0: {}
@ -2195,13 +2300,9 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.4.14
magic-string@0.29.0:
magic-string@0.30.17:
dependencies:
'@jridgewell/sourcemap-codec': 1.4.14
magic-string@0.30.0:
dependencies:
'@jridgewell/sourcemap-codec': 1.4.14
'@jridgewell/sourcemap-codec': 1.5.4
markdown-table@3.0.3: {}
@ -2327,13 +2428,13 @@ snapshots:
dependencies:
'@types/mdast': 3.0.10
mdsvex@0.10.5(svelte@3.55.1):
mdn-data@2.0.30: {}
mdsvexrs-wasm@0.1.0: {}
mdsvexrs@0.1.2:
dependencies:
'@types/unist': 2.0.6
prism-svelte: 0.4.7
prismjs: 1.29.0
svelte: 3.55.1
vfile-message: 2.0.4
mdsvexrs-wasm: 0.1.0
merge2@1.4.1: {}
@ -2550,8 +2651,6 @@ snapshots:
dependencies:
mime-db: 1.52.0
mime@3.0.0: {}
mri@1.2.0: {}
mrmime@1.0.1: {}
@ -2594,6 +2693,12 @@ snapshots:
path-parse@1.0.7: {}
periscopic@3.1.0:
dependencies:
'@types/estree': 1.0.8
estree-walker: 3.0.3
is-reference: 3.0.3
picocolors@1.0.0: {}
picomatch@2.3.1: {}
@ -2606,10 +2711,6 @@ snapshots:
prelude-ls@1.1.2: {}
prism-svelte@0.4.7: {}
prismjs@1.29.0: {}
promise-polyfill@8.3.0: {}
property-information@5.6.0:
@ -2727,7 +2828,7 @@ snapshots:
dependencies:
xmlchars: 2.2.0
set-cookie-parser@2.5.1: {}
set-cookie-parser@2.7.1: {}
shiki@0.14.1:
dependencies:
@ -2751,13 +2852,11 @@ snapshots:
stackframe@0.3.1: {}
streamsearch@1.1.0: {}
supports-preserve-symlinks-flag@1.0.0: {}
svelte-hmr@0.15.1(svelte@3.55.1):
svelte-hmr@0.15.3(svelte@4.2.20):
dependencies:
svelte: 3.55.1
svelte: 4.2.20
svelte-sequential-preprocessor@0.0.7:
dependencies:
@ -2766,6 +2865,23 @@ snapshots:
svelte@3.55.1: {}
svelte@4.2.20:
dependencies:
'@ampproject/remapping': 2.3.0
'@jridgewell/sourcemap-codec': 1.5.4
'@jridgewell/trace-mapping': 0.3.29
'@types/estree': 1.0.8
acorn: 8.15.0
aria-query: 5.3.2
axobject-query: 4.1.0
code-red: 1.0.4
css-tree: 2.3.1
estree-walker: 3.0.3
is-reference: 3.0.3
locate-character: 3.0.0
magic-string: 0.30.17
periscopic: 3.1.0
symbol-tree@3.2.4: {}
three@0.148.0: {}
@ -2827,9 +2943,9 @@ snapshots:
dependencies:
prelude-ls: 1.1.2
undici@5.20.0:
undici@5.29.0:
dependencies:
busboy: 1.6.0
'@fastify/busboy': 2.1.1
unified@10.1.2:
dependencies:
@ -2859,10 +2975,6 @@ snapshots:
dependencies:
'@types/unist': 2.0.6
unist-util-stringify-position@2.0.3:
dependencies:
'@types/unist': 2.0.6
unist-util-stringify-position@3.0.3:
dependencies:
'@types/unist': 2.0.6
@ -2921,11 +3033,6 @@ snapshots:
kleur: 4.1.5
sade: 1.8.1
vfile-message@2.0.4:
dependencies:
'@types/unist': 2.0.6
unist-util-stringify-position: 2.0.3
vfile-message@3.1.4:
dependencies:
'@types/unist': 2.0.6
@ -2958,7 +3065,7 @@ snapshots:
fsevents: 2.3.2
vitefu@0.2.4(vite@4.1.4):
dependencies:
optionalDependencies:
vite: 4.1.4
vscode-oniguruma@1.7.0: {}

View file

@ -6,9 +6,10 @@
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="%sveltekit.assets%/global.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css">
%sveltekit.head%
</head>
<body class="dark">
<body class="dark" style="background-color: #110F1A;">
<div id="svelte">%sveltekit.body%</div>
</body>
</html>

View file

@ -1,4 +1,4 @@
<nav class="bar-component backdrop-blur">
<nav class="bar-component">
<slot />
</nav>
@ -6,13 +6,9 @@
nav {
width: calc(100% - 20px);
border-radius: 5px;
background: rgba(255,255,255, 0.2);
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
}
:global(.dark nav.bar-component) {
background: rgba(28, 28, 33, 0.2);
}
</style>

View file

@ -1,14 +1,12 @@
<script>
import Bar from "./bar.svelte";
import Split from "./split.svelte";
</script>
<div class="bottombar">
<Bar>
<h3>Daniel Bulant</h3>
<Split />
<h3>
2020-2024
2020-2025
</h3>
</Bar>
</div>
@ -26,10 +24,6 @@
.bottombar {
margin: 30px 0 0 0;
width: 100%;
background: white;
}
:global(.dark) .bottombar {
background: rgb(28, 28, 33);
}
}
.bottombar {
@ -40,12 +34,8 @@
font-weight: bold;
margin: 0;
}
:global(.dark) h3 {
color: rgb(191, 191, 191);
}
h3 {
font-size: 29px;
font-weight: 400;
color: #282B29;
}
</style>

View file

@ -13,7 +13,7 @@
});
</script>
<div class="rounded-lg bg-dark-800 text-gray-300 max-w-100 m-auto mb-5 mt-15 p-5">
<div class="rounded-lg bg-bg-code text-gray-300 max-w-100 m-auto mb-5 mt-15 p-5">
<div class="list">
<a href="https://goo.gl/maps/pM3bGyx9u5uBuqqv5" class="flex items-center justify-center w-full p-5" rel="noreferrer noopener" target="_blank">
<div class="text-gray-400 h-7 w-7">
@ -21,7 +21,7 @@
</div>
Prague, Czech Republic
</a>
<div class="profiles">
<div class="profiles max-w-80 m-auto flex flex-col">
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="https://github.com/danbulant" use:goatCounter data-goatcounter-click="contact-github" rel="me noopener" target="_blank">
<span class="platform">GitHub</span>
@ -93,9 +93,6 @@
.main {
@apply flex gap-3 pt-1 items-center;
}
.profiles {
@apply max-w-80 m-auto flex flex-col;
}
a:hover, a:active {
@apply no-underline;
}

View file

@ -11,34 +11,35 @@
onMount(() => {
let i = setInterval(() => {
current++;
if(current > 3) current = 0;
if(current > 4) current = 0;
}, 5000);
return () => clearInterval(i);
});
</script>
<div class="hero">
{#each [0, 1, 2] as i}
<div class="hero rounded-lg bg-bg-code">
<!-- {#each [0, 1, 2] as i}
<div class="{i !== 1 ? "bg" : "blur"} z-{i}">
{#if i !== 1}
<img class="bg1" style="right: {(current - 3) * 100}%;" src="/screenshots/heaventaker/heaventaker.webp" alt="">
<img class="bg2" style="right: {(current - 2) * 100}%;" src="/screenshots/animasher.webp" alt="">
<img class="bg3" style="right: {(current - 1) * 100}%;" src="/screenshots/tictactoe.png" alt="">
<img class="bg4" style="right: {(current - 0) * 100}%;" src="/screenshots/mangadex.webp" alt="">
<img class="bg1" style="right: {(current - 4) * 100}%;" src="/screenshots/heaventaker/heaventaker.webp" alt="">
<img class="bg2" style="right: {(current - 3) * 100}%;" src="/screenshots/haxagon.webp" alt="">
<img class="bg3" style="right: {(current - 2) * 100}%;" src="/screenshots/animasher.webp" alt="">
<img class="bg4" style="right: {(current - 1) * 100}%;" src="/screenshots/tictactoe.png" alt="">
<img class="bg5" style="right: {(current - 0) * 100}%;" src="/screenshots/mangadex.webp" alt="">
{/if}
</div>
{/each}
{/each} -->
<slot />
</div>
<style>
.hero {
border-radius: 5px;
background: rgba(244, 196, 196, 0.616);
/* background: rgba(244, 196, 196, 0.616); */
/* background: #100d11ab; */
position: relative;
padding: 40px 120px;
padding: 40px min(120px, 10vw);
margin: 2rem auto;
margin: 2rem auto 3rem;
max-height: 1080px;
max-width: 1500px;
}
@ -51,7 +52,7 @@
border-radius: 5px;
z-index: -1;
filter: darken(20%);
background: #F4C4C4;
background: #100d11;
overflow: hidden;
}
.bg img {

View file

@ -33,7 +33,7 @@
on:click={handle}
use:goatCounter
>
<div class="project">
<div class="project bg-bg-code rounded-lg">
<div class="imgcon">
{#if crossfadesend}
<img
@ -43,6 +43,7 @@
alt={name}
draggable={false}
class:grayscale
class:extradark
{width}
{height}
/>
@ -52,6 +53,7 @@
alt={name}
draggable={false}
class:grayscale
class:extradark
{width}
{height}
/>
@ -64,9 +66,9 @@
</div>
{/if}
</div>
<h3><slot /></h3>
<h3 class="text-xl font-normal px-4 pb-4"><slot /></h3>
{#if clickable}
<div class="clickable">Click to view details</div>
<div class="clickable px-4 pb-4">Click to view details</div>
{/if}
</div>
</a>
@ -89,6 +91,9 @@
.project:hover img {
filter: blur(35px);
}
.project:hover img.extradark {
filter: blur(35px) brightness(0.8);
}
.desc {
@apply absolute top-0 left-0 w-full h-full rounded-lg opacity-0 select-none flex flex-col py-2rem px-2rem;
transition: background-color 0.3s, opacity 0.3s;
@ -113,10 +118,10 @@
transition: filter 0.3s;
filter: blur(0px) grayscale(0);
}
img.extradark {
filter: blur(0px) grayscale(0) brightness(0.8);
}
img.grayscale {
filter: blur(0px) grayscale(100%);
}
h3 {
@apply font-normal text-xl;
}
</style>

View file

@ -7,6 +7,30 @@
<div class="projects" id="projects">
<div>
<Project
link="https://haxagon.cz"
image="/screenshots/haxagon.webp"
name="Haxagon"
width={3714}
height={2346}
>
<b>Haxagon</b> - cybersecurity and programming e-learning platform
<svelte:fragment slot="desc">
<p>
Haxagon is a platform for learning cybersecurity and programming skills.
It provides a wide range of challenges, tutorials, and resources to help users improve their skills in these areas.
</p>
<p>
I'm working on back-end including API, reactivity, permission checking and permissions. I also sometimes dabble into
front-end, my largest additions there being code and challenge editors.
</p>
<p>
I have also created multiple challenges and lessons, both into our (largest national) CTF competition as well as materials
for my previous job as a teacher at a high school.
</p>
</svelte:fragment>
</Project>
<Project
image="/screenshots/animasher.webp"
grayscale={appTypeHover && appTypeHover !== "websites"}

View file

@ -2,13 +2,8 @@
import darkmode from "$lib/stores/darkmode";
import { onMount } from "svelte";
import Button from "./button.svelte";
import Split from "./split.svelte";
import { browser } from "$app/environment";
function toggle() {
$darkmode = !$darkmode;
}
var scrollTop = 0;
onMount(() => {
@ -28,12 +23,10 @@
</script>
<nav class="bar fixed top-0 left-0 z-99 w-100vw mx-auto mb-30px"
style:background="rgba({$darkmode ? "28,28,33" : "255,255,255"}, {progress * 0.2})"
style:background="rgba({$darkmode ? "16, 13, 17" : "255,255,255"}, {progress * 0.9})"
style:backdrop-filter="blur({progress*20}px)">
<div class="subbar w-full flex items-center justify-between max-w-8xl m-auto">
<a href="/"><h3>Daniel Bulant</h3></a>
<Split />
<!-- <Button text on:click={toggle}>{$darkmode ? "Light" : "Dark"} mode</Button> -->
<div class="big">
<Button text href="/#contact" class="big">Contact</Button>
<Button text href="/notes" class="big">Notes</Button>

View file

@ -5,8 +5,8 @@
{#key url}
<div
in:fly={{ x: -5, duration: 500, delay: 500 }}
out:fly={{ x: 5, duration: 500 }}
in:fly={{ x: -2, duration: 200, delay: 200 }}
out:fly={{ x: 2, duration: 200 }}
class="absolute bg-inherit w-full"
>
<slot />

View file

@ -21,7 +21,7 @@
</script>
<!-- A simple callout with header and slot body. Header background colored according to color, and the whole callout has a left border colored as well. -->
<div class:minimal class:closed class:closable class="w-full rounded border-l border-l-4 my-6 color-shadow" style:border-left-color={color} style:--shadow-color="{color}0D">
<div class:minimal class:closed class:closable class="w-full rounded border-l border-l-4 my-6" style:border-left-color={color} style:--shadow-color="{color}0D">
<div on:click={toggle} on:keydown={toggle} class="header rounded-tr-lg" style:background-color="{color}40" class:dark-bg={isDark}>
<h1>
<slot name="title"/>
@ -30,7 +30,7 @@
<span class="toggle">{closed ? "Click to view more" : "Click to dismiss"}</span>
{/if}
</div>
<div class="content rounded-br-lg p-4 backdrop-blur -mt-1 pt-5">
<div class="content rounded-br-lg p-4 -mt-1 pt-5">
<slot />
</div>
</div>

View file

@ -1,7 +0,0 @@
<!-- Used for custom code highlight -->
{#if $$props["data-mdx-pretty-code"]}
<code data-theme={$$props["data-theme"]} style:color={$$props["data-color"]}><slot /></code>
{:else}
<code {...$$props}><slot /></code>
{/if}

View file

@ -1,7 +0,0 @@
<!-- Used for inline code highlight -->
{#if $$props["data-mdx-pretty-code"]}
<code data-theme={$$props["data-theme"]} style:color={$$props["data-color"]}><slot /></code>
{:else}
<span {...$$props}><slot /></span>
{/if}

View file

@ -1,7 +0,0 @@
<div></div>
<style>
div {
flex-grow: 1;
}
</style>

View file

@ -1,14 +1,11 @@
<script context="module">
// module context is used for when something else imports this file.
// Here, it's used to have custom components for certain elements in blog posts.
import span from "../components/posts/span.svelte";
import code from "../components/posts/code.svelte";
import a from "../components/posts/a.svelte";
export { span, code, a };
export { a };
</script>
<script>
import darkmode from "$lib/stores/darkmode";
import { DateTime } from "luxon";
export let title;
@ -167,13 +164,10 @@
@apply inline;
}
:global(body .post-layout pre) {
@apply rounded-lg bg-dark-400 p-4 my-4 max-w-full overflow-auto;
}
:global(.dark .post-layout code) {
@apply rounded-lg bg-dark-400 p-1;
@apply rounded-lg bg-bg-code p-4 my-4 max-w-full overflow-auto;
}
:global(body .post-layout code) {
@apply rounded-lg bg-dark-400/03 p-1 transition-colors duration-300;
@apply rounded-lg bg-bg-code transition-colors duration-300;
}
:global(body .post-layout ul) {
@apply list-disc mx-4;

View file

@ -10,18 +10,18 @@ import { writable } from "svelte/store";
// );
const darkmode = writable(true)
darkmode.subscribe(v => {
if(typeof window !== "undefined")
localStorage.setItem("darkmode", JSON.stringify(v));
// darkmode.subscribe(v => {
// if(typeof window !== "undefined")
// localStorage.setItem("darkmode", JSON.stringify(v));
if(typeof document !== "undefined") {
if(v) {
document.body.classList.add("dark");
} else {
document.body.classList.remove("dark");
}
}
});
// if(typeof document !== "undefined") {
// if(v) {
// document.body.classList.add("dark");
// } else {
// document.body.classList.remove("dark");
// }
// }
// });
export default darkmode;

View file

@ -20,7 +20,7 @@
<Navbar />
{#if $navigating}
<div transition:fly={{ duration: 200, opacity: 0, y: -20 }} class="spinner-container">
<div transition:fly={{ duration: 200, delay: 100, opacity: 0, y: -20 }} class="spinner-container">
<Spinner />
</div>
{/if}

View file

@ -34,9 +34,7 @@
<main>
<Hero {appTypeHover}>
<h1 class="font-bold">I'm making <b on:mouseenter={() => appTypeHover = "websites"} on:mouseleave={() => appTypeHover === "websites" && (appTypeHover = null)}>websites</b>,
<b on:mouseenter={() => appTypeHover = "applications"} on:mouseleave={() => appTypeHover === "applications" && (appTypeHover = null)}>mobile applications</b> and
<b on:mouseenter={() => appTypeHover = "websites"} on:mouseleave={() => appTypeHover === "website" && (appTypeHover = null)}>online games</b>.</h1>
<h1 class="font-bold text-white text-6xl">Full-stack developer and cybersecurity enthusiast.</h1>
<!-- <h3>To be used later</h3> -->
<div class="flex gap-4">
<Button blur class="!p-4" href="#contact">Send me a message</Button>
@ -72,18 +70,10 @@
<Bottombar />
<style>
img.white {
background: white;
border-radius: 50%;
}
main {
margin: 0 min(50px, 5%) 0 min(50px, 5%);
width: calc(100% - min(100px, 10%));
}
h1 {
color: #282B29;
font-size: 64px;
}
@media (max-width: 1100px) {
h1 {
font-size: 40px;

View file

@ -1,3 +1,4 @@
import { error } from "@sveltejs/kit";
import { json } from "@sveltejs/kit";
function loadAll(files) {
@ -18,15 +19,29 @@ function loadAll(files) {
* @type {import("@sveltejs/kit").RequestHandler}
*/
export async function GET(req) {
const allPostFiles = import.meta.glob('../../posts/**/*.md');
const allNotesFiles = import.meta.glob('../../notes/**/*.md');
const allPosts = (await loadAll(allPostFiles)).filter(t => !t.draft);
const allNotes = (await loadAll(allNotesFiles));
allPosts.sort((a, b) => {
return new Date(b.date) - new Date(a.date)
});
let allPosts = [];
let allNotes = [];
try {
const allPostFiles = import.meta.glob('../../posts/**/*.md');
const allNotesFiles = import.meta.glob('../../notes/**/*.md');
allPosts = (await loadAll(allPostFiles)).filter(t => !t.draft);
allNotes = (await loadAll(allNotesFiles));
allPosts.sort((a, b) => {
return new Date(b.date) - new Date(a.date)
});
allNotes.sort((a, b) => {
return new Date(b.date) - new Date(a.date)
});
} catch (e) {
console.error("Error loading posts or notes:", e);
return json({
message: "Failed to load posts or notes."
}, {
status: 500
})
}
return json({
posts: allPosts.filter(t => new Date(t.date) < Date.now()),

View file

@ -4,7 +4,8 @@ import { error } from '@sveltejs/kit';
export async function load({ fetch }) {
const response = await fetch("/api/posts.json");
if(!response.ok) {
throw error(response.statusText, response.status);
console.log(response)
throw error(response.status, await response.text());
}
return response.json();

View file

@ -6,7 +6,7 @@ date: 2025-07-06
Using spread operator within react with untrusted user input is a recipe for XSS; embedding raw HTML into website.
React supports embedding raw HTML via an attribute called `dangerouslySetInnerHTML.__html`.
React supports embedding raw HTML via an attribute called `dangerouslySetInnerHTML.__html{:jsx}`.
```jsx
return (
@ -14,7 +14,7 @@ return (
)
```
Which is different from how for example svelte handles it - by using a different tag / template (the equivalent would be `<p>{@html "..."}</p>`).
Which is different from how for example svelte handles it - by using a different tag / template (the equivalent would be `<p>{@html "..."}</p>{:jsx}`).
JSX supports spread operators just like any JS object, as it creates one under the hood anyway.
Which is nice for passing props to another component:
@ -59,8 +59,8 @@ function Component({ props, key }) {
}
```
The above app is vulnerable, because the latter spread operator can override `props`, which is then spreaded `div`.
This would be safe - if buggy - if all we could do is set `props` to a string value.
The above app is vulnerable, because the latter spread operator can override `props{:jsx}`, which is then spreaded `div`.
This would be safe - if buggy - if all we could do is set `props{:jsx}` to a string value.
But `qs` also parses objects. So you're just one `?props[dangerouslySetInnerHTML][__html]="<b>pwned</b>"` away from danger.
But `qs{:jsx}` also parses objects. So you're just one `?props[dangerouslySetInnerHTML][__html]="<b>pwned</b>"` away from danger.
Check your vibe coded apps, and perhaps choose technologies with sane & safe defaults.

View file

@ -12,48 +12,29 @@ description: Rust is a fast memory-safe low level programming language. And here
<script>
import Callout from "$lib/components/posts/callout.svelte";
import { browser } from "$app/environment";
var story = true;
</script>
{#if browser}
*I seem to like storytelling a bit too much.*
<div style="display: flex; align-items: center;">
<label for="enable_story" style="padding-right: 10px">Enable story</label>
<input type="checkbox" style="padding: 0; margin: 0;" bind:checked={story} id="enable_story">
</div>
{/if}
> I really do enjoy reading blog posts like these, so I figured I'd try writing few of my own as well. I hope you'll enjoy it, if so, leave a comment below.
{#if story}
I first started programming with PHP. Some of it's syntax felt clunky and unnatural, sometimes plainly annoying (why do I have to prefix each variable with `$` when it understands constants without `$` just fine?). I don't really like the language now after learning other languages, but I do like some parts of it, like how it's easy to loop over an array or that it has multiple programming paradigms, from functional to OOP to traits (which I learnt about much later after I stopped using PHP).
I first started programming with PHP. Some of it's syntax felt clunky and unnatural, sometimes plainly annoying (why do I have to prefix each variable with `$` when it understands constants without `$` just fine?). I don't really like the language now after learning other languages, but I do like some parts of it, like how it's easy to loop over an array or that it has multiple programming paradigms, from functional to OOP to traits (which I learnt about much later after I stopped using PHP).
I later moved to JS which looked a lot like C, which I saw everywhere.
I later moved to JS which looked a lot like C, which I saw everywhere.
I also did few projects with Java and C#, but I always returned to JS afterwards.
I also did few projects with Java and C#, but I always returned to JS afterwards.
I also tried learning C (and C++), and although I did have a certificate about both of them on Sololearn (I no longer have the C++ one as they added new lessons), I never really used them outside, as everything seemed way to complicated.
I also tried learning C (and C++), and although I did have a certificate about both of them on Sololearn (I no longer have the C++ one as they added new lessons), I never really used them outside, as everything seemed way to complicated.
Fast RAM access is cool and all, but why do I have to use `free`? Why can't it know that if I go outside the scope it should free the memory?
Fast RAM access is cool and all, but why do I have to use `free{:c}`? Why can't it know that if I go outside the scope it should free the memory?
So I always went just back to programming in JS where I didn't have to think about memory. And IO-bound stuff isn't really slowed down by V8 now anyway.
{/if}
So I always went just back to programming in JS where I didn't have to think about memory. And IO-bound stuff isn't really slowed down by V8 now anyway.
## Actually learning Rust
{#if story}
Then I heard about this small language developed by Mozilla, which won StackOverflow's most loved language for multiple years, even surpassing Typescript which I loved for it's type-safety (`Hello undefined! Goodbye null`). So I figured I'd give it a try.
{/if}
Then I heard about this small language developed by Mozilla, which won StackOverflow's most loved language for multiple years, even surpassing Typescript which I loved for it's type-safety (`Hello undefined! Goodbye null`). So I figured I'd give it a try.
### Resources
{#if story}
One of the things I had problems with was finding good resources that are easy to understand and short. I don't like youtube videos, I'd much rather read a content I can quickly skim, or read on my way without eating up my limited data plan.
{/if}
One of the things I had problems with was finding good resources that are easy to understand and short. I don't like youtube videos, I'd much rather read a content I can quickly skim, or read on my way without eating up my limited data plan.
Here's a list of resources I found useful:
- [rust book](https://doc.rust-lang.org/book/) - an online book with short chapters about common things people want to do with Rust
@ -245,14 +226,14 @@ An interesting quirk is that you can use `(){:rust}` (empty tuple) to return "vo
#### Common structs
##### Option&amp;lt;T&amp;gt;
##### Option&lt;T>
Is an enum (we'll get to how `enum{:rust}`s work later. They're kind of different from other languages) with either **`Some(T){:rust}` or `None{:rust}`** values.
To get the value, you can use **[`match{:rust}`](#match)** like with other enums, or use **`.unwrap(){:rust}`** (which will panic if it's `None{:rust}`).
See also [Declaring enums](#declaring-enums).
##### Result&amp;lt;T, E&amp;gt;
##### Result&lt;T, E>
Similar to `Option{:rust}`, but used to handle errors (commonly returned by <abbr title="Input Output">IO</abbr> methods).
It's values are either `Ok(T){:rust}` or `Err(E){:rust}`.
@ -269,7 +250,7 @@ fn example() -> Result<(), Error> { // An Error type. For simplicity, you can us
If a function can error out, use `Result{:rust}` instead of `panic{:rust}`s - `panic{:rust}` cannot be easily handled and should only be used for catastrophic irrecoverable errors (or when your too lazy to implement proper error handling using `Result{:rust}` for pet projects).
##### Vec&amp;lt;T&amp;gt;
##### Vec&lt;T&gt;
`Vec{:rust}`tors are growable arrays whose values are stored on the heap.
@ -279,7 +260,7 @@ Javascript arrays behave sort of like `Vec{:rust}` - they have a set limit, and
`Vec` stores it's current size, it's reserved size, and an array of pointers to `Box{:rust}`ed values. Meaning, there's no need (and in fact hurts performance) to do `Vec<Box<T>>{:rust}`.
##### Box&amp;lt;T&amp;gt;
##### Box&lt;T&gt;
Stores `T` on heap. Useful for using [`enum`s](#declaring-enums) in structs, or to free up stack space.
@ -312,7 +293,7 @@ struct Something = u8; // a single value
```
As stated earlier, `struct` **sizes are static**. This means you cannot use [`enum{:rust}`s](#declaring-enums) with self-referencing (recursive) values directly in `struct{:rust}`s.
One of possible ``workarounds'' is to use the [heap](#heap-vs-stack) for actually storing the values, for example by using [Box&amp;lt;T&amp;gt;](#boxlttgt).
One of possible ``workarounds'' is to use the [heap](#heap-vs-stack) for actually storing the values, for example by using [Box&lt;T&gt;](#boxlttgt).
```rust
struct Something {
@ -331,10 +312,7 @@ struct MaybeRecursive {
}
```
{#if story}
This is something I hit when trying to create an abstract syntax tree for my shell.
{/if}
This is something I hit when trying to create an abstract syntax tree for my shell.
To instantiate the struct, use the following notation (kind of similar to defining arrays in <abbr title="See sharp">C#</abbr>):
@ -782,6 +760,6 @@ let var = "something";
---
Thanks for reading this {story ? "little story (with some documentation)" : "post"}. Hope that you learned something (which I did, even during writing of this post).
Thanks for reading this post. Hope that you learned something (which I did, even during writing of this post).
*no crabs were harmed in the making of this post. I'm not affiliated with any of the mentioned products or companies.*

View file

@ -47,15 +47,16 @@ pnpm init svelte@next
```
<Callout color="#139ab4" closed minimal>
<span slot="title">
<span slot="title">
*(side note: I'm using [pnpm](https://pnpm.io) as it's a faster alternative to npm which also saves disk space)*
</span>
*(side note: I'm using [pnpm](https://pnpm.io) as it's a faster alternative to npm which also saves disk space)*
</span>
[pnpm](https://pnpm.io) uses [symlinks](https://en.wikipedia.org/wiki/Symbolic_link) to store each dependency exactly once on disk
(symlinks, symbolic links, are a sort of alias to files), which makes it use less storage. In addition, it's faster and has better
monorepo support.
[pnpm](https://pnpm.io) uses [symlinks](https://en.wikipedia.org/wiki/Symbolic_link) to store each dependency exactly once on disk
(symlinks, symbolic links, are a sort of alias to files), which makes it use less storage. In addition, it's faster and has better
monorepo support.
</Callout>
This creates a new [Svelte Kit](https://kit.svelte.dev) project, by first asking for configuration (i.e. if you want typescript, ESLint and/or prettifier) and then initalizing from a template.
@ -98,7 +99,7 @@ An example component:
As you can see, little code is needed to achieve simple synchronization between text input, variable and title.
The `bind:` feels almost like magic. Coming from React's `onValueChanged={(value) => this.setState({ value })}`, I immediately fell in love and stopped using React. Now React feels kind of clunky in comparison to me.
The `bind:` feels almost like magic. Coming from React's `onValueChanged={(value) => this.setState({ value })}{:js}`, I immediately fell in love and stopped using React. Now React feels kind of clunky in comparison.
Another part of the `bind:` directive is that it's bi-directional - `input` doesn't have sole ownership of it, and will change it's contents when `name` changes outside of it, like so:
@ -120,7 +121,7 @@ I personally always prefer dark mode, but I know many people that like light mod
You can try toggling to {$darkmode ? "light" : "dark"} mode using the button on the navigation bar in top right, or using this:
<Button text on:click={() => $darkmode = !$darkmode}>{$darkmode ? "Light" : "Dark"} mode</Button>
<Button text on:click="{() => $darkmode = !$darkmode}">{$darkmode ? "Light" : "Dark"} mode</Button>
Instead of writing how to use Svelte here, **I'd recommend trying their excellent interactive tutorial [here](https://svelte.dev/tutorial)**.

View file

@ -10,16 +10,15 @@ html, body {
}
body {
color: #333;
/* color: #333; */
margin: 0;
box-sizing: border-box;
font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
transition: color .3s, background-color .3s;
background-color: #110F1A;
color: rgb(191, 191, 191) !important;
}
body.dark {
background-color: #1f1f1f;
color: rgb(191, 191, 191);
}
h1 {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View file

@ -1,14 +1,5 @@
import adapter from '@sveltejs/adapter-static';
import { mdsvex } from 'mdsvex';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import rehypeSlug from 'rehype-slug';
import remarkMath from 'remark-math';
import remarkTwemoji from 'remark-twemoji';
import remarkGfm from 'remark-gfm';
import remarkExtendedTable from 'remark-extended-table';
import rehypeKatexSvelte from "rehype-katex-svelte";
import { prettyCode } from './remark/code.js';
import { rehypeEscapeHighlight, remarkEscapeInlineCode, remarkUnescapeHighlight } from './remark/unescapehighlight.js';
import { mdsvexrs } from 'mdsvexrs'
/** @type {import('@sveltejs/kit').Config} */
const config = {
@ -24,32 +15,7 @@ const config = {
extensions: ['.svelte', '.md'],
preprocess: [
mdsvex({
extensions: ['.md'],
layout: {
_: "./src/lib/layouts/post.svelte"
},
smartypants: {
quotes: false,
backticks: "all"
},
highlight: false,
rehypePlugins: [
rehypeSlug,
rehypeAutolinkHeadings,
rehypeKatexSvelte,
rehypeEscapeHighlight
],
remarkPlugins: [
remarkGfm,
remarkMath,
remarkTwemoji,
remarkExtendedTable,
remarkUnescapeHighlight,
prettyCode,
remarkEscapeInlineCode
]
})
mdsvexrs({ layout: "$lib/layouts/post.svelte", customTags: ['a'] })
]
};

View file

@ -7,7 +7,15 @@ export default defineConfig({
extend: {
colors: {
github: "#fafafa",
discord: "#7289da"
discord: "#7289da",
'primary-dark': '#242038',
primary: '#9067C6',
bg: '#110F1A',
'bg-code': '#100d11',
success: '#7CEEC8'
},
fontFamily: {
mono: "'Fira Code VF', 'Fira Code', monospace"
}
}
},