Changes in code after first review from Google AI Studio
Deploy to Production / deploy (push) Successful in 12s
Details
Deploy to Production / deploy (push) Successful in 12s
Details
This commit is contained in:
parent
4c58da3eba
commit
2807a55b26
File diff suppressed because it is too large
Load Diff
|
|
@ -9,6 +9,7 @@
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="../css/style.css">
|
||||||
|
<script>document.documentElement.classList.add('js-enabled');</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="site-shell">
|
<div class="site-shell">
|
||||||
|
|
@ -61,7 +62,7 @@
|
||||||
<article class="form-card" data-animate>
|
<article class="form-card" data-animate>
|
||||||
<h2 class="form-card__title">Fill out to connect</h2>
|
<h2 class="form-card__title">Fill out to connect</h2>
|
||||||
<div class="form-card__accent"></div>
|
<div class="form-card__accent"></div>
|
||||||
<form class="form" action="./" method="post" novalidate data-contact-form>
|
<form class="form" action="https://formspree.io/f/YOUR_ID_HERE" method="post" novalidate data-contact-form>
|
||||||
<div class="form__grid">
|
<div class="form__grid">
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label class="form-field__label" for="full-name">Full Name</label>
|
<label class="form-field__label" for="full-name">Full Name</label>
|
||||||
|
|
@ -91,7 +92,7 @@
|
||||||
</div>
|
</div>
|
||||||
<button class="button button--dark button--block" type="submit">Send Message</button>
|
<button class="button button--dark button--block" type="submit">Send Message</button>
|
||||||
<div class="form-status" aria-live="polite" data-form-status></div>
|
<div class="form-status" aria-live="polite" data-form-status></div>
|
||||||
<p class="form-note">This is a static form prepared for backend connection later. Current validation runs entirely in the browser.</p>
|
<p class="form-note">Replace the placeholder Formspree action with your real form ID to enable live submissions.</p>
|
||||||
</form>
|
</form>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,8 @@ body {
|
||||||
|
|
||||||
body.menu-open {
|
body.menu-open {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
height: 100vh;
|
||||||
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
|
|
@ -1541,7 +1543,7 @@ textarea {
|
||||||
color: var(--color-text-soft);
|
color: var(--color-text-soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-animate] {
|
.js-enabled [data-animate] {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(18px);
|
transform: translateY(18px);
|
||||||
transition: opacity 520ms ease, transform 520ms ease;
|
transition: opacity 520ms ease, transform 520ms ease;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="../css/style.css">
|
||||||
|
<script>document.documentElement.classList.add('js-enabled');</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="site-shell">
|
<div class="site-shell">
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="css/style.css">
|
<link rel="stylesheet" href="css/style.css">
|
||||||
|
<script>document.documentElement.classList.add('js-enabled');</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="site-shell">
|
<div class="site-shell">
|
||||||
|
|
@ -271,7 +272,10 @@
|
||||||
<h2 class="cta-banner__title">Start a conversation.</h2>
|
<h2 class="cta-banner__title">Start a conversation.</h2>
|
||||||
<p class="cta-banner__text">Whether it is a strategic partnership, a governance initiative, or a project that needs measured leadership, the next step can start here.</p>
|
<p class="cta-banner__text">Whether it is a strategic partnership, a governance initiative, or a project that needs measured leadership, the next step can start here.</p>
|
||||||
<div class="cta-banner__actions">
|
<div class="cta-banner__actions">
|
||||||
<a class="button button--secondary" href="mailto:popovskik02@yahoo.com">Email</a>
|
<a class="button button--secondary" href="mailto:popovskik02@yahoo.com">
|
||||||
|
<svg class="button__icon" viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4-8 5-8-5V6l8 5 8-5v2z"/></svg>
|
||||||
|
Email Me
|
||||||
|
</a>
|
||||||
<a class="button button--secondary" href="https://www.linkedin.com/in/popovski-k/" target="_blank" rel="noreferrer">LinkedIn</a>
|
<a class="button button--secondary" href="https://www.linkedin.com/in/popovski-k/" target="_blank" rel="noreferrer">LinkedIn</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -288,7 +292,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="site-footer__links">
|
<div class="site-footer__links">
|
||||||
<a class="site-footer__link" href="projects/">Projects</a>
|
<a class="site-footer__link" href="projects/">Projects</a>
|
||||||
<a class="site-footer__link" href="cv/">Download CV</a>
|
<a class="site-footer__link" href="assets/documents/cv_full.pdf" target="_blank" rel="noreferrer">Download CV</a>
|
||||||
<a class="site-footer__link" href="mailto:popovskik02@yahoo.com">Email</a>
|
<a class="site-footer__link" href="mailto:popovskik02@yahoo.com">Email</a>
|
||||||
<a class="site-footer__link" href="https://www.linkedin.com/in/popovski-k/" target="_blank" rel="noreferrer">LinkedIn</a>
|
<a class="site-footer__link" href="https://www.linkedin.com/in/popovski-k/" target="_blank" rel="noreferrer">LinkedIn</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
31
js/script.js
31
js/script.js
|
|
@ -136,6 +136,9 @@ function setupContactForm() {
|
||||||
|
|
||||||
const fields = Array.from(form.querySelectorAll("[data-required], [type='email']"));
|
const fields = Array.from(form.querySelectorAll("[data-required], [type='email']"));
|
||||||
const status = form.querySelector("[data-form-status]");
|
const status = form.querySelector("[data-form-status]");
|
||||||
|
const action = (form.getAttribute("action") || "").trim();
|
||||||
|
const hasExternalEndpoint = /^https?:\/\//i.test(action);
|
||||||
|
const hasPlaceholderEndpoint = action.includes("YOUR_ID_HERE");
|
||||||
|
|
||||||
const validators = {
|
const validators = {
|
||||||
email: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
|
email: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
|
||||||
|
|
@ -209,14 +212,30 @@ function setupContactForm() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
status.textContent = "Thanks. Your message structure is validated and ready for backend integration.";
|
status.classList.remove("is-success");
|
||||||
status.classList.add("is-success");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
form.reset();
|
if (!hasExternalEndpoint || hasPlaceholderEndpoint) {
|
||||||
fields.forEach((field) => setFieldError(field, ""));
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
status.textContent = hasPlaceholderEndpoint
|
||||||
|
? "Replace the Formspree form ID to enable live message delivery."
|
||||||
|
: "Thanks. Your message structure is validated and ready for backend integration.";
|
||||||
|
status.classList.toggle("is-success", !hasPlaceholderEndpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasPlaceholderEndpoint) {
|
||||||
|
form.reset();
|
||||||
|
fields.forEach((field) => setFieldError(field, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
status.textContent = "Submitting your message...";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="../css/style.css">
|
||||||
|
<script>document.documentElement.classList.add('js-enabled');</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="site-shell">
|
<div class="site-shell">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue