Updated telegram and formatting

This commit is contained in:
2023-01-01 21:58:51 +03:00
parent 35b6170959
commit 3963b68a73
18 changed files with 131 additions and 103 deletions

View File

@@ -1,32 +1,39 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" />
<title>Anatoly Kopyl</title>
<!-- Yandex.Metrika counter --> <head>
<script type="text/javascript" > <meta charset="utf-8" />
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; <meta name="viewport" content="width=device-width, initial-scale=1" />
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) <meta name="theme-color" content="#000000" />
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" />
<title>Anatoly Kopyl</title>
<!-- Yandex.Metrika counter -->
<script type="text/javascript">
(function (m, e, t, r, i, k, a) {
m[i] = m[i] || function () { (m[i].a = m[i].a || []).push(arguments) };
m[i].l = 1 * new Date(); k = e.createElement(t), a = e.getElementsByTagName(t)[0], k.async = 1, k.src = r, a.parentNode.insertBefore(k, a)
})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(88895893, "init", { ym(88895893, "init", {
clickmap:true, clickmap: true,
trackLinks:true, trackLinks: true,
accurateTrackBounce:true, accurateTrackBounce: true,
webvisor:true webvisor: true
}); });
</script> </script>
<noscript><div><img src="https://mc.yandex.ru/watch/88895893" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <noscript>
<!-- /Yandex.Metrika counter --> <div><img src="https://mc.yandex.ru/watch/88895893" style="position:absolute; left:-9999px;" alt="" /></div>
</head> </noscript>
<body> <!-- /Yandex.Metrika counter -->
<noscript>You need to enable JavaScript to run this app.</noscript> </head>
<div id="root"></div>
<script src="/src/index.tsx" type="module"></script> <body>
</body> <noscript>You need to enable JavaScript to run this app.</noscript>
</html> <div id="root"></div>
<script src="/src/index.tsx" type="module"></script>
</body>
</html>

View File

@@ -8,10 +8,10 @@ import ContactForm from './components/ContactForm'
const App: Component = () => { const App: Component = () => {
return ( return (
<div class='App'> <div class='App'>
<Controls/> <Controls />
<Hero/> <Hero />
<Projects/> <Projects />
<ContactForm/> <ContactForm />
</div> </div>
); );
}; };

View File

@@ -11,7 +11,7 @@
align-items: center; align-items: center;
} }
.form > * { .form>* {
width: 100%; width: 100%;
max-width: 600px; max-width: 600px;
box-sizing: border-box; box-sizing: border-box;
@@ -28,4 +28,4 @@
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
} }
} }

View File

@@ -9,7 +9,7 @@ import styles from './ContactForm.module.css';
export default () => { export default () => {
const [t] = useI18n(); const [t] = useI18n();
const [state, setters] = useStore() as Store; const [state, setters] = useStore() as Store;
const [observer] = createViewportObserver({threshold: 0.9}); const [observer] = createViewportObserver({ threshold: 0.9 });
const chapterName = 'mail'; const chapterName = 'mail';
return ( return (
@@ -21,7 +21,7 @@ export default () => {
} else if (state.visibleChapter() === chapterName) { } else if (state.visibleChapter() === chapterName) {
setters.setScrolling(false) setters.setScrolling(false)
} }
// Сраный костыль // Сраный костыль
} else if (state.visibleChapter() === chapterName) { } else if (state.visibleChapter() === chapterName) {
setters.setVisibleChapter('projects'); setters.setVisibleChapter('projects');
} }
@@ -35,14 +35,14 @@ export default () => {
method="post" method="post"
autocomplete='off' autocomplete='off'
> >
<input <input
type="text" type="text"
name="name" name="name"
placeholder={t('name')} placeholder={t('name')}
></input> ></input>
<textarea <textarea
name="message" name="message"
placeholder={t('message')} placeholder={t('message')}
rows='4' rows='4'
></textarea> ></textarea>
@@ -55,7 +55,7 @@ export default () => {
<input <input
class={styles.submit} class={styles.submit}
type="submit" type="submit"
value={t('submit')} value={t('submit')}
></input> ></input>
</form> </form>

View File

@@ -1,3 +1,7 @@
:root {
--blob-distance: 70px;
}
.Controls { .Controls {
position: fixed; position: fixed;
background: var(--clr-bg-secondary); background: var(--clr-bg-secondary);
@@ -12,12 +16,13 @@
.chapters { .chapters {
position: relative; position: relative;
height: calc(70px * 3); height: calc(var(--blob-distance) * 3);
width: 100%; width: 100%;
margin-bottom: var(--gap-md); margin-bottom: var(--gap-md);
} }
.controlsWrapper, .gooWrapper { .controlsWrapper,
.gooWrapper {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
@@ -29,7 +34,8 @@
filter: url('#goo'); filter: url('#goo');
} }
.control, .blob { .control,
.blob {
position: absolute; position: absolute;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
@@ -46,7 +52,7 @@
box-sizing: border-box; box-sizing: border-box;
} }
.control > img { .control>img {
width: 100%; width: 100%;
} }
@@ -62,15 +68,16 @@
.selected { .selected {
width: 64px; width: 64px;
height: 64px; height: 64px;
transform: translateX(-50%);
} }
.control:nth-child(2), .blob:nth-child(2) { .control:nth-child(2),
top: 70px; .blob:nth-child(2) {
top: var(--blob-distance);
} }
.control:nth-child(3), .blob:nth-child(3) { .control:nth-child(3),
top: calc(70px * 2); .blob:nth-child(3) {
top: calc(var(--blob-distance) * 2);
} }
@media screen and (max-width: 1080px) { @media screen and (max-width: 1080px) {
@@ -85,29 +92,33 @@
} }
.chapters { .chapters {
width: calc(70px * 3); width: calc(var(--blob-distance) * 3);
height: 64px; height: 64px;
margin: auto; margin: auto;
} }
.control, .blob { .control,
.blob {
top: 0; top: 0;
left: 0; left: 0;
transform: translateX(0); transform: translateX(0);
} }
.control, .control > img { .control,
.control>img {
width: auto; width: auto;
height: 100%; height: 100%;
} }
.control:nth-child(2), .blob:nth-child(2) { .control:nth-child(2),
.blob:nth-child(2) {
top: unset; top: unset;
left: 70px; left: var(--blob-distance);
} }
.control:nth-child(3), .blob:nth-child(3) { .control:nth-child(3),
.blob:nth-child(3) {
top: unset; top: unset;
left: calc(70px * 2); left: calc(var(--blob-distance) * 2);
} }
} }

View File

@@ -9,7 +9,7 @@ import gridIcon from '../assets/icons/grid.svg'
import mailIcon from '../assets/icons/mail.svg' import mailIcon from '../assets/icons/mail.svg'
export default () => { export default () => {
const [state, {setVisibleChapter, setScrolling}] = useStore() as Store; const [state, { setVisibleChapter, setScrolling }] = useStore() as Store;
const [selected, setSelected] = createSignal('home'); const [selected, setSelected] = createSignal('home');
const [blobby, setBlobby] = createSignal(['home']); const [blobby, setBlobby] = createSignal(['home']);
const chapters = [ const chapters = [
@@ -42,7 +42,7 @@ export default () => {
<div class={styles.chapters}> <div class={styles.chapters}>
<div class={styles.gooWrapper}> <div class={styles.gooWrapper}>
<For each={chapters}>{(chapter) => <For each={chapters}>{(chapter) =>
<div <div
class={styles.blob} class={styles.blob}
classList={{ classList={{
[styles.selected]: blobby().includes(chapter.name) [styles.selected]: blobby().includes(chapter.name)
@@ -52,14 +52,14 @@ export default () => {
</div> </div>
<div class={styles.controlsWrapper}> <div class={styles.controlsWrapper}>
<For each={chapters}>{(chapter) => <For each={chapters}>{(chapter) =>
<div <div
onClick={() => { onClick={() => {
setScrolling(true); setScrolling(true);
selectChapter(chapter.name) selectChapter(chapter.name)
}} }}
class={styles.control} class={styles.control}
> >
<img <img
src={chapter.icon} src={chapter.icon}
/> />
</div> </div>
@@ -71,13 +71,13 @@ export default () => {
</div> </div>
<svg style="display: none;" xmlns="http://www.w3.org/2000/svg" version="1.1"> <svg style="display: none;" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs> <defs>
<filter id="goo"> <filter id="goo">
<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" /> <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
<feColorMatrix in="blur" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" /> <feColorMatrix in="blur" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/> <feComposite in="SourceGraphic" in2="goo" operator="atop" />
</filter> </filter>
</defs> </defs>
</svg> </svg>
</> </>
) )

View File

@@ -14,13 +14,13 @@
.gradientText { .gradientText {
max-width: 100%; max-width: 100%;
display: inline-block; display: inline-block;
font-size: 86px; font-size: 86px;
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
animation: gradient 5s ease infinite; animation: gradient 5s ease infinite;
width: max-content; width: max-content;
background-size: 200% auto; background-size: 200% auto;
word-break: break-word; word-break: break-word;
} }
@@ -41,9 +41,11 @@
0% { 0% {
background-position: 0% 50%; background-position: 0% 50%;
} }
50% { 50% {
background-position: 100% 50%; background-position: 100% 50%;
} }
100% { 100% {
background-position: 0% 50%; background-position: 0% 50%;
} }
@@ -53,4 +55,4 @@
.gradientText { .gradientText {
font-size: 72px; font-size: 72px;
} }
} }

View File

@@ -9,13 +9,13 @@ import styles from './Hero.module.css';
export default () => { export default () => {
const [t] = useI18n(); const [t] = useI18n();
const [observer] = createViewportObserver({threshold: 0.8}); const [observer] = createViewportObserver({ threshold: 0.8 });
const [state, setters] = useStore() as Store; const [state, setters] = useStore() as Store;
const chapterName = 'home' const chapterName = 'home'
return ( return (
<header <header
use:observer={(event) => { use:observer={(event) => {
if (event.isIntersecting) { if (event.isIntersecting) {
if (!state.scrolling()) { if (!state.scrolling()) {
setters.setVisibleChapter(chapterName); setters.setVisibleChapter(chapterName);
@@ -36,7 +36,7 @@ export default () => {
<Links /> <Links />
<div <div
class={styles.blur} class={styles.blur}
ref={(element) => { ref={(element) => {
setTimeout(() => element.style.opacity = '0') setTimeout(() => element.style.opacity = '0')

View File

@@ -8,7 +8,7 @@
margin: auto; margin: auto;
} }
.LanguageSelector > img { .LanguageSelector>img {
margin-right: 6px; margin-right: 6px;
} }
@@ -19,4 +19,4 @@
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
} }
} }

View File

@@ -35,7 +35,7 @@ export default () => {
}} }}
class={styles.LanguageSelector} class={styles.LanguageSelector}
> >
<img src={globeIcon}/> <img src={globeIcon} />
{t('lang')} {t('lang')}
</div> </div>
) )

View File

@@ -3,7 +3,7 @@
bottom: var(--gap-lg); bottom: var(--gap-lg);
} }
.Links > a { .Links>a {
margin: 0 var(--gap-sm); margin: 0 var(--gap-sm);
} }
@@ -11,4 +11,4 @@
.Links { .Links {
bottom: calc(64px + var(--gap-lg)); bottom: calc(64px + var(--gap-lg));
} }
} }

View File

@@ -3,20 +3,20 @@ import styles from './Links.module.css';
export default () => { export default () => {
return ( return (
<div class={styles.Links}> <div class={styles.Links}>
<a <a
href='https://github.com/anatolykopyl' href='https://github.com/anatolykopyl'
target='_blank' target='_blank'
> >
github github
</a> </a>
<a <a
href='https://www.linkedin.com/in/akopyl/' href='https://www.linkedin.com/in/akopyl/'
target='_blank' target='_blank'
> >
linkedin linkedin
</a> </a>
<a <a
href='https://t.me/avkopyl' href='https://t.me/anatolykopyl'
target='_blank' target='_blank'
> >
telegram telegram

View File

@@ -36,5 +36,5 @@
@media screen and (max-width: 1464px) { @media screen and (max-width: 1464px) {
.Project { .Project {
width: calc(50% - var(--gap-lg)); width: calc(50% - var(--gap-lg));
} }
} }

View File

@@ -3,7 +3,7 @@ import { useI18n } from "@solid-primitives/i18n";
import styles from './Project.module.css'; import styles from './Project.module.css';
import type { Project } from './projectList'; import type { Project } from './projectList';
export default (props: {project: Project}) => { export default (props: { project: Project }) => {
const [t] = useI18n(); const [t] = useI18n();
return ( return (

View File

@@ -16,4 +16,4 @@
box-sizing: border-box; box-sizing: border-box;
flex-direction: column; flex-direction: column;
} }
} }

View File

@@ -11,7 +11,7 @@ import type { Project as ProjectType } from './projectList';
export default () => { export default () => {
const [state, setters] = useStore() as Store; const [state, setters] = useStore() as Store;
const [observer] = createViewportObserver({threshold: 0.1}); const [observer] = createViewportObserver({ threshold: 0.1 });
const chapterName = 'projects' const chapterName = 'projects'
return ( return (
@@ -33,7 +33,7 @@ export default () => {
project={project} project={project}
/> />
}</For> }</For>
</div> </div>
) )
}; };

View File

@@ -15,8 +15,8 @@
--radius-md: 12px; --radius-md: 12px;
--ff-default: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', --ff-default: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif; sans-serif;
--font-sm: normal normal 300 16px var(--ff-default); --font-sm: normal normal 300 16px var(--ff-default);
--font-md: normal normal 400 18px var(--ff-default); --font-md: normal normal 400 18px var(--ff-default);
} }
@@ -34,7 +34,12 @@ body {
background: var(--clr-bg); background: var(--clr-bg);
} }
h1, h2, h3, h4, h5, h6 { h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0; margin: 0;
} }
@@ -49,7 +54,8 @@ code {
monospace; monospace;
} }
input, textarea { input,
textarea {
background: var(--clr-bg-secondary); background: var(--clr-bg-secondary);
border: none; border: none;
padding: var(--gap-sm); padding: var(--gap-sm);
@@ -62,10 +68,12 @@ textarea {
resize: none; resize: none;
} }
textarea:focus, input:focus{ textarea:focus,
input:focus {
outline: none; outline: none;
} }
input::placeholder, textarea::placeholder { input::placeholder,
textarea::placeholder {
color: var(--clr-text-secondary); color: var(--clr-text-secondary);
} }

View File

@@ -11,10 +11,10 @@ import localization from './localization';
render( render(
() => ( () => (
<StoreProvider> <StoreProvider>
<I18nContext.Provider value={localization}> <I18nContext.Provider value={localization}>
<App /> <App />
</I18nContext.Provider> </I18nContext.Provider>
</StoreProvider> </StoreProvider>
), ),
document.getElementById('root') as HTMLElement document.getElementById('root') as HTMLElement
); );