Compare commits

2 Commits

Author SHA1 Message Date
Ovidiu U
28cd60a427 Move portfolio case studies to data-driven template system and archive old individual files 2026-03-15 18:04:56 +00:00
Ovidiu U
ac917dbc0a new design finished 2026-03-15 08:25:22 +00:00
26 changed files with 5280 additions and 1188 deletions

View File

@@ -9,6 +9,12 @@ RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Portfolio index
RewriteRule ^portfolio$ /portfolio.php [L,QSA]
# Portfolio case study pages: /portfolio/{slug} → portfolio-page.php
RewriteRule ^portfolio/([a-z0-9\-]+)$ /portfolio-page.php?slug=$1 [L,QSA]
# Security headers
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"

1
.idea/php.xml generated
View File

@@ -15,6 +15,7 @@
<phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="7e064064-f569-4fa2-87dd-a1bd0db5798f" timeout="30000" />
</phpcs_settings>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="8.4" />
<component name="PhpStan">
<PhpStan_settings>
<phpstan_by_interpreter asDefaultInterpreter="true" interpreter_id="7e064064-f569-4fa2-87dd-a1bd0db5798f" timeout="60000" />

31
LocalValetDriver.php Normal file
View File

@@ -0,0 +1,31 @@
<?php
class LocalValetDriver extends \Valet\Drivers\BasicValetDriver
{
public function frontControllerPath(string $sitePath, string $siteName, string $uri): ?string
{
$path = trim(parse_url($uri, PHP_URL_PATH), '/');
// /portfolio → portfolio.php
if ($path === 'portfolio') {
return $this->servePhpFile($sitePath, '/portfolio.php');
}
// /portfolio/{slug} → portfolio-page.php?slug={slug}
if (preg_match('#^portfolio/([a-z0-9-]+)$#', $path, $m)) {
$_GET['slug'] = $m[1];
return $this->servePhpFile($sitePath, '/portfolio-page.php');
}
return parent::frontControllerPath($sitePath, $siteName, $uri);
}
private function servePhpFile(string $sitePath, string $file): string
{
$_SERVER['SCRIPT_FILENAME'] = $sitePath . $file;
$_SERVER['SCRIPT_NAME'] = $file;
$_SERVER['DOCUMENT_ROOT'] = $sitePath;
return $sitePath . $file;
}
}

View File

@@ -0,0 +1,85 @@
<?php
$cs_slug = 'lhbeng';
require __DIR__ . '/../../includes/cs_header.php';
?>
<main>
<section class="cs-overview">
<div class="cs-overview-label">
<span class="section-label">Project Overview</span>
</div>
<div class="cs-overview-body">
<p class="cs-overview-text">
Full website redesign with a simple content manager — so the team can update their portfolio, staff profiles, and job listings without needing a developer every time. Clean, modern layout that reflects the scale and quality of their structural engineering work.
</p>
</div>
</section>
<div class="category-divider">
<h2>Screenshots</h2>
</div>
<section class="screenshots-section">
<div class="screenshot-hero">
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url"><?php echo htmlspecialchars($p['domain']); ?></span>
</div>
<div class="browser-scroll-wrap">
<div class="browser-scroll">
<img src="/img/lhbeng/hero.jpg" alt="LHB Engineering — Homepage">
</div>
</div>
</div>
</div>
<div class="screenshots-label">
<span class="section-label">Website CMS</span>
</div>
<div class="screenshot-grid">
<div>
<span class="screenshot-card-label">Content Manager</span>
<p class="screenshot-card-desc">A full-featured CMS lets the team manage portfolio items, team profiles, and job listings without touching code. Day-to-day updates handled entirely in-house.</p>
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url"><?php echo htmlspecialchars($p['domain']); ?>/admin</span>
</div>
<img src="/img/lhbeng/admin.jpg" alt="LHB Engineering — CMS admin panel">
</div>
</div>
</div>
</section>
<div class="category-divider">
<h2>Execution</h2>
</div>
<section class="cs-overview">
<div class="cs-overview-label">
<span class="section-label">Craft &amp; Execution</span>
</div>
<div class="cs-overview-body">
<p class="cs-overview-text">
Built a full redesign for LHB Engineering, replacing their outdated site with a clean, modern layout that better reflects the scale and quality of their work. The new site is fast, fully responsive, and structured so visitors can quickly find services, past projects, and contact details. Alongside the redesign, a custom PHP/MySQL CMS gives the team full control over content — no developer needed for day-to-day updates.
</p>
</div>
</section>
</main>
<?php require __DIR__ . '/../../includes/cs_footer.php'; ?>

View File

@@ -0,0 +1,132 @@
<?php
/*
* ═══════════════════════════════════════════════════════════════════
* CASE STUDY TEMPLATE
* ═══════════════════════════════════════════════════════════════════
*
* HOW TO USE
* ──────────
* 1. Copy this folder to portfolio/{slug}/
* 2. Fill in every TODO below — nothing should say TODO when live
* 3. Add an entry to $projects in data/projects.php (including page_title, page_desc)
* 4. Drop screenshots into /img/{slug}/
*
* IMAGES
* ──────
* hero.jpg — full-page screenshot (used as grid thumbnail too)
* feature-1.jpg — first feature / flow screenshot
* feature-2.jpg — second feature / flow screenshot
* Add more as needed — duplicate the 2-col screenshot section below.
*
* SECTIONS (delete what you don't need)
* ──────────────────────────────────────
* · Project Overview — always include
* · Hero screenshot — always include
* · Feature section — include if there's a flow / feature worth showing
* · Craft & Execution — include if the build has something worth saying
* · CTA — always include, comes from cs_footer.php
* ═══════════════════════════════════════════════════════════════════
*/
// ── Set the slug — everything else lives in data/projects.php ─────
$cs_slug = 'project'; // e.g. 'northgate'
require __DIR__ . '/../../includes/cs_header.php';
?>
<main>
<section class="cs-overview">
<div class="cs-overview-label">
<span class="section-label">Project Overview</span>
</div>
<div class="cs-overview-body">
<p class="cs-overview-text">
Thompson Service Centre needed more than a website — they needed a digital presence that matched 25 years of earned trust. We built a high-fidelity landing page that puts credibility front and centre: a bold hero section, a trust bar loaded with real credentials, and service cards that communicate competence without the usual garage-site clichés.
</p>
</div>
</section>
<div class="category-divider">
<h2>Screenshots</h2>
</div>
<section class="screenshots-section">
<div class="screenshot-hero">
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url"><?php echo htmlspecialchars($p['domain']); ?></span>
</div>
<div class="browser-scroll-wrap">
<div class="browser-scroll">
<img src="/img/thompson/hero.jpg" alt="Thompson Service Centre — Homepage">
</div>
</div>
</div>
</div>
<div class="screenshots-label">
<span class="section-label">Booking Flow</span>
</div>
<div class="screenshot-grid">
<div>
<span class="screenshot-card-label">Vehicle Lookup</span>
<p class="screenshot-card-desc">Registration plate lookup pulls vehicle details instantly — reducing form friction and building user confidence from the first interaction.</p>
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url"><?php echo htmlspecialchars($p['domain']); ?>/book</span>
</div>
<img src="/img/thompson/booking-lookup.jpg" alt="Thompson Service Centre — vehicle lookup step">
</div>
</div>
<div>
<span class="screenshot-card-label">Booking Form</span>
<p class="screenshot-card-desc">A clean, single-column booking form with service selection and date picker. Designed for speed on mobile — no unnecessary steps, no dead ends.</p>
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url"><?php echo htmlspecialchars($p['domain']); ?>/book</span>
</div>
<img src="/img/thompson/booking-confirm.jpg" alt="Thompson Service Centre — booking confirmation step">
</div>
</div>
</div>
</section>
<div class="category-divider">
<h2>Execution</h2>
</div>
<section class="cs-overview">
<div class="cs-overview-label">
<span class="section-label">Craft &amp; Execution</span>
</div>
<div class="cs-overview-body">
<p class="cs-overview-text">
Built with vanilla HTML, Tailwind CSS v4, and GSAP-powered scroll animations, the page loads fast and feels premium on every device. The design system — rooted in Workshop Navy and Safety Orange — draws from real automotive heritage rather than off-the-shelf templates.
</p>
</div>
</section>
</main>
<?php require __DIR__ . '/../../includes/cs_footer.php'; ?>

View File

@@ -0,0 +1,101 @@
<?php
$cs_slug = 'thompson';
require __DIR__ . '/../../includes/cs_header.php';
?>
<main>
<section class="cs-overview">
<div class="cs-overview-label">
<span class="section-label">Project Overview</span>
</div>
<div class="cs-overview-body">
<p class="cs-overview-text">
Thompson Service Centre needed more than a website — they needed a digital presence that matched 25 years of earned trust. We built a high-fidelity landing page that puts credibility front and centre: a bold hero section, a trust bar loaded with real credentials, and service cards that communicate competence without the usual garage-site clichés.
</p>
</div>
</section>
<div class="category-divider">
<h2>Screenshots</h2>
</div>
<section class="screenshots-section">
<div class="screenshot-hero">
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url"><?php echo htmlspecialchars($p['domain']); ?></span>
</div>
<div class="browser-scroll-wrap">
<div class="browser-scroll">
<img src="/img/thompson/hero.jpg" alt="Thompson Service Centre — Homepage">
</div>
</div>
</div>
</div>
<div class="screenshots-label">
<span class="section-label">Booking Flow</span>
</div>
<div class="screenshot-grid">
<div>
<span class="screenshot-card-label">Vehicle Lookup</span>
<p class="screenshot-card-desc">Registration plate lookup pulls vehicle details instantly — reducing form friction and building user confidence from the first interaction.</p>
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url"><?php echo htmlspecialchars($p['domain']); ?>/book</span>
</div>
<img src="/img/thompson/booking-lookup.jpg" alt="Thompson Service Centre — vehicle lookup step">
</div>
</div>
<div>
<span class="screenshot-card-label">Booking Form</span>
<p class="screenshot-card-desc">A clean, single-column booking form with service selection and date picker. Designed for speed on mobile — no unnecessary steps, no dead ends.</p>
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url"><?php echo htmlspecialchars($p['domain']); ?>/book</span>
</div>
<img src="/img/thompson/booking-confirm.jpg" alt="Thompson Service Centre — booking confirmation step">
</div>
</div>
</div>
</section>
<div class="category-divider">
<h2>Execution</h2>
</div>
<section class="cs-overview">
<div class="cs-overview-label">
<span class="section-label">Craft &amp; Execution</span>
</div>
<div class="cs-overview-body">
<p class="cs-overview-text">
Built with vanilla HTML, Tailwind CSS v4, and GSAP-powered scroll animations, the page loads fast and feels premium on every device. The design system — rooted in Workshop Navy and Safety Orange — draws from real automotive heritage rather than off-the-shelf templates.
</p>
</div>
</section>
</main>
<?php require __DIR__ . '/../../includes/cs_footer.php'; ?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,64 @@
# Summary
A brutalist editorial design system for high-fashion, streetwear, or luxury brands. Featuring a raw, industrial aesthetic with massive typography, high-contrast photography, and utilitarian components. Key elements include a noise-grain texture overlay, a monochromatic palette with burnt orange and neon green accents, and asymmetrical layout grids. The style uses 'Clash Grotesk' for aggressive impact and 'General Sans' for technical clarity. Ideal for product launches, lookbooks, and fashion portfolios looking for a 'Raw Campaign' or 'Modern Brutalist' feel with scroll-triggered visual impact.
# Style
The style is defined by a 'Raw' aesthetic: a neutral beige background (#E3E2DE) paired with deep brownish-black (#1B0E0D) and burnt red (#C72A09) accents. A constant noise texture (0.08 opacity) is applied over the entire interface. Typography features heavy use of 'Clash Grotesk' for massive, tight-tracked headings and 'General Sans' or Mono fonts for technical metadata. Animations are swift and purposeful, including image scaling and neon-green hover states (#31EF07).
## Spec
Create a design with a 'Modern Brutalist' aesthetic. Use a background color of #E3E2DE and primary text in #1B0E0D. Apply a persistent noise texture overlay (SVG fractalNoise at 0.08 opacity, mix-blend-mode: multiply). Typography: Use 'Clash Grotesk' for display headings with font-weight: 700, letter-spacing: -0.04em, and leading: 0.85. For body and technical info, use 'General Sans' or a monospace font for price/data points. Accent colors: #C72A09 (Primary accent/Action) and #31EF07 (Neon Green for micro-interactions/hovers). Links should feature a custom hover animation using a 2px neon green underline that scales from 0 to 1 with cubic-bezier(0.165, 0.84, 0.44, 1). Images must be high-contrast, often grayscale, with a hover scale effect of 1.05.
# Layout & Structure
The layout uses a 12-column asymmetric grid. It features massive, screen-filling typography dividers and a mix of full-width blocks and offset product columns to create a sense of 'ordered chaos'.
## Navigation
Sticky top navigation using mix-blend-mode: difference to ensure legibility against any background. Left-aligned branding in uppercase bold (24px), centered text links (Shop, Editorial) with neon-green hover-underline animations, and right-aligned icons (Search, Cart) in 24px size. Text color should be #E3E2DE to work with the blend mode.
## Hero Section
Full-screen (100vh) hero section with a dark background (#1B0E0D). Background image should be grayscale and high-contrast at 60% opacity. Bottom-aligned content containing a thin #E3E2DE border, technical metadata in monospace tracking-widest, and a large burnt-orange (#C72A09) CTA button. The main headline must be massive (16vw on mobile, 13.5vw on desktop) using Clash Grotesk, with parts of the text indented (e.g., 20vw) to create negative space.
## Manifesto Section
A 12-column grid section. Columns 1-4 contain a small uppercase label (Manifesto) above a top border. Columns 5-12 contain large-scale editorial text (32px-48px) in uppercase font-medium with a significant paragraph indent (approx 3rem). Highlight key phrases in deep brown (#61220F).
## Category Divider
A full-width section bounded by top and bottom borders (#D9D9D9). Contains a single, massive heading 'OUTERWEAR' at 12vw size in #61220F. The text should have tight tracking and minimal vertical padding to create a 'ribbon' effect.
## Product Grid
An asymmetrical 12-column grid. Items should vary in width and vertical offset. Example: Product A (7 columns, aspect 4:5), Product B (5 columns, aspect 3:4 with a 128px top margin offset). Product details below images include a bold uppercase title and a monospace price tag separated by a border-bottom that changes to burnt orange (#C72A09) on hover. Include a 'Quick View' badge in neon green (#31EF07) that appears on hover.
## Footer
Multi-column layout (4 columns) on beige background. Section headers in bold uppercase (20px). Newsletter signup uses a dark block (#1B0E0D) with an integrated underline-style input and neon-green 'Send' button. The very bottom features a massive 'ghost' title of the brand (8vw) in light gray (#D9D9D9) for brand reinforcement.
# Special Components
## Neon Interaction Badge
A sharp-edged, high-visibility utility badge for product status or quick actions.
Rectangle component with zero border-radius. Background color: #31EF07. Text: 10px bold uppercase #1B0E0D. Positioned absolutely in the top-right of containers, appearing only on hover with a 300ms ease-in-out transition.
## Texture Overlay
Full-screen SVG noise grain that unifies the brutalist aesthetic.
Fixed 100vw/100vh div with pointer-events: none. Apply an SVG filter: feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'. Set opacity to 0.08 and mix-blend-mode to multiply. Ensure it sits at z-index: 50.
## Split-Indented Headline
A typography style for hero headers that utilizes large-scale indentation for visual tension.
Font: Clash Grotesk, 13.5vw. Line 1: Left-aligned. Line 2: Indented by 20vw. Color: Mix of burnt-red (#C72A09) and beige (#E3E2DE). Line-height: 0.75. Tracking: -0.05em.
## Preview
https://p.superdesign.dev/draft/10ecb2c3-19d7-405b-926e-3fa74e142661
## Preview source code
./brutalist-01.html

781
brutalist-01/index.html Normal file
View File

@@ -0,0 +1,781 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ovidiu Ungureanu — Web Developer</title>
<link rel="preconnect" href="https://api.fontshare.com">
<link href="https://api.fontshare.com/v2/css?f[]=clash-grotesk@700,600,500,400&f[]=general-sans@700,600,500,400&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--bg: #E3E2DE;
--dark: #1B0E0D;
--mid: #61220F;
--accent: #C72A09;
--neon: #31EF07;
--border: #D9D9D9;
--clash: 'Clash Grotesk', sans-serif;
--general: 'General Sans', sans-serif;
}
html { scroll-behavior: smooth; }
body {
font-family: var(--general);
background: var(--bg);
color: var(--dark);
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
::selection { background: var(--accent); color: var(--bg); }
/* ── NOISE ──────────────────────────────────────── */
.noise {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 50;
mix-blend-mode: multiply;
opacity: 0.08;
}
/* ── NAV ────────────────────────────────────────── */
.nav {
position: fixed;
top: 0; left: 0; right: 0;
z-index: 40;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.5rem 2.5rem;
mix-blend-mode: difference;
color: var(--bg);
transition: background 0.2s ease;
}
.nav--scrolled {
mix-blend-mode: normal;
background: rgba(27,14,13,0.8);
}
.nav-logo {
font-family: var(--clash);
font-weight: 700;
font-size: 1.5rem;
letter-spacing: -0.02em;
text-transform: uppercase;
}
.nav-links {
display: flex;
gap: 2.5rem;
font-family: var(--general);
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.nav-link {
position: relative;
}
.nav-link::after {
content: '';
position: absolute;
bottom: -3px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.nav-link:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.nav-cta {
font-family: var(--general);
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
}
/* ── HERO ───────────────────────────────────────── */
.hero {
position: relative;
height: 70vh;
max-height: 650px;
min-height: 520px;
background-color: var(--dark);
background-image: radial-gradient(circle, rgba(227,226,222,0.055) 1px, transparent 1px);
background-size: 48px 48px;
display: flex;
flex-direction: column;
justify-content: flex-end;
overflow: hidden;
}
.hero::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(ellipse at 50% 100%, transparent 40%, rgba(27,14,13,0.55) 100%);
pointer-events: none;
z-index: 1;
}
.hero-content {
position: relative;
z-index: 2;
padding: 0 2.5rem 3rem;
}
.hero-divider {
width: 100%;
height: 1px;
background: rgba(227,226,222,0.25);
margin-bottom: 1.5rem;
}
.hero-meta-row {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 1rem;
margin-bottom: 0.25rem;
}
.hero-meta {
font-family: var(--general);
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.15em;
color: rgba(227,226,222,0.5);
display: flex;
flex-direction: column;
gap: 0.2rem;
}
.hero-cta-btn {
display: inline-block;
font-family: var(--clash);
font-size: 0.85rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
padding: 1rem 2rem;
background: var(--accent);
color: var(--bg);
transition: background 0.2s, color 0.2s;
}
.hero-cta-btn:hover {
background: var(--neon);
color: var(--dark);
}
.hero-headline {
font-family: var(--clash);
font-weight: 700;
font-size: 13.5vw;
line-height: 0.75;
letter-spacing: -0.05em;
text-transform: uppercase;
margin-top: 2.25rem;
padding: 0 1rem;
}
.hero-headline .line1 {
display: block;
color: var(--accent);
}
.hero-headline .line2 {
display: block;
color: var(--bg);
margin-left: 20vw;
}
/* ── MANIFESTO / ABOUT ──────────────────────────── */
.manifesto {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 2rem;
padding: 6rem 2.5rem;
}
.manifesto-label-col {
grid-column: span 4;
border-top: 1px solid var(--dark);
padding-top: 1rem;
}
.section-label {
font-family: monospace;
font-size: 0.75rem;
font-weight: 400;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--mid);
}
.manifesto-text-col {
grid-column: span 8;
border-top: 1px solid var(--dark);
padding-top: 1rem;
}
.manifesto-text {
font-family: var(--clash);
font-size: clamp(1.75rem, 3.2vw, 3rem);
font-weight: 500;
line-height: 1.15;
text-transform: uppercase;
text-indent: 3rem;
}
.manifesto-text .hl { color: var(--mid); }
/* ── CATEGORY DIVIDER ───────────────────────────── */
.category-divider {
width: 100%;
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
padding: 0 2.5rem;
overflow: hidden;
}
.category-divider h2 {
font-family: var(--clash);
font-size: 12vw;
font-weight: 700;
letter-spacing: -0.04em;
line-height: 0.95;
color: var(--mid);
text-transform: uppercase;
padding: 0.2rem 0;
}
/* ── SERVICES ───────────────────────────────────── */
.services {
border-top: 1px solid rgba(27,14,13,0.15);
padding: 0 2.5rem;
}
.service-row {
display: flex;
align-items: flex-start;
gap: 2rem;
border-bottom: 1px solid rgba(27,14,13,0.15);
padding: 2.5rem 0;
margin: 0 -2.5rem;
padding-left: 2.5rem;
padding-right: 2.5rem;
position: relative;
overflow: hidden;
cursor: default;
transition: background 0.15s ease;
}
/* .service-row:hover { background: var(--dark); } */
.service-num {
font-family: var(--general);
font-size: 0.9rem;
font-weight: 700;
color: var(--accent);
padding-top: 0.8rem;
flex-shrink: 0;
width: 3.5rem;
}
/* .service-row:hover .service-num { color: var(--neon); } */
.service-body { flex: 1; min-width: 0; }
.service-title {
font-family: var(--clash);
font-size: clamp(1.75rem, 3.2vw, 3rem);
font-weight: 500;
line-height: 1.15;
text-transform: uppercase;
text-indent: 3rem;
color: var(--dark);
margin-bottom: 1.1rem;
}
/* .service-row:hover .service-title { color: var(--bg); } */
.service-row--alt .service-title > span {
background-color: var(--accent);
color: var(--bg);
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
padding: 0.04em 0.15em;
display: inline;
}
.service-tags {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.service-tag {
font-family: var(--general);
font-size: 0.65rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.07em;
padding: 4px 12px;
border: 1px solid rgba(27,14,13,0.25);
border-radius: 100px;
color: var(--mid);
}
/* .service-row:hover .service-tag {
border-color: rgba(227,226,222,0.25);
color: rgba(227,226,222,0.5);
} */
.service-badge {
position: absolute;
top: 2.25rem;
right: 2.5rem;
background: var(--neon);
color: var(--dark);
font-family: var(--general);
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
padding: 6px 12px;
opacity: 0;
}
/* .service-row:hover .service-badge { opacity: 1; } */
/* ── CONTACT ────────────────────────────────────── */
.contact-section {
background: var(--dark);
padding: 7rem 2.5rem 6rem;
position: relative;
overflow: hidden;
}
.contact-section::before {
content: '';
position: absolute;
inset: 0;
background-image: radial-gradient(circle, rgba(227,226,222,0.04) 1px, transparent 1px);
background-size: 48px 48px;
pointer-events: none;
}
.contact-inner { position: relative; z-index: 1; }
.contact-section .section-label {
color: rgba(227,226,222,0.35);
display: block;
margin-bottom: 3rem;
}
.contact-headline {
font-family: var(--clash);
font-size: clamp(3rem, 6vw, 6rem);
font-weight: 700;
text-transform: uppercase;
color: var(--bg);
line-height: 0.88;
letter-spacing: -0.04em;
margin-bottom: 3rem;
}
.contact-headline .accent { color: var(--accent); }
.contact-email {
display: block;
font-family: var(--clash);
font-size: clamp(1.5rem, 3.5vw, 3.75rem);
font-weight: 700;
color: var(--bg);
letter-spacing: -0.02em;
margin-bottom: 3rem;
width: fit-content;
position: relative;
}
.contact-email::after {
content: '';
position: absolute;
bottom: -4px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.35s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.contact-email:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.contact-meta {
font-family: var(--general);
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.12em;
color: rgba(227,226,222,0.35);
display: flex;
align-items: center;
gap: 1.25rem;
}
.contact-meta .dot { opacity: 0.4; }
/* ── FOOTER ─────────────────────────────────────── */
.footer {
background: var(--bg);
border-top: 1px solid var(--dark);
padding: 4.5rem 2.5rem 0;
}
.footer-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 3rem;
margin-bottom: 4.5rem;
}
.footer-heading {
font-family: var(--clash);
font-size: 1.1rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: -0.01em;
margin-bottom: 1.25rem;
}
.footer-links {
list-style: none;
display: flex;
flex-direction: column;
gap: 0.65rem;
}
.footer-links a {
font-family: var(--general);
font-size: 0.875rem;
color: var(--mid);
transition: color 0.15s;
}
.footer-links a:hover { color: var(--accent); }
.footer-address {
font-family: var(--general);
font-size: 0.875rem;
color: var(--mid);
line-height: 1.8;
font-style: normal;
}
.footer-address a { font-weight: 700; }
.footer-address a:hover { color: var(--accent); }
.footer-cta {
background: var(--dark);
padding: 1.5rem;
}
.footer-cta label {
display: block;
font-family: var(--general);
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.15em;
color: var(--bg);
margin-bottom: 1rem;
}
.footer-input-row {
display: flex;
align-items: center;
border-bottom: 1px solid rgba(227,226,222,0.4);
gap: 0.5rem;
}
.footer-input-row input {
background: transparent;
border: none;
outline: none;
font-family: var(--general);
font-size: 0.8rem;
color: var(--bg);
text-transform: uppercase;
width: 100%;
padding: 0.5rem 0;
}
.footer-input-row input::placeholder { color: rgba(227,226,222,0.25); }
.footer-input-row button {
background: none;
border: none;
cursor: pointer;
font-family: var(--general);
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--neon);
padding: 0.5rem 0;
white-space: nowrap;
transition: color 0.15s;
}
.footer-input-row button:hover { color: var(--bg); }
.footer-bottom {
border-top: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: flex-end;
padding-top: 1.5rem;
}
.footer-ghost {
font-family: var(--clash);
font-size: 8vw;
font-weight: 700;
text-transform: uppercase;
color: var(--border);
line-height: 1;
letter-spacing: -0.04em;
user-select: none;
pointer-events: none;
}
.footer-legal {
font-family: var(--general);
font-size: 0.7rem;
color: var(--mid);
padding-bottom: 0.3rem;
}
/* ── RESPONSIVE ─────────────────────────────────── */
@media (max-width: 960px) {
.manifesto { grid-template-columns: 1fr; gap: 1rem; }
.manifesto-label-col,
.manifesto-text-col { grid-column: span 1; }
.footer-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.nav { padding: 1.25rem 1.5rem; }
.nav-links { display: none; }
.hero {
height: auto;
min-height: 0;
padding-top: 5rem;
}
.hero-content { padding: 0 1.5rem 2.5rem; }
.hero-meta-row {
flex-direction: column;
align-items: flex-start;
gap: 1rem;
margin-bottom: 1.5rem;
}
.hero-headline { font-size: 12vw; }
.hero-headline .line2 { margin-left: 5vw; }
.manifesto { padding: 4rem 1.5rem; }
.manifesto-text { font-size: 1.75rem; text-indent: 1.5rem; }
.category-divider { padding: 0 1.5rem; }
.services { padding: 0 1.5rem; }
.service-row { margin: 0 -1.5rem; padding: 2rem 1.5rem; }
.service-badge { right: 1.5rem; }
.service-title { font-size: clamp(1.5rem, 5vw, 2.5rem); text-indent: 1.5rem; }
.contact-section { padding: 4rem 1.5rem; }
.footer { padding: 3rem 1.5rem 0; }
.footer-grid { grid-template-columns: 1fr; gap: 2rem; }
.footer-ghost { font-size: 16vw; }
}
</style>
</head>
<body>
<!-- Noise Texture Overlay -->
<div class="noise" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<filter id="n">
<feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="3" stitchTiles="stitch"/>
</filter>
<rect width="100%" height="100%" filter="url(#n)"/>
</svg>
</div>
<!-- Navigation -->
<nav class="nav">
<a href="#" class="nav-logo">U. ovidiu</a>
<div class="nav-links">
<a href="#about" class="nav-link">About</a>
<a href="#services" class="nav-link">Services</a>
<a href="portfolio.html" class="nav-link">Work</a>
<a href="#contact" class="nav-link">Contact</a>
</div>
</nav>
<!-- Hero -->
<header class="hero">
<div class="hero-content">
<div class="hero-divider"></div>
<div class="hero-meta-row">
<div class="hero-meta">
<span>Web Developer — Peterborough, UK</span>
<span>I build web applications that work.</span>
<span>Available for freelance</span>
</div>
<a href="#contact" class="hero-cta-btn">Let's Talk →</a>
</div>
<h1 class="hero-headline">
<span class="line1">CleanCode</span>
<span class="line2">Studio</span>
</h1>
</div>
</header>
<main>
<!-- About / Manifesto -->
<section class="manifesto" id="about">
<div class="manifesto-label-col">
<span class="section-label">001 — About</span>
</div>
<div class="manifesto-text-col">
<p class="manifesto-text">
I build websites and online tools for small businesses
<span class="hl">— booking systems, customer dashboards</span>.
<br/>Fast, affordable, and built to last.
Built for businesses that need something real.
</p>
</div>
</section>
<!-- Services Category Divider -->
<div class="category-divider">
<h2>Services</h2>
</div>
<!-- Services List -->
<section class="services" id="services">
<div class="service-row">
<span class="service-num">(01)</span>
<div class="service-body">
<h3 class="service-title">Website Design<br>&amp; Development</h3>
<div class="service-tags">
<span class="service-tag">Design</span>
<span class="service-tag">Development</span>
<span class="service-tag">Responsive</span>
</div>
</div>
<span class="service-badge">Enquire →</span>
</div>
<div class="service-row service-row--alt">
<span class="service-num">(02)</span>
<div class="service-body">
<h3 class="service-title"><span>Custom Tools<br>&amp; Systems</span></h3>
<div class="service-tags">
<span class="service-tag">PHP</span>
<span class="service-tag">MySQL</span>
<span class="service-tag">Custom Builds</span>
</div>
</div>
<span class="service-badge">Enquire →</span>
</div>
<div class="service-row">
<span class="service-num">(03)</span>
<div class="service-body">
<h3 class="service-title">Booking &amp;<br>Scheduling</h3>
<div class="service-tags">
<span class="service-tag">Bookings</span>
<span class="service-tag">Automation</span>
<span class="service-tag">Small Business</span>
</div>
</div>
<span class="service-badge">Enquire →</span>
</div>
<div class="service-row service-row--alt">
<span class="service-num">(04)</span>
<div class="service-body">
<h3 class="service-title"><span>Ongoing Support<br>&amp; Updates</span></h3>
<div class="service-tags">
<span class="service-tag">Maintenance</span>
<span class="service-tag">Performance</span>
<span class="service-tag">Support</span>
</div>
</div>
<span class="service-badge">Enquire →</span>
</div>
</section>
<!-- Contact -->
<section class="contact-section" id="contact">
<div class="contact-inner">
<span class="section-label">004 — Contact</span>
<h2 class="contact-headline">
Got a project<br>
<span class="accent">in mind?</span>
</h2>
<a href="mailto:hello@uovidiu.com" class="contact-email">hello@uovidiu.com</a>
<div class="contact-meta">
<span>Peterborough, UK</span>
<span class="dot">·</span>
<span>Available for freelance</span>
</div>
</div>
</section>
</main>
<!-- Footer -->
<footer class="footer">
<div class="footer-grid">
<div>
<h4 class="footer-heading">Studio</h4>
<address class="footer-address">
Peterborough, UK<br>
<a href="mailto:hello@uovidiu.com">hello@uovidiu.com</a>
</address>
</div>
<div>
<h4 class="footer-heading">Navigate</h4>
<ul class="footer-links">
<li><a href="#about">About</a></li>
<li><a href="#services">Services</a></li>
<li><a href="/portfolio">Portfolio</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<span class="footer-ghost">U. ovidiu</span>
<span class="footer-legal">© 2026 Ovidiu Ungureanu</span>
</div>
</footer>
<script>
const nav = document.querySelector('.nav');
window.addEventListener('scroll', () => {
nav.classList.toggle('nav--scrolled', window.scrollY > 50);
}, { passive: true });
</script>
</body>
</html>

View File

@@ -0,0 +1,883 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thompson Service Centre — Ovidiu Ungureanu</title>
<link rel="preconnect" href="https://api.fontshare.com">
<link href="https://api.fontshare.com/v2/css?f[]=clash-grotesk@700,600,500,400&f[]=general-sans@700,600,500,400&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--bg: #E3E2DE;
--dark: #1B0E0D;
--mid: #61220F;
--accent: #C72A09;
--neon: #31EF07;
--border: #D9D9D9;
--clash: 'Clash Grotesk', sans-serif;
--general: 'General Sans', sans-serif;
}
html { scroll-behavior: smooth; }
body {
font-family: var(--general);
background: var(--bg);
color: var(--dark);
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
::selection { background: var(--accent); color: var(--bg); }
/* ── NOISE ──────────────────────────────────────── */
.noise {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 50;
mix-blend-mode: multiply;
opacity: 0.08;
}
/* ── NAV ────────────────────────────────────────── */
.nav {
position: fixed;
top: 0; left: 0; right: 0;
z-index: 40;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.5rem 2.5rem;
mix-blend-mode: difference;
color: var(--bg);
transition: background 0.2s ease;
}
.nav--scrolled {
mix-blend-mode: normal;
background: rgba(27,14,13,0.9);
}
.nav-left {
display: flex;
align-items: center;
gap: 2rem;
}
.nav-back {
font-family: var(--general);
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
position: relative;
}
.nav-back::after {
content: '';
position: absolute;
bottom: -3px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.nav-back:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.nav-logo {
font-family: var(--clash);
font-weight: 700;
font-size: 1.5rem;
letter-spacing: -0.02em;
text-transform: uppercase;
}
.nav-links {
display: flex;
gap: 2.5rem;
font-family: var(--general);
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.nav-link {
position: relative;
}
.nav-link::after {
content: '';
position: absolute;
bottom: -3px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.nav-link:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.nav-cta {
font-family: var(--general);
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
}
/* ── SECTION LABEL ───────────────────────────────── */
.section-label {
font-family: monospace;
font-size: 0.75rem;
font-weight: 400;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--mid);
}
/* ── HERO ───────────────────────────────────────── */
.hero {
position: relative;
height: 100vh;
max-height: 760px;
min-height: 600px;
background-color: var(--dark);
background-image: radial-gradient(circle, rgba(227,226,222,0.055) 1px, transparent 1px);
background-size: 48px 48px;
display: flex;
flex-direction: column;
justify-content: flex-end;
overflow: hidden;
}
.hero::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(ellipse at 50% 100%, transparent 40%, rgba(27,14,13,0.55) 100%);
pointer-events: none;
z-index: 1;
}
.hero-content {
position: relative;
z-index: 2;
padding: 0 2.5rem 3rem;
}
.hero-divider {
width: 100%;
height: 1px;
background: rgba(227,226,222,0.25);
margin-bottom: 1.5rem;
}
.hero-meta-row {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 1rem;
margin-bottom: 0.25rem;
}
.hero-meta {
font-family: var(--general);
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.15em;
color: rgba(227,226,222,0.5);
display: flex;
flex-direction: column;
gap: 0.2rem;
}
.hero-cta-btn {
display: inline-block;
font-family: var(--clash);
font-size: 0.85rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
padding: 1rem 2rem;
background: var(--accent);
color: var(--bg);
transition: background 0.2s, color 0.2s;
}
.hero-cta-btn:hover {
background: var(--neon);
color: var(--dark);
}
.hero-headline {
font-family: var(--clash);
font-weight: 700;
font-size: 9vw;
line-height: 0.82;
letter-spacing: -0.05em;
text-transform: uppercase;
margin-top: 2.25rem;
}
.hero-headline .line1 {
display: block;
color: var(--accent);
}
.hero-headline .line2 {
display: block;
color: var(--bg);
margin-left: 10vw;
}
/* ── META BAR ────────────────────────────────────── */
.meta-bar {
border-top: 1px solid var(--dark);
border-bottom: 1px solid var(--dark);
padding: 0 2.5rem;
display: grid;
grid-template-columns: repeat(4, 1fr);
background: var(--bg);
}
.meta-col {
padding: 2rem 0;
border-right: 1px solid rgba(27,14,13,0.15);
}
.meta-col:last-child { border-right: none; }
.meta-col:not(:first-child) { padding-left: 2rem; }
.meta-col-label {
font-family: var(--general);
font-size: 0.6rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.15em;
color: var(--mid);
opacity: 0.65;
margin-bottom: 0.5rem;
display: block;
}
.meta-col-value {
font-family: var(--clash);
font-size: 1rem;
font-weight: 500;
text-transform: uppercase;
color: var(--dark);
letter-spacing: -0.01em;
}
/* ── CS OVERVIEW ─────────────────────────────────── */
.cs-overview {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 2rem;
padding: 6rem 2.5rem;
}
.cs-overview-label {
grid-column: span 4;
border-top: 1px solid var(--dark);
padding-top: 1rem;
}
.cs-overview-body {
grid-column: span 8;
border-top: 1px solid var(--dark);
padding-top: 1rem;
}
.cs-overview-text {
font-family: var(--general);
font-size: clamp(1rem, 1.4vw, 1.25rem);
color: var(--mid);
line-height: 1.6;
}
/* ── CATEGORY DIVIDER ───────────────────────────── */
.category-divider {
width: 100%;
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
padding: 0 2.5rem;
overflow: hidden;
}
.category-divider h2 {
font-family: var(--clash);
font-size: 12vw;
font-weight: 700;
letter-spacing: -0.04em;
line-height: 0.95;
color: var(--mid);
text-transform: uppercase;
padding: 0.2rem 0;
}
/* ── SCREENSHOTS ─────────────────────────────────── */
.screenshots-section {
padding: 5rem 2.5rem;
}
.screenshots-label {
border-top: 1px solid var(--dark);
padding-top: 1rem;
margin-bottom: 3rem;
}
/* Browser chrome frame */
.browser-frame {
background: var(--dark);
border-radius: 0;
}
.browser-bar {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.75rem 1.25rem;
border-bottom: 1px solid rgba(255,255,255,0.06);
}
.browser-dots {
display: flex;
gap: 6px;
flex-shrink: 0;
}
.browser-dot {
width: 8px;
height: 8px;
border-radius: 50%;
}
.browser-dot--red { background: var(--accent); }
.browser-dot--beige { background: var(--bg); }
.browser-dot--green { background: var(--neon); }
.browser-url {
font-family: var(--general);
font-size: 0.7rem;
color: rgba(227,226,222,0.4);
letter-spacing: 0.02em;
}
.browser-frame img {
width: 100%;
display: block;
}
.browser-scroll-wrap {
position: relative;
}
.browser-scroll-wrap::after {
content: 'SCROLL ↓';
position: absolute;
top: 0; left: 0; right: 0;
height: 80px;
background: linear-gradient(to bottom, rgba(27,14,13,0.9), transparent);
display: flex;
justify-content: center;
align-items: flex-start;
padding-top: 1rem;
font-family: monospace;
font-size: 0.65rem;
letter-spacing: 0.25em;
text-shadow: 0 0 8px var(--neon);
color: var(--neon);
pointer-events: none;
z-index: 2;
}
.browser-scroll {
max-height: 560px;
overflow-y: scroll;
scrollbar-width: thin;
scrollbar-color: var(--accent) var(--dark);
}
/* Full-width hero screenshot */
.screenshot-hero {
margin-bottom: 4rem;
}
/* 2-col screenshot grid */
.screenshot-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
}
.screenshot-card-label {
font-family: var(--general);
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--mid);
margin-bottom: 0.5rem;
display: block;
}
.screenshot-card-desc {
font-family: var(--general);
font-size: 0.9rem;
color: var(--mid);
line-height: 1.6;
margin-bottom: 1.25rem;
}
/* ── PROJECT NAV ─────────────────────────────────── */
.project-nav {
background: var(--dark);
display: flex;
justify-content: space-between;
align-items: center;
padding: 3rem 2.5rem;
border-top: 1px solid rgba(227,226,222,0.1);
}
.project-nav-link {
font-family: var(--clash);
font-size: 0.85rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--bg);
position: relative;
transition: color 0.2s;
}
.project-nav-link::after {
content: '';
position: absolute;
bottom: -4px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.project-nav-link:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.project-nav-link:hover { color: var(--neon); }
/* ── FOOTER ─────────────────────────────────────── */
.footer {
background: var(--bg);
border-top: 1px solid var(--dark);
padding: 4.5rem 2.5rem 0;
}
.footer-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 3rem;
margin-bottom: 4.5rem;
}
.footer-heading {
font-family: var(--clash);
font-size: 1.1rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: -0.01em;
margin-bottom: 1.25rem;
}
.footer-links {
list-style: none;
display: flex;
flex-direction: column;
gap: 0.65rem;
}
.footer-links a {
font-family: var(--general);
font-size: 0.875rem;
color: var(--mid);
transition: color 0.15s;
}
.footer-links a:hover { color: var(--accent); }
.footer-address {
font-family: var(--general);
font-size: 0.875rem;
color: var(--mid);
line-height: 1.8;
font-style: normal;
}
.footer-address a { font-weight: 700; }
.footer-address a:hover { color: var(--accent); }
.footer-cta {
background: var(--dark);
padding: 1.5rem;
}
.footer-cta label {
display: block;
font-family: var(--general);
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.15em;
color: var(--bg);
margin-bottom: 1rem;
}
.footer-input-row {
display: flex;
align-items: center;
border-bottom: 1px solid rgba(227,226,222,0.4);
gap: 0.5rem;
}
.footer-input-row input {
background: transparent;
border: none;
outline: none;
font-family: var(--general);
font-size: 0.8rem;
color: var(--bg);
text-transform: uppercase;
width: 100%;
padding: 0.5rem 0;
}
.footer-input-row input::placeholder { color: rgba(227,226,222,0.25); }
.footer-input-row button {
background: none;
border: none;
cursor: pointer;
font-family: var(--general);
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--neon);
padding: 0.5rem 0;
white-space: nowrap;
transition: color 0.15s;
}
.footer-input-row button:hover { color: var(--bg); }
.footer-bottom {
border-top: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: flex-end;
padding-top: 1.5rem;
}
.footer-ghost {
font-family: var(--clash);
font-size: 8vw;
font-weight: 700;
text-transform: uppercase;
color: var(--border);
line-height: 1;
letter-spacing: -0.04em;
user-select: none;
pointer-events: none;
}
.footer-legal {
font-family: var(--general);
font-size: 0.7rem;
color: var(--mid);
padding-bottom: 0.3rem;
}
/* ── RESPONSIVE ─────────────────────────────────── */
@media (max-width: 960px) {
.cs-overview { grid-template-columns: 1fr; gap: 1rem; }
.cs-overview-label,
.cs-overview-body { grid-column: span 1; }
.meta-bar { grid-template-columns: repeat(2, 1fr); }
.meta-col:nth-child(2) { border-right: none; }
.meta-col:nth-child(3) { border-right: 1px solid rgba(27,14,13,0.15); }
.footer-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.nav { padding: 1.25rem 1.5rem; }
.nav-links { display: none; }
.hero {
height: auto;
min-height: 0;
padding-top: 5rem;
}
.hero-content { padding: 0 1.5rem 2.5rem; }
.hero-meta-row {
flex-direction: column;
align-items: flex-start;
gap: 1rem;
margin-bottom: 1.5rem;
}
.hero-headline { font-size: 12vw; line-height: 0.85; }
.hero-headline .line2 { margin-left: 5vw; }
.meta-bar {
grid-template-columns: repeat(2, 1fr);
padding: 0 1.5rem;
}
.meta-col:nth-child(2) { border-right: none; }
.meta-col:nth-child(3) {
border-right: 1px solid rgba(27,14,13,0.15);
border-top: 1px solid rgba(27,14,13,0.15);
padding-left: 0;
}
.meta-col:nth-child(4) { border-top: 1px solid rgba(27,14,13,0.15); }
.cs-overview { padding: 4rem 1.5rem; }
.category-divider { padding: 0 1.5rem; }
.screenshots-section { padding: 4rem 1.5rem; }
.screenshot-grid { grid-template-columns: 1fr; }
.project-nav {
padding: 2rem 1.5rem;
flex-direction: column;
gap: 1.5rem;
align-items: flex-start;
}
.footer { padding: 3rem 1.5rem 0; }
.footer-grid { grid-template-columns: 1fr; gap: 2rem; }
.footer-ghost { font-size: 16vw; }
}
</style>
</head>
<body>
<!-- Noise Texture Overlay -->
<div class="noise" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<filter id="n">
<feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="3" stitchTiles="stitch"/>
</filter>
<rect width="100%" height="100%" filter="url(#n)"/>
</svg>
</div>
<!-- Navigation -->
<nav class="nav">
<div class="nav-left">
<a href="portfolio.html" class="nav-back">← Portfolio</a>
<a href="index.html" class="nav-logo">Uovidiu</a>
</div>
<div class="nav-links">
<a href="index.html#about" class="nav-link">About</a>
<a href="index.html#services" class="nav-link">Services</a>
<a href="index.html#contact" class="nav-link">Contact</a>
</div>
<a href="https://thompsonservicecentre.co.uk" target="_blank" rel="noopener" class="nav-cta">Visit Site →</a>
</nav>
<!-- Hero -->
<header class="hero">
<div class="hero-content">
<div class="hero-divider"></div>
<div class="hero-meta-row">
<div class="hero-meta">
<span>01 / WEB_DEV · 2025</span>
<span>Thompson Service Centre, Peterborough</span>
</div>
<a href="https://thompsonservicecentre.co.uk" target="_blank" rel="noopener" class="hero-cta-btn">Visit Site →</a>
</div>
<h1 class="hero-headline">
<span class="line1">Thompson</span>
<span class="line2">Service Centre</span>
</h1>
</div>
</header>
<main>
<!-- Project Meta Bar -->
<div class="meta-bar">
<div class="meta-col">
<span class="meta-col-label">Client</span>
<span class="meta-col-value">Thompson Service Centre</span>
</div>
<div class="meta-col">
<span class="meta-col-label">Year</span>
<span class="meta-col-value">2025</span>
</div>
<div class="meta-col">
<span class="meta-col-label">Stack</span>
<span class="meta-col-value">HTML · Tailwind v4 · GSAP</span>
</div>
</div>
<!-- Project Overview -->
<section class="cs-overview">
<div class="cs-overview-label">
<span class="section-label">Project Overview</span>
</div>
<div class="cs-overview-body">
<p class="cs-overview-text">
Thompson Service Centre needed more than a website — they needed a digital presence that matched 25 years of earned trust. We built a high-fidelity landing page that puts credibility front and center: a bold hero section, a trust bar loaded with real credentials, and service cards that communicate competence without the usual garage-site clichés.
</p>
</div>
</section>
<!-- Screenshots Category Divider -->
<div class="category-divider">
<h2>Screenshots</h2>
</div>
<!-- Screenshots -->
<section class="screenshots-section">
<!-- Full-width hero screenshot -->
<div class="screenshot-hero">
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url">thompsonservicecentre.co.uk</span>
</div>
<div class="browser-scroll-wrap">
<div class="browser-scroll">
<img src="/img/thompson/hero.jpg" alt="Thompson Service Centre — hero section screenshot">
</div>
</div>
</div>
</div>
<!-- 2-col screenshots: Booking Flow -->
<div class="screenshots-label">
<span class="section-label">Booking Flow</span>
</div>
<div class="screenshot-grid">
<div>
<span class="screenshot-card-label">Vehicle Lookup</span>
<p class="screenshot-card-desc">Registration plate lookup pulls vehicle details instantly — reducing form friction and building user confidence from the first interaction.</p>
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url">thompsonservicecentre.co.uk/book</span>
</div>
<img src="/img/thompson/booking-lookup.jpg" alt="Thompson Service Centre — vehicle lookup step">
</div>
</div>
<div>
<span class="screenshot-card-label">Booking Form</span>
<p class="screenshot-card-desc">A clean, single-column booking form with service selection and date picker. Designed for speed on mobile — no unnecessary steps, no dead ends.</p>
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url">thompsonservicecentre.co.uk/book</span>
</div>
<img src="/img/thompson/booking-confirm.jpg" alt="Thompson Service Centre — booking confirmation step">
</div>
</div>
</div>
</section>
<!-- Execution Category Divider -->
<div class="category-divider">
<h2>Execution</h2>
</div>
<!-- Craft & Execution -->
<section class="cs-overview">
<div class="cs-overview-label">
<span class="section-label">Craft &amp; Execution</span>
</div>
<div class="cs-overview-body">
<p class="cs-overview-text">
Built with vanilla HTML, Tailwind CSS v4, and GSAP-powered scroll animations, the page loads fast and feels premium on every device. The design system — rooted in Workshop Navy and Safety Orange — draws from real automotive heritage rather than off-the-shelf templates.
</p>
</div>
</section>
<!-- Project Navigation -->
<div class="project-nav">
<a href="portfolio.html" class="project-nav-link">← Back to Portfolio</a>
<a href="#" class="project-nav-link">Next Project → LHB Engineering</a>
</div>
</main>
<!-- Footer -->
<footer class="footer">
<div class="footer-grid">
<div>
<h4 class="footer-heading">Studio</h4>
<address class="footer-address">
Peterborough, UK<br>
<a href="mailto:hello@uovidiu.com">hello@uovidiu.com</a>
</address>
</div>
<div>
<h4 class="footer-heading">Navigate</h4>
<ul class="footer-links">
<li><a href="index.html#about">About</a></li>
<li><a href="index.html#services">Services</a></li>
<li><a href="portfolio.html">Portfolio</a></li>
<li><a href="index.html#contact">Contact</a></li>
</ul>
</div>
<div>
<h4 class="footer-heading">Work</h4>
<ul class="footer-links">
<li><a href="#">LHB Engineering</a></li>
<li><a href="portfolio-project.html">Thompson Auto</a></li>
</ul>
</div>
<div>
<div class="footer-cta">
<label for="footer-email">Start a project</label>
<div class="footer-input-row">
<input type="email" id="footer-email" placeholder="Your email">
<button type="button">Send</button>
</div>
</div>
</div>
</div>
<div class="footer-bottom">
<span class="footer-ghost">Uovidiu</span>
<span class="footer-legal">© 2026 Ovidiu Ungureanu</span>
</div>
</footer>
<script>
const nav = document.querySelector('.nav');
window.addEventListener('scroll', () => {
nav.classList.toggle('nav--scrolled', window.scrollY > 50);
}, { passive: true });
</script>
</body>
</html>

735
brutalist-01/portfolio.html Normal file
View File

@@ -0,0 +1,735 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Portfolio — Ovidiu Ungureanu</title>
<link rel="preconnect" href="https://api.fontshare.com">
<link href="https://api.fontshare.com/v2/css?f[]=clash-grotesk@700,600,500,400&f[]=general-sans@700,600,500,400&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--bg: #E3E2DE;
--dark: #1B0E0D;
--mid: #61220F;
--accent: #C72A09;
--neon: #31EF07;
--border: #D9D9D9;
--clash: 'Clash Grotesk', sans-serif;
--general: 'General Sans', sans-serif;
}
html { scroll-behavior: smooth; }
body {
font-family: var(--general);
background: var(--bg);
color: var(--dark);
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
::selection { background: var(--accent); color: var(--bg); }
/* ── NOISE ──────────────────────────────────────── */
.noise {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 50;
mix-blend-mode: multiply;
opacity: 0.08;
}
/* ── NAV ────────────────────────────────────────── */
.nav {
position: fixed;
top: 0; left: 0; right: 0;
z-index: 40;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.5rem 2.5rem;
mix-blend-mode: difference;
color: var(--bg);
transition: background 0.2s ease;
}
.nav--scrolled {
mix-blend-mode: normal;
background: rgba(27,14,13,0.9);
}
.nav-logo {
font-family: var(--clash);
font-weight: 700;
font-size: 1.5rem;
letter-spacing: -0.02em;
text-transform: uppercase;
}
.nav-links {
display: flex;
gap: 2.5rem;
font-family: var(--general);
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.nav-link {
position: relative;
}
.nav-link::after {
content: '';
position: absolute;
bottom: -3px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.nav-link:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.nav-cta {
font-family: var(--general);
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
}
/* ── HERO ───────────────────────────────────────── */
.hero {
position: relative;
height: 75vh;
max-height: 650px;
min-height: 520px;
background-color: var(--dark);
background-image: radial-gradient(circle, rgba(227,226,222,0.055) 1px, transparent 1px);
background-size: 48px 48px;
display: flex;
flex-direction: column;
justify-content: flex-end;
overflow: hidden;
}
.hero::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(ellipse at 50% 100%, transparent 40%, rgba(27,14,13,0.55) 100%);
pointer-events: none;
z-index: 1;
}
.hero-content {
position: relative;
z-index: 2;
padding: 0 2.5rem 3rem;
}
.hero-divider {
width: 100%;
height: 1px;
background: rgba(227,226,222,0.25);
margin-bottom: 1.5rem;
}
.hero-meta-row {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 1rem;
margin-bottom: 0.25rem;
}
.hero-meta {
font-family: var(--general);
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.15em;
color: rgba(227,226,222,0.5);
display: flex;
flex-direction: column;
gap: 0.2rem;
}
.hero-cta-btn {
display: inline-block;
font-family: var(--clash);
font-size: 0.85rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
padding: 1rem 2rem;
background: var(--accent);
color: var(--bg);
transition: background 0.2s, color 0.2s;
}
.hero-cta-btn:hover {
background: var(--neon);
color: var(--dark);
}
.hero-headline {
font-family: var(--clash);
font-weight: 700;
font-size: 13.5vw;
line-height: 0.75;
letter-spacing: -0.05em;
text-transform: uppercase;
margin-top: 2.25rem;
}
.hero-headline .line1 {
display: block;
color: var(--accent);
}
.hero-headline .line2 {
display: block;
color: var(--bg);
margin-left: 20vw;
}
/* ── SECTION LABEL ───────────────────────────────── */
.section-label {
font-family: monospace;
font-size: 0.75rem;
font-weight: 400;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--mid);
}
/* ── PORTFOLIO GRID ──────────────────────────────── */
.portfolio-section {
padding: 6rem 2.5rem;
}
.portfolio-header {
border-top: 1px solid var(--dark);
padding-top: 1rem;
margin-bottom: 3rem;
}
.portfolio-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 2.5rem;
}
.project-card {
display: flex;
flex-direction: column;
cursor: pointer;
}
/* — Thumbnail — */
.project-card__thumb {
position: relative;
aspect-ratio: 4 / 3;
overflow: hidden;
background: var(--dark);
}
.project-card__thumb img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
transition: transform 0.45s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.project-card:hover .project-card__thumb img {
transform: scale(1.05);
}
.project-card__label {
position: absolute;
top: 0; left: 0;
font-family: var(--general);
font-size: 0.65rem;
font-weight: 700;
color: var(--accent);
background: var(--dark);
padding: 0.3rem 0.75rem;
z-index: 2;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.project-card__badge {
position: absolute;
top: 1rem; right: 1rem;
background: var(--neon);
color: var(--dark);
font-family: var(--general);
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
padding: 6px 12px;
opacity: 0;
z-index: 2;
transition: opacity 0.25s ease;
}
.project-card:hover .project-card__badge { opacity: 1; }
/* — Body — */
.project-card__body {
padding: 1.25rem 0;
border-bottom: 1px solid var(--dark);
display: flex;
flex-direction: column;
flex: 1;
transition: border-color 0.2s ease;
}
.project-card:hover .project-card__body {
border-color: var(--accent);
}
.project-card__title {
font-family: var(--clash);
font-size: clamp(1.4rem, 2.2vw, 2rem);
font-weight: 700;
text-transform: uppercase;
letter-spacing: -0.02em;
line-height: 1;
color: var(--dark);
margin-bottom: 0.6rem;
}
.project-card__desc {
font-family: var(--general);
font-size: 1rem;
color: var(--mid);
line-height: 1.6;
flex: 1;
}
/* — Footer row — */
.project-card__footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 1rem;
}
.project-card__year {
font-family: var(--general);
font-size: 0.65rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--mid);
}
.project-card__arrow {
display: flex;
align-items: center;
justify-content: center;
width: 2rem; height: 2rem;
border: 1px solid var(--accent);
font-size: 1rem;
color: var(--accent);
flex-shrink: 0;
transition: background 0.15s, color 0.15s;
}
.project-card:hover .project-card__arrow {
background: var(--accent);
color: var(--bg);
}
/* ── CONTACT CTA ──────────────────────────────────── */
.contact-section {
background: var(--dark);
padding: 5rem 2.5rem 4.5rem;
position: relative;
overflow: hidden;
}
.contact-section::before {
content: '';
position: absolute;
inset: 0;
background-image: radial-gradient(circle, rgba(227,226,222,0.04) 1px, transparent 1px);
background-size: 48px 48px;
pointer-events: none;
}
.contact-inner { position: relative; z-index: 1; }
.contact-section .section-label {
color: rgba(227,226,222,0.35);
display: block;
margin-bottom: 2.5rem;
}
.contact-headline {
font-family: var(--clash);
font-size: clamp(2.5rem, 5vw, 5.5rem);
font-weight: 700;
text-transform: uppercase;
color: var(--bg);
line-height: 0.88;
letter-spacing: -0.04em;
margin-bottom: 2.5rem;
}
.contact-headline .accent { color: var(--accent); }
.contact-email {
display: block;
font-family: var(--clash);
font-size: clamp(1.5rem, 3.5vw, 3.75rem);
font-weight: 700;
color: var(--bg);
letter-spacing: -0.02em;
margin-bottom: 3rem;
width: fit-content;
position: relative;
}
.contact-email::after {
content: '';
position: absolute;
bottom: -4px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.35s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.contact-email:hover::after {
transform: scaleX(1);
transform-origin: left;
}
/* ── FOOTER ─────────────────────────────────────── */
.footer {
background: var(--bg);
border-top: 1px solid var(--dark);
padding: 4.5rem 2.5rem 0;
}
.footer-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 3rem;
margin-bottom: 4.5rem;
}
.footer-heading {
font-family: var(--clash);
font-size: 1.1rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: -0.01em;
margin-bottom: 1.25rem;
}
.footer-links {
list-style: none;
display: flex;
flex-direction: column;
gap: 0.65rem;
}
.footer-links a {
font-family: var(--general);
font-size: 0.875rem;
color: var(--mid);
transition: color 0.15s;
}
.footer-links a:hover { color: var(--accent); }
.footer-address {
font-family: var(--general);
font-size: 0.875rem;
color: var(--mid);
line-height: 1.8;
font-style: normal;
}
.footer-address a { font-weight: 700; }
.footer-address a:hover { color: var(--accent); }
.footer-cta {
background: var(--dark);
padding: 1.5rem;
}
.footer-cta label {
display: block;
font-family: var(--general);
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.15em;
color: var(--bg);
margin-bottom: 1rem;
}
.footer-input-row {
display: flex;
align-items: center;
border-bottom: 1px solid rgba(227,226,222,0.4);
gap: 0.5rem;
}
.footer-input-row input {
background: transparent;
border: none;
outline: none;
font-family: var(--general);
font-size: 0.8rem;
color: var(--bg);
text-transform: uppercase;
width: 100%;
padding: 0.5rem 0;
}
.footer-input-row input::placeholder { color: rgba(227,226,222,0.25); }
.footer-input-row button {
background: none;
border: none;
cursor: pointer;
font-family: var(--general);
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--neon);
padding: 0.5rem 0;
white-space: nowrap;
transition: color 0.15s;
}
.footer-input-row button:hover { color: var(--bg); }
.footer-bottom {
border-top: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: flex-end;
padding-top: 1.5rem;
}
.footer-ghost {
font-family: var(--clash);
font-size: 8vw;
font-weight: 700;
text-transform: uppercase;
color: var(--border);
line-height: 1;
letter-spacing: -0.04em;
user-select: none;
pointer-events: none;
}
.footer-legal {
font-family: var(--general);
font-size: 0.7rem;
color: var(--mid);
padding-bottom: 0.3rem;
}
/* ── RESPONSIVE ─────────────────────────────────── */
@media (max-width: 960px) {
.footer-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.nav { padding: 1.25rem 1.5rem; }
.nav-links { display: none; }
.hero {
height: auto;
min-height: 0;
padding-top: 5rem;
}
.hero-content { padding: 0 1.5rem 2.5rem; }
.hero-meta-row {
flex-direction: column;
align-items: flex-start;
gap: 1rem;
margin-bottom: 1.5rem;
}
.hero-headline { font-size: 12vw; }
.hero-headline .line2 { margin-left: 5vw; }
.portfolio-section { padding: 4rem 1.5rem; }
.portfolio-grid {
grid-template-columns: 1fr;
gap: 3rem;
}
.contact-section { padding: 4rem 1.5rem; }
.footer { padding: 3rem 1.5rem 0; }
.footer-grid { grid-template-columns: 1fr; gap: 2rem; }
.footer-ghost { font-size: 16vw; }
}
</style>
</head>
<body>
<!-- Noise Texture Overlay -->
<div class="noise" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<filter id="n">
<feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="3" stitchTiles="stitch"/>
</filter>
<rect width="100%" height="100%" filter="url(#n)"/>
</svg>
</div>
<!-- Navigation -->
<nav class="nav">
<a href="index.html" class="nav-logo">Uovidiu</a>
<div class="nav-links">
<a href="index.html#about" class="nav-link">About</a>
<a href="index.html#services" class="nav-link">Services</a>
<a href="index.html#contact" class="nav-link">Contact</a>
</div>
<a href="index.html#contact" class="nav-cta">Hire Me →</a>
</nav>
<!-- Hero -->
<header class="hero">
<div class="hero-content">
<div class="hero-divider"></div>
<div class="hero-meta-row">
<div class="hero-meta">
<span>Portfolio — 2 Projects</span>
<span>Web Design &amp; Development</span>
</div>
<a href="index.html" class="hero-cta-btn">← Back to Home</a>
</div>
<h1 class="hero-headline">
<span class="line1">Selected</span>
<span class="line2">Work</span>
</h1>
</div>
</header>
<main>
<!-- Portfolio Grid -->
<section class="portfolio-section">
<div class="portfolio-header">
<span class="section-label">001 — Selected Work</span>
</div>
<div class="portfolio-grid">
<!-- Project 1: Thompson -->
<a href="portfolio-project.html" class="project-card">
<div class="project-card__thumb">
<span class="project-card__badge">View Project →</span>
<img src="/img/thompson/hero.jpg" alt="Thompson Service Centre website screenshot" loading="lazy">
</div>
<div class="project-card__body">
<h2 class="project-card__title">Thompson Service Centre</h2>
<p class="project-card__desc">A high-fidelity automotive landing page that puts credibility front and centre. Bold hero, trust bar, and service cards — without the usual garage-site clichés.</p>
<div class="project-card__footer">
<span class="project-card__year">2025 · HTML · Tailwind · GSAP</span>
<span class="project-card__arrow"></span>
</div>
</div>
</a>
<!-- Project 2: LHB Engineering -->
<a href="#" class="project-card">
<div class="project-card__thumb">
<span class="project-card__badge">View Project →</span>
<img src="/img/lhbeng/hero.jpg" alt="LHB Engineering website screenshot" loading="lazy">
</div>
<div class="project-card__body">
<h2 class="project-card__title">LHB Engineering</h2>
<p class="project-card__desc">Full website redesign with a self-service CMS for portfolio, team profiles, and job listings — no developer needed for day-to-day updates.</p>
<div class="project-card__footer">
<span class="project-card__year">2022 · HTML · CSS · PHP</span>
<span class="project-card__arrow"></span>
</div>
</div>
</a>
</div>
</section>
<!-- Contact CTA -->
<section class="contact-section">
<div class="contact-inner">
<span class="section-label">002 — Contact</span>
<h2 class="contact-headline">
Got a project<br>
<span class="accent">in mind?</span>
</h2>
<a href="mailto:hello@uovidiu.com" class="contact-email">hello@uovidiu.com</a>
</div>
</section>
</main>
<!-- Footer -->
<footer class="footer">
<div class="footer-grid">
<div>
<h4 class="footer-heading">Studio</h4>
<address class="footer-address">
Peterborough, UK<br>
<a href="mailto:hello@uovidiu.com">hello@uovidiu.com</a>
</address>
</div>
<div>
<h4 class="footer-heading">Navigate</h4>
<ul class="footer-links">
<li><a href="index.html#about">About</a></li>
<li><a href="index.html#services">Services</a></li>
<li><a href="portfolio.html">Portfolio</a></li>
<li><a href="index.html#contact">Contact</a></li>
</ul>
</div>
<div>
<h4 class="footer-heading">Work</h4>
<ul class="footer-links">
<li><a href="#">LHB Engineering</a></li>
<li><a href="portfolio-project.html">Thompson Auto</a></li>
</ul>
</div>
<div>
<div class="footer-cta">
<label for="footer-email">Start a project</label>
<div class="footer-input-row">
<input type="email" id="footer-email" placeholder="Your email">
<button type="button">Send</button>
</div>
</div>
</div>
</div>
<div class="footer-bottom">
<span class="footer-ghost">Uovidiu</span>
<span class="footer-legal">© 2026 Ovidiu Ungureanu</span>
</div>
</footer>
<script>
const nav = document.querySelector('.nav');
window.addEventListener('scroll', () => {
nav.classList.toggle('nav--scrolled', window.scrollY > 50);
}, { passive: true });
</script>
</body>
</html>

View File

@@ -1,38 +1,43 @@
/* ========================================
PORTFOLIO — extends style.css only
======================================== */
.nav-links a.active {
color: var(--accent);
text-decoration: underline;
/* ── CASE STUDY HERO ─────────────────────────────── */
.hero--cs {
height: auto;
min-height: 0;
padding-top: 7rem;
}
/* ========================================
PORTFOLIO GRID — 3-col card index
======================================== */
.hero--cs .hero-headline .line2 {
font-size: 7.5vw;
margin-left: 0;
text-transform: none;
letter-spacing: 0;
padding-top: 0.5rem;
}
@media (max-width: 768px) {
.hero--cs .hero-headline .line2 { font-size: 8vw; }
}
/* ── PORTFOLIO GRID ──────────────────────────────── */
.portfolio-section {
padding: 6rem 2.5rem;
}
.portfolio-header {
border-top: 1px solid var(--dark);
padding-top: 1rem;
margin-bottom: 3rem;
}
.portfolio-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
grid-template-columns: repeat(2, 1fr);
gap: 2.5rem;
}
/* — Project card — */
.project-card {
display: flex;
flex-direction: column;
background: var(--black);
border: 4px solid var(--black);
box-shadow: 8px 8px 0 var(--black);
color: var(--white);
text-decoration: none;
transition: transform 0.1s, box-shadow 0.1s;
}
.project-card:hover {
transform: translate(-2px, -2px);
box-shadow: 8px 8px 0 var(--accent);
cursor: pointer;
}
.project-card--wip {
@@ -41,12 +46,11 @@
}
/* — Thumbnail — */
.project-card__thumb {
position: relative;
aspect-ratio: 4 / 3;
background: var(--grey-light);
overflow: hidden;
background: var(--dark);
}
.project-card__thumb img {
@@ -54,339 +58,370 @@
height: 100%;
object-fit: cover;
display: block;
transition: transform 0.45s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.project-card:hover .project-card__thumb img {
transform: scale(1.05);
}
.project-card__label {
position: absolute;
top: 0;
left: 0;
font-family: var(--mono);
font-size: 0.75rem;
font-weight: 700;
color: var(--accent);
background: var(--black);
padding: 0.3rem 0.6rem;
z-index: 1;
letter-spacing: 0.04em;
top: 0; left: 0;
font-family: monospace;
font-size: 0.65rem;
font-weight: 400;
color: var(--bg);
background: var(--accent);
padding: 0.3rem 0.75rem;
z-index: 2;
letter-spacing: 0.1em;
text-transform: uppercase;
}
/* — Body — */
.project-card__badge {
position: absolute;
top: 1rem; right: 1rem;
background: var(--neon);
color: var(--dark);
font-family: var(--general);
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
padding: 6px 12px;
opacity: 0;
z-index: 2;
transition: opacity 0.25s ease;
}
.project-card:hover .project-card__badge { opacity: 1; }
/* — Body — */
.project-card__body {
padding: 1.25rem;
padding: 1.25rem 0;
border-bottom: 1px solid var(--dark);
display: flex;
flex-direction: column;
flex: 1;
border-top: 2px solid var(--grey-dark);
transition: border-color 0.2s ease;
}
.project-card:hover .project-card__body {
border-color: var(--accent);
}
.project-card__title {
font-family: var(--mono);
font-size: 0.9rem;
font-weight: 800;
font-family: var(--clash);
font-size: clamp(1.4rem, 2.2vw, 2rem);
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.02em;
color: var(--white);
letter-spacing: -0.02em;
line-height: 1;
color: var(--dark);
margin-bottom: 0.6rem;
line-height: 1.3;
}
.project-card__desc {
font-family: var(--sans);
font-size: 0.85rem;
font-weight: 400;
color: var(--grey-text);
line-height: 1.5;
font-family: var(--general);
font-size: 1rem;
color: var(--mid);
line-height: 1.6;
flex: 1;
}
/* — Footer row — */
.project-card__footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 1.25rem;
margin-top: 1rem;
}
.project-card__year {
font-family: var(--mono);
font-family: var(--general);
font-size: 0.65rem;
color: var(--grey-text);
letter-spacing: 0.06em;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--mid);
}
.project-card__arrow {
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border: 2px solid var(--accent);
font-family: var(--mono);
width: 2rem; height: 2rem;
border: 1px solid var(--accent);
font-size: 1rem;
color: var(--accent);
flex-shrink: 0;
transition: background 0.1s, color 0.1s;
transition: background 0.15s, color 0.15s;
}
.project-card:hover .project-card__arrow {
background: var(--accent);
color: var(--black);
color: var(--bg);
}
/* — Tags — */
.tags-row {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
margin-top: 0.5rem;
/* ── CONTACT CTA (portfolio page variant) ─────────── */
.contact-section--slim {
padding: 5rem 2.5rem 4.5rem;
}
.tag {
font-family: var(--mono);
font-size: 0.62rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
padding: 0.3rem 0.65rem;
background: var(--black);
border: 2px solid var(--grey-dark);
color: var(--grey-text);
}
/* — Case study breadcrumb bar — */
.cs-breadcrumb {
display: flex;
justify-content: space-between;
align-items: center;
background: var(--black);
border: 4px solid var(--black);
box-shadow: 8px 8px 0 var(--black);
padding: 0.75rem 1.25rem;
margin-bottom: 2rem;
}
.cs-breadcrumb-label {
font-family: var(--mono);
font-size: 0.75rem;
font-weight: 700;
color: var(--accent);
letter-spacing: 0.04em;
}
/* — Case study inline meta bar — */
.cs-meta-bar {
list-style: none;
display: flex;
flex-direction: column;
gap: 0;
padding: 0.75rem 1rem;
background: var(--grey-dark);
border-left: 6px solid var(--grey-text);
/*border-top: 4px solid var(--grey-text);*/
margin-top: 1.5rem;
max-width: clamp(380px, 55vw, 750px);
box-shadow: var(--shadow);
}
.cs-meta-bar li {
font-family: var(--mono);
font-size: 0.8rem;
font-weight: 400;
color: var(--grey-text);
line-height: 1.8;
}
/* — Case study back link — */
.cs-back {
display: inline-block;
font-family: var(--mono);
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--accent);
text-decoration: none;
margin-bottom: 1.5rem;
transition: opacity 0.1s;
}
.cs-back:hover {
opacity: 0.7;
}
.cs-back--lg {
font-size: 0.85rem;
display: block;
margin-bottom: 2rem;
}
/* — Case study meta grid — */
.cs-meta-grid {
/* ── META BAR ────────────────────────────────────── */
.meta-bar {
border-top: 1px solid var(--dark);
border-bottom: 1px solid var(--dark);
padding: 0 2.5rem;
display: grid;
grid-template-columns: repeat(4, 1fr);
background: var(--bg);
}
.cs-meta-grid .service-item h3 {
font-size: 0.95rem;
text-transform: none;
.meta-col {
padding: 2rem 0;
border-right: 1px solid rgba(27,14,13,0.15);
}
.meta-col:last-child { border-right: none; }
.meta-col:not(:first-child) { padding-left: 2rem; }
.meta-col-label {
font-family: var(--general);
font-size: 0.6rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.15em;
color: var(--mid);
opacity: 0.65;
margin-bottom: 0.5rem;
display: block;
}
.meta-col-value {
font-family: var(--clash);
font-size: 1rem;
font-weight: 500;
color: var(--white);
text-transform: uppercase;
color: var(--dark);
letter-spacing: -0.01em;
}
/* — Browser chrome — */
/* ── CS OVERVIEW ─────────────────────────────────── */
.cs-overview {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 2rem;
padding: 6rem 2.5rem;
}
.browser-chrome {
.cs-overview-label {
grid-column: span 4;
border-top: 1px solid var(--dark);
padding-top: 1rem;
}
.cs-overview-body {
grid-column: span 8;
border-top: 1px solid var(--dark);
padding-top: 1rem;
}
.cs-overview-text {
font-family: var(--general);
font-size: clamp(1rem, 1.4vw, 1.25rem);
color: var(--mid);
line-height: 1.6;
}
/* ── SCREENSHOTS ─────────────────────────────────── */
.screenshots-section {
padding: 5rem 2.5rem;
}
.screenshots-label {
border-top: 1px solid var(--dark);
padding-top: 1rem;
margin-bottom: 3rem;
}
/* Browser chrome frame */
.browser-frame {
background: var(--dark);
border-radius: 0;
}
.browser-bar {
display: flex;
align-items: center;
gap: 1rem;
padding: 0.6rem 1rem;
background: var(--black);
border: var(--border-orange);
border-bottom: none;
}
.browser-chrome--sm {
padding: 0.45rem 0.75rem;
margin-bottom: 1rem;
gap: 0.75rem;
padding: 0.75rem 1.25rem;
border-bottom: 1px solid rgba(255,255,255,0.06);
}
.browser-dots {
display: flex;
gap: 0.35rem;
gap: 6px;
flex-shrink: 0;
}
.browser-dots span {
width: 0.5rem;
height: 0.5rem;
.browser-dot {
width: 8px;
height: 8px;
border-radius: 50%;
}
.browser-dot--red { background: var(--accent); }
.browser-dot--beige { background: var(--bg); }
.browser-dot--green { background: var(--neon); }
.browser-url {
font-family: var(--general);
font-size: 0.7rem;
color: rgba(227,226,222,0.4);
letter-spacing: 0.02em;
}
.browser-frame img {
width: 100%;
display: block;
}
.browser-dots span:first-child {
background: #ff5f57;
}
.browser-dots span:nth-child(2) {
background: #febc2e;
}
.browser-dots span:nth-child(3) {
background: #28c840;
}
.browser-url {
font-family: var(--mono);
font-size: 0.65rem;
color: var(--grey-text);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* — Screenshots — */
.screenshot-hero-wrap {
width: 70%;
margin: 0 auto;
border: var(--border-orange);
box-shadow: var(--shadow-orange);
}
.screenshot-hero-wrap .browser-chrome {
border: none;
border-bottom: 2px solid var(--accent);
}
.screenshot-hero-scroll {
.browser-scroll-wrap {
position: relative;
max-height: 600px;
overflow-y: scroll;
scrollbar-width: thin;
scrollbar-color: var(--accent) #1a1a1a;
}
.screenshot-hero-scroll--no-hint::before {
display: none;
}
.screenshot-hero-scroll::before {
content: '↓ scroll to view whole page';
position: sticky;
top: 0;
.browser-scroll-wrap::after {
content: 'SCROLL ↓';
position: absolute;
top: 0; left: 0; right: 0;
height: 80px;
background: linear-gradient(to bottom, rgba(27,14,13,0.9), transparent);
display: flex;
justify-content: center;
align-items: flex-start;
padding-top: 1.5rem;
height: 120px;
margin-bottom: -120px;
background: linear-gradient(to top, transparent, rgba(10, 10, 10, 0.9));
font-family: var(--mono);
font-size: 1rem;
letter-spacing: 0.12em;
color: var(--white);
padding-top: 1rem;
font-family: monospace;
font-size: 0.65rem;
letter-spacing: 0.25em;
text-shadow: 0 0 8px var(--neon);
color: var(--neon);
pointer-events: none;
z-index: 1;
z-index: 2;
}
.browser-scroll {
max-height: 560px;
overflow-y: scroll;
scrollbar-width: thin;
scrollbar-color: var(--accent) var(--dark);
}
/* Full-width hero screenshot */
.screenshot-hero {
display: block;
width: 100%;
margin-bottom: 4rem;
}
.screenshot-card {
padding: 2rem;
}
.screenshot-card__desc {
font-family: var(--sans);
font-size: 0.85rem;
color: var(--grey);
margin: 0.4rem 0 1.25rem;
line-height: 1.5;
}
.screenshot-screen {
display: block;
width: 100%;
border: var(--border-orange);
border-top: none;
}
/* ========================================
RESPONSIVE
======================================== */
@media (max-width: 960px) {
.cs-meta-grid {
/* 2-col screenshot grid */
.screenshot-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
gap: 2rem;
}
.screenshot-card-label {
font-family: var(--general);
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--mid);
margin-bottom: 0.5rem;
display: block;
}
.screenshot-card-desc {
font-family: var(--general);
font-size: 0.9rem;
color: var(--mid);
line-height: 1.6;
margin-bottom: 1.25rem;
}
/* ── PROJECT NAV ─────────────────────────────────── */
.project-nav {
background: var(--dark);
display: flex;
justify-content: space-between;
align-items: center;
padding: 3rem 2.5rem;
border-top: 1px solid rgba(227,226,222,0.1);
}
.project-nav-link {
font-family: var(--clash);
font-size: 0.85rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--bg);
position: relative;
transition: color 0.2s;
}
.project-nav-link::after {
content: '';
position: absolute;
bottom: -4px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.project-nav-link:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.project-nav-link:hover { color: var(--neon); }
/* ── RESPONSIVE ─────────────────────────────────── */
@media (max-width: 960px) {
.cs-overview { grid-template-columns: 1fr; gap: 1rem; }
.cs-overview-label,
.cs-overview-body { grid-column: span 1; }
.meta-bar { grid-template-columns: repeat(2, 1fr); }
.meta-col:nth-child(2) { border-right: none; }
.meta-col:nth-child(3) { border-right: 1px solid rgba(27,14,13,0.15); }
}
@media (max-width: 768px) {
.portfolio-section { padding: 4rem 1.5rem; }
.portfolio-grid {
grid-template-columns: 1fr;
gap: 3rem;
}
.meta-bar {
grid-template-columns: repeat(2, 1fr);
gap: 1.25rem;
padding: 0 1.5rem;
}
.screenshot-hero-wrap {
width: 100%;
.meta-col:nth-child(2) { border-right: none; }
.meta-col:nth-child(3) {
border-right: 1px solid rgba(27,14,13,0.15);
border-top: 1px solid rgba(27,14,13,0.15);
padding-left: 0;
}
.meta-col:nth-child(4) { border-top: 1px solid rgba(27,14,13,0.15); }
.cs-meta-grid {
grid-template-columns: 1fr;
}
}
@media (max-width: 480px) {
.portfolio-grid {
grid-template-columns: 1fr;
gap: 1rem;
.cs-overview { padding: 4rem 1.5rem; }
.screenshots-section { padding: 4rem 1.5rem; }
.screenshot-grid { grid-template-columns: 1fr; }
.project-nav {
padding: 2rem 1.5rem;
flex-direction: column;
gap: 1.5rem;
align-items: flex-start;
}
}

View File

@@ -1,427 +1,606 @@
/* ========================================
RESET & BASE (ORANGE & GRAY BRUTALIST)
======================================== */
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
/* Industrial Palette */
--black: #000000;
--white: #ffffff;
--grey-dark: #2b2d30; /* Slate Concrete */
--grey-light: #3f4246; /* Industrial Surface */
--grey-text: #b0b0b0;
--accent: #ff5500; /* Safety Orange */
--mono: 'JetBrains Mono', monospace;
--sans: 'DM Sans', sans-serif;
/* Brutalist Variables */
--border-thick: 4px solid var(--black);
--border-orange: 4px solid var(--accent);
--shadow: 8px 8px 0px var(--black);
--shadow-orange: 8px 8px 0px var(--accent);
--bg: #E3E2DE;
--dark: #1B0E0D;
--mid: #61220F;
--accent: #C72A09;
--neon: #31EF07;
--border: #D9D9D9;
--clash: 'Clash Grotesk', sans-serif;
--general: 'General Sans', sans-serif;
}
html {
scroll-behavior: smooth;
font-size: 16px;
}
html { scroll-behavior: smooth; }
body {
font-family: var(--sans);
background: var(--grey-dark);
color: var(--white);
line-height: 1.2; /* Tighter brutalist spacing */
font-family: var(--general);
background: var(--bg);
color: var(--dark);
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
padding: 10px; /* Outer frame */
}
a {
color: var(--white);
text-decoration: none;
transition: all 0.1s ease;
a { color: inherit; text-decoration: none; }
::selection { background: var(--accent); color: var(--bg); }
/* ── NOISE ──────────────────────────────────────── */
.noise {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 50;
mix-blend-mode: multiply;
opacity: 0.08;
}
::selection {
background: var(--accent);
color: var(--black);
}
/* ========================================
NAV - THE CONTROL PANEL
======================================== */
/* ── NAV ────────────────────────────────────────── */
.nav {
position: fixed;
top: 20px;
left: 20px;
right: 20px;
z-index: 100;
top: 0; left: 0; right: 0;
z-index: 40;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: var(--black);
border: var(--border-orange);
box-shadow: var(--shadow);
padding: 1.5rem 2.5rem;
mix-blend-mode: difference;
color: var(--bg);
transition: background 0.2s ease;
}
.nav--scrolled {
mix-blend-mode: normal;
background: rgba(27,14,13,0.9);
}
.nav-left {
display: flex;
align-items: center;
gap: 1.25rem;
gap: 2rem;
}
.nav-logo {
font-family: var(--mono);
font-weight: 800;
font-size: 1.25rem;
font-family: var(--clash);
font-weight: 700;
font-size: 1.5rem;
letter-spacing: -0.02em;
color: var(--accent);
text-transform: uppercase;
}
.nav-back {
font-family: var(--mono);
font-size: 1rem;
color: var(--white);
opacity: 0.5;
transition: opacity 0.15s;
font-family: var(--general);
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
position: relative;
}
.nav-back:hover {
opacity: 1;
.nav-back::after {
content: '';
position: absolute;
bottom: -3px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.nav-back:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.nav-links {
display: flex;
gap: 2rem;
font-family: var(--mono);
font-size: 0.8rem;
gap: 2.5rem;
font-family: var(--general);
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.nav-link {
position: relative;
}
.nav-link::after {
content: '';
position: absolute;
bottom: -3px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.25s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.nav-link:hover::after,
.nav-link--active::after {
transform: scaleX(1);
transform-origin: left;
}
.nav-cta {
font-family: var(--general);
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.nav-links a:hover {
color: var(--accent);
text-decoration: underline;
}
/* ========================================
HERO - IMPACT ZONE
======================================== */
/* ── HERO ───────────────────────────────────────── */
.hero {
min-height: 60vh;
position: relative;
height: 70vh;
max-height: 650px;
min-height: 520px;
background-color: var(--dark);
background-image: radial-gradient(circle, rgba(227,226,222,0.055) 1px, transparent 1px);
background-size: 48px 48px;
display: flex;
flex-direction: column;
justify-content: center;
padding: 7rem 3rem 2rem;
border: var(--border-thick);
background: var(--grey-light);
margin-bottom: 2rem;
box-shadow: var(--shadow);
justify-content: flex-end;
overflow: hidden;
}
.hero .section-label {
background: var(--accent);
color: var(--black);
font-size: 0.85rem;
padding: 4px 12px;
margin-bottom: 2rem;
width: fit-content;
.hero::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(ellipse at 50% 100%, transparent 40%, rgba(27,14,13,0.55) 100%);
pointer-events: none;
z-index: 1;
}
.hero h1 {
font-family: var(--mono);
font-size: clamp(3rem, 10vw, 8rem);
font-weight: 800;
line-height: 0.85;
letter-spacing: -0.05em;
margin-bottom: 2rem;
text-transform: uppercase;
color: var(--white);
.hero-content {
position: relative;
z-index: 2;
padding: 0 2.5rem 3rem;
}
.hero h1 .h1-sub {
font-size: 0.6em;
}
.hero-sub {
font-size: 1.25rem;
color: var(--white);
background: var(--black);
padding: 1rem;
max-width: clamp(280px, 40vw, 550px);
margin-bottom: 2rem;
border-left: 8px solid var(--accent);
}
/* ========================================
BUTTONS - INDUSTRIAL ACTUATORS
======================================== */
.hero-cta {
display: flex;
gap: 1.5rem;
align-items: center;
}
.btn {
display: inline-block;
font-family: var(--mono);
font-size: 0.9rem;
font-weight: 900;
text-transform: uppercase;
padding: 1.2rem 2.5rem;
background: var(--accent);
color: var(--black);
border: var(--border-thick);
box-shadow: 4px 4px 0px var(--black);
transition: transform 0.1s, box-shadow 0.1s;
}
.btn:hover {
transform: translate(-2px, -2px);
box-shadow: 7px 7px 0px var(--black);
background: var(--white);
}
.btn-ghost {
background: transparent;
border-color: var(--white);
color: var(--white);
}
.btn-ghost:hover {
background: var(--white);
color: var(--black);
}
/* ========================================
SECTIONS - MODULE CONTAINERS
======================================== */
.section {
padding: 3rem 2.5rem;
background: var(--grey-light);
border: var(--border-thick);
margin-bottom: 2rem;
box-shadow: var(--shadow);
}
.section-label {
font-family: var(--mono);
font-size: 0.8rem;
text-transform: uppercase;
background: var(--black);
color: var(--accent);
padding: 5px 15px;
display: inline-block;
margin-bottom: 3rem;
font-weight: 900;
}
.large-text {
font-size: 1.75rem;
line-height: 1.3;
margin-bottom: 2rem;
font-weight: 700;
color: var(--accent);
}
.section-content p {
color: var(--white);
.hero-divider {
width: 100%;
height: 1px;
background: rgba(227,226,222,0.25);
margin-bottom: 1.5rem;
line-height: 1.6;
font-size: 1.1rem;
}
/* ========================================
SERVICES - LIST ROWS
======================================== */
.services-section {
background: var(--grey-light);
padding: 3rem 2.5rem 0;
margin-bottom: 2rem;
box-shadow: var(--shadow);
.hero-meta-row {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 1rem;
margin-bottom: 0.25rem;
}
.services-section-label {
font-family: var(--mono);
font-size: 0.8rem;
.hero-meta {
font-family: var(--general);
font-size: 0.7rem;
text-transform: uppercase;
background: var(--black);
color: var(--accent);
padding: 5px 15px;
letter-spacing: 0.15em;
color: rgba(227,226,222,0.5);
display: flex;
flex-direction: column;
gap: 0.2rem;
}
.hero-cta-btn {
display: inline-block;
margin-bottom: 2rem;
font-weight: 900;
border: 1px solid rgba(255,255,255,0.15);
}
.services-heading {
font-family: 'Archivo Black', sans-serif;
font-size: clamp(4rem, 13vw, 13rem);
font-weight: 900;
font-family: var(--clash);
font-size: 0.85rem;
font-weight: 700;
text-transform: uppercase;
color: #ffffff;
line-height: 0.88;
letter-spacing: -0.02em;
margin-bottom: 3rem;
letter-spacing: 0.06em;
padding: 1rem 2rem;
background: var(--accent);
color: var(--bg);
transition: background 0.2s, color 0.2s;
}
.hero-cta-btn:hover {
background: var(--neon);
color: var(--dark);
}
.services-list {
border-top: 1px solid rgba(255,255,255,0.2);
.hero-headline {
font-family: var(--clash);
font-weight: 700;
font-size: 13.5vw;
line-height: 0.75;
letter-spacing: -0.05em;
text-transform: uppercase;
margin-top: 2.25rem;
padding: 0 1rem;
}
.hero-headline .line1 {
display: block;
color: var(--accent);
}
.hero-headline .line2 {
display: block;
color: var(--bg);
margin-left: 20vw;
}
/* ── SECTION LABEL ───────────────────────────────── */
.section-label {
font-family: monospace;
font-size: 0.75rem;
font-weight: 400;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--mid);
}
/* ── MANIFESTO / ABOUT ──────────────────────────── */
.manifesto {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 2rem;
padding: 6rem 2.5rem;
}
.manifesto-label-col {
grid-column: span 4;
border-top: 1px solid var(--dark);
padding-top: 1rem;
}
.manifesto-text-col {
grid-column: span 8;
border-top: 1px solid var(--dark);
padding-top: 1rem;
}
.manifesto-text {
font-family: var(--clash);
font-size: clamp(1.75rem, 3.2vw, 3rem);
font-weight: 500;
line-height: 1.15;
text-transform: uppercase;
text-indent: 3rem;
}
.manifesto-text .hl { color: var(--mid); }
/* ── CATEGORY DIVIDER ───────────────────────────── */
.category-divider {
width: 100%;
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
padding: 0 2.5rem;
overflow: hidden;
}
.category-divider h2 {
font-family: var(--clash);
font-size: 12vw;
font-weight: 700;
letter-spacing: -0.04em;
line-height: 0.95;
color: var(--mid);
text-transform: uppercase;
padding: 0.2rem 0;
}
/* ── SERVICES ───────────────────────────────────── */
.services {
border-top: 1px solid rgba(27,14,13,0.15);
padding: 0 2.5rem;
}
.service-row {
display: flex;
align-items: center;
padding: 2.5rem 1rem;
margin: 0 -1rem;
border-bottom: 1px solid rgba(255,255,255,0.2);
cursor: default;
align-items: flex-start;
gap: 2rem;
border-bottom: 1px solid rgba(27,14,13,0.15);
padding: 2.5rem 0;
margin: 0 -2.5rem;
padding-left: 2.5rem;
padding-right: 2.5rem;
position: relative;
overflow: hidden;
cursor: default;
transition: background 0.15s ease;
}
.service-row:hover {
background: var(--black);
}
.service-row-body {
display: flex;
align-items: flex-start;
gap: 1.75rem;
flex: 1;
min-width: 0;
}
.service-row-num {
font-family: var(--mono);
font-size: 1rem;
.service-num {
font-family: var(--general);
font-size: 0.9rem;
font-weight: 700;
color: #ff4d00;
padding-top: 0.6rem;
white-space: nowrap;
flex-shrink: 0;
}
.service-row-content {
flex: 1;
min-width: 0;
}
.service-row-title {
font-family: var(--mono), serif;
font-size: clamp(3rem, 8vw, 8rem);
font-weight: 900;
text-transform: uppercase;
color: #ffffff;
line-height: 0.92;
letter-spacing: -0.02em;
margin-bottom: 1.25rem;
transition: color 0.15s ease;
}
.service-row:hover .service-row-title {
color: var(--accent);
padding-top: 0.8rem;
flex-shrink: 0;
width: 3.5rem;
}
.service-row-tags {
.service-body { flex: 1; min-width: 0; }
.service-title {
font-family: var(--clash);
font-size: clamp(1.75rem, 3.2vw, 3rem);
font-weight: 500;
line-height: 1.15;
text-transform: uppercase;
text-indent: 3rem;
color: var(--dark);
margin-bottom: 1.1rem;
}
.service-row--alt .service-title > span {
background-color: var(--accent);
color: var(--bg);
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
padding: 0.04em 0.15em;
display: inline;
}
.service-tags {
display: flex;
gap: 0.6rem;
gap: 0.5rem;
flex-wrap: wrap;
}
.service-tag {
font-family: var(--mono);
font-size: 0.7rem;
font-family: var(--general);
font-size: 0.65rem;
font-weight: 600;
text-transform: uppercase;
color: #ffffff;
border: 1px solid rgba(255,255,255,0.35);
letter-spacing: 0.07em;
padding: 4px 12px;
border: 1px solid rgba(27,14,13,0.25);
border-radius: 100px;
padding: 5px 14px;
color: var(--mid);
}
.service-badge {
position: absolute;
top: 2.25rem;
right: 2.5rem;
background: var(--neon);
color: var(--dark);
font-family: var(--general);
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
white-space: nowrap;
padding: 6px 12px;
opacity: 0;
}
@media (max-width: 768px) {
.services-section {
padding: 2rem 1.5rem 0;
}
.service-row {
padding: 2rem 0;
}
.service-row-num {
padding-top: 0.3rem;
}
.service-row-arrow {
display: none;
}
.service-row-title {
font-size: clamp(2rem, 10vw, 3rem);
}
/* ── CONTACT ────────────────────────────────────── */
.contact-section {
background: var(--dark);
padding: 7rem 2.5rem 6rem;
position: relative;
overflow: hidden;
}
/* ========================================
CONTACT & FOOTER
======================================== */
.contact-section::before {
content: '';
position: absolute;
inset: 0;
background-image: radial-gradient(circle, rgba(227,226,222,0.04) 1px, transparent 1px);
background-size: 48px 48px;
pointer-events: none;
}
.contact-inner { position: relative; z-index: 1; }
.contact-section .section-label {
color: rgba(227,226,222,0.35);
display: block;
margin-bottom: 3rem;
}
.contact-headline {
font-family: var(--clash);
font-size: clamp(3rem, 6vw, 6rem);
font-weight: 700;
text-transform: uppercase;
color: var(--bg);
line-height: 0.88;
letter-spacing: -0.04em;
margin-bottom: 3rem;
}
.contact-headline .accent { color: var(--accent); }
.contact-email {
display: block;
font-family: var(--mono);
font-size: clamp(1.2rem, 5vw, 3.5rem);
font-weight: 900;
margin: 2rem 0;
color: var(--white);
text-decoration: underline;
text-decoration-color: var(--accent);
text-underline-offset: 8px;
font-family: var(--clash);
font-size: clamp(1.5rem, 3.5vw, 3.75rem);
font-weight: 700;
color: var(--bg);
letter-spacing: -0.02em;
margin-bottom: 3rem;
width: fit-content;
position: relative;
}
.contact-email::after {
content: '';
position: absolute;
bottom: -4px; left: 0;
width: 100%; height: 2px;
background: var(--neon);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.35s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.contact-email:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.contact-email:hover {
color: var(--accent);
background: var(--black);
.contact-meta {
font-family: var(--general);
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.12em;
color: rgba(227,226,222,0.35);
display: flex;
align-items: center;
gap: 1.25rem;
}
.contact-meta .dot { opacity: 0.4; }
/* ── FOOTER ─────────────────────────────────────── */
.footer {
background: var(--black);
border: var(--border-orange);
color: var(--grey-text);
padding: 2rem 3rem;
margin-top: 4rem;
background: var(--bg);
border-top: 1px solid var(--dark);
padding: 4.5rem 2.5rem 0;
}
/* ========================================
RESPONSIVE
======================================== */
.footer-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 3rem;
margin-bottom: 4.5rem;
}
.footer-heading {
font-family: var(--clash);
font-size: 1.1rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: -0.01em;
margin-bottom: 1.25rem;
}
.footer-links {
list-style: none;
display: flex;
flex-direction: column;
gap: 0.65rem;
}
.footer-links a {
font-family: var(--general);
font-size: 0.875rem;
color: var(--mid);
transition: color 0.15s;
}
.footer-links a:hover { color: var(--accent); }
.footer-address {
font-family: var(--general);
font-size: 0.875rem;
color: var(--mid);
line-height: 1.8;
font-style: normal;
}
.footer-address a { font-weight: 700; }
.footer-address a:hover { color: var(--accent); }
.footer-cta {
background: var(--dark);
padding: 1.5rem;
}
.footer-cta label {
display: block;
font-family: var(--general);
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.15em;
color: var(--bg);
margin-bottom: 1rem;
}
.footer-input-row {
display: flex;
align-items: center;
border-bottom: 1px solid rgba(227,226,222,0.4);
gap: 0.5rem;
}
.footer-input-row input {
background: transparent;
border: none;
outline: none;
font-family: var(--general);
font-size: 0.8rem;
color: var(--bg);
text-transform: uppercase;
width: 100%;
padding: 0.5rem 0;
}
.footer-input-row input::placeholder { color: rgba(227,226,222,0.25); }
.footer-input-row button {
background: none;
border: none;
cursor: pointer;
font-family: var(--general);
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--neon);
padding: 0.5rem 0;
white-space: nowrap;
transition: color 0.15s;
}
.footer-input-row button:hover { color: var(--bg); }
.footer-bottom {
border-top: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: flex-end;
padding-top: 1.5rem;
}
.footer-ghost {
font-family: var(--clash);
font-size: 8vw;
font-weight: 700;
text-transform: uppercase;
color: var(--border);
line-height: 1;
letter-spacing: -0.04em;
user-select: none;
pointer-events: none;
}
.footer-legal {
font-family: var(--general);
font-size: 0.7rem;
color: var(--mid);
padding-bottom: 0.3rem;
}
/* ── RESPONSIVE ─────────────────────────────────── */
@media (max-width: 960px) {
.manifesto { grid-template-columns: 1fr; gap: 1rem; }
.manifesto-label-col,
.manifesto-text-col { grid-column: span 1; }
.footer-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.nav {
top: 10px; left: 10px; right: 10px;
padding: 1rem;
}
.nav { padding: 1.25rem 1.5rem; }
.nav-links { display: none; }
.hero, .section {
padding: 6rem 1.5rem 3rem;
.hero-content { padding: 0 1.5rem 2.5rem; }
.hero-meta-row {
flex-direction: column;
align-items: flex-start;
gap: 1rem;
margin-bottom: 1.5rem;
}
.hero-headline { font-size: 12vw; }
.hero-headline .line2 { margin-left: 5vw; }
.services-grid {
grid-template-columns: 1fr;
}
.manifesto { padding: 4rem 1.5rem; }
.manifesto-text { font-size: 1.75rem; text-indent: 1.5rem; }
.service-item {
padding: 2rem;
}
.category-divider { padding: 0 1.5rem; }
.services { padding: 0 1.5rem; }
.service-row { margin: 0 -1.5rem; padding: 2rem 1.5rem; }
.service-badge { right: 1.5rem; }
.service-title { font-size: clamp(1.5rem, 5vw, 2.5rem); text-indent: 1.5rem; }
.contact-section { padding: 4rem 1.5rem; }
.footer { padding: 3rem 1.5rem 0; }
.footer-grid { grid-template-columns: 1fr; gap: 2rem; }
.footer-ghost { font-size: 16vw; }
}

View File

@@ -17,22 +17,64 @@ $projects = [
'domain' => 'thompsonservicecentre.co.uk',
'page_title' => 'Thompson Service Centre — Case Study',
'page_desc' => 'How we built a trust-first digital presence for a 25-year Peterborough garage.',
'overview' => 'Thompson Service Centre needed more than a website — they needed a digital presence that matched 25 years of earned trust. We built a high-fidelity landing page that puts credibility front and centre: a bold hero section, a trust bar loaded with real credentials, and service cards that communicate competence without the usual garage-site clichés.',
'execution' => 'Built with vanilla HTML, Tailwind CSS v4, and GSAP-powered scroll animations, the page loads fast and feels premium on every device. The design system — rooted in Workshop Navy and Safety Orange — draws from real automotive heritage rather than off-the-shelf templates.',
'hero_img' => '/img/thompson/hero.jpg',
'screenshots' => [
[
'label' => 'Booking Flow',
'items' => [
[
'label' => 'Vehicle Lookup',
'desc' => 'Registration plate lookup pulls vehicle details instantly — reducing form friction and building user confidence from the first interaction.',
'img' => '/img/thompson/booking-lookup.jpg',
'alt' => 'Thompson Service Centre — vehicle lookup step',
'url_suffix' => '/book',
],
[
'label' => 'Booking Form',
'desc' => 'A clean, single-column booking form with service selection and date picker. Designed for speed on mobile — no unnecessary steps, no dead ends.',
'img' => '/img/thompson/booking-confirm.jpg',
'alt' => 'Thompson Service Centre — booking confirmation step',
'url_suffix' => '/book',
],
],
],
],
],
'lhbeng' => [
'num' => '02',
'code' => 'WEB_DEV',
'title' => 'LHB Eng',
'title' => 'LHB Engineering',
'desc' => 'Structural Engineers designing projects that build strong communities.',
'year' => '2022',
'thumb' => '/img/lhbeng/hero.jpg',
'live' => true,
'h1' => ['LHB', 'Lynch, Harrison & Brumleve, Inc.'],
'sub' => 'Website Redesign · 2022',
'stack' => 'HTML · CSS',
'stack' => 'HTML · CSS · PHP · MySQL',
'location' => 'LHB Eng, Indianapolis',
'domain' => 'lhb-eng.com',
'page_title' => 'LHB Engineering — Case Study',
'page_desc' => 'Full website redesign for LHB Engineering with a self-service CMS for portfolio, team, and job listings.',
'overview' => 'Full website redesign with a simple content manager — so the team can update their portfolio, staff profiles, and job listings without needing a developer every time. Clean, modern layout that reflects the scale and quality of their structural engineering work.',
'execution' => 'Built a full redesign for LHB Engineering, replacing their outdated site with a clean, modern layout that better reflects the scale and quality of their work. The new site is fast, fully responsive, and structured so visitors can quickly find services, past projects, and contact details. Alongside the redesign, a custom PHP/MySQL CMS gives the team full control over content — no developer needed for day-to-day updates.',
'hero_img' => '/img/lhbeng/hero.jpg',
'screenshots' => [
[
'label' => 'Website CMS',
'items' => [
[
'label' => 'Content Manager',
'desc' => 'A full-featured CMS lets the team manage portfolio items, team profiles, and job listings without touching code. Day-to-day updates handled entirely in-house.',
'img' => '/img/lhbeng/admin.jpg',
'alt' => 'LHB Engineering — CMS admin panel',
'url_suffix' => '/admin',
],
],
],
],
],
];

View File

@@ -1,12 +1,22 @@
<?php
$slugs = array_keys($projects);
$idx = array_search($cs_slug, $slugs);
$prev = $idx > 0 ? $slugs[$idx - 1] : null;
$next = $idx < count($slugs) - 1 ? $slugs[$idx + 1] : null;
?>
<section class="section section-cta">
<div class="section-label"> Next</div>
<div class="section-content">
<a href="/portfolio" class="cs-back cs-back--lg"> Back to All Work</a>
<p class="large-text">Got a project in mind?</p>
<a href="mailto:hello@uovidiu.com" class="btn">Let's Talk →</a>
</div>
</section>
<div class="project-nav">
<?php if ($prev): ?>
<a href="/portfolio/<?php echo htmlspecialchars($prev); ?>/" class="project-nav-link">← <?php echo htmlspecialchars($projects[$prev]['title']); ?></a>
<?php else: ?>
<a href="/portfolio" class="project-nav-link">← Back to Portfolio</a>
<?php endif; ?>
<?php if ($next): ?>
<a href="/portfolio/<?php echo htmlspecialchars($next); ?>/" class="project-nav-link">Next Project → <?php echo htmlspecialchars($projects[$next]['title']); ?></a>
<?php else: ?>
<a href="/portfolio" class="project-nav-link">← Back to Portfolio</a>
<?php endif; ?>
</div>
<script src="/js/screenshot-scroll-hint.js"></script>
<?php require __DIR__ . '/footer.php'; ?>

View File

@@ -3,13 +3,8 @@
/*
* Case Study Header Partial
* ─────────────────────────────────────────────────────────────────
* Requires the following variables set by the calling page BEFORE
* requiring this file:
*
* Requires the following variable set by the calling page:
* $cs_slug string Key into $projects, e.g. 'thompson'
*
* Everything else ($title, $description, hero content) is read from
* $projects[$cs_slug] in data/projects.php.
* ─────────────────────────────────────────────────────────────────
*/
@@ -18,21 +13,42 @@ require __DIR__ . '/../data/projects.php';
$p = $projects[$cs_slug];
$title = $p['page_title'];
$description = $p['page_desc'];
$nav_back = ['url' => '/portfolio', 'label' => '← Portfolio'];
//$nav_cta = ['url' => 'https://' . $p['domain'], 'label' => 'Visit Site →'];
require __DIR__ . '/header.php';
?>
<div class="cs-breadcrumb">
<a href="/portfolio" class="cs-back">← All Work</a>
<span class="cs-breadcrumb-label">[<?= htmlspecialchars($p['num']) ?> / <?= htmlspecialchars($p['code']) ?>]</span>
</div>
<header class="hero">
<div class="section-label">Case Study — <?= htmlspecialchars($p['num']) ?></div>
<h1><?= htmlspecialchars($p['h1'][0]) ?><br><span class="h1-sub"><?= htmlspecialchars($p['h1'][1]) ?></span></h1>
<p class="hero-sub"><?= htmlspecialchars($p['sub']) ?></p>
<ul class="cs-meta-bar">
<li><?= htmlspecialchars($p['stack']) ?></li>
<li><?= htmlspecialchars($p['location']) ?></li>
<li><?= htmlspecialchars($p['year']) ?></li>
</ul>
<header class="hero hero--cs">
<div class="hero-content">
<div class="hero-divider"></div>
<div class="hero-meta-row">
<div class="hero-meta">
<span><?php echo htmlspecialchars($p['num']); ?> / WEB_DEV · <?php echo htmlspecialchars($p['year']); ?></span>
<span><?php echo htmlspecialchars($p['location']); ?></span>
</div>
</div>
<h1 class="hero-headline">
<span class="line1"><?php echo htmlspecialchars($p['h1'][0]); ?></span>
<span class="line2"><?php echo htmlspecialchars($p['h1'][1]); ?></span>
</h1>
</div>
</header>
<div class="meta-bar">
<div class="meta-col">
<span class="meta-col-label">Client</span>
<span class="meta-col-value"><?php echo htmlspecialchars($p['title']); ?></span>
</div>
<div class="meta-col">
<span class="meta-col-label">Year</span>
<span class="meta-col-value"><?php echo htmlspecialchars($p['year']); ?></span>
</div>
<div class="meta-col">
<span class="meta-col-label">Stack</span>
<span class="meta-col-value"><?php echo htmlspecialchars($p['stack']); ?></span>
</div>
<div class="meta-col">
<span class="meta-col-label">Location</span>
<span class="meta-col-value"><?php echo htmlspecialchars($p['location']); ?></span>
</div>
</div>

View File

@@ -1,7 +1,47 @@
<footer class="footer">
<span>© <?php echo date('Y'); ?> Ovidiu Ungureanu</span>
<span>Built with PHP, no JS frameworks were harmed.</span>
</footer>
<footer class="footer">
<div class="footer-grid">
<div>
<h4 class="footer-heading">Studio</h4>
<address class="footer-address">
Peterborough, UK<br>
<a href="mailto:hello@uovidiu.com">hello@uovidiu.com</a>
</address>
</div>
<div>
<h4 class="footer-heading">Navigate</h4>
<ul class="footer-links">
<li><a href="/#about">About</a></li>
<li><a href="/#services">Services</a></li>
<li><a href="/portfolio">Portfolio</a></li>
<li><a href="/#contact">Contact</a></li>
</ul>
</div>
<!-- <div>-->
<!-- <div class="footer-cta">-->
<!-- <label for="footer-email">Start a project</label>-->
<!-- <div class="footer-input-row">-->
<!-- <input type="email" id="footer-email" placeholder="Your email" autocomplete="email">-->
<!-- <button type="button">Send</button>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
</div>
<div class="footer-bottom">
<span class="footer-ghost">U. ovidiu</span>
<span class="footer-legal">© <?php echo date('Y'); ?> Ovidiu Ungureanu</span>
</div>
</footer>
<script>
const nav = document.querySelector('.nav');
window.addEventListener('scroll', () => {
nav.classList.toggle('nav--scrolled', window.scrollY > 50);
}, { passive: true });
</script>
</body>
</html>

View File

@@ -1,3 +1,4 @@
<?php $current = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); ?>
<!DOCTYPE html>
<html lang="en">
<head>
@@ -5,9 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($title); ?></title>
<meta name="description" content="<?php echo htmlspecialchars($description); ?>">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700;900&family=DM+Sans:wght@400;500&family=Archivo+Black&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://api.fontshare.com">
<link href="https://api.fontshare.com/v2/css?f[]=clash-grotesk@700,600,500,400&f[]=general-sans@700,600,500,400&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/css/style.css">
<?php if (!empty($extra_css)): ?>
<link rel="stylesheet" href="<?php echo htmlspecialchars($extra_css); ?>">
@@ -15,18 +15,36 @@
</head>
<body>
<?php $current = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); ?>
<nav class="nav">
<div class="noise" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<filter id="n">
<feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="3" stitchTiles="stitch"/>
</filter>
<rect width="100%" height="100%" filter="url(#n)"/>
</svg>
</div>
<nav class="nav">
<?php if (!empty($nav_back)): ?>
<div class="nav-left">
<a href="/" class="nav-logo">OU</a>
<?php if (str_starts_with($current, '/portfolio/')): ?>
<a href="/portfolio" class="nav-back">←(back)</a>
<?php endif; ?>
<a href="<?php echo htmlspecialchars($nav_back['url']); ?>" class="nav-back"><?php echo htmlspecialchars($nav_back['label']); ?></a>
<a href="/" class="nav-logo">U. ovidiu</a>
</div>
<div class="nav-links">
<a href="/#about">About</a>
<a href="/#services">Services</a>
<a href="/portfolio"<?php echo (str_starts_with($current, '/portfolio')) ? ' class="active"' : ''; ?>>Work</a>
<a href="/#contact">Contact</a>
<a href="/#about" class="nav-link">About</a>
<a href="/#services" class="nav-link">Services</a>
<a href="/#contact" class="nav-link">Contact</a>
</div>
</nav>
<?php if (!empty($nav_cta)): ?>
<a href="<?php echo htmlspecialchars($nav_cta['url']); ?>" target="_blank" rel="noopener" class="nav-cta"><?php echo htmlspecialchars($nav_cta['label']); ?></a>
<?php endif; ?>
<?php else: ?>
<a href="/" class="nav-logo">U. ovidiu</a>
<div class="nav-links">
<a href="/#about" class="nav-link">About</a>
<a href="/#services" class="nav-link">Services</a>
<a href="/portfolio" class="nav-link<?php echo str_starts_with($current, '/portfolio') ? ' nav-link--active' : ''; ?>">Work</a>
<a href="/#contact" class="nav-link">Contact</a>
</div>
<?php endif; ?>
</nav>

145
index.php
View File

@@ -1,107 +1,124 @@
<?php
$title = 'Ovidiu Ungureanu — Web Developer';
$description = 'PHP/MySQL developer based in Peterborough. I build custom web apps, ERP systems, and backends for businesses that need something specific.';
require __DIR__.'/includes/header.php';
$description = 'PHP/MySQL developer based in Peterborough. I build custom web apps, booking systems, and backends for small businesses.';
require __DIR__ . '/includes/header.php';
?>
<header class="hero">
<div class="section-label">Web Developer — UK</div>
<h1>Ovidiu<br>Ungureanu</h1>
<p class="hero-sub">I build web applications that work.<br>PHP, MySQL, clean code, no nonsense.</p>
<div class="hero-cta">
<a href="/portfolio" class="btn">View Work →</a>
<a href="#contact" class="btn btn-ghost">Let's Talk</a>
<div class="hero-content">
<div class="hero-divider"></div>
<div class="hero-meta-row">
<div class="hero-meta">
<span>Web Developer — Peterborough, UK</span>
<span>I build web applications that work.</span>
<span>Available for freelance</span>
</div>
<a href="#contact" class="hero-cta-btn">Let's Talk →</a>
</div>
<h1 class="hero-headline">
<span class="line1">CleanCode</span>
<span class="line2">Studio</span>
</h1>
</div>
</header>
<section id="about" class="section">
<div class="section-label">001 — About</div>
<div class="section-content">
<p> I'm a web developer based in Peterborough.</p>
<p>I build websites and online tools for small businesses — things like booking systems, customer dashboards, and the bits that make your day-to-day easier to manage.</p>
<p>Whether you need a fresh website, an online booking page for your garage, or a simple system to keep track of jobs and customers — I'll build it quickly, affordably, and without the jargon.</p>
</div>
</section>
<main>
<!-- About / Manifesto -->
<section class="manifesto" id="about">
<div class="manifesto-label-col">
<span class="section-label">001 — About</span>
</div>
<div class="manifesto-text-col">
<p class="manifesto-text">
I build websites and online tools for small businesses
<span class="hl">— booking systems, customer dashboards</span>.
<br>Fast, affordable, and built to last.
Built for businesses that need something real.
</p>
</div>
</section>
<!-- Services Category Divider -->
<div class="category-divider">
<h2>Services</h2>
</div>
<!-- Services List -->
<section class="services" id="services">
<section id="services" class="services-section">
<div class="services-section-label">002 — Services</div>
<div class="services-list">
<div class="service-row">
<div class="service-row-body">
<span class="service-row-num">(01)</span>
<div class="service-row-content">
<h3 class="service-row-title">Website Design<br>&amp; Development</h3>
<div class="service-row-tags">
<span class="service-num">(01)</span>
<div class="service-body">
<h3 class="service-title">Website Design<br>&amp; Development</h3>
<div class="service-tags">
<span class="service-tag">Design</span>
<span class="service-tag">Development</span>
<span class="service-tag">Responsive</span>
</div>
</div>
<span class="service-badge">Enquire →</span>
</div>
</div>
<div class="service-row">
<div class="service-row-body">
<span class="service-row-num">(02)</span>
<div class="service-row-content">
<h3 class="service-row-title">Custom Tools<br>&amp; Systems</h3>
<div class="service-row-tags">
<div class="service-row service-row--alt">
<span class="service-num">(02)</span>
<div class="service-body">
<h3 class="service-title"><span>Custom Tools<br>&amp; Systems</span></h3>
<div class="service-tags">
<span class="service-tag">PHP</span>
<span class="service-tag">MySQL</span>
<span class="service-tag">Custom Builds</span>
</div>
</div>
<span class="service-badge">Enquire →</span>
</div>
</div>
<div class="service-row">
<div class="service-row-body">
<span class="service-row-num">(03)</span>
<div class="service-row-content">
<h3 class="service-row-title">Booking &amp;<br>Scheduling</h3>
<div class="service-row-tags">
<span class="service-num">(03)</span>
<div class="service-body">
<h3 class="service-title">Booking &amp;<br>Scheduling</h3>
<div class="service-tags">
<span class="service-tag">Bookings</span>
<span class="service-tag">Automation</span>
<span class="service-tag">Small Business</span>
</div>
</div>
<span class="service-badge">Enquire →</span>
</div>
</div>
<div class="service-row">
<div class="service-row-body">
<span class="service-row-num">(04)</span>
<div class="service-row-content">
<h3 class="service-row-title">Ongoing Support<br>&amp; Updates</h3>
<div class="service-row-tags">
<div class="service-row service-row--alt">
<span class="service-num">(04)</span>
<div class="service-body">
<h3 class="service-title"><span>Ongoing Support<br>&amp; Updates</span></h3>
<div class="service-tags">
<span class="service-tag">Maintenance</span>
<span class="service-tag">Performance</span>
<span class="service-tag">Support</span>
</div>
</div>
<span class="service-badge">Enquire →</span>
</div>
</div>
</div>
</section>
<!--<section class="section section-cta">-->
<!-- <div class="section-label">003 — Work</div>-->
<!-- <div class="section-content">-->
<!-- <p class="large-text">A few recent builds.</p>-->
<!-- <a href="/portfolio" class="btn">View Work →</a>-->
<!-- </div>-->
<!--</section>-->
</section>
<section id="contact" class="section">
<div class="section-label">004 — Contact</div>
<div class="section-content">
<p class="large-text">Got a project in mind?</p>
<!-- Contact -->
<section class="contact-section" id="contact">
<div class="contact-inner">
<span class="section-label">004 — Contact</span>
<h2 class="contact-headline">
Got a project<br>
<span class="accent">in mind?</span>
</h2>
<a href="mailto:hello@uovidiu.com" class="contact-email">hello@uovidiu.com</a>
<div class="contact-details">
<div class="contact-meta">
<span>Peterborough, UK</span>
<span>·</span>
<span class="dot">·</span>
<span>Available for freelance</span>
</div>
</div>
</section>
</section>
<?php
require __DIR__.'/includes/footer.php'; ?>
</main>
<?php require __DIR__ . '/includes/footer.php'; ?>

151
portfolio-page.php Normal file
View File

@@ -0,0 +1,151 @@
<?php
require __DIR__ . '/data/projects.php';
$slug = isset($_GET['slug']) ? preg_replace('/[^a-z0-9\-]/', '', strtolower($_GET['slug'])) : '';
if (!$slug || !isset($projects[$slug])) {
http_response_code(404);
require __DIR__ . '/404.php';
exit;
}
$p = $projects[$slug];
$title = htmlspecialchars($p['page_title']);
$description = htmlspecialchars($p['page_desc']);
$extra_css = '/css/portfolio.css';
$nav_back = ['url' => '/portfolio', 'label' => '← Portfolio'];
//if (!empty($p['domain'])) {
// $nav_cta = ['url' => 'https://' . $p['domain'], 'label' => 'Visit Site →'];
//}
require __DIR__ . '/includes/header.php';
?>
<header class="hero hero--cs">
<div class="hero-content">
<div class="hero-divider"></div>
<div class="hero-meta-row">
<div class="hero-meta">
<span><?= htmlspecialchars($p['num']) ?> / <?= htmlspecialchars($p['code']) ?> · <?= htmlspecialchars($p['year']) ?></span>
<span><?= htmlspecialchars($p['location']) ?></span>
<span><?= htmlspecialchars($p['sub']) ?></span>
</div>
</div>
<h1 class="hero-headline">
<span class="line1"><?= htmlspecialchars($p['h1'][0]) ?></span>
<span class="line2"><?= htmlspecialchars($p['h1'][1]) ?></span>
</h1>
</div>
</header>
<main>
<!-- Project Meta Bar -->
<div class="meta-bar">
<div class="meta-col">
<span class="meta-col-label">Client</span>
<span class="meta-col-value"><?= htmlspecialchars($p['title']) ?></span>
</div>
<div class="meta-col">
<span class="meta-col-label">Year</span>
<span class="meta-col-value"><?= htmlspecialchars($p['year']) ?></span>
</div>
<div class="meta-col">
<span class="meta-col-label">Stack</span>
<span class="meta-col-value"><?= htmlspecialchars($p['stack']) ?></span>
</div>
</div>
<!-- Project Overview -->
<section class="cs-overview">
<div class="cs-overview-label">
<span class="section-label">Project Overview</span>
</div>
<div class="cs-overview-body">
<p class="cs-overview-text"><?= htmlspecialchars($p['overview']) ?></p>
</div>
</section>
<!-- Screenshots Category Divider -->
<div class="category-divider">
<h2>Screenshots</h2>
</div>
<!-- Screenshots -->
<section class="screenshots-section">
<!-- Full-width hero screenshot -->
<div class="screenshot-hero">
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url"><?= htmlspecialchars($p['domain']) ?></span>
</div>
<div class="browser-scroll-wrap">
<div class="browser-scroll">
<img src="<?= htmlspecialchars($p['hero_img']) ?>" alt="<?= htmlspecialchars($p['title']) ?> — Homepage">
</div>
</div>
</div>
</div>
<?php foreach ($p['screenshots'] as $group): ?>
<div class="screenshots-label">
<span class="section-label"><?= htmlspecialchars($group['label']) ?></span>
</div>
<div class="screenshot-grid">
<?php foreach ($group['items'] as $shot): ?>
<div>
<span class="screenshot-card-label"><?= htmlspecialchars($shot['label']) ?></span>
<p class="screenshot-card-desc"><?= htmlspecialchars($shot['desc']) ?></p>
<div class="browser-frame">
<div class="browser-bar">
<div class="browser-dots">
<span class="browser-dot browser-dot--red"></span>
<span class="browser-dot browser-dot--beige"></span>
<span class="browser-dot browser-dot--green"></span>
</div>
<span class="browser-url"><?= htmlspecialchars($p['domain'] . $shot['url_suffix']) ?></span>
</div>
<img src="<?= htmlspecialchars($shot['img']) ?>" alt="<?= htmlspecialchars($shot['alt']) ?>">
</div>
</div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</section>
<!-- Execution Category Divider -->
<div class="category-divider">
<h2>Execution</h2>
</div>
<!-- Craft & Execution -->
<section class="cs-overview">
<div class="cs-overview-label">
<span class="section-label">Craft &amp; Execution</span>
</div>
<div class="cs-overview-body">
<p class="cs-overview-text"><?= htmlspecialchars($p['execution']) ?></p>
</div>
</section>
<!-- Project Navigation -->
<div class="project-nav">
<a href="/portfolio" class="project-nav-link">← Back to Portfolio</a>
</div>
</main>
<?php require __DIR__ . '/includes/footer.php'; ?>

View File

@@ -1,71 +1,71 @@
<?php
$title = 'Portfolio — Ovidiu Ungureanu';
$description = 'Selected web development projects by Ovidiu Ungureanu.';
$extra_css = '/css/portfolio.css';
require __DIR__.'/includes/header.php';
require __DIR__ . '/includes/header.php';
require __DIR__ . '/data/projects.php';
?>
<header class="hero">
<div class="section-label">Portfolio — Selected Work</div>
<h1>Selected<br>Work</h1>
<p class="hero-sub">Client projects and builds.</p>
<div class="hero-content">
<div class="hero-divider"></div>
<div class="hero-meta-row">
<div class="hero-meta">
<span>Portfolio — <?php echo count($projects); ?> Projects</span>
<span>Web Design &amp; Development</span>
</div>
<a href="/" class="hero-cta-btn">← Back to Home</a>
</div>
<h1 class="hero-headline">
<span class="line1">Selected</span>
<span class="line2">Work</span>
</h1>
</div>
</header>
<section class="section">
<div class="section-label">001 — <?php
echo count($projects); ?> Projects
<main>
<section class="portfolio-section">
<div class="portfolio-header">
<span class="section-label">001 — Selected Work</span>
</div>
<div class="portfolio-grid">
<?php
foreach ($projects as $slug => $p): ?>
<a href="/portfolio/<?php
echo htmlspecialchars($slug); ?>/"
class="project-card<?php
echo $p['live'] ? '' : ' project-card--wip'; ?>">
<?php foreach ($projects as $slug => $p): ?>
<a href="/portfolio/<?php echo htmlspecialchars($slug); ?>/" class="project-card<?php echo $p['live'] ? '' : ' project-card--wip'; ?>">
<div class="project-card__thumb">
<span class="project-card__label">[<?php
echo htmlspecialchars($p['num']); ?> / <?php
echo htmlspecialchars($p['code']); ?>]</span>
<?php
if ($p['thumb']): ?>
<img src="<?php
echo htmlspecialchars($p['thumb']); ?>"
alt="<?php
echo htmlspecialchars($p['title']); ?>"
loading="lazy">
<?php
endif; ?>
<span class="project-card__label"><?php echo htmlspecialchars($p['num']); ?> / <?php echo htmlspecialchars($p['code']); ?></span>
<span class="project-card__badge">View Project →</span>
<?php if ($p['thumb']): ?>
<img src="<?php echo htmlspecialchars($p['thumb']); ?>" alt="<?php echo htmlspecialchars($p['title']); ?>" loading="lazy">
<?php endif; ?>
</div>
<div class="project-card__body">
<h3 class="project-card__title"><?php
echo htmlspecialchars($p['title']); ?></h3>
<p class="project-card__desc"><?php
echo htmlspecialchars($p['desc']); ?></p>
<h2 class="project-card__title"><?php echo htmlspecialchars($p['title']); ?></h2>
<p class="project-card__desc"><?php echo htmlspecialchars($p['desc']); ?></p>
<div class="project-card__footer">
<span class="project-card__year"><?php
echo htmlspecialchars($p['year']); ?></span>
<span class="project-card__year"><?php echo htmlspecialchars($p['year']); ?> · <?php echo htmlspecialchars($p['stack']); ?></span>
<span class="project-card__arrow">→</span>
</div>
</div>
</a>
<?php
endforeach; ?>
<?php endforeach; ?>
</div>
</section>
<section class="section section-cta">
<div class="section-label">002 — Contact</div>
<div class="section-content">
<p class="large-text">Got a project in mind?</p>
<a href="mailto:hello@uovidiu.com" class="btn">Let's Talk →</a>
</section>
<section class="contact-section contact-section--slim">
<div class="contact-inner">
<span class="section-label">002 — Contact</span>
<h2 class="contact-headline">
Got a project<br>
<span class="accent">in mind?</span>
</h2>
<a href="mailto:hello@uovidiu.com" class="contact-email">hello@uovidiu.com</a>
</div>
</section>
</section>
<?php
require __DIR__.'/includes/footer.php'; ?>
</main>
<?php require __DIR__ . '/includes/footer.php'; ?>

View File

@@ -1,118 +0,0 @@
<?php
/*
* ═══════════════════════════════════════════════════════════════════
* CASE STUDY TEMPLATE
* ═══════════════════════════════════════════════════════════════════
*
* HOW TO USE
* ──────────
* 1. Copy this folder to portfolio/{slug}/
* 2. Fill in every TODO below — nothing should say TODO when live
* 3. Add an entry to $projects in data/projects.php (including page_title, page_desc)
* 4. Drop screenshots into /img/{slug}/
*
* IMAGES
* ──────
* hero.jpg — full-page screenshot (used as grid thumbnail too)
* feature-1.jpg — first feature / flow screenshot
* feature-2.jpg — second feature / flow screenshot
* Add more as needed — duplicate the 2-col screenshot section below.
*
* SECTIONS (delete what you don't need)
* ──────────────────────────────────────
* · Project Overview — always include
* · Hero screenshot — always include
* · Feature section — include if there's a flow / feature worth showing
* · Craft & Execution — include if the build has something worth saying
* · CTA — always include, comes from cs_footer.php
* ═══════════════════════════════════════════════════════════════════
*/
// ── Set the slug — everything else lives in data/projects.php ─────
$cs_slug = 'TODO'; // e.g. 'northgate'
require __DIR__ . '/../../includes/cs_header.php';
?>
<!-- ── HERO SCREENSHOT ───────────────────────────────────────────── -->
<section class="section">
<div class="section-label">Project Overview</div>
<div class="section-content">
<p>TODO What problem did the client have and what did you build to fix it? Keep it to 23 sentences. Be specific — name the feature, the constraint, the outcome.</p>
</div>
<div class="screenshot-hero-wrap">
<div class="browser-chrome">
<div class="browser-dots">
<span></span><span></span><span></span>
</div>
<span class="browser-url"><?= htmlspecialchars($p['domain']) ?></span>
</div>
<div class="screenshot-hero-scroll">
<img
src="/img/<?= htmlspecialchars($cs_slug) ?>/hero.jpg"
alt="TODO Client Name — TODO description"
class="screenshot-hero"
loading="lazy"
>
</div>
</div>
</section>
<!-- ── FEATURE / FLOW SCREENSHOTS (2-col) ────────────────────────── -->
<!-- Delete this section if you don't have feature screenshots -->
<section class="section">
<div class="section-label">TODO Section Label</div><!-- e.g. Booking Flow / Admin Panel / Listings -->
<div class="services-grid">
<div class="service-item screenshot-card">
<span class="service-num">TODO Feature label</span><!-- e.g. Step 1 / Vehicle Lookup -->
<p class="screenshot-card__desc">TODO Feature description.</p>
<div class="browser-chrome browser-chrome--sm">
<div class="browser-dots">
<span></span><span></span><span></span>
</div>
<span class="browser-url"><?= htmlspecialchars($p['domain']) ?>/TODO-path</span>
</div>
<img
src="/img/<?= htmlspecialchars($cs_slug) ?>/feature-1.jpg"
alt="TODO description"
class="screenshot-screen"
loading="lazy"
>
</div>
<div class="service-item screenshot-card">
<span class="service-num">TODO Feature label</span>
<p class="screenshot-card__desc">TODO Feature description.</p>
<div class="browser-chrome browser-chrome--sm">
<div class="browser-dots">
<span></span><span></span><span></span>
</div>
<span class="browser-url"><?= htmlspecialchars($p['domain']) ?>/TODO-path</span>
</div>
<img
src="/img/<?= htmlspecialchars($cs_slug) ?>/feature-2.jpg"
alt="TODO description"
class="screenshot-screen"
loading="lazy"
>
</div>
</div>
</section>
<!-- ── CRAFT & EXECUTION ─────────────────────────────────────────── -->
<!-- Delete this section if there's nothing distinctive about the build -->
<section class="section">
<div class="section-label">Craft & Execution</div>
<div class="section-content">
<p>TODO Anything worth saying about how it was built — a technical decision, a performance win, something that made the difference. If you can't think of anything specific, delete this section.</p>
</div>
</section>
<?php require __DIR__ . '/../../includes/cs_footer.php'; ?>

View File

@@ -1,64 +0,0 @@
<?php
$cs_slug = 'lhbeng';
require __DIR__ . '/../../includes/cs_header.php';
?>
<!-- ── HERO SCREENSHOT ───────────────────────────────────────────── -->
<section class="section">
<div class="section-label">Project Overview</div>
<div class="section-content">
<p>Full website redesign with a simple content manager — so you can update your portfolio, team profiles, and job listings yourself without needing a developer every time.</p>
</div>
<div class="screenshot-hero-wrap">
<div class="browser-chrome">
<div class="browser-dots">
<span></span><span></span><span></span>
</div>
<span class="browser-url"><?= htmlspecialchars($p['domain']) ?></span>
</div>
<img
src="/img/lhbeng/hero.jpg"
alt="LHB Engineering — Homepage"
class="screenshot-hero"
loading="lazy"
>
</div>
</section>
<!-- ── FEATURE / FLOW SCREENSHOTS (2-col) ────────────────────────── -->
<section class="section">
<div class="section-label">Website CMS</div>
<div class="services-grid">
<div class="service-item screenshot-card">
<span class="service-num">Website CMS</span>
<p class="screenshot-card__desc">Full-fledged CMS for content.</p>
<div class="browser-chrome browser-chrome--sm">
<div class="browser-dots">
<span></span><span></span><span></span>
</div>
<span class="browser-url"><?= htmlspecialchars($p['domain']) ?>/admin</span>
</div>
<img
src="/img/lhbeng/admin.jpg"
alt="LHB Engineering CMS admin panel"
class="screenshot-screen"
loading="lazy"
>
</div>
</div>
</section>
<!-- ── CRAFT & EXECUTION ─────────────────────────────────────────── -->
<section class="section">
<div class="section-label">Craft & Execution</div>
<div class="section-content">
<p>Built a full redesign for LHB Engineering, replacing their outdated site with a clean, modern layout that better reflects the scale and quality of their work. <br/>The new site is fast, fully responsive, and structured so visitors can quickly find services, past projects, and contact details. <br/>
Alongside the redesign, I built a simple CMS so the team can manage their portfolio, staff profiles, and job listings themselves — no developer needed for day-to-day updates.</p>
</div>
</section>
<?php require __DIR__ . '/../../includes/cs_footer.php'; ?>

View File

@@ -1,81 +0,0 @@
<?php
$cs_slug = 'thompson';
require __DIR__ . '/../../includes/cs_header.php';
?>
<section class="section">
<div class="section-label">Project Overview</div>
<div class="section-content">
<p>Thompson Service Centre needed more than a website — they needed a digital presence that matched 25 years of earned trust. We built a high-fidelity
landing page that puts credibility front and center: a bold hero section, a trust bar loaded with real credentials, and service cards that
communicate competence without the usual garage-site clichés. Every element was designed to make a first-time visitor feel like they'd already found
their mechanic.</p>
</div>
<div class="screenshot-hero-wrap">
<div class="browser-chrome">
<div class="browser-dots">
<span></span><span></span><span></span>
</div>
<span class="browser-url"><?= htmlspecialchars($p['domain']) ?></span>
</div>
<div class="screenshot-hero-scroll">
<img
src="/img/thompson/hero.jpg"
alt="Thompson Service Centre — Homepage"
class="screenshot-hero"
loading="lazy"
>
</div>
</div>
</section>
<section class="section">
<div class="section-label">Booking Flow</div>
<div class="services-grid">
<div class="service-item screenshot-card">
<span class="service-num">Vehicle Lookup</span>
<p class="screenshot-card__desc">Enter your registration plate to pull vehicle details automatically.</p>
<div class="browser-chrome browser-chrome--sm">
<div class="browser-dots">
<span></span><span></span><span></span>
</div>
<span class="browser-url"><?= htmlspecialchars($p['domain']) ?>/book</span>
</div>
<img
src="/img/thompson/booking-lookup.jpg"
alt="Vehicle registration lookup"
class="screenshot-screen"
loading="lazy"
>
</div>
<div class="service-item screenshot-card">
<span class="service-num">Booking Form</span>
<p class="screenshot-card__desc">Confirm your vehicle and fill in the booking details in one clean step.</p>
<div class="browser-chrome browser-chrome--sm">
<div class="browser-dots">
<span></span><span></span><span></span>
</div>
<span class="browser-url"><?= htmlspecialchars($p['domain']) ?>/book</span>
</div>
<img
src="/img/thompson/booking-confirm.jpg"
alt="Vehicle confirmed and booking form"
class="screenshot-screen"
loading="lazy"
>
</div>
</div>
</section>
<section class="section">
<div class="section-label">Craft & Execution</div>
<div class="section-content">
<p>Built with vanilla HTML, Tailwind CSS v4, and GSAP-powered scroll animations, the page loads fast and feels premium on every device. The design
system — rooted in Workshop Navy and Safety Orange — draws from real automotive heritage rather than off-the-shelf templates. Noise overlays,
layered gradients, and spring-eased micro-interactions give it a tactile warmth that sets it apart from every other garage site in the postcode.</p>
</div>
</section>
<?php require __DIR__ . '/../../includes/cs_footer.php'; ?>