completed up till skills section
4
.prettierrc
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"plugins": ["prettier-plugin-svelte", "prettier-plugin-astro"],
|
||||||
|
"tabWidth": 4
|
||||||
|
}
|
||||||
6
.vscode/settings.json
vendored
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"prettier.documentSelectors": ["**/*.astro"],
|
|
||||||
"[astro]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from "astro/config";
|
||||||
|
|
||||||
import tailwind from "@astrojs/tailwind";
|
import tailwind from "@astrojs/tailwind";
|
||||||
import svelte from "@astrojs/svelte";
|
import svelte from "@astrojs/svelte";
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [tailwind(), svelte()]
|
integrations: [tailwind(), svelte()],
|
||||||
|
server: {
|
||||||
|
port: 8008,
|
||||||
|
hostname: "RythonDev",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
13
package-lock.json
generated
|
|
@ -16,7 +16,8 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.0.3",
|
||||||
"prettier-plugin-astro": "^0.12.0"
|
"prettier-plugin-astro": "^0.12.0",
|
||||||
|
"prettier-plugin-svelte": "^3.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@alloc/quick-lru": {
|
"node_modules/@alloc/quick-lru": {
|
||||||
|
|
@ -4653,6 +4654,16 @@
|
||||||
"integrity": "sha512-o/ObKgtMzl8SlpIdzaxFnt7SATKPxu4oIP/1NL+HDJRzxfJcAkOTAb/ZKMRyULbz4q+1t2/DAebs2Z1QairkZw==",
|
"integrity": "sha512-o/ObKgtMzl8SlpIdzaxFnt7SATKPxu4oIP/1NL+HDJRzxfJcAkOTAb/ZKMRyULbz4q+1t2/DAebs2Z1QairkZw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/prettier-plugin-svelte": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-dLhieh4obJEK1hnZ6koxF+tMUrZbV5YGvRpf2+OADyanjya5j0z1Llo8iGwiHmFWZVG/hLEw/AJD5chXd9r3XA==",
|
||||||
|
"dev": true,
|
||||||
|
"peerDependencies": {
|
||||||
|
"prettier": "^3.0.0",
|
||||||
|
"svelte": "^3.2.0 || ^4.0.0-next.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prismjs": {
|
"node_modules/prismjs": {
|
||||||
"version": "1.29.0",
|
"version": "1.29.0",
|
||||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
|
||||||
|
|
|
||||||
43
package.json
|
|
@ -1,23 +1,24 @@
|
||||||
{
|
{
|
||||||
"name": "dev-portfolio",
|
"name": "dev-portfolio",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"start": "astro dev",
|
"start": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/svelte": "^4.0.2",
|
"@astrojs/svelte": "^4.0.2",
|
||||||
"@astrojs/tailwind": "^5.0.0",
|
"@astrojs/tailwind": "^5.0.0",
|
||||||
"astro": "^3.2.0",
|
"astro": "^3.2.0",
|
||||||
"svelte": "^4.2.1",
|
"svelte": "^4.2.1",
|
||||||
"tailwindcss": "^3.3.3"
|
"tailwindcss": "^3.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.0.3",
|
||||||
"prettier-plugin-astro": "^0.12.0"
|
"prettier-plugin-astro": "^0.12.0",
|
||||||
}
|
"prettier-plugin-svelte": "^3.0.3"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
public/images/logo_circle.webp
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
public/images/pfp-862x1078.webp
Normal file
|
After Width: | Height: | Size: 654 KiB |
BIN
public/images/pfp-square.webp
Normal file
|
After Width: | Height: | Size: 574 KiB |
BIN
public/images/projects/coworking-guide.webp
Normal file
|
After Width: | Height: | Size: 160 KiB |
45
public/images/socials/codepen.svg
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="31.665px" height="31.665px" viewBox="0 0 31.665 31.665" fill="#000" style="enable-background:new 0 0 31.665 31.665;"
|
||||||
|
xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path d="M16.878,0.415c-0.854-0.565-1.968-0.552-2.809,0.034L1.485,9.214c-0.671,0.468-1.071,1.233-1.071,2.052v9.444
|
||||||
|
c0,0.84,0.421,1.623,1.122,2.086l12.79,8.455c0.836,0.553,1.922,0.553,2.758,0l13.044-8.618c0.7-0.463,1.122-1.246,1.122-2.086
|
||||||
|
v-9.279c0-0.839-0.421-1.622-1.121-2.085L16.878,0.415z M26.621,10.645l-4.821,3.237l-4.521-3.288L17.25,4.127L26.621,10.645z
|
||||||
|
M13.979,4.133v6.329l-4.633,3.24l-4.621-3.099L13.979,4.133z M3.458,13.722l2.991,2.004l-2.991,2.093V13.722z M14.058,27.215
|
||||||
|
l-9.331-6.258l4.661-3.258l4.67,3.133V27.215z M12.286,15.674l3.021-2.113l3.519,2.313l-3.119,2.095L12.286,15.674z M17.354,27.215
|
||||||
|
V20.83l4.463-2.991l4.805,3.159L17.354,27.215z M27.954,17.927l-3.168-2.082l3.168-2.125V17.927z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
47
public/images/socials/email.svg
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 483.3 483.3" fill="#007BFF" style="enable-background:new 0 0 483.3 483.3;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M424.3,57.75H59.1c-32.6,0-59.1,26.5-59.1,59.1v249.6c0,32.6,26.5,59.1,59.1,59.1h365.1c32.6,0,59.1-26.5,59.1-59.1
|
||||||
|
v-249.5C483.4,84.35,456.9,57.75,424.3,57.75z M456.4,366.45c0,17.7-14.4,32.1-32.1,32.1H59.1c-17.7,0-32.1-14.4-32.1-32.1v-249.5
|
||||||
|
c0-17.7,14.4-32.1,32.1-32.1h365.1c17.7,0,32.1,14.4,32.1,32.1v249.5H456.4z"/>
|
||||||
|
<path d="M304.8,238.55l118.2-106c5.5-5,6-13.5,1-19.1c-5-5.5-13.5-6-19.1-1l-163,146.3l-31.8-28.4c-0.1-0.1-0.2-0.2-0.2-0.3
|
||||||
|
c-0.7-0.7-1.4-1.3-2.2-1.9L78.3,112.35c-5.6-5-14.1-4.5-19.1,1.1c-5,5.6-4.5,14.1,1.1,19.1l119.6,106.9L60.8,350.95
|
||||||
|
c-5.4,5.1-5.7,13.6-0.6,19.1c2.7,2.8,6.3,4.3,9.9,4.3c3.3,0,6.6-1.2,9.2-3.6l120.9-113.1l32.8,29.3c2.6,2.3,5.8,3.4,9,3.4
|
||||||
|
c3.2,0,6.5-1.2,9-3.5l33.7-30.2l120.2,114.2c2.6,2.5,6,3.7,9.3,3.7c3.6,0,7.1-1.4,9.8-4.2c5.1-5.4,4.9-14-0.5-19.1L304.8,238.55z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
5
public/images/socials/github.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
|
<title>github</title>
|
||||||
|
<path d="M0 15.968q0-3.264 1.28-6.208 2.528-5.952 8.48-8.48 2.944-1.28 6.208-1.28t6.208 1.28q5.888 2.496 8.48 8.48 1.28 3.040 1.28 6.208t-1.28 6.208q-2.592 6.016-8.48 8.544-2.944 1.28-6.208 1.28t-6.208-1.28q-5.952-2.56-8.48-8.544-1.28-2.944-1.28-6.208zM2.496 15.968q0 4.512 2.688 8.064 2.656 3.488 6.944 4.96v-2.56q0-1.92 1.28-2.784-0.64-0.032-1.504-0.224-1.632-0.288-2.784-1.024-2.912-1.76-2.912-6.368 0-2.4 1.6-4.096-0.736-1.888 0.16-4.096h0.64q0.32 0 0.8 0.16 1.248 0.384 2.784 1.408 1.952-0.512 3.84-0.512t3.872 0.512q1.248-0.832 2.336-1.28 1.024-0.384 1.472-0.32l0.384 0.032q0.864 2.208 0.16 4.096 1.6 1.696 1.6 4.096 0 3.584-1.76 5.408-0.96 1.024-2.528 1.6-1.312 0.48-2.912 0.608 1.312 0.928 1.312 2.784v2.56q4.128-1.472 6.816-5.024 2.624-3.52 2.624-8 0-2.72-1.056-5.248-1.024-2.432-2.88-4.288-1.792-1.792-4.288-2.848-2.56-1.088-5.216-1.088-2.624 0-5.248 1.088-2.4 1.024-4.288 2.848-1.792 1.856-2.88 4.288-1.056 2.528-1.056 5.248z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
47
public/images/socials/linkedin.svg
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="430.117px" height="430.118px" viewBox="0 0 430.117 430.118" fill="#007BFF" style="enable-background:new 0 0 430.117 430.118;"
|
||||||
|
xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path id="LinkedIn__x28_alt_x29_" d="M398.355,0H31.782C14.229,0,0.002,13.793,0.002,30.817v368.471
|
||||||
|
c0,17.025,14.232,30.83,31.78,30.83h366.573c17.549,0,31.76-13.814,31.76-30.83V30.817C430.115,13.798,415.904,0,398.355,0z
|
||||||
|
M130.4,360.038H65.413V165.845H130.4V360.038z M97.913,139.315h-0.437c-21.793,0-35.92-14.904-35.92-33.563
|
||||||
|
c0-19.035,14.542-33.535,36.767-33.535c22.227,0,35.899,14.496,36.331,33.535C134.654,124.415,120.555,139.315,97.913,139.315z
|
||||||
|
M364.659,360.038h-64.966V256.138c0-26.107-9.413-43.921-32.907-43.921c-17.973,0-28.642,12.018-33.327,23.621
|
||||||
|
c-1.736,4.144-2.166,9.94-2.166,15.728v108.468h-64.954c0,0,0.85-175.979,0-194.192h64.964v27.531
|
||||||
|
c8.624-13.229,24.035-32.1,58.534-32.1c42.76,0,74.822,27.739,74.822,87.414V360.038z M230.883,193.99
|
||||||
|
c0.111-0.182,0.266-0.401,0.42-0.614v0.614H230.883z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
5
public/images/socials/twitch.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 32 32">
|
||||||
|
<title>twitch</title>
|
||||||
|
<path d="M3.421 0.75l-1.988 5.305v21.217h7.29v3.978h3.98l3.975-3.98h5.967l7.955-7.953v-18.567h-27.177zM6.070 3.4h21.878v14.589l-4.642 4.642h-7.291l-3.975 3.975v-3.975h-5.97v-19.23zM13.366 16.663h2.65v-7.955h-2.65v7.955zM20.655 16.663h2.65v-7.955h-2.65v7.955z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 428 B |
5
public/images/socials/youtube.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
|
<title>youtube</title>
|
||||||
|
<path d="M23.2 6.937c1.428 0.144 3.285 0 4.285 1.144 1.143 1.143 1.287 2.999 1.287 4.428 0.142 1.714 0.142 4.144 0.142 5.713-0.142 1.573 0 3.428-0.716 4.859-0.712 1.569-1.999 2.143-3.57 2.284-1.716 0.142-12.286 0.142-15.713 0-1.572-0.142-3.429-0.142-4.572-1.428-1-1.144-1-2.857-1.143-4.285 0-1.715 0-4.144 0-5.857 0-1.572 0-3.428 0.714-4.857 0.715-1.428 2.143-1.714 3.714-1.856 1.714-0.144 12.141-0.286 15.571-0.144zM13.2 11.794v8.57l7.857-4.285-7.857-4.285z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 629 B |
|
|
@ -1,61 +1,62 @@
|
||||||
---
|
---
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
primaryColor: string;
|
||||||
body: string;
|
bgColor: string;
|
||||||
href: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { href, title, body } = Astro.props;
|
const { primaryColor, bgColor = "#282828" } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<li class="link-card">
|
<div class="card">
|
||||||
<a href={href}>
|
<slot />
|
||||||
<h2>
|
</div>
|
||||||
{title}
|
|
||||||
<span>→</span>
|
<style define:vars={{ primaryColor, bgColor }}>
|
||||||
</h2>
|
* {
|
||||||
<p>
|
box-sizing: border-box;
|
||||||
{body}
|
}
|
||||||
</p>
|
|
||||||
</a>
|
h1,
|
||||||
</li>
|
h2,
|
||||||
<style>
|
h3,
|
||||||
.link-card {
|
p {
|
||||||
list-style: none;
|
margin: 0rem;
|
||||||
display: flex;
|
}
|
||||||
padding: 1px;
|
|
||||||
background-color: #23262d;
|
.card {
|
||||||
background-image: none;
|
height: inherit;
|
||||||
background-size: 400%;
|
position: relative;
|
||||||
border-radius: 7px;
|
background-color: var(--bgColor);
|
||||||
background-position: 100%;
|
border: 1px solid rgb(255 255 255 / 5%);
|
||||||
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
border-radius: 1.5rem;
|
||||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
|
padding: 0.5rem;
|
||||||
}
|
}
|
||||||
.link-card > a {
|
|
||||||
width: 100%;
|
.card:after {
|
||||||
text-decoration: none;
|
content: "";
|
||||||
line-height: 1.4;
|
height: 70px;
|
||||||
padding: calc(1.5rem - 1px);
|
width: 1px;
|
||||||
border-radius: 8px;
|
position: absolute;
|
||||||
color: white;
|
left: -1px;
|
||||||
background-color: #23262d;
|
top: 65%;
|
||||||
opacity: 0.8;
|
transition: top, opacity;
|
||||||
}
|
transition-duration: 600ms;
|
||||||
h2 {
|
transition-timing-function: ease;
|
||||||
margin: 0;
|
background: linear-gradient(
|
||||||
font-size: 1.25rem;
|
transparent,
|
||||||
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
var(--primaryColor),
|
||||||
}
|
transparent
|
||||||
p {
|
);
|
||||||
margin-top: 0.5rem;
|
opacity: 0;
|
||||||
margin-bottom: 0;
|
}
|
||||||
}
|
|
||||||
.link-card:is(:hover, :focus-within) {
|
.card:after {
|
||||||
background-position: 0;
|
top: 65%;
|
||||||
background-image: var(--accent-gradient);
|
opacity: 0;
|
||||||
}
|
}
|
||||||
.link-card:is(:hover, :focus-within) h2 {
|
|
||||||
color: rgb(var(--accent-light));
|
.card:hover:after {
|
||||||
}
|
top: 25%;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
61
src/components/Education.astro
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
import Card from "./Card.astro";
|
||||||
|
import Line from "./NetworkLine.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
<div id="Experience" class="h-fit py-10">
|
||||||
|
<h1 class="text-5xl text-center">Education</h1>
|
||||||
|
<div class="flex flex-col items-center pt-10">
|
||||||
|
<div class="w-[90%] md:w-[500px]">
|
||||||
|
<Card primaryColor="#fff">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="flex flex-col justify-left w-full mb-3">
|
||||||
|
<h2 class="font-bold text-xl">
|
||||||
|
Diploma in Computer Science
|
||||||
|
</h2><h3>Jan 2022 - Present</h3>
|
||||||
|
</div>
|
||||||
|
<hr class="w-full mb-3" />
|
||||||
|
<h3 class="mb-1 font-bold text-lg">Achievements</h3>
|
||||||
|
<ul class="list-disc list-inside">
|
||||||
|
<li>3-time Dean's List recipient</li>
|
||||||
|
<li>President of Computer Programming Club</li>
|
||||||
|
<li>Vice President of Diploma Union</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
<Line height="100px" />
|
||||||
|
<Card primaryColor="#fff">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="flex flex-col justify-left w-full mb-3">
|
||||||
|
<h2 class="font-bold text-xl">Cambridge IGCSE</h2><h3>
|
||||||
|
Sep 2016 - June 2021
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<hr class="w-full mb-3" />
|
||||||
|
<h3 class="mb-1 font-bold text-lg">Achievements</h3>
|
||||||
|
<ul class="list-disc list-inside">
|
||||||
|
<li>IGCSE 5 A*s, 3 A's</li>
|
||||||
|
<li>President of Technology Society</li>
|
||||||
|
<li>Technology Manager of Prefects' Board</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.card-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-image: radial-gradient(
|
||||||
|
rgba(255, 255, 255, 0.1) 1px,
|
||||||
|
transparent 1px
|
||||||
|
);
|
||||||
|
background-position: 50% 50%;
|
||||||
|
background-size: 1.1rem 1.1rem;
|
||||||
|
padding: 2rem 2rem;
|
||||||
|
border-radius: 1.25rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,19 +1,195 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
// Greeting
|
||||||
|
let date = new Date();
|
||||||
|
let hour = date.getHours();
|
||||||
|
|
||||||
|
let greeting: string = "";
|
||||||
|
|
||||||
|
if (hour >= 0 && hour < 12) {
|
||||||
|
greeting = "morning";
|
||||||
|
} else if (hour >= 12 && hour < 18) {
|
||||||
|
greeting = "afternoon";
|
||||||
|
} else if (hour >= 18) {
|
||||||
|
greeting = "evening";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intro
|
||||||
|
let intro1: string = "I like to make cool stuff";
|
||||||
|
let intro2: string = "as a ";
|
||||||
|
let introState1: string = "";
|
||||||
|
let introState2: string = "";
|
||||||
|
let lineOneFinished: boolean = false;
|
||||||
|
|
||||||
|
async function animateIntro(interval: number) {
|
||||||
|
for (let i = 0; i < intro1.length; i++) {
|
||||||
|
introState1 += intro1[i];
|
||||||
|
await sleep(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
lineOneFinished = true;
|
||||||
|
|
||||||
|
for (let j = 0; j < intro2.length; j++) {
|
||||||
|
introState2 += intro2[j];
|
||||||
|
await sleep(interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Roles
|
||||||
|
let roles: string[] = [
|
||||||
|
"developer",
|
||||||
|
"streamer",
|
||||||
|
"content creator",
|
||||||
|
"student",
|
||||||
|
];
|
||||||
|
let roleState: string = "";
|
||||||
|
let role: string;
|
||||||
|
let counter: number = 0;
|
||||||
|
let roleEmpty: boolean = true;
|
||||||
|
const roleInterval: number = 50;
|
||||||
|
const roleUpdateDelay: number = 2000; // delay after updating
|
||||||
|
const roleRemoveDelay: number = 500; // delay after removing
|
||||||
|
|
||||||
|
// Intro animation
|
||||||
|
function removeLastCharacter(str: string) {
|
||||||
|
return str.slice(0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCharacter(str1: string, str2: string) {
|
||||||
|
// str1: incomplete string, add a character after this
|
||||||
|
// str2: complete string, add a character from this
|
||||||
|
|
||||||
|
let str1Length = str1.length;
|
||||||
|
let str2Length = str2.length;
|
||||||
|
|
||||||
|
if (str1Length < str2Length) {
|
||||||
|
return str1 + str2[str1Length];
|
||||||
|
} else {
|
||||||
|
return str1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sleep(ms: number) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function animateRoles() {
|
||||||
|
role = roles[counter];
|
||||||
|
|
||||||
|
if (roleEmpty) {
|
||||||
|
for (let i = 0; i < role.length; i++) {
|
||||||
|
roleState = addCharacter(roleState, role);
|
||||||
|
await sleep(roleInterval);
|
||||||
|
}
|
||||||
|
await sleep(roleUpdateDelay);
|
||||||
|
roleEmpty = false;
|
||||||
|
|
||||||
|
animateRoles();
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < role.length; i++) {
|
||||||
|
roleState = removeLastCharacter(roleState);
|
||||||
|
await sleep(roleInterval);
|
||||||
|
}
|
||||||
|
await sleep(roleRemoveDelay);
|
||||||
|
if (counter < roles.length - 1) {
|
||||||
|
counter++;
|
||||||
|
} else {
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
roleEmpty = true;
|
||||||
|
animateRoles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// after window finish loading, call animateRoles()
|
||||||
|
onMount(async () => {
|
||||||
|
await sleep(800);
|
||||||
|
await animateIntro(50);
|
||||||
|
animateRoles();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="w-full h-[90vh] text-white flex justify-center items-center">
|
<div
|
||||||
<div class="w-4/5 flex flex-row">
|
id="intro"
|
||||||
<div class="text-4xl flex flex-col">
|
class="w-full h-[105vh]
|
||||||
<p>
|
text-white
|
||||||
Nice to meet you, I am
|
flex justify-center items-end"
|
||||||
<br>
|
>
|
||||||
Ryan
|
<div
|
||||||
<br>
|
id="intro-content"
|
||||||
I like to make cool stuff
|
class="
|
||||||
<br>
|
flex flex-row justify-between items-center
|
||||||
as a programmer
|
w-4/5 h-4/5
|
||||||
|
p-20 mt-24
|
||||||
|
border-[#404040] border-2 border-solid
|
||||||
|
rounded-3xl"
|
||||||
|
>
|
||||||
|
<div class="w-1/2">
|
||||||
|
<h1 class="text-4xl mt-10">Good {greeting}, I'm</h1>
|
||||||
|
<h2
|
||||||
|
id="name"
|
||||||
|
class="animate-gradient text-5xl text-center py-2 font-bold w-fit"
|
||||||
|
>
|
||||||
|
RythonDev
|
||||||
|
</h2>
|
||||||
|
<p class="text-2xl mt-5 leading-7">
|
||||||
|
{introState1}<span
|
||||||
|
class:animate-pulse={!lineOneFinished}
|
||||||
|
class:opacity-0={lineOneFinished}>|</span
|
||||||
|
>
|
||||||
|
<br />{introState2}
|
||||||
|
{roleState}<span
|
||||||
|
class="opacity-0"
|
||||||
|
class:animate-pulse={lineOneFinished}
|
||||||
|
class:opacity-1={lineOneFinished}>|</span
|
||||||
|
>
|
||||||
</p>
|
</p>
|
||||||
|
<div class="mt-10">
|
||||||
|
<p class="text-lg leading-6">
|
||||||
|
A computer science undergraduate student, passionate in
|
||||||
|
frontend web development and content creation.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-10"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#intro {
|
||||||
|
background: rgba(30, 32, 34, 1);
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(30, 32, 34, 1) 0%,
|
||||||
|
rgba(30, 32, 34, 1) 95%,
|
||||||
|
rgba(20, 22, 24, 0) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#intro-content {
|
||||||
|
background: rgb(29, 32, 35);
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
rgba(29, 32, 35, 1) 0%,
|
||||||
|
rgba(29, 32, 35, 1) 70%,
|
||||||
|
rgba(50, 53, 58, 1) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#name {
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
#ff7dac 0%,
|
||||||
|
#33d2ff 55%,
|
||||||
|
#9845e8 100%
|
||||||
|
);
|
||||||
|
|
||||||
|
background-size: 300%;
|
||||||
|
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
40
src/components/NetworkLine.astro
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
height: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { height } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div id="line-container" class="flex justify-center items-center p-0 relative">
|
||||||
|
<div id="line" class="w-[1px] h-full"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style define:vars={{ height }}>
|
||||||
|
@keyframes gradientAnimation {
|
||||||
|
0% {
|
||||||
|
background-position: 0 -100%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 0 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#line-container {
|
||||||
|
height: var(--height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#line {
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
#404040 5%,
|
||||||
|
#aaa 10%,
|
||||||
|
#404040 15%
|
||||||
|
);
|
||||||
|
background-size: 100% 200%;
|
||||||
|
animation: gradientAnimation 2s linear infinite;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
453
src/components/Projects.svelte
Normal file
|
|
@ -0,0 +1,453 @@
|
||||||
|
<script lang="ts">
|
||||||
|
// import { onMount } from "svelte";
|
||||||
|
|
||||||
|
const streamers = [
|
||||||
|
{
|
||||||
|
streamer: "4l1c3_0",
|
||||||
|
task: "mental breakdance",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "Acrone",
|
||||||
|
task: "play Valorant with twin brother",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "Ama_xinita",
|
||||||
|
task: "estudiar leyes",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "andolivconc",
|
||||||
|
task: "estudar Direito",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "arcanexviii",
|
||||||
|
task: "babysit",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "AuspexOneGaming",
|
||||||
|
task: "teach computer science",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "BintonDev",
|
||||||
|
task: "rubber duck debugging",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "brisim_claimhte",
|
||||||
|
task: "rewrite history thesis",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "brunixwho",
|
||||||
|
task: "Ensinar ingl\u00eas",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "Bubxmicn",
|
||||||
|
task: "drive a truck",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "charliosaurus",
|
||||||
|
task: "release another song on YouTube",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "cheshirepope",
|
||||||
|
task: "write 1000 words",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "chocomi_tv",
|
||||||
|
task: "improve English",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "Clarishy",
|
||||||
|
task: "be sweaty",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "cloudydayzzz",
|
||||||
|
task: "interpret ASL",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "creativepepper",
|
||||||
|
task: "develop mobile app",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "DarthTorLin",
|
||||||
|
task: "watch Star Wars",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "DATJI_",
|
||||||
|
task: "IRL KBBQ stream",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "EarliestTea",
|
||||||
|
task: "chat about MBTI",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "Elly78456",
|
||||||
|
task: "sell YOUthversity merch",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "Emerald_Glowo",
|
||||||
|
task: "drawing stream",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "emzkx",
|
||||||
|
task: "study public health, psychology and exercise science",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "eri__berry",
|
||||||
|
task: "play Palia",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "HarryIsTrying",
|
||||||
|
task: "be a strategy consultant",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "Hawokai",
|
||||||
|
task: "be a shark",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "itsbrandonut",
|
||||||
|
task: "stream music then play valorant",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "j3dg",
|
||||||
|
task: "spin class",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "jerrrs",
|
||||||
|
task: "play Animal Crossing",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "lala_xitlali",
|
||||||
|
task: "design fashionable clothes",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "long1nteger",
|
||||||
|
task: "AI project",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "lyricalclove",
|
||||||
|
task: "teach English",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "mikewhatwhere",
|
||||||
|
task: "be a dietician",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "msmushh",
|
||||||
|
task: "vibe on stream",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "nachoburrit0",
|
||||||
|
task: "update spreadsheets",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "nick_kendall",
|
||||||
|
task: "Instagram post",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "nihn_jnesyo",
|
||||||
|
task: "Release new Lo-fi music",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "novellaHT",
|
||||||
|
task: "play Don't Starve Together",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "pcc_lanezzz",
|
||||||
|
task: "be a supermodel",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "PineappleEffect",
|
||||||
|
task: "edit video",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "pinsaregood",
|
||||||
|
task: "go on another hiatus",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "procrastilate",
|
||||||
|
task: "chaos",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "samkitkat",
|
||||||
|
task: "learn React",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "studypaws",
|
||||||
|
task: "be a vet",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "sunfflawer",
|
||||||
|
task: "be a sunflower",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "Supernaturalwriter",
|
||||||
|
task: "hit the gym",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "TheCake404",
|
||||||
|
task: "wear a demon costume",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "ThePainfulPhD",
|
||||||
|
task: "study about pain",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "theyolotato",
|
||||||
|
task: "be a potato",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "valecey",
|
||||||
|
task: "graduate from university",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "wafflesdot025",
|
||||||
|
task: "perform in another musical",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "wasmishtaken_",
|
||||||
|
task: "simp for levi ackerman",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streamer: "xeno_hiraeth",
|
||||||
|
task: "anki flashcards",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// let primaryDivHeight: string;
|
||||||
|
|
||||||
|
// onMount(() => {
|
||||||
|
// const animatedElement = document.querySelector(".primary");
|
||||||
|
// if (animatedElement) {
|
||||||
|
// primaryDivHeight = `${animatedElement.clientHeight}px`;
|
||||||
|
// }
|
||||||
|
// console.log(streamers.length);
|
||||||
|
// console.log(primaryDivHeight);
|
||||||
|
// });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id="projects" class="h-fit pt-20 pb-10 [perspective:1000px]">
|
||||||
|
<h1 class="text-5xl text-center">Projects</h1>
|
||||||
|
|
||||||
|
<div class="mt-10 w-full">
|
||||||
|
<div
|
||||||
|
class="flex flex-col md:flex-row justify-between h-fit w-full px-20"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="image-container w-full md:w-1/2 aspect-video [perspective:200px] relative md:ml-20"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/images/projects/coworking-guide.webp"
|
||||||
|
alt="coworking guide"
|
||||||
|
class="absolute max-w-full
|
||||||
|
top-1/2 left-1/2
|
||||||
|
[transform:rotateY(5deg)_rotateX(0deg)_translateZ(-50px)_translateX(-50%)_translateY(-50%)] opacity-40
|
||||||
|
border-2 border-solid border-white rounded-xl"
|
||||||
|
width="600"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="/images/projects/coworking-guide.webp"
|
||||||
|
alt="coworking guide"
|
||||||
|
width="600"
|
||||||
|
class="absolute max-w-full
|
||||||
|
top-1/2 left-1/2
|
||||||
|
[transform:rotateY(5deg)_rotateX(0deg)_translateZ(-50px)_translateX(-48%)_translateY(-52%)] opacity-1
|
||||||
|
border-2 border-solid border-white rounded-xl"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="visit-div absolute w-[600px] bg-[rgba(0,0,0,0.5)] opacity-0
|
||||||
|
aspect-video
|
||||||
|
rounded-xl
|
||||||
|
[transform:translateX(-50%)_translateY(-50%)] top-1/2 left-1/2
|
||||||
|
border-2 border-solid border-white
|
||||||
|
max-w-full"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href="https://coworking-guide.vercel.app/"
|
||||||
|
target="_blank"
|
||||||
|
class="absolute [transform:translateX(-50%)_translateY(-50%)] top-1/2 left-1/2
|
||||||
|
px-5 py-3 bg-blue-500 rounded-xl opacity-1
|
||||||
|
font-bold">Visit site</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="w-full md:w-1/2 h-[340px] flex flex-col justify-center md:pr-20"
|
||||||
|
>
|
||||||
|
<h2 class="text-3xl font-bold mb-5">Coworking Guide</h2>
|
||||||
|
<p class="text-xl">
|
||||||
|
A guide to coworking streams for Twitch streamers, covers
|
||||||
|
wide range of topics from tips on how to get started with
|
||||||
|
setting up stream to how to grow your audience!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex flex-col-reverse md:flex-row justify-between h-fit w-full px-16"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="w-full md:w-1/2 h-[340px] flex flex-col justify-center md:pl-20"
|
||||||
|
>
|
||||||
|
<h2 class="text-3xl font-bold mb-5">Chat-Task-Tic Widget</h2>
|
||||||
|
<p class="text-xl">
|
||||||
|
A widget for Coworking and Study Twitch streamers, allows
|
||||||
|
the streamer and the chatters to add their tasks to the
|
||||||
|
widget, to be displayed on stream!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="image-container w-full md:w-1/2 aspect-video [perspective:200px] relative md:ml-20"
|
||||||
|
>
|
||||||
|
<!-- task bot -->
|
||||||
|
<div
|
||||||
|
class="task-widget absolute flex flex-col opacity-30
|
||||||
|
w-full h-[99%]
|
||||||
|
top-1/2 left-1/2 [transform:translateX(-59%)_translateY(-49%)_translateZ(-50px)_rotateY(-3deg)]"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="w-full bg-black border-solid border-2 border-white
|
||||||
|
rounded-lg
|
||||||
|
px-5 py-2
|
||||||
|
text-xl text-white
|
||||||
|
flex flex-row justify-between items-center
|
||||||
|
font-['Fredoka',_sans-serif]"
|
||||||
|
>
|
||||||
|
<span>Hover here!</span>
|
||||||
|
<span>0/52</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="scroll-parent relative h-full overflow-hidden font-['Fredoka',_sans-serif]"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="scroll-element primary px-1 absolute w-full"
|
||||||
|
>
|
||||||
|
{#each streamers as { streamer, task }}
|
||||||
|
<div
|
||||||
|
class="w-full px-5 py-1 bg-white text-black my-2 rounded-full
|
||||||
|
whitespace-nowrap overflow-hidden overflow-ellipsis"
|
||||||
|
>
|
||||||
|
O {streamer} : {task}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="scroll-element secondary px-1 absolute w-full"
|
||||||
|
>
|
||||||
|
{#each streamers as { streamer, task }}
|
||||||
|
<div
|
||||||
|
class="w-full px-5 py-1 bg-white text-black my-2 rounded-full
|
||||||
|
whitespace-nowrap overflow-hidden overflow-ellipsis"
|
||||||
|
>
|
||||||
|
O {streamer} : {task}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="task-widget absolute flex flex-col
|
||||||
|
w-full h-[99%]
|
||||||
|
top-1/2 left-1/2 [transform:translateX(-60%)_translateY(-50%)_translateZ(-50px)_rotateY(-3deg)]"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="w-full bg-black border-solid border-2 border-white
|
||||||
|
rounded-lg
|
||||||
|
px-5 py-2
|
||||||
|
text-xl text-white
|
||||||
|
flex flex-row justify-between items-center
|
||||||
|
font-['Fredoka',_sans-serif]"
|
||||||
|
>
|
||||||
|
<span>Hover here!</span>
|
||||||
|
<span>0/52</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="scroll-parent relative h-full overflow-hidden font-['Fredoka',_sans-serif]"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="scroll-element primary px-1 absolute w-full"
|
||||||
|
>
|
||||||
|
{#each streamers as { streamer, task }}
|
||||||
|
<div
|
||||||
|
class="w-full px-5 py-1 bg-white text-black my-2 rounded-full
|
||||||
|
whitespace-nowrap overflow-hidden overflow-ellipsis"
|
||||||
|
>
|
||||||
|
O {streamer} : {task}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="scroll-element secondary px-1 absolute w-full"
|
||||||
|
>
|
||||||
|
{#each streamers as { streamer, task }}
|
||||||
|
<div
|
||||||
|
class="w-full px-5 py-1 bg-white text-black my-2 rounded-full
|
||||||
|
whitespace-nowrap overflow-hidden overflow-ellipsis"
|
||||||
|
>
|
||||||
|
O {streamer} : {task}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="visit-div absolute w-full h-full bg-[rgba(0,0,0,0.5)] opacity-0
|
||||||
|
rounded-md
|
||||||
|
[transform:translateX(-50%)_translateY(-50%)] top-1/2 left-1/2
|
||||||
|
border-2 border-solid border-white
|
||||||
|
overflow-hidden"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href="https://github.com/liyunze-coding/multi-task-widget-infinity"
|
||||||
|
target="_blank"
|
||||||
|
class="absolute [transform:translateX(-50%)_translateY(-50%)] top-1/2 left-1/2
|
||||||
|
px-5 py-3 bg-blue-500 rounded-xl opacity-1
|
||||||
|
font-bold">View repository</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.image-container img,
|
||||||
|
.image-container .task-widget {
|
||||||
|
transition: transform 0.5s ease-in-out;
|
||||||
|
}
|
||||||
|
.image-container:hover > img,
|
||||||
|
.image-container:hover > .task-widget {
|
||||||
|
transform: rotateY(0deg) rotateX(0deg) translateZ(0px) translateX(-50%)
|
||||||
|
translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-container:hover > .visit-div {
|
||||||
|
opacity: 100%;
|
||||||
|
transition: opacity 0.3s ease-in-out;
|
||||||
|
transition-delay: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary {
|
||||||
|
animation: primary 30s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondary {
|
||||||
|
animation: secondary 30s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes primary {
|
||||||
|
from {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(-2175px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes secondary {
|
||||||
|
from {
|
||||||
|
transform: translateY(2175px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
44
src/components/Skills.astro
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
import Card from "../components/Card.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="w-full h-[200vh]">
|
||||||
|
<h1 class="text-center text-5xl">Skills</h1>
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<div class="w-1/2 pt-10">
|
||||||
|
<Card primaryColor="#fff">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="flex flex-col justify-left w-full mb-3">
|
||||||
|
<h2 class="font-bold text-xl">
|
||||||
|
Diploma in Computer Science
|
||||||
|
</h2><h3>Jan 2022 - Present</h3>
|
||||||
|
</div>
|
||||||
|
<hr class="w-full mb-3" />
|
||||||
|
<h3 class="mb-1 font-bold text-lg">Achievements</h3>
|
||||||
|
<ul class="list-disc list-inside">
|
||||||
|
<li>3-time Dean's List recipient</li>
|
||||||
|
<li>President of Computer Programming Club</li>
|
||||||
|
<li>Vice President of Diploma Union</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.card-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
background-image: radial-gradient(
|
||||||
|
rgba(255, 255, 255, 0.1) 1px,
|
||||||
|
transparent 1px
|
||||||
|
);
|
||||||
|
background-position: 50% 50%;
|
||||||
|
background-size: 1.1rem 1.1rem;
|
||||||
|
padding: 2rem 2rem;
|
||||||
|
border-radius: 1.25rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
61
src/components/WhatIDo.astro
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
import Card from "../components/Card.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="w-full h-fit flex justify-center items-center flex-col">
|
||||||
|
<div class="h-[1px] w-1/3 bg-[#404040] mb-5"></div>
|
||||||
|
<h1 class="text-center text-5xl mb-10">What I Do</h1>
|
||||||
|
<div
|
||||||
|
class="grid grid-cols-1 xl:grid-cols-3 place-content-center justify-center w-4/5 gap-12"
|
||||||
|
>
|
||||||
|
<Card primaryColor="#be68ed">
|
||||||
|
<div class="card-content">
|
||||||
|
<h2 class="font-bold text-xl text-center">Data Science</h2>
|
||||||
|
<hr class="w-full" />
|
||||||
|
<p class="text-center">
|
||||||
|
I possess knowledge of data science and machine learning,
|
||||||
|
particularly interested in Computer Vision.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card primaryColor="#be68ed">
|
||||||
|
<div class="card-content">
|
||||||
|
<h2 class="font-bold text-xl text-center">Web Development</h2>
|
||||||
|
<hr class="w-full" />
|
||||||
|
<p class="text-center">
|
||||||
|
I like to code things for the web, whether it's to inform or
|
||||||
|
to entertain.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card primaryColor="#be68ed">
|
||||||
|
<div class="card-content">
|
||||||
|
<h2 class="font-bold text-xl text-center">Content Creation</h2>
|
||||||
|
<hr class="w-full" />
|
||||||
|
<p class="text-center">
|
||||||
|
I am experienced in streaming on Twitch and marketing
|
||||||
|
myself, but I aim to improve my video editing skills.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.card-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
background-image: radial-gradient(
|
||||||
|
rgba(255, 255, 255, 0.1) 1px,
|
||||||
|
transparent 1px
|
||||||
|
);
|
||||||
|
background-position: 50% 50%;
|
||||||
|
background-size: 1.1rem 1.1rem;
|
||||||
|
padding: 2rem 2rem;
|
||||||
|
border-radius: 1.25rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { title } = Astro.props;
|
const { title } = Astro.props;
|
||||||
|
|
@ -8,116 +8,115 @@ const { title } = Astro.props;
|
||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="description" content="Astro description" />
|
<meta name="description" content="Astro description" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<slot />
|
<slot />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
<style is:global>
|
<style is:global>
|
||||||
/* Fredoka Fonts */
|
/* Fredoka Fonts */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Fredoka';
|
font-family: "Fredoka";
|
||||||
src: url('fonts/Fredoka-Bold.ttf') format('truetype');
|
src: url("fonts/Fredoka-Bold.ttf") format("truetype");
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Fredoka';
|
font-family: "Fredoka";
|
||||||
src: url('fonts/Fredoka-Light.ttf') format('truetype');
|
src: url("fonts/Fredoka-Light.ttf") format("truetype");
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Fredoka';
|
font-family: "Fredoka";
|
||||||
src: url('fonts/Fredoka-Medium.ttf') format('truetype');
|
src: url("fonts/Fredoka-Medium.ttf") format("truetype");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Fredoka';
|
font-family: "Fredoka";
|
||||||
src: url('fonts/Fredoka-Regular.ttf') format('truetype');
|
src: url("fonts/Fredoka-Regular.ttf") format("truetype");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Montserrat Fonts */
|
/* Montserrat Fonts */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Montserrat';
|
font-family: "Montserrat";
|
||||||
src: url('fonts/Montserrat-Bold.ttf') format('truetype');
|
src: url("fonts/Montserrat-Bold.ttf") format("truetype");
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Montserrat';
|
font-family: "Montserrat";
|
||||||
src: url('fonts/Montserrat-Light.ttf') format('truetype');
|
src: url("fonts/Montserrat-Light.ttf") format("truetype");
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Montserrat';
|
font-family: "Montserrat";
|
||||||
src: url('fonts/Montserrat-Medium.ttf') format('truetype');
|
src: url("fonts/Montserrat-Medium.ttf") format("truetype");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Montserrat';
|
font-family: "Montserrat";
|
||||||
src: url('fonts/Montserrat-Regular.ttf') format('truetype');
|
src: url("fonts/Montserrat-Regular.ttf") format("truetype");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Montserrat';
|
font-family: "Montserrat";
|
||||||
src: url('fonts/Montserrat-SemiBold.ttf') format('truetype');
|
src: url("fonts/Montserrat-SemiBold.ttf") format("truetype");
|
||||||
font-weight: 600; /* You can adjust this value if needed */
|
font-weight: 600; /* You can adjust this value if needed */
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Poppins Fonts */
|
/* Poppins Fonts */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Poppins-Light';
|
font-family: "Poppins-Light";
|
||||||
src: url('fonts/Poppins-Light.ttf') format('truetype');
|
src: url("fonts/Poppins-Light.ttf") format("truetype");
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Poppins-Medium';
|
font-family: "Poppins-Medium";
|
||||||
src: url('fonts/Poppins-Medium.ttf') format('truetype');
|
src: url("fonts/Poppins-Medium.ttf") format("truetype");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Poppins-Regular';
|
font-family: "Poppins-Regular";
|
||||||
src: url('fonts/Poppins-Regular.ttf') format('truetype');
|
src: url("fonts/Poppins-Regular.ttf") format("truetype");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* You can add more font-face rules for other fonts as needed */
|
* {
|
||||||
* {
|
margin: 0;
|
||||||
margin:0;
|
padding: 0;
|
||||||
padding:0;
|
box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: "Montserrat", sans-serif;
|
font-family: "Montserrat", sans-serif;
|
||||||
background: #141414;
|
background: #202020;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,18 @@
|
||||||
---
|
---
|
||||||
import Layout from '../layouts/Layout.astro';
|
import Layout from "../layouts/Layout.astro";
|
||||||
import Card from '../components/Card.astro';
|
import NetworkLine from "../components/NetworkLine.astro";
|
||||||
import Intro from '../components/Intro.svelte';
|
import WhatIDo from "../components/WhatIDo.astro";
|
||||||
|
import Intro from "../components/Intro.svelte";
|
||||||
|
import Projects from "../components/Projects.svelte";
|
||||||
|
import Education from "../components/Education.astro";
|
||||||
|
import Skills from "../components/Skills.astro";
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Ryan's Portfolio">
|
<Layout title="Ryan's Portfolio">
|
||||||
<Intro client:load />
|
<Intro client:load />
|
||||||
|
<NetworkLine height="100px" />
|
||||||
|
<WhatIDo />
|
||||||
|
<Projects client:idle />
|
||||||
|
<Education />
|
||||||
|
<Skills />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,25 @@
|
||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {
|
||||||
},
|
keyframes: {
|
||||||
plugins: [],
|
gradient: {
|
||||||
}
|
"0%": {
|
||||||
|
"background-position": "0% 50%",
|
||||||
|
},
|
||||||
|
"50%": {
|
||||||
|
"background-position": "100% 50%",
|
||||||
|
},
|
||||||
|
"100%": {
|
||||||
|
"background-position": "0% 50%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
gradient: "gradient 15s ease infinite",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
};
|
||||||
|
|
|
||||||