Update Home page links and enhance styling for improved user experience

This commit is contained in:
Kiyan 2026-01-01 22:00:14 +02:00
parent 1a43ad08e4
commit 6606dc2611
5 changed files with 307 additions and 409 deletions

View File

@ -29,8 +29,8 @@ public class Home {
//navbar links //navbar links
model.addAttribute("links", List.of( model.addAttribute("links", List.of(
new Link("About", "#about"), new Link("About", "#about"),
new Link("Experience", "#experience"), new Link("Experience", "#resume-details"),
new Link("Education", "#education"), new Link("Education", "#resume-details"),
new Link("Projects", "#projects"), new Link("Projects", "#projects"),
new Link("Contact", "#contact") new Link("Contact", "#contact")
)); ));

View File

@ -1,108 +1,96 @@
body { body {
scroll-behavior: smooth; scroll-behavior: smooth;
font-family: 'Inter', system-ui, -apple-system, sans-serif;
color: #333;
} }
section { section {
padding: 4rem 0; padding: 5rem 0;
border-bottom: 1px solid var(--bs-secondary-bg-subtle);
} }
h1, h2, h3, h4, h5 { /* Reduced spacing for Hero */
letter-spacing: 0.02em; .intro {
padding: 100px 0 60px 0;
background: radial-gradient(circle at top right, #f8f9ff 0%, #ffffff 100%);
} }
/* ---------- NAVBAR ---------- */ .profile-img {
.navbar { border: 8px solid #fff;
backdrop-filter: blur(6px); box-shadow: 0 10px 30px rgba(0,0,0,0.1);
object-fit: cover;
border-radius: 50%;
} }
.nav-link { /* Skill Badges */
.skill-badge {
background: #f0f2f5;
color: #475569;
padding: 0.4rem 0.8rem;
border-radius: 6px;
font-size: 0.85rem;
font-weight: 500;
border: 1px solid rgba(0,0,0,0.05);
}
/* Timeline UI to fix "weird" wide cards */
.timeline-card {
position: relative; position: relative;
padding-left: 1.5rem;
border-left: 2px solid #e9ecef;
margin-bottom: 2rem;
transition: 0.3s;
} }
.nav-link::after { .timeline-card::before {
content: ""; content: "";
position: absolute; position: absolute;
left: 0; left: -7px;
bottom: -4px; top: 4px;
width: 0; width: 12px;
height: 2px; height: 12px;
background-color: var(--bs-primary); border-radius: 50%;
transition: width 0.3s ease; background: var(--bs-primary);
} }
.nav-link:hover::after { /* Section Headers */
width: 100%;
}
/* ---------- ICON LINKS ---------- */
.icon-link i {
font-size: 1.6rem;
transition: color 0.3s ease, transform 0.3s ease;
}
.icon-link:hover i {
color: var(--bs-primary);
transform: translateY(-3px);
}
/* ---------- INTRO / HERO ---------- */
.intro {
min-height: 70vh;
display: flex;
align-items: center;
background: linear-gradient(180deg, var(--bs-light), #ffffff);
}
.intro img {
border: 4px solid var(--bs-white);
}
.skill-badge {
background: var(--bs-secondary-bg);
border-radius: 2rem;
padding: 0.4rem 0.9rem;
font-size: 0.85rem;
}
/* ---------- CARDS (GLOBAL) ---------- */
.card,
.project-item,
.contact-box {
border-radius: 1rem;
border: 1px solid var(--bs-secondary-bg-subtle);
transition: transform 0.3s ease, box-shadow 0.3s ease;
background: var(--bs-white);
}
.card:hover,
.project-item:hover,
.contact-box:hover {
transform: translateY(-6px);
box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.08);
}
/* ---------- SECTION HEADERS ---------- */
.section-header { .section-header {
text-align: center; margin-bottom: 2.5rem;
margin-bottom: 3rem; border-bottom: 2px solid #f0f0f0;
padding-bottom: 0.75rem;
} }
.section-header i { /* Modern Project Cards */
font-size: 2rem; .project-item {
color: var(--bs-primary); border-radius: 12px;
background: white;
border: 1px solid rgba(0,0,0,0.05);
transition: all 0.3s ease;
} }
/* ---------- FOOTER ---------- */ .project-item:hover {
footer a { transform: translateY(-5px);
text-decoration: none; box-shadow: 0 15px 35px rgba(0,0,0,0.1) !important;
transition: color 0.3s ease; border-color: var(--bs-primary);
} }
footer a:hover { .w-fit {
color: var(--bs-primary); width: fit-content;
} }
footer i { /* Form Controls */
font-size: 1.4rem; .form-control {
padding: 0.75rem;
border-radius: 8px;
border: 1px solid #e0e0e0;
}
.form-control:focus {
box-shadow: 0 0 0 4px rgba(13, 110, 253, 0.1);
}
/* Navbar blur effect */
.navbar {
backdrop-filter: blur(10px);
background-color: rgba(255, 255, 255, 0.8) !important;
border-bottom: 1px solid rgba(0,0,0,0.05);
} }

View File

@ -1,104 +1,62 @@
body { body {
scroll-behavior: smooth; scroll-behavior: smooth;
font-family: 'Inter', system-ui, -apple-system, sans-serif;
background-color: #f9fbff; /* Very slight blue tint for a technical look */
} }
section { /* --- HERO --- */
padding: 5rem 0;
border-bottom: 1px solid var(--bs-secondary-bg-subtle);
}
h1,
h2,
h3,
h4,
h5 {
letter-spacing: 0.02em;
}
.hero { .hero {
min-height: 65vh; padding: 80px 0 40px;
background: #ffffff;
}
.project-badge {
text-transform: uppercase;
letter-spacing: 0.1rem;
font-size: 0.75rem;
font-weight: 700;
color: var(--bs-primary);
}
/* --- DYNAMIC CONTENT TABS --- */
.nav-pills .nav-link {
color: #6c757d;
font-weight: 600;
padding: 0.8rem 1.5rem;
border-radius: 8px;
transition: all 0.2s;
}
.nav-pills .nav-link.active {
background-color: var(--bs-primary);
box-shadow: 0 4px 12px rgba(13, 110, 253, 0.2);
}
.dynamic-container {
background: #ffffff;
border: 1px solid rgba(0,0,0,0.05);
border-radius: 16px;
padding: 3rem;
min-height: 400px; /* Prevents jumping when switching tabs */
box-shadow: 0 10px 30px rgba(0,0,0,0.02);
}
/* --- CAROUSEL --- */
.browser-frame {
border: 1px solid #dee2e6;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 20px 50px rgba(0,0,0,0.1);
}
.browser-bar {
background: #f1f1f1;
height: 30px;
display: flex; display: flex;
align-items: center; align-items: center;
text-align: center; padding-left: 15px;
gap: 6px;
} }
.hero img { .dot { height: 8px; width: 8px; border-radius: 50%; background: #ddd; }
transition: transform 0.4s ease;
}
/* ---------- NAVBAR ---------- */
.navbar {
backdrop-filter: blur(6px);
}
.nav-link {
position: relative;
}
.nav-link::after {
content: "";
position: absolute;
left: 0;
bottom: -4px;
width: 0;
height: 2px;
background-color: var(--bs-primary);
transition: width 0.3s ease;
}
.nav-link:hover::after {
width: 100%;
}
.nav-link::after {
content: "";
position: absolute;
left: 0;
bottom: -4px;
width: 0;
height: 2px;
background-color: var(--bs-primary);
transition: width 0.3s ease;
}
.icon-link i {
font-size: 1.5rem;
transition: color 0.3s ease, transform 0.3s ease;
}
.icon-link:hover i {
color: var(--bs-primary);
transform: translateY(-2px);
}
.card,
.project-box {
border-radius: 1rem;
border: 1px solid var(--bs-secondary-bg-subtle);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover,
.project-box:hover {
transform: translateY(-5px);
box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.08);
}
.tech-chips {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.tech-chip {
padding: 0.375rem 0.75rem;
font-size: 0.875rem;
font-weight: 500;
border-radius: 999px;
background-color: #f1f3f5;
color: #495057;
border: 1px solid #dee2e6;
white-space: nowrap;
}

View File

@ -12,183 +12,135 @@
<link th:href="@{/assets/css/bootstrap.min.css}" rel="stylesheet"> <link th:href="@{/assets/css/bootstrap.min.css}" rel="stylesheet">
<link th:href="@{https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css}" rel="stylesheet"> <link th:href="@{https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css}" rel="stylesheet">
<link rel="stylesheet" th:href="@{/assets/css/home.css}"> <link rel="stylesheet" th:href="@{/assets/css/home.css}">
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
</head> </head>
<body> <body>
<!-- NAVBAR -->
<div th:replace="~{fragments/navbar :: navbar}"></div> <div th:replace="~{fragments/navbar :: navbar}"></div>
<!-- INTRO / HERO + ABOUT -->
<header id="about" class="intro"> <header id="about" class="intro">
<div class="container"> <div class="container">
<div class="row align-items-center gy-4"> <div class="row align-items-center gy-4">
<div class="col-md-4 text-center"> <div class="col-md-4 text-center">
<img th:src="@{/assets/images/profileImage.jpg}" class="rounded-circle mb-3" width="160" <img th:src="@{/assets/images/profileImage.jpg}" class="profile-img mb-3" width="180" height="180" alt="Kiyan Mckop">
height="160" alt="Kiyan Mckop">
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<h1 class="fw-bold">Kiyan Mckop</h1> <h1 class="display-5 fw-bold">Kiyan Mckop</h1>
<p class="lead text-muted mb-3"> <p class="lead text-secondary mb-3">
Software Engineer specializing in Java, Spring Boot, and backend systems. Software Engineer specializing in <span class="text-primary fw-semibold">Java, Spring Boot</span>, and backend systems.
</p> </p>
<p class="text-muted">
<p> Honours graduate in IT with experience building secure, maintainable enterprise software and internal ERP systems.
Honours graduate in Information Technology with experience building secure,
maintainable enterprise software and internal ERP systems.
</p> </p>
<div class="d-flex flex-wrap gap-2 my-4">
<!-- Skills -->
<div class="d-flex flex-wrap gap-2 my-3">
<span class="skill-badge">Java</span> <span class="skill-badge">Java</span>
<span class="skill-badge">Spring Boot</span> <span class="skill-badge">Spring Boot</span>
<span class="skill-badge">REST APIs</span> <span class="skill-badge">REST APIs</span>
<span class="skill-badge">SQL</span> <span class="skill-badge">SQL</span>
<span class="skill-badge">Docker</span> <span class="skill-badge">Docker</span>
</div> </div>
<div class="d-flex gap-4">
<!-- Actions --> <a class="icon-link" th:href="@{/resume}" title="Resume"><i class="bi bi-file-earmark-person"></i></a>
<div class="d-flex gap-4 mt-3"> <a class="icon-link" th:href="@{/cv}" title="CV"><i class="bi bi-file-earmark-text"></i></a>
<a class="icon-link" th:href="@{/resume}" title="Resume"> <a class="icon-link" href="https://mckopserver.ddns.net" target="_blank" title="Server"><i class="bi bi-hdd-network"></i></a>
<i class="bi bi-file-earmark-person"></i>
</a>
<a class="icon-link" th:href="@{/cv}"
title="CV">
<i class="bi bi-file-earmark-text"></i>
</a>
<a class="icon-link" href="https://mckopserver.ddns.net" target="_blank" title="Server">
<i class="bi bi-hdd-network"></i>
</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</header> </header>
<!-- EXPERIENCE --> <section id="resume-details" class="bg-light">
<section id="experience"> <div class="container">
<div class="row g-5">
<div class="col-lg-6">
<div class="section-header">
<h2 class="fw-bold"><i class="bi bi-briefcase me-2"></i>Experience</h2>
</div>
<div class="card p-4 border-0 shadow-sm">
<div class="timeline-card">
<h5 class="fw-bold mb-0">Graduate Software Engineer</h5>
<p class="text-primary small mb-2">WBHO Construction · 2025</p>
<p class="small text-muted mb-0">Developed and maintained internal ERP software systems.</p>
</div>
<div class="timeline-card">
<h5 class="fw-bold mb-0">Data Capturer</h5>
<p class="text-primary small mb-2">Wealth Associates · 2022</p>
<p class="small text-muted mb-0">Handled sensitive data with high accuracy and integrity.</p>
</div>
<div class="timeline-card mb-0">
<h5 class="fw-bold mb-0">General Office Work</h5>
<p class="text-primary small mb-2">Wealth Associates · 2019</p>
<p class="small text-muted mb-0">Administrative and operational support.</p>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="section-header">
<h2 class="fw-bold"><i class="bi bi-mortarboard me-2"></i>Education</h2>
</div>
<div class="card p-4 border-0 shadow-sm">
<div class="timeline-card">
<h5 class="fw-bold mb-0">BSc Honours in IT</h5>
<p class="text-primary small mb-2">Software Engineering</p>
<p class="small text-muted mb-0">Graduated with Honours</p>
</div>
<div class="timeline-card">
<h5 class="fw-bold mb-0">BSc in IT</h5>
<p class="text-primary small mb-2">Software Engineering</p>
</div>
<div class="timeline-card mb-0">
<h5 class="fw-bold mb-0">Matric Certificate</h5>
<p class="text-primary small mb-2">IT | CAT | Business</p>
</div>
</div>
</div>
</div>
</div>
</section>
<section id="projects" class="bg-white">
<div class="container"> <div class="container">
<div class="section-header"> <div class="section-header">
<i class="bi bi-briefcase"></i> <h2 class="fw-bold"><i class="bi bi-code-slash me-2"></i>Projects</h2>
<h2 class="fw-bold mt-2">Work Experience</h2>
</div> </div>
<div class="row g-4"> <div class="row g-4">
<div class="col-md-4" th:each="exp : ${null}">
<!-- Static cards retained -->
</div>
<!-- WBHO -->
<div class="col-md-4">
<div class="card h-100 p-3">
<h5>Graduate Software Engineer</h5>
<p class="text-muted">WBHO Construction · 2025</p>
<p>Developed and maintained internal ERP software systems.</p>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 p-3">
<h5>Data Capturer</h5>
<p class="text-muted">Wealth Associates · 2022</p>
<p>Handled sensitive data with high accuracy and integrity.</p>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 p-3">
<h5>General Office Work</h5>
<p class="text-muted">Wealth Associates · 2019</p>
<p>Administrative and operational support.</p>
</div>
</div>
</div>
</div>
</section>
<!-- EDUCATION -->
<section id="education" class="bg-light">
<div class="container">
<div class="section-header">
<i class="bi bi-mortarboard"></i>
<h2 class="fw-bold mt-2">Education</h2>
</div>
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card p-4 text-center">
<h5>BSc Honours in Information Technology</h5>
<p class="text-muted mb-1">Specialization: Software Engineering</p>
<p class="text-muted">Graduated with Honours</p>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card p-4 text-center">
<h5>BSc in Information Technology</h5>
<p class="text-muted mb-1">Specialization: Software Engineering</p>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card p-4 text-center">
<h5>Matric Certificate</h5>
<p class="text-muted mb-1">Major Subjects: IT | CAT |Business</p>
</div>
</div>
</div>
</div>
</section>
<!-- PROJECTS -->
<section id="projects">
<div class="container">
<div class="section-header">
<i class="bi bi-code-slash"></i>
<h2 class="fw-bold mt-2">Projects</h2>
<p class="text-muted">Selected technical work</p>
</div>
<div class="row g-4 d-inline-flex justify-content-center align-items-center" style="width: 100%;">
<div class="col-md-6 col-lg-4" th:each="project : ${projects}"> <div class="col-md-6 col-lg-4" th:each="project : ${projects}">
<div class="project-item h-100 p-3 "> <div class="project-item h-100 p-4 d-flex flex-column shadow-sm">
<h5 th:text="${project.name}"></h5> <h5 class="fw-bold mb-1" th:text="${project.name}">Project Name</h5>
<p class="small text-muted" th:text="${project.default_branch}"></p> <p class="text-muted small flex-grow-1">2025 - Present</p>
<p th:text="${project.description}"></p> <!-- <code class="small text-primary mb-3" th:text="${project.default_branch}">main</code> -->
<a th:href="@{/project/{repo}(repo=${project.name})}">View Details</a> <p class="text-muted small flex-grow-1" th:text="${project.description}">Description goes here...</p>
<a class="btn btn-outline-primary btn-sm mt-3 w-fit" th:href="@{/project/{repo}(repo=${project.name})}">
View Details <i class="bi bi-arrow-right ms-1"></i>
</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<!-- CONTACT -->
<section id="contact" class="bg-light"> <section id="contact" class="bg-light">
<div class="container"> <div class="container">
<div class="section-header">
<i class="bi bi-envelope"></i>
<h2 class="fw-bold mt-2">Contact</h2>
<p class="text-muted">Lets work together</p>
</div>
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-6"> <div class="col-md-6">
<div class="contact-box p-4"> <div class="section-header text-center border-0">
<form method="post" th:action="@{/contact}"> <h2 class="fw-bold"><i class="bi bi-envelope me-2"></i>Contact</h2>
<input class="form-control mb-3" name="name" placeholder="Name" required> <p class="text-muted">Lets work together</p>
<input type="email" class="form-control mb-3" name="email" placeholder="Email" required> </div>
<textarea class="form-control mb-3" name="message" rows="4" placeholder="Message" <div class="contact-box p-4 shadow-sm border-0">
required></textarea> <form th:action="@{/contact}" th:attr="hx-post=@{/contact}" hx-target="#toast-container" hx-swap="beforeend" hx-on:htmx:after-request="this.reset()">
<button class="btn btn-primary w-100">Send Message</button> <div class="mb-3">
<input class="form-control" name="name" placeholder="Name" required>
</div>
<div class="mb-3">
<input type="email" class="form-control" name="email" placeholder="Email" required>
</div>
<div class="mb-3">
<textarea class="form-control" name="message" rows="4" placeholder="Your Message" required></textarea>
</div>
<button class="btn btn-primary w-100 py-2 fw-bold">Send Message</button>
</form> </form>
</div> </div>
</div> </div>
@ -196,12 +148,20 @@
</div> </div>
</section> </section>
<div th:fragment="alertSuccess" role="alert" class='alert alert-success' th:text="${alertMessage}">Thank you! Your message has been sent.</div> <div id="toast-container" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
<div th:fragment="alertSuccess" th:if="${alertMessage}">
<div class="toast show align-items-center text-bg-success border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body" th:text="${alertMessage}">
Message sent successfully!
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
</div>
<!-- FOOTER -->
<div th:replace="~{fragments/footer :: footer}"></div> <div th:replace="~{fragments/footer :: footer}"></div>
<script th:src="@{/assets/js/bootstrap.bundle.min.js}"></script> <script th:src="@{/assets/js/bootstrap.bundle.min.js}"></script>
</body> </body>
</html> </html>

View File

@ -2,15 +2,9 @@
<html lang="en" data-bs-theme="light" xmlns:th="http://www.thymeleaf.org"> <html lang="en" data-bs-theme="light" xmlns:th="http://www.thymeleaf.org">
<head> <head>
<!-- ================= META ================= -->
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title th:text="${project.name} + ' | Project Details'">Project</title>
<title th:text="${project.name} + ' | Kiyan Mckop'">Project</title>
<!-- SEO -->
<meta name="description" th:content="${project.description}">
<meta name="author" content="Kiyan Mckop">
<link th:href="@{/assets/css/bootstrap.min.css}" rel="stylesheet"> <link th:href="@{/assets/css/bootstrap.min.css}" rel="stylesheet">
<link th:href="@{https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css}" rel="stylesheet"> <link th:href="@{https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css}" rel="stylesheet">
@ -19,115 +13,113 @@
<body> <body>
<!-- ================= NAVBAR ================= -->
<div th:replace="~{fragments/navbar :: navbar}"></div> <div th:replace="~{fragments/navbar :: navbar}"></div>
<!-- ================= HERO ================= --> <header class="hero">
<header class="hero bg-light"> <div class="container">
<div class="container text-center"> <div class="row align-items-center">
<h1 class="fw-bold" th:text="${project.name}">Project Name</h1> <div class="col-lg-7">
<span class="project-badge">Project Case Study</span>
<h1 class="display-4 fw-bold mt-2" th:text="${project.name}">Project Name</h1>
<p class="lead text-muted" th:text="${project.description}">Short description.</p>
<p class="lead text-muted mt-2" th:text="${project.description}"> <div class="d-flex gap-3 mt-4">
Project description <!-- <a th:href="${project.githubUrl}" target="_blank" class="btn btn-dark px-4 py-2 rounded-pill">
</p> <i class="bi bi-github me-2"></i> GitHub
</a> -->
<!-- Project Links --> <a th:if="${project.liveUrl != null}" th:href="${project.liveUrl}" target="_blank" class="btn btn-outline-primary px-4 py-2 rounded-pill">
<div class="d-flex justify-content-center gap-4 mt-4"> <i class="bi bi-globe me-2"></i> Live Demo
<a th:href="${project.githubUrl}" target="_blank" class="icon-link" title="GitHub Repository"> </a>
<i class="bi bi-github"></i> </div>
</a> </div>
<a th:if="${project.liveUrl != null}" th:href="${project.liveUrl}" target="_blank" class="icon-link"
title="Live Application">
<i class="bi bi-box-arrow-up-right"></i>
</a>
</div> </div>
</div> </div>
</header> </header>
<!-- ================= SCREENSHOTS ================= --> <section class="py-4" th:if="${project.screenshots != null && !project.screenshots.isEmpty()}">
<section th:if="${project.screenshots != null && !project.screenshots.isEmpty()}">
<div class="container"> <div class="container">
<h2 class="fw-bold text-center mb-5">Application Screenshots</h2> <div class="browser-frame">
<div class="browser-bar">
<div id="projectCarousel" class="carousel slide" data-bs-ride="carousel"> <div class="dot"></div><div class="dot"></div><div class="dot"></div>
<div class="carousel-inner rounded-4 shadow-sm"> </div>
<div th:each="img, stat : ${project.screenshots}" <div id="projectCarousel" class="carousel slide" data-bs-ride="carousel">
th:class="'carousel-item ' + (${stat.index} == 0 ? 'active' : '')"> <div class="carousel-inner">
<img th:src="${img}" class="d-block w-100" alt="Project Screenshot"> <div th:each="img, stat : ${project.screenshots}"
</div> th:class="'carousel-item ' + (${stat.index} == 0 ? 'active' : '')">
<img th:src="${img}" class="d-block w-100" alt="Screenshot">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#projectCarousel" data-bs-slide="prev">
<span class="carousel-control-prev-icon"></span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#projectCarousel" data-bs-slide="next">
<span class="carousel-control-next-icon"></span>
</button>
</div> </div>
<button class="carousel-control-prev" type="button" data-bs-target="#projectCarousel"
data-bs-slide="prev">
<span class="carousel-control-prev-icon"></span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#projectCarousel"
data-bs-slide="next">
<span class="carousel-control-next-icon"></span>
</button>
</div> </div>
</div> </div>
</section> </section>
<!-- ================= OVERVIEW & STACK ================= --> <section class="py-5">
<section id="project-overview" class="bg-light">
<div class="container"> <div class="container">
<div class="row gy-4"> <ul class="nav nav-pills mb-4 gap-2 justify-content-center" id="projectTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="overview-tab" data-bs-toggle="pill" data-bs-target="#overview" type="button" role="tab">Overview</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="stack-tab" data-bs-toggle="pill" data-bs-target="#stack" type="button" role="tab">Tech Stack</button>
</li>
<li class="nav-item" role="presentation" th:if="${project.documentationHtml != null}">
<button class="nav-link" id="docs-tab" data-bs-toggle="pill" data-bs-target="#docs" type="button" role="tab">Documentation</button>
</li>
<li class="nav-item" role="presentation" th:if="${project.futureHtml != null}">
<button class="nav-link" id="future-tab" data-bs-toggle="pill" data-bs-target="#future" type="button" role="tab">Future Plans</button>
</li>
</ul>
<!-- Overview --> <div class="tab-content dynamic-container" id="projectTabContent">
<div class="col-lg-8"> <div class="tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
<h2 class="fw-bold">Project Overview</h2> <h3 class="fw-bold mb-4">Project Overview</h3>
<div th:utext="${project.overviewHtml}"></div> <div class="lh-lg" th:utext="${project.overviewHtml}"></div>
</div> </div>
<!-- Stack --> <div class="tab-pane fade" id="stack" role="tabpanel" aria-labelledby="stack-tab">
<div class="col-lg-4"> <h3 class="fw-bold mb-4">Technology Stack</h3>
<div class="card h-100 shadow-sm"> <div class="stack-content" th:utext="${project.stackHtml}"></div>
<div class="card-body"> </div>
<div th:utext="${project.stackHtml}"></div>
<div class="tab-pane fade" id="docs" role="tabpanel" aria-labelledby="docs-tab" th:if="${project.documentationHtml != null}">
<h3 class="fw-bold mb-4">Technical Documentation</h3>
<div class="lh-lg" th:utext="${project.documentationHtml}"></div>
</div>
<div class="tab-pane fade" id="future" role="tabpanel" aria-labelledby="future-tab" th:if="${project.futureHtml != null}">
<h3 class="fw-bold mb-4">The Roadmap</h3>
<div class="lh-lg" th:utext="${project.futureHtml}"></div>
</div>
</div>
</div>
</section>
<section id="demo-vid" class="bg-dark py-5 text-white">
<div class="container text-center">
<h2 class="fw-bold mb-5"><i class="bi bi-play-btn me-2"></i>Video Demonstration</h2>
<div class="row justify-content-center">
<div class="col-lg-10">
<div class="ratio ratio-16x9 rounded-4 shadow-lg overflow-hidden bg-secondary">
<div class="d-flex align-items-center justify-content-center h-100">
<div class="text-center">
<i class="bi bi-camera-video display-1 opacity-25"></i>
<p class="mt-3">Walkthrough Video Coming Soon</p>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<!-- ================= DOCUMENTATION ================= -->
<section id="documentation" th:if="${project.documentationHtml != null}">
<div class="container">
<h2 class="fw-bold text-center mb-5">Documentation</h2>
<div th:utext="${project.documentationHtml}"></div>
</div>
</section>
<!-- ================= FUTURE PLANS ================= -->
<section id="future-plans" class="bg-light" th:if="${project.futureHtml != null}">
<div class="container">
<h2 class="fw-bold text-center mb-5">Future Plans</h2>
<div th:utext="${project.futureHtml}"></div>
</div>
</section>
<!-- ================= DEMO ================= -->
<section id="demo-vid">
<div class="container">
<h2 class="fw-bold text-center mb-5">Demo Video</h2>
<div class="ratio ratio-16x9 rounded-4 shadow-sm overflow-hidden text-center">
<span><em>Coming Soon</em></span>
</div>
</div>
</section>
<!-- ================= FOOTER ================= -->
<div th:replace="~{fragments/footer :: footer}"></div> <div th:replace="~{fragments/footer :: footer}"></div>
<script th:src="@{/assets/js/bootstrap.bundle.min.js}"></script> <script th:src="@{/assets/js/bootstrap.bundle.min.js}"></script>
</body> </body>
</html> </html>