initalizing
This commit is contained in:
commit
04ffbccb28
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Vue 3 + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).
|
13
index.html
Normal file
13
index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + Vue</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
1197
package-lock.json
generated
Normal file
1197
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
package.json
Normal file
20
package.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "my-vue-app",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"format": "prettier --write \"src/**/*.{js,vue,css,html,json}\""
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vue": "^3.5.13"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
|
"prettier": "^3.5.3",
|
||||||
|
"vite": "^6.2.0"
|
||||||
|
}
|
||||||
|
}
|
1
public/vite.svg
Normal file
1
public/vite.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
133
src/App.vue
Normal file
133
src/App.vue
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app">
|
||||||
|
<Header />
|
||||||
|
<main>
|
||||||
|
<Landing />
|
||||||
|
<div class="content">
|
||||||
|
<Experience />
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Header from "./components/Header.vue";
|
||||||
|
import Landing from "./components/Landing.vue";
|
||||||
|
import Experience from "./components/Experience.vue";
|
||||||
|
import Footer from "./components/Footer.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "App",
|
||||||
|
components: {
|
||||||
|
Header,
|
||||||
|
Landing,
|
||||||
|
Experience,
|
||||||
|
Footer,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Global Styles */
|
||||||
|
:root {
|
||||||
|
--duck-yellow: #ffdb58;
|
||||||
|
--duck-orange: #f97316;
|
||||||
|
--duck-blue: #4682b4;
|
||||||
|
--duck-dark-blue: #1e3a8a;
|
||||||
|
--duck-green: #228b22;
|
||||||
|
--bg-color: #fffdf7;
|
||||||
|
--text-color: #333;
|
||||||
|
--gray-600: #4b5563;
|
||||||
|
--gray-700: #374151;
|
||||||
|
--gray-500: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family:
|
||||||
|
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu,
|
||||||
|
Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||||
|
background-color: var(--bg-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
overflow-x: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: var(--bg-color);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex: 1;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin-top: 2rem;
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.content {
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animation Classes */
|
||||||
|
@keyframes float {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes wave {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: rotate(-5deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: rotate(5deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes splash {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-float {
|
||||||
|
animation: float 6s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-wave {
|
||||||
|
animation: wave 3s ease-in-out infinite;
|
||||||
|
transform-origin: bottom center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-splash {
|
||||||
|
animation: splash 0.5s ease-out forwards;
|
||||||
|
}
|
||||||
|
</style>
|
BIN
src/assets/duck-dance.gif
Normal file
BIN
src/assets/duck-dance.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 MiB |
BIN
src/assets/duck-dance2.gif
Normal file
BIN
src/assets/duck-dance2.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 MiB |
BIN
src/assets/duck-dance3.gif
Normal file
BIN
src/assets/duck-dance3.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 MiB |
BIN
src/assets/duck.gif
Normal file
BIN
src/assets/duck.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
1
src/assets/vue.svg
Normal file
1
src/assets/vue.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
After Width: | Height: | Size: 496 B |
311
src/components/DuckTerminal.vue
Normal file
311
src/components/DuckTerminal.vue
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
<template>
|
||||||
|
<div class="duck-terminal">
|
||||||
|
<div class="terminal-header">
|
||||||
|
<div class="terminal-buttons">
|
||||||
|
<span class="terminal-button close"></span>
|
||||||
|
<span class="terminal-button minimize"></span>
|
||||||
|
<span class="terminal-button maximize"></span>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-title">portfolio@duck:~</div>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-body">
|
||||||
|
<div class="terminal-content" ref="terminalContent">
|
||||||
|
<div
|
||||||
|
class="terminal-line"
|
||||||
|
v-for="(line, index) in displayedLines"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<template v-if="line.type === 'command'">
|
||||||
|
<span class="terminal-prompt">portfolio@duck:~$</span>
|
||||||
|
<span class="terminal-text">{{ line.text }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="line.type === 'skills'">
|
||||||
|
<div class="terminal-output skills-grid">
|
||||||
|
<div class="skill-item" v-for="(skill, skillIndex) in line.skills" :key="skillIndex">
|
||||||
|
{{ skill }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<span class="terminal-output">{{ line.text }}</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="terminal-line typing-line"
|
||||||
|
v-if="currentLineIndex < terminalLines.length && isTypingCommand"
|
||||||
|
>
|
||||||
|
<span class="terminal-prompt">portfolio@duck:~$</span>
|
||||||
|
<span class="terminal-text typing">{{ currentText }}</span>
|
||||||
|
<span class="terminal-cursor"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DuckTerminal",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
terminalLines: [
|
||||||
|
{ type: "command", text: "cat profil.txt" },
|
||||||
|
{
|
||||||
|
type: "output",
|
||||||
|
text: "Développeur PHP et Admin Sys/Réseau avec passion pour le web",
|
||||||
|
},
|
||||||
|
{ type: "command", text: "cat experience.txt" },
|
||||||
|
{
|
||||||
|
type: "output",
|
||||||
|
text: "Plus de 4 ans d'expérience dans différents contextes professionnels",
|
||||||
|
},
|
||||||
|
{ type: "command", text: "ls -la skills/" },
|
||||||
|
{
|
||||||
|
type: "skills",
|
||||||
|
skills: [
|
||||||
|
"PHP", "Laravel", "MySQL", "Linux",
|
||||||
|
"Symfony", "Docker", "Git", "Networking",
|
||||||
|
"JavaScript", "REST API", "DevOps", "Cloud"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ type: "command", text: "whoami" },
|
||||||
|
{
|
||||||
|
type: "output",
|
||||||
|
text: "Expert en développement PHP et en administration système/réseau",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
displayedLines: [],
|
||||||
|
currentLineIndex: 0,
|
||||||
|
currentText: "",
|
||||||
|
currentCharIndex: 0,
|
||||||
|
typingSpeed: 40,
|
||||||
|
commandDelay: 300,
|
||||||
|
outputDelay: 300,
|
||||||
|
isTypingCommand: false,
|
||||||
|
isProcessing: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.startTyping();
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
this.scrollToBottom();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
scrollToBottom() {
|
||||||
|
if (this.$refs.terminalContent) {
|
||||||
|
this.$refs.terminalContent.scrollTop = this.$refs.terminalContent.scrollHeight;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
startTyping() {
|
||||||
|
this.processNextLine();
|
||||||
|
},
|
||||||
|
processNextLine() {
|
||||||
|
if (this.currentLineIndex >= this.terminalLines.length || this.isProcessing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentLine = this.terminalLines[this.currentLineIndex];
|
||||||
|
this.isProcessing = true;
|
||||||
|
|
||||||
|
if (currentLine.type === "command") {
|
||||||
|
// For command lines, animate typing
|
||||||
|
this.isTypingCommand = true;
|
||||||
|
this.currentText = "";
|
||||||
|
this.currentCharIndex = 0;
|
||||||
|
this.typeCurrentLine();
|
||||||
|
} else {
|
||||||
|
// For output and skills lines, just add them after a delay
|
||||||
|
this.isTypingCommand = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.displayedLines.push(currentLine);
|
||||||
|
this.currentLineIndex++;
|
||||||
|
this.isProcessing = false;
|
||||||
|
this.processNextLine();
|
||||||
|
}, this.outputDelay);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
typeCurrentLine() {
|
||||||
|
if (!this.isTypingCommand || this.currentLineIndex >= this.terminalLines.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentLine = this.terminalLines[this.currentLineIndex];
|
||||||
|
|
||||||
|
if (this.currentCharIndex < currentLine.text.length) {
|
||||||
|
// Still typing the current character
|
||||||
|
this.currentText = currentLine.text.substring(
|
||||||
|
0,
|
||||||
|
this.currentCharIndex + 1
|
||||||
|
);
|
||||||
|
this.currentCharIndex++;
|
||||||
|
setTimeout(this.typeCurrentLine, this.typingSpeed);
|
||||||
|
} else {
|
||||||
|
// Finished typing this command
|
||||||
|
setTimeout(() => {
|
||||||
|
// Add the completed command to displayed lines
|
||||||
|
this.displayedLines.push({ ...currentLine });
|
||||||
|
this.currentLineIndex++;
|
||||||
|
this.isTypingCommand = false;
|
||||||
|
this.isProcessing = false;
|
||||||
|
|
||||||
|
// Wait a bit before processing the next line
|
||||||
|
setTimeout(this.processNextLine, this.commandDelay);
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.duck-terminal {
|
||||||
|
width: 620px; /* Fixed width as requested */
|
||||||
|
max-width: 620px;
|
||||||
|
min-width: 620px;
|
||||||
|
background-color: #1a1b26;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
font-family: "Courier New", monospace;
|
||||||
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
|
||||||
|
border: 1px solid #30374b;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
height: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-header {
|
||||||
|
height: 36px;
|
||||||
|
background-color: #24283b;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 12px;
|
||||||
|
border-bottom: 1px solid #30374b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-button {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-button.close {
|
||||||
|
background-color: #ff5f57;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-button.minimize {
|
||||||
|
background-color: #febc2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-button.maximize {
|
||||||
|
background-color: #28c840;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-title {
|
||||||
|
flex-grow: 1;
|
||||||
|
text-align: center;
|
||||||
|
color: #a9b1d6;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-body {
|
||||||
|
height: calc(100% - 36px);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-content {
|
||||||
|
padding: 1.25rem;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
color: #a9b1d6;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: #30374b #1a1b26;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-content::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-content::-webkit-scrollbar-track {
|
||||||
|
background: #1a1b26;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-content::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #30374b;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-line {
|
||||||
|
line-height: 1.6;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-prompt {
|
||||||
|
color: var(--duck-yellow, #ffdb58);
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-text {
|
||||||
|
color: #a9b1d6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-output {
|
||||||
|
color: #7aa2f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skills-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
grid-gap: 0.5rem;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-item {
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-cursor {
|
||||||
|
display: inline-block;
|
||||||
|
width: 8px;
|
||||||
|
height: 16px;
|
||||||
|
background-color: #7aa2f7;
|
||||||
|
animation: blink 1s step-start infinite;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
0%,
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
51%,
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.typing-line {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.typing {
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make the terminal responsive while maintaining aspect ratio */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.duck-terminal {
|
||||||
|
width: 100%;
|
||||||
|
min-width: auto;
|
||||||
|
max-width: 620px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
501
src/components/Experience.vue
Normal file
501
src/components/Experience.vue
Normal file
@ -0,0 +1,501 @@
|
|||||||
|
<template>
|
||||||
|
<section id="experience" class="experience">
|
||||||
|
<div class="experience-container">
|
||||||
|
<h2 class="section-title">Compétences</h2>
|
||||||
|
<div class="skills-grid">
|
||||||
|
<div class="skill-card animate-splash">
|
||||||
|
<h3 class="skill-title">Langages & Frameworks</h3>
|
||||||
|
<div class="skill-tags">
|
||||||
|
<span class="skill-tag">PHP</span>
|
||||||
|
<span class="skill-tag">Drupal</span>
|
||||||
|
<span class="skill-tag">Symfony</span>
|
||||||
|
<span class="skill-tag">Laravel</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="skill-card animate-splash">
|
||||||
|
<h3 class="skill-title">Systèmes & DevOps</h3>
|
||||||
|
<div class="skill-tags">
|
||||||
|
<span class="skill-tag">Docker</span>
|
||||||
|
<span class="skill-tag">Linux</span>
|
||||||
|
<span class="skill-tag">Git</span>
|
||||||
|
<span class="skill-tag">CI/CD</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="skill-card animate-splash">
|
||||||
|
<h3 class="skill-title">Administration & Sécurité</h3>
|
||||||
|
<div class="skill-tags">
|
||||||
|
<span class="skill-tag">Administration Systèmes</span>
|
||||||
|
<span class="skill-tag">Sécurité Web</span>
|
||||||
|
<span class="skill-tag">Monitoring</span>
|
||||||
|
<span class="skill-tag">SQL</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="experience-section">
|
||||||
|
<h2 class="section-title">Mon Parcours</h2>
|
||||||
|
<div class="timeline">
|
||||||
|
<div class="timeline-title">
|
||||||
|
<h3 class="timeline-heading">Expérience Professionnelle</h3>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="timeline-icon timeline-icon-work"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M8 3c.132 0 .263 0 .393 0 7.107.007 10.372 6.167 11.917 11.917.078.287.156.575.234.863"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
d="M20.039 17.39c-.221-.89-.943-1.396-1.871-1.394a1.99 1.99 0 0 0-1.988 1.994v.012a1.998 1.998 0 0 0 2.004 1.998c.464 0 .91-.196 1.244-.548"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
d="M7.05 4.095c-1.815-.407-3.246-.089-4.028 1.007C1.082 7.547 1.603 12.19 4 16c2.492 0 4.623-1.33 6.234-3.219"
|
||||||
|
></path>
|
||||||
|
<path d="M11.167 12c1.174-1.525 2.272-3.747 2.272-6.8V3"></path>
|
||||||
|
<circle cx="16" cy="10" r="1"></circle>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-items">
|
||||||
|
<div
|
||||||
|
class="timeline-card animate-splash"
|
||||||
|
style="animation-delay: 0s"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div>
|
||||||
|
<h3 class="card-title">
|
||||||
|
Administrateur Systèmes et Réseaux Web | STUDIO BESTIO
|
||||||
|
</h3>
|
||||||
|
<p class="card-date">Février 2025 - Aujourd'hui</p>
|
||||||
|
<div class="card-location">
|
||||||
|
<span>Nancy, France</span>
|
||||||
|
<span>· Indépendant</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-tags">
|
||||||
|
<span class="card-tag">Docker</span>
|
||||||
|
<span class="card-tag">Linux</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<p>
|
||||||
|
Gestion de l'hébergement, de sauvegardes, de la maintenance et
|
||||||
|
de la sécurité des sites web pour Studiobestio. Administration
|
||||||
|
des serveurs, supervision des performances, gestion de la
|
||||||
|
journalisation, mise en place de solutions de sécurité pour
|
||||||
|
assurer une protection contre les cybermenaces. Garantir le
|
||||||
|
bon fonctionnement, la sécurité et la fiabilité des sites web
|
||||||
|
des clients.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="timeline-card animate-splash"
|
||||||
|
style="animation-delay: 0.1s"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div>
|
||||||
|
<h3 class="card-title">Développeur PHP | GIE SIMA</h3>
|
||||||
|
<p class="card-date">Mai 2023 - Aujourd'hui</p>
|
||||||
|
<div class="card-location">
|
||||||
|
<span>Nancy, France</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-tags">
|
||||||
|
<span class="card-tag">PHP</span>
|
||||||
|
<span class="card-tag">Drupal</span>
|
||||||
|
<span class="card-tag">Docker</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<p>
|
||||||
|
Réecriture et maintenance d'une application pour la vente de
|
||||||
|
contrats de santé ou prévoyance déstinée à des
|
||||||
|
courtiers/conseillers.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="timeline-card animate-splash"
|
||||||
|
style="animation-delay: 0.2s"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div>
|
||||||
|
<h3 class="card-title">Consultant | DAVIDSON CONSULTING</h3>
|
||||||
|
<p class="card-date">Février 2023 - Mai 2023</p>
|
||||||
|
<div class="card-location">
|
||||||
|
<span>Nancy, France</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-tags">
|
||||||
|
<span class="card-tag">PHP</span>
|
||||||
|
<span class="card-tag">Drupal</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<p>Développement d'applications clients</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="timeline-card animate-splash"
|
||||||
|
style="animation-delay: 0.3s"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div>
|
||||||
|
<h3 class="card-title">
|
||||||
|
Développeur web | GANTOIS INDUSTRIES
|
||||||
|
</h3>
|
||||||
|
<p class="card-date">Sept. 2021 - Avr. 2022</p>
|
||||||
|
<div class="card-location">
|
||||||
|
<span>Saint-Dié, France</span>
|
||||||
|
<span>· Intérimaire</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-tags">
|
||||||
|
<span class="card-tag">PHP</span>
|
||||||
|
<span class="card-tag">Symfony</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<p>Développement d'applications métier</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="timeline-card animate-splash"
|
||||||
|
style="animation-delay: 0.4s"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div>
|
||||||
|
<h3 class="card-title">
|
||||||
|
Développeur web | GANTOIS INDUSTRIES
|
||||||
|
</h3>
|
||||||
|
<p class="card-date">Nov. 2020 - Sept. 2021</p>
|
||||||
|
<div class="card-location">
|
||||||
|
<span>Saint-Dié, France</span>
|
||||||
|
<span>· Alternance</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-tags">
|
||||||
|
<span class="card-tag">PHP</span>
|
||||||
|
<span class="card-tag">Symfony</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<p>
|
||||||
|
Développement et maintenance d'une application de contrôle
|
||||||
|
qualité pour les pièces industrielles.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="timeline-card animate-splash"
|
||||||
|
style="animation-delay: 0.5s"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div>
|
||||||
|
<h3 class="card-title">
|
||||||
|
Développeur Full Stack | 2110 FINANCE
|
||||||
|
</h3>
|
||||||
|
<p class="card-date">Juillet 2020</p>
|
||||||
|
<div class="card-location">
|
||||||
|
<span>Saint-Dié, France</span>
|
||||||
|
<span>· Stage</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-tags">
|
||||||
|
<span class="card-tag">PHP</span>
|
||||||
|
<span class="card-tag">Laravel</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<p>Application de messagerie interne</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section-divider"></div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="timeline-title">
|
||||||
|
<h3 class="timeline-heading">Formation</h3>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="timeline-icon timeline-icon-education"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M22 12A10 10 0 1 1 12 2a1 1 0 0 1 1 1v1a1 1 0 1 1-2 0V3.07A8 8 0 1 0 19 12h-3a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h1"
|
||||||
|
></path>
|
||||||
|
<path d="M11.8 22h.2a3 3 0 0 0 3-3v-1"></path>
|
||||||
|
<path
|
||||||
|
d="M20 19a2 2 0 0 0 2-2v-1a3 3 0 0 0-3-3h-1a2 2 0 0 0-2 2"
|
||||||
|
></path>
|
||||||
|
<circle cx="12" cy="12" r="3"></circle>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-items">
|
||||||
|
<div
|
||||||
|
class="timeline-card education-card animate-splash"
|
||||||
|
style="animation-delay: 0s"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div>
|
||||||
|
<h3 class="card-title">
|
||||||
|
Licence en application web et mobile | Université de
|
||||||
|
Lorraine
|
||||||
|
</h3>
|
||||||
|
<p class="card-date">2020 - 2021</p>
|
||||||
|
<div class="card-location">
|
||||||
|
<span>Nancy, France</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<p>
|
||||||
|
Formation en développement d'applications web et mobiles
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="timeline-card education-card animate-splash"
|
||||||
|
style="animation-delay: 0.1s"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div>
|
||||||
|
<h3 class="card-title">
|
||||||
|
DUT informatique | Université de Lorraine
|
||||||
|
</h3>
|
||||||
|
<p class="card-date">2018 - 2020</p>
|
||||||
|
<div class="card-location">
|
||||||
|
<span>Nancy, France</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<p>
|
||||||
|
Formation en informatique générale avec spécialisation en
|
||||||
|
développement
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="timeline-card education-card animate-splash"
|
||||||
|
style="animation-delay: 0.2s"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div>
|
||||||
|
<h3 class="card-title">
|
||||||
|
Baccalauréat Scientifique | Lycée Gaston Bachelard
|
||||||
|
</h3>
|
||||||
|
<p class="card-date">2015 - 2018</p>
|
||||||
|
<div class="card-location">
|
||||||
|
<span>Bar-sur-Aube, France</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<p>Baccalauréat avec option mathématiques</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Experience",
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.experience {
|
||||||
|
padding: 2rem 0;
|
||||||
|
scroll-margin-top: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.experience-container {
|
||||||
|
max-width: 64rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 1.875rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skills-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-card {
|
||||||
|
background-color: white;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: var(--duck-dark-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-tags {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-tag {
|
||||||
|
background-color: var(--duck-yellow);
|
||||||
|
padding: 0.25rem 0.75rem;
|
||||||
|
border-radius: 9999px;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.experience-section {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-heading {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-icon {
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-icon-work {
|
||||||
|
color: var(--duck-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-icon-education {
|
||||||
|
color: var(--duck-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-items {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-card {
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border-left: 4px solid var(--duck-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.education-card {
|
||||||
|
border-left: 4px solid var(--duck-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-date {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--gray-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-location {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--gray-600);
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-tags {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-tag {
|
||||||
|
background-color: rgba(34, 139, 34, 0.2);
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content {
|
||||||
|
padding: 1.5rem;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content p {
|
||||||
|
color: var(--gray-700);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-divider {
|
||||||
|
height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #e5e7eb;
|
||||||
|
margin: 2.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.skills-grid {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
174
src/components/Footer.vue
Normal file
174
src/components/Footer.vue
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
<template>
|
||||||
|
<footer class="footer">
|
||||||
|
<div class="footer-container">
|
||||||
|
<div class="footer-left">
|
||||||
|
<DuckSvg svgClass="footer-duck" />
|
||||||
|
<div>
|
||||||
|
<h3 class="footer-title">Romaric SIRI</h3>
|
||||||
|
<p class="footer-subtitle">Développeur PHP | Admin Sys</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer-right">
|
||||||
|
<p class="footer-text">
|
||||||
|
Nancy, Grand Est —
|
||||||
|
<a href="tel:0632717245" class="footer-link">06 32 71 72 45</a>
|
||||||
|
</p>
|
||||||
|
<p class="footer-text">
|
||||||
|
<a href="mailto:contact@maric.ro" class="footer-link"
|
||||||
|
>contact@maric.ro</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer-duck-right animate-float">
|
||||||
|
<DuckSvg />
|
||||||
|
<div class="duck-shadow"></div>
|
||||||
|
</div>
|
||||||
|
<div class="footer-duck-left animate-float">
|
||||||
|
<DuckSvg />
|
||||||
|
<div class="duck-shadow"></div>
|
||||||
|
</div>
|
||||||
|
<p class="copyright">© 2025 Romaric SIRI. All rights reserved. 🦆</p>
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DuckSvg from "./ducks/Duck1.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Footer",
|
||||||
|
components: {
|
||||||
|
DuckSvg,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.footer {
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
background-color: rgba(255, 219, 88, 0.2);
|
||||||
|
margin-top: 2rem;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-container {
|
||||||
|
max-width: 72rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-duck {
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-title {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-subtitle {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--gray-600);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-right {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-text {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--gray-600);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link {
|
||||||
|
color: var(--gray-600);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-duck-right {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -1.25rem;
|
||||||
|
right: 1rem;
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-duck-right svg {
|
||||||
|
width: 4rem;
|
||||||
|
height: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-duck-left {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -1.25rem;
|
||||||
|
left: 1rem;
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 0.3;
|
||||||
|
animation-delay: 2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-duck-left svg {
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-shadow {
|
||||||
|
position: absolute;
|
||||||
|
width: 6rem;
|
||||||
|
height: 2rem;
|
||||||
|
background-color: rgba(70, 130, 180, 0.3);
|
||||||
|
border-radius: 9999px;
|
||||||
|
bottom: -1rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--gray-500);
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.footer {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-container {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-left {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-duck-right {
|
||||||
|
right: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-duck-left {
|
||||||
|
left: 5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
240
src/components/Header.vue
Normal file
240
src/components/Header.vue
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
<template>
|
||||||
|
<header class="header">
|
||||||
|
<div class="header-container">
|
||||||
|
<div class="header-left">
|
||||||
|
<div class="duck-container">
|
||||||
|
<DuckSvg svgClass="duck-svg animate-float" />
|
||||||
|
<div class="bubble animate-wave">
|
||||||
|
<span class="bubble-text">Quack!</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="header-info">
|
||||||
|
<h1 class="header-title">Romaric SIRI</h1>
|
||||||
|
<p class="header-subtitle">
|
||||||
|
Développeur PHP | Administrateur Systèmes & Réseaux Web
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="social-links">
|
||||||
|
<a href="mailto:contact@maric.ro" title="Email" class="social-link">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="icon"
|
||||||
|
>
|
||||||
|
<rect width="20" height="16" x="2" y="4" rx="2"></rect>
|
||||||
|
<path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a href="tel:0632717245" title="Téléphone" class="social-link">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="icon"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://linkedin.com/in/romaric-siri-a25949181"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
title="LinkedIn"
|
||||||
|
class="social-link"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="icon"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"
|
||||||
|
></path>
|
||||||
|
<rect width="4" height="12" x="2" y="9"></rect>
|
||||||
|
<circle cx="4" cy="4" r="2"></circle>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://github.com/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
title="GitHub"
|
||||||
|
class="social-link"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="icon"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"
|
||||||
|
></path>
|
||||||
|
<path d="M9 18c-4.51 2-5-2-7-2"></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DuckSvg from "./ducks/Duck1.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Header",
|
||||||
|
components: {
|
||||||
|
DuckSvg,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.header {
|
||||||
|
position: relative;
|
||||||
|
padding: 2.5rem 1rem 1rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-svg {
|
||||||
|
width: 5rem;
|
||||||
|
height: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
transform: translateX(80%) translateY(-30%);
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 1rem;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border: 8px solid transparent;
|
||||||
|
border-right-color: white;
|
||||||
|
border-left: 0;
|
||||||
|
margin-top: -8px;
|
||||||
|
margin-left: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble-text {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-info {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
font-size: 1.875rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--duck-dark-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-subtitle {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
color: var(--gray-600);
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-links {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-link {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
background-color: white;
|
||||||
|
color: var(--text-color);
|
||||||
|
transition:
|
||||||
|
background-color 0.2s,
|
||||||
|
color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-link:hover {
|
||||||
|
background-color: #f3f4f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.header {
|
||||||
|
padding: 2.5rem 2rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-container {
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
332
src/components/Landing.vue
Normal file
332
src/components/Landing.vue
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
<template>
|
||||||
|
<section class="landing">
|
||||||
|
<div class="landing-container">
|
||||||
|
<div class="landing-content animate-splash">
|
||||||
|
<div class="terminal-duck-container">
|
||||||
|
<div class="terminal-wrapper">
|
||||||
|
<DuckTerminal />
|
||||||
|
</div>
|
||||||
|
<div class="duck-container">
|
||||||
|
<div class="duck-placeholder">
|
||||||
|
<img
|
||||||
|
src="../assets/duck.gif"
|
||||||
|
alt="Dancing Duck"
|
||||||
|
class="dancing-duck"
|
||||||
|
@load="duckLoaded = true"
|
||||||
|
:class="{ 'duck-loaded': duckLoaded }"
|
||||||
|
/>
|
||||||
|
<div class="duck-loading" v-if="!duckLoaded">
|
||||||
|
<span class="loading-text">Chargement du canard...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="landing-buttons">
|
||||||
|
<button class="btn btn-primary">
|
||||||
|
Voir mon parcours
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="btn-icon"
|
||||||
|
>
|
||||||
|
<path d="M12 5v14"></path>
|
||||||
|
<path d="m19 12-7 7-7-7"></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<a href="mailto:contact@maric.ro" class="btn btn-secondary"
|
||||||
|
>Me contacter</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="duck-container-small">
|
||||||
|
<DuckSvg svgClass="duck-svg animate-float" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Background Duck Elements -->
|
||||||
|
<div class="bg-duck bg-duck-1">
|
||||||
|
<DuckSvg />
|
||||||
|
</div>
|
||||||
|
<div class="bg-duck bg-duck-2">
|
||||||
|
<DuckSvg />
|
||||||
|
</div>
|
||||||
|
<div class="bg-duck bg-duck-3">
|
||||||
|
<DuckSvg />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DuckSvg from "./ducks/Duck1.vue";
|
||||||
|
import DuckTerminal from "./DuckTerminal.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Landing",
|
||||||
|
components: {
|
||||||
|
DuckSvg,
|
||||||
|
DuckTerminal,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
duckLoaded: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.landing {
|
||||||
|
padding: 4rem 1rem;
|
||||||
|
min-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
max-width: 90%;
|
||||||
|
margin: 0 auto;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-content {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-duck-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-wrapper {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-container {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
height: 2.75rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
padding: 0 2rem;
|
||||||
|
transition: all 0.2s;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: var(--duck-yellow);
|
||||||
|
color: black;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: rgba(255, 219, 88, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid var(--duck-blue);
|
||||||
|
color: var(--duck-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background-color: rgba(70, 130, 180, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-icon {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-container-small {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-svg {
|
||||||
|
width: 5rem;
|
||||||
|
height: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dancing-duck {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
object-fit: contain;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-placeholder {
|
||||||
|
width: 320px;
|
||||||
|
height: 320px;
|
||||||
|
position: relative;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-loaded {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-loading {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
color: var(--duck-yellow, #ffdb58);
|
||||||
|
font-family: "Courier New", monospace;
|
||||||
|
font-size: 1rem;
|
||||||
|
animation: duck-bounce 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes duck-bounce {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Background Duck Elements */
|
||||||
|
.bg-duck {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0.1;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-duck-1 {
|
||||||
|
top: 8rem;
|
||||||
|
right: 2.5rem;
|
||||||
|
transform: rotate(12deg);
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-duck-1 svg {
|
||||||
|
width: 16rem;
|
||||||
|
height: 16rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-duck-2 {
|
||||||
|
bottom: 40%;
|
||||||
|
left: 0;
|
||||||
|
transform: rotate(-12deg);
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-duck-2 svg {
|
||||||
|
width: 12rem;
|
||||||
|
height: 12rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-duck-3 {
|
||||||
|
bottom: 33.333%;
|
||||||
|
right: 33.333%;
|
||||||
|
opacity: 0.05;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-duck-3 svg {
|
||||||
|
width: 24rem;
|
||||||
|
height: 24rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.landing-content {
|
||||||
|
text-align: left;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-duck-container {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-wrapper {
|
||||||
|
width: 60%;
|
||||||
|
margin-right: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-container {
|
||||||
|
width: 40%;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-buttons {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duck-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-duck-1,
|
||||||
|
.bg-duck-2 {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.bg-duck-3 {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
34
src/components/ducks/Duck1.vue
Normal file
34
src/components/ducks/Duck1.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
:class="svgClass"
|
||||||
|
>
|
||||||
|
<ellipse cx="256" cy="256" rx="180" ry="170" fill="#FFDB58" />
|
||||||
|
<circle cx="360" cy="180" r="90" fill="#FFDB58" />
|
||||||
|
<circle cx="390" cy="160" r="15" fill="#333" />
|
||||||
|
<path d="M430 190 L480 180 L430 210 Z" fill="#F97316" />
|
||||||
|
<path d="M180 370 L150 410 L210 410 Z" fill="#F97316" />
|
||||||
|
<path d="M300 370 L270 410 L330 410 Z" fill="#F97316" />
|
||||||
|
<ellipse
|
||||||
|
cx="200"
|
||||||
|
cy="250"
|
||||||
|
rx="60"
|
||||||
|
ry="40"
|
||||||
|
fill="#FFE082"
|
||||||
|
transform="rotate(-10, 200, 250)"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DuckSvg",
|
||||||
|
props: {
|
||||||
|
svgClass: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
0
src/components/ducks/Duck2.vue
Normal file
0
src/components/ducks/Duck2.vue
Normal file
5
src/main.js
Normal file
5
src/main.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { createApp } from "vue";
|
||||||
|
import "./style.css";
|
||||||
|
import App from "./App.vue";
|
||||||
|
|
||||||
|
createApp(App).mount("#app");
|
0
src/style.css
Normal file
0
src/style.css
Normal file
7
vite.config.js
Normal file
7
vite.config.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
})
|
Loading…
x
Reference in New Issue
Block a user