Compare commits

...

61 Commits

Author SHA1 Message Date
Dejvino
c435ceacda tweak print style to 2 pages 2026-07-27 19:13:59 +02:00
Dejvino
d590ba1b21 style: denser selected work 2026-07-27 18:15:43 +02:00
Dejvino
5407e5133e style: two column selected work side-by-side 2026-07-27 17:58:39 +02:00
Dejvino
9d6f0e21a2 tweak: selected work text in two columns 2026-07-27 17:40:22 +02:00
Dejvino
e365a24ad5 CV expanded 2026-07-27 17:08:20 +02:00
Dejvino
53f1cd59c5 CV tuning and interests cleanup 2026-07-27 16:56:38 +02:00
Dejvino
d79f454b8d CV tuning 2026-07-27 16:30:14 +02:00
Dejvino
4e41649002 refactor: update CV styling, implement print-specific pill link visibility 2026-07-27 14:17:07 +02:00
Dejvino
5ea3bf21b2 refactor: update CV styling and documentation to include a detailed professional profile 2026-07-27 14:00:59 +02:00
Dejvino
f2ca5e5171 CV cleanup 2026-05-26 06:47:06 +02:00
Dejvino
0a3d373cc7 style: condensed skills 2026-05-26 06:22:42 +02:00
Dejvino
6478dc37df Print CV button 2026-05-25 22:48:17 +02:00
Dejvino
2f8de3cd7d Denser CV skills 2026-05-24 22:54:59 +02:00
Dejvino
595b9ca233 CV design tuning 2026-05-24 22:50:56 +02:00
Dejvino
64efd8ebce interests in CV mode 2026-05-24 18:38:15 +02:00
Dejvino
3c0cc155dc interests showcase in files 2026-05-24 18:30:49 +02:00
Dejvino
b574e2531c style: drop notable creations and redesign interests as wide tag cloud
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 20:42:55 +02:00
Dejvino
9af492998f style: vertically center content on body
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 19:36:01 +02:00
Dejvino
af23da9b5f style: adjust grayscale and brightness filter values 2026-05-23 19:35:18 +02:00
Dejvino
fcefd3c957 refactor: standardize pill rendering and replace SVG icons with emojis
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 19:13:14 +02:00
Dejvino
a89cd9c09f feat: conditionally render sections based on CV path 2026-05-23 19:11:59 +02:00
Dejvino
0c8bcabaef style: center-align navigation and contact pills
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 18:21:55 +02:00
Dejvino
9c75405d11 feat: add notable creations section and restructure data.json
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 18:07:15 +02:00
Dejvino
65cdf845bb style: adjust avatar color shift animation values 2026-05-23 18:05:46 +02:00
Dejvino
bb2cfd342e fix: smooth avatar color shift animation with consistent filter chain
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 16:43:46 +02:00
Dejvino
e45b6625e3 style: update avatar color shift to cyan, light blue, and white
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 15:57:05 +02:00
Dejvino
c751b91bbb fix: restore avatar color shift animation and handle cv mode
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 09:25:50 +02:00
Dejvino
9628205375 style: add monochromatic color-shifting animation to avatar
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 09:10:54 +02:00
Dejvino
b7707bb8ed fix: drop preload concept and fix CV section visibility
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 09:00:19 +02:00
Dejvino
7c009ee851 refactor: render CV only on /cv path and remove toggle
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-23 08:45:37 +02:00
Dejvino
597b673958 feat: add htaccess rule to route /cv to index.php
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-22 21:46:14 +02:00
Dejvino
9abb6efd73 feat: replace hash-based CV toggle with path-based routing
Co-authored-by: aider (openai/qwen3.6) <aider@aider.chat>
2026-05-22 18:39:52 +02:00
Dejvino
dc42199ba4 date for highlights 2026-05-22 17:43:36 +02:00
Dejvino
7f61ca4965 CV update 2026-05-21 22:52:57 +02:00
Dejvino
b079cc1b57 fix missing company name 2026-05-21 18:47:07 +02:00
Dejvino
81cd3ba093 printing cutoff fix 2026-05-21 18:25:36 +02:00
Dejvino
bd849d6e34 fixed Modified location 2026-05-21 18:19:09 +02:00
Dejvino
6ffb41b23e interests style in printing 2026-05-21 15:25:25 +02:00
Dejvino
e81fb842d0 CV cleanup step 2026-05-21 15:21:32 +02:00
Dejvino
44d08f8583 Resume text tweak 2026-05-21 15:11:07 +02:00
Dejvino
2181e912d2 interests 2026-05-21 14:50:16 +02:00
Dejvino
bd2faca3de Drop summary 2026-05-21 12:54:21 +02:00
Dejvino
0d97902b40 link pills 2026-05-21 12:46:30 +02:00
Dejvino
86b5743f7a Re-layouting 2026-05-20 21:12:34 +02:00
Dejvino
c204fc0ab8 Print elemenets horizontally 2026-05-20 20:40:15 +02:00
Dejvino
35c5106521 Add comprehensive CSS enhancements: avatar styling, gradient removal, and print layout support 2026-05-20 17:17:34 +02:00
Dejvino
c1df821c5f refactor(ui): remove skills section from index page
Remove the skills section and its associated rendering logic from the
main index template to clean up the layout.
2026-05-20 09:42:31 +02:00
Dejvino
ec4780b20b feat(ui): add experience duration calculation
Add a helper function to calculate the number of years for each
experience entry based on the date range. Display the calculated
duration next to the date in the experience section.
2026-05-20 09:38:43 +02:00
Dejvino
319c01c59c reformat 2026-05-20 09:29:08 +02:00
Dejvino
e7cb2ec37a last and past experiences split 2026-05-20 09:28:01 +02:00
Dejvino
6d776b74c0 CV data in JSON 2026-05-20 09:18:46 +02:00
Dejvino
697afe6667 docs: Add Cloudflare Web Analytics script 2026-05-20 00:18:24 +02:00
Dejvino
ff65b74864 Socials 2026-05-19 20:26:17 +02:00
Dejvino
26fa67a233 Tweak modified date 2026-05-19 19:13:04 +02:00
Dejvino
ebc81f5d8e Tuneup 2026-05-19 07:57:14 +02:00
Dejvino
adee14fabc CV as a scroll-out 2026-05-19 07:33:17 +02:00
Dejvino
229b5dee94 Tune up transitions 2026-05-18 22:51:34 +02:00
Dejvino
0365b26e67 CV foldout 2026-05-18 22:37:19 +02:00
Dejvino
d3abf042ad Gradual transitions 2026-05-18 21:42:25 +02:00
Dejvino
0ad194041c Improved style and added base CV 2026-05-18 20:52:34 +02:00
Dejvino
29581ad66e More cyberpunk 2026-05-18 20:10:31 +02:00
5 changed files with 2115 additions and 124 deletions

View File

@ -30,3 +30,8 @@ RewriteRule ^domains/[^/]+/(.+[^/])$ /$1/ [R]
# subdomeny - spravne presmerovani pri chybejicim /
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^subdom/[^/]+/(.+[^/])$ /$1/ [R]
# Route /cv to index.php for CV view
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^cv/?$ index.php [L,QSA]

185
data.json Normal file
View File

@ -0,0 +1,185 @@
{
"name": "David Hrdina Němeček",
"photo": "photo.png",
"headline": "Principal Software Engineer at Oracle NetSuite",
"summary": "UI platform architect specializing in AI-assisted engineering enablement, telemetry and performance.",
"email": "explosive@dejvino.cz",
"location": "Brno, Czechia",
"phone": "+420 775 26 26 32",
"contact_links": {
"Website": "https://www.dejvino.cz",
"Email": "mailto:explosive@dejvino.cz",
"Resume": "https://dejvino.cz/cv"
},
"about": [
"Principal Software Engineer at Oracle NetSuite, focusing on AI-assisted developer enablement, UI platform architecture, performance, and observability for 40k+ enterprise customers."
],
"highlights": [
{
"title": "AI-first Design System Guidance Tooling",
"description": [
"Researched and prototyped an AI-first UI Toolkit guidance system leveraging Model Context Protocol (MCP). The tool covered over 260 component guideline documents, code samples and development best practices. It was authored in collaboration with 3 frontrunner UX designers, scaling their expertise across multiple teams.",
"Created an automated code review bot leveraging this knowledge corpus, successfully trialed across 4 platform and app delivery teams to validate UI changes early in development."
],
"date": "2025 2026"
},
{
"title": "Telemetry Stack Architecture",
"description": [
"Shaped product telemetry architecture spanning frontend UI, backend integration, and AI interaction streams. Championed migration from legacy telemetry solutions to OpenTelemetry. Integrated Oracle APM for enterprise-grade performance monitoring.",
"Designed action-root hybrid sampling strategy to achieve a 92% telemetry volume reduction while preserving critical user-behavior signals.",
"Delivered in-app trace visualizer, driving up telemetry adoption among teams."
],
"date": "2024 2026"
},
{
"title": "UI Performance & Bootstrap Optimization",
"description": [
"Analyzed UI app bootstrap performance, driving improvements that gained 28% speed improvement.",
"Eliminated redundant network requests by introducing TanStack Query network caching. Defined tiered JavaScript dependency loading mechanism for on-demand toolkit loading."
],
"date": "2025 2026"
},
{
"title": "Consumer-driven Contract Testing",
"description": [
"Prototyped UI <=> backend API contract testing using Pact to prevent cross-system breaking changes early in the development lifecycle.",
"Defined consumer test suites, contract generation, and provider verification workflows between frontend UI applications and backend services."
],
"date": "2025 2026"
},
{
"title": "UI Testing Strategy & Architecture",
"description": [
"Led senior QA engineers in defining and executing the long-term UI testing architecture strategy across platform teams.",
"Established automated test suites and quality guardrails to elevate testing standards."
],
"date": "2021 2023"
},
{
"title": "Pluggable Tax Calculation Engine",
"description": [
"Architected and led the development of a pluggable tax calculation engine for NetSuite cloud ERP.",
"Coordinated technical strategy across 20+ software engineers in 4 squads, standardizing global tax calculation pipelines."
],
"date": "2017 2020"
}
],
"cv": {
"experience": [
{
"title": "Principal Software Engineer (UI Platform Architecture)",
"company": "Oracle|NetSuite",
"date": "2023 present",
"description": "Driving technical vision and solution architecture for the NetSuite UI Platform (NetSuite Next). Leading initiatives in AI-assisted developer enablement, telemetry architecture, performance optimization."
},
{
"title": "Senior Software Development Manager (UI Platform)",
"company": "Oracle|NetSuite",
"date": "2022 2023",
"description": "Engineering lead for multiple UI Platform teams building core framework components and developer tooling."
},
{
"title": "Software Development Manager (UI Platform)",
"company": "Oracle|NetSuite",
"date": "2020 2022",
"description": "Engineering lead for a UI Platform team building shared UI components. Acted as technical product owner while bootstrapping the team and establishing component delivery standards."
},
{
"title": "Software Development Manager (ERP, Tax)",
"company": "Oracle|NetSuite",
"date": "2017 2020",
"description": "Engineering lead for ERP Tax domain. Designed and delivered a pluggable tax calculation engine, coordinating technical direction for 20+ engineers across 4 squads."
},
{
"title": "Senior Software Engineer (ERP, Tax)",
"company": "Oracle|NetSuite",
"date": "2013 2017",
"description": "Development of cloud ERP tax calculation and reporting modules. Led large-scale refactoring of legacy codebases and improved calculation reliability for enterprise clients."
},
{
"title": "Software Engineer",
"company": "Q2 Interactive",
"date": "2009 2013",
"description": "Development of e-commerce, ERP, and CRM web applications and custom services."
}
],
"skills": {
"Architecture & Domains": [
"UI Platform Architecture",
"AI-Assisted Engineering",
"Developer Enablement & Tooling",
"Telemetry & Observability",
"Performance Optimization",
"Consumer-Driven Contract Testing"
],
"Languages & Core Ecosystems": [
"TypeScript",
"JavaScript",
"Node.js",
"Java",
"Python",
"OpenTelemetry",
"Model Context Protocol (MCP)"
],
"Spoken Languages": [
"Czech (native)",
"English (proficient)",
"German (elementary)"
],
"Certifications": [
"OCI 2025 Certified Observability Professional",
"OCI 2025 Certified AI Foundations Associate"
]
},
"education": [
{
"degree": "Master's degree",
"field": "Parallel and Distributed Systems",
"institution": "Faculty of Informatics, Masaryk University Brno",
"date": "2011 2013",
"thesis": "Efficient computation and visualization of correlations in medical signals. High-performance computation of correlations on large volumes of analog data in C++ using supercomputers. Visualization of the computed results through interactive exploration and processing of the data by a researcher in Python."
},
{
"degree": "Bachelor's degree",
"field": "Parallel and Distributed Systems",
"institution": "Faculty of Informatics, Masaryk University Brno",
"date": "2008 2011",
"thesis": "Parallel implementation of force-field decompression algorithm. Executed on a supercomputer cluster to perform real-time simulation of molecular forces, providing haptic feedback to a 3D pointing device."
}
],
"philosophy": "I design platform layers that stay out of the way while enabling everything else.</br>Quiet infrastructure. Measurable value."
},
"interests": [
{
"name": "Mandolin",
"caption": "Octave mandolin is my instrument of choice. Wide range of tones, pleasant sound. Great way to relax your mind, explore melodies and harmonies.",
"image": null
},
{
"name": "Electronics tinkering",
"caption": "Building a useful device from scratch. Retrofitting modern brains into a broken vintage shell. Electronics is the magic that makes things alive.",
"image": null
},
{
"name": "Synthwave",
"caption": "Neon-filled nostalgia. Fun to create, relaxing to listen to it.",
"image": "interests/synthwave.png"
},
{
"name": "3D Printing & Design",
"caption": "Designing and printing custom parts that serve a purpose. Unique designs, useful accessories, toys or just repairs.",
"image": null
},
{
"name": "Mountain Biking",
"caption": "Going places under your own power. Exploring forests, trails and nature where cars aren't allowed.",
"image": null
},
{
"name": "RC Cars",
"caption": "Rock crawlers, construction trucks, military vehicles. Building a custom offroad course in the garden to trial them all.",
"image": null
}
]
}

409
index.php
View File

@ -1,38 +1,158 @@
<?php
/**
* Content config:
*/
$name = "David Hrdina Němeček";
$site_title = "www.dejvino.cz";
$site_url = "https://www.dejvino.cz/";
$site_desc = "$name - Software Developer";
$subtitle = "Software Developer, Architect, Problem Solver";
$photo_file = "photo.png";
$email_user = "ciao";
$cvData = json_decode(file_get_contents(__DIR__ . '/data.json'), true);
$about_text = [
"Full-stack developer focused on pragmatic architecture, observability and performance.",
//""
$isCvPath = strpos($_SERVER['REQUEST_URI'], '/cv') !== false;
$name = $cvData['name'] ?? '';
$headline = $cvData['headline'] ?? '';
$summary = $cvData['summary'] ?? '';
$location = $cvData['location'] ?? '';
$photo_file = $cvData['photo'] ?? '';
$nav_links = [
'Blog' => 'https://wp.dejvino.com/',
'Projects' => 'https://projects.dejvino.com/',
'Code' => 'https://git.dejvino.cz/',
];
$highlights = $cvData['highlights'] ?? [];
/**
* Sourced Interests Showcase (from data.json)
*/
$interests_showcase = [];
if (!empty($cvData['interests'])) {
foreach ($cvData['interests'] as $item) {
$img = $item['image'] ?? null;
$has_image = $img && file_exists(__DIR__ . '/' . $img);
$interests_showcase[] = [
'name' => $item['name'] ?? '',
'image' => $has_image ? $img : null,
'caption' => $item['caption'] ?? ''
];
}
}
$site_url = "https://www.dejvino.cz/";
$site_title = $name;
$site_desc = "$name - $headline";
$mailto_link = $cvData['contact_links']['Email'] ?? '';
if (preg_match('/mailto:([^@]+)/', $mailto_link, $m)) {
$email_user = $m[1];
} else {
$email_user = $cvData['email'] ?? '';
}
$extra_contact_links = $cvData['contact_links'] ?? [];
/**
* Emoji icons for link pills
*/
$pill_icons = [
'Website' => '🌐',
'Email' => '✉️',
'Resume' => '📄',
'CV' => '📄',
'PDF' => '📑',
'Blog' => '✍️',
'Projects' => '📁',
'Code' => '💻',
'GitLab' => '🔶',
'GitHub' => '🐙',
];
$nav_links = [
"~/blog" => "https://wp.dejvino.com/",
"~/projects" => "https://projects.dejvino.com/",
"~/code" => "https://git.dejvino.cz/",
];
/**
* Extract a readable URL from a href (strip protocol, trailing slash)
*/
function pillUrl(string $href): string {
$url = $href;
if (preg_match('/^[a-z]+:\/\//i', $url)) {
$url = preg_replace('/^[a-z]+:\/\//i', '', $url);
}
$url = rtrim($url, '/');
return strlen($url) > 30 ? mb_substr($url, 0, 27) . '…' : $url;
}
$hardware_info = "Playing the mandolin, mountain biking, 3D printing and tinkering.";
/**
* Render a standardized pill link
*/
function render_pill(string $href, string $label, string $icon_emoji, string $class_suffix = ''): string {
$url_display = pillUrl($href);
$classes = $class_suffix ? "pill {$class_suffix}" : 'pill';
return sprintf(
'<a href="%s" target="_blank" class="%s">' .
'<span class="pill-icon">%s</span>' .
'<span class="pill-label">%s</span>' .
'<span class="pill-url">%s</span>' .
'</a>',
htmlspecialchars($href, ENT_QUOTES, 'UTF-8'),
$classes,
$icon_emoji,
htmlspecialchars($label, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($url_display, ENT_QUOTES, 'UTF-8')
);
}
/**
* CV Data
*/
// Map experience to expected structure
$cv_experience = array_map(function ($e) {
return [
'title' => $e['title'] ?? '',
'org' => $e['company'] ?? '',
'date' => $e['date'] ?? '',
'desc' => $e['description'] ?? '',
];
}, $cvData['cv']['experience'] ?? []);
// Helper to calculate years between start and end dates
function calculateYears($dateStr) {
// Extract start and end years, support 'present' or 'current'
$dateStr = str_replace(['', '—', '', '-'], '-', $dateStr);
$parts = array_map('trim', explode('-', $dateStr, 2));
if (count($parts) < 2) {
return 0;
}
$start = (int)$parts[0];
$endRaw = strtolower($parts[1]);
$end = ($endRaw === 'present' || $endRaw === 'current') ? (int)date('Y') : (int)$endRaw;
$years = $end - $start;
if ($years <= 1) {
return "1 year";
}
return "$years years";
}
// Map education to expected structure
$cv_education = array_map(function ($e) {
return [
'title' => $e['degree'] ?? '',
'org' => $e['institution'] ?? '',
'date' => $e['date'] ?? '',
'desc' => $e['thesis'] ?? '',
];
}, $cvData['cv']['education'] ?? []);
// Keep skills categories as provided
$cv_skills = $cvData['cv']['skills'] ?? [];
/**
* Page design:
* - clean and simple, human-maintaninable
* - clean and simple, human-maintainable
* - no dependencies
* - single-file website
*/
?>
<!DOCTYPE html>
<html lang="en">
<head>
<head>
<meta charset="utf-8">
<title><?= $site_title ?></title>
<link rel="canonical" href="<?= $site_url ?>">
@ -44,68 +164,239 @@ $hardware_info = "Playing the mandolin, mountain biking, 3D printing and tinker
<meta property="og:type" content="website">
<meta property="og:url" content="<?= $site_url ?>">
<meta property="og:title" content="<?= $name ?>">
<meta property="og:description" content="<?= $subtitle ?>">
<meta property="og:description" content="<?= $headline ?>">
<style>
<?php
<?php
include 'style.css';
?>
?>
</style>
<link rel="shortcut icon" href="favicon.ico">
</head>
<body>
</head>
<body class="<?= $isCvPath ? 'cv-mode' : '' ?>">
<main class="bento-grid">
<section class="card profile">
<?php
<section class="card hero">
<div class="hero-row hero-identity">
<?php
if (file_exists($photo_file)) {
$avatarBase64 = base64_encode(file_get_contents($photo_file));
echo '<img src="data:image/png;base64,' . $avatarBase64 . '" alt="' . $name . '" class="avatar" width="120" height="160" />';
echo '<img src="data:image/png;base64,' . $avatarBase64 . '" alt="' . $name . '" class="avatar" width="80" height="106" />';
} else {
echo '<div class="avatar-placeholder"></div>';
}
?>
<div class="header-text">
<h1><?= $name ?></h1>
<p class="subtitle"><?= $subtitle ?></p>
?>
<div class="hero-name">
<h1><?= $name ?></h1>
<?php if ($headline): ?>
<p class="headline"><?= $headline ?></p>
<?php endif; ?>
<?php if ($location): ?>
<p class="location"><?= $location ?></p>
<?php endif; ?>
</div>
</div>
<button class="print-button" onclick="window.print()">
🖨️ Print CV
</button>
<?php if ($summary): ?>
<div class="hero-row hero-description">
<p><?= $summary ?></p>
</div>
<?php endif; ?>
<div class="hero-row hero-contacts">
<?php foreach ($extra_contact_links as $label => $href): ?>
<?= render_pill($href, $label, $pill_icons[$label] ?? '🔗', 'contact-pill' . ($label === 'CV' || $label === 'Resume' ? ' pill-cv-only-print' : '')) ?>
<?php endforeach; ?>
</div>
<div class="hero-row hero-nav">
<?php foreach ($nav_links as $label => $href): ?>
<?= render_pill(trim($href), $label, $pill_icons[$label] ?? '🔗', 'nav-pill') ?>
<?php endforeach; ?>
</div>
</section>
<section class="card about">
<h2>Bio</h2>
<?php foreach ($about_text as $para): ?>
<p><?= $para ?></p>
<?php endforeach; ?>
</section>
<section class="card links">
<h2>Navigation</h2>
<ul class="link-grid">
<?php foreach ($nav_links as $label => $url): ?>
<li><a href="<?= $url ?>"><span><?= $label ?></span></a></li>
<?php if (!$isCvPath && $interests_showcase): ?>
<?php // Hardcoded palette of dark, varied tints
$bg_palette = [
'#1e2a33', // Dark Blue
'#1e332a', // Dark Green
'#2a1e33', // Dark Purple
'#331e2a', // Dark Red
'#1a3333', // Dark Teal
'#33331a', // Dark Olive
];
$palette_size = count($bg_palette);
?>
<section class="card interests-showcase">
<nav class="interests-nav">
<h2>Things I like to do</h2>
<ul>
<?php foreach ($interests_showcase as $i => $item): ?>
<li class="<?= $i === 0 ? 'active' : '' ?>" data-index="<?= $i ?>">
<?= htmlspecialchars($item['name']) ?>
</li>
<?php endforeach; ?>
</ul>
</nav>
<div class="interests-display">
<?php foreach ($interests_showcase as $i => $item): ?>
<div class="interest-slide <?= $i === 0 ? 'active' : '' ?>" data-index="<?= $i ?>" style="background-color: <?= $bg_palette[$i % $palette_size] ?>;">
<?php if ($item['image']): ?>
<img src="<?= htmlspecialchars($item['image']) ?>" alt="<?= htmlspecialchars($item['name']) ?>">
<?php endif; ?>
<p class="caption"><?= htmlspecialchars($item['caption']) ?></p>
</div>
<?php endforeach; ?>
</ul>
</div>
</section>
<?php endif; ?>
<section class="card interests">
<h2>Likes</h2>
<p><?= $hardware_info ?></p>
</section>
<?php if ($isCvPath): ?>
<?php if ($highlights): ?>
<section class="card selected-work">
<h2>Selected Work</h2>
<?php foreach ($highlights as $h): ?>
<article class="highlight-item">
<h3><?= $h['title'] ?? '' ?><?php if ($h['date'] ?? ''): ?> <time class="highlight-date"><?= $h['date'] ?></time><?php endif; ?></h3>
<?php if ($h['description']): ?>
<div class="highlight-descriptions">
<?php if (is_array($h['description'])): ?>
<?php foreach ($h['description'] as $desc): ?>
<p class="highlight-description"><?= $desc ?></p>
<?php endforeach; ?>
<?php else: ?>
<p class="highlight-description"><?= $h['description'] ?></p>
<?php endif; ?>
</div>
<?php endif; ?>
</article>
<?php endforeach; ?>
<?php if ($cvData['cv']['philosophy'] ?? ''): ?>
<blockquote class="philosophy"><?= $cvData['cv']['philosophy'] ?></blockquote>
<?php endif; ?>
</section>
<?php endif; ?>
<section class="card contact">
<h2>Remote_Access</h2>
<p class="mono-addr">
Contact email: <span id="contact-mail">uncovering...</span>
</p>
</section>
<section class="card skills">
<h2>Skills</h2>
<div class="skill-categories">
<?php foreach ($cv_skills as $category => $skills): ?>
<div class="skill-group">
<h3><?= $category ?></h3>
<div class="skill-tags">
<?php foreach ($skills as $skill): ?>
<span class="tag"><?= $skill ?></span>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</section>
<?php
$firstJob = $cv_experience[0] ?? null;
if ($firstJob):
?>
<section class="card first-experience">
<h2>Latest Experience</h2>
<article class="cv-item">
<header class="cv-item-header">
<h3 class="cv-title"><?= $firstJob['title'] ?></h3>
<span class="cv-date"><?= $firstJob['date'] ?> (<?= calculateYears($firstJob['date']) ?>)</span>
</header>
<p class="cv-org"><?= $firstJob['org'] ?></p>
<p class="cv-desc"><?= $firstJob['desc'] ?></p>
</article>
</section>
<?php endif; ?>
<section class="card experience">
<h2>Past Experience</h2>
<?php foreach (array_slice($cv_experience, 1) as $job): ?>
<article class="cv-item">
<header class="cv-item-header">
<h3 class="cv-title"><?= $job['title'] ?></h3>
<span class="cv-date"><?= $job['date'] ?> (<?= calculateYears($job['date']) ?>)</span>
</header>
<p class="cv-org"><?= $job['org'] ?></p>
<p class="cv-desc"><?= $job['desc'] ?></p>
</article>
<?php endforeach; ?>
</section>
<section class="card education">
<h2>Education</h2>
<?php foreach ($cv_education as $edu): ?>
<article class="cv-item">
<header class="cv-item-header">
<h3 class="cv-title"><?= $edu['title'] ?></h3>
<time class="cv-date"><?= $edu['date'] ?></time>
</header>
<p class="cv-org"><?= $edu['org'] ?></p>
<?php if ($edu['desc']): ?>
<p class="cv-desc"><?= $edu['desc'] ?></p>
<?php endif; ?>
</article>
<?php endforeach; ?>
</section>
<?php if ($interests_showcase): ?>
<section class="card personal">
<h2>Interests</h2>
<div class="personal-tags">
<?php foreach ($interests_showcase as $item): ?>
<span class="personal-tag"><?= htmlspecialchars($item['name']) ?></span>
<?php endforeach; ?>
</div>
</section>
<?php endif; ?>
<?php endif; ?>
</main>
<script>
((u, d, t) => {
const addr = u + '@' + d + '.' + t;
const el = document.getElementById("contact-mail");
el.innerHTML = `<a href="mailto:${addr}">${addr}</a>`;
})('<?= $email_user ?>', 'dejvino', 'cz');
((u, d, t) => {
const addr = (atob(u) + '@' + d + '.' + t).trim();
const el = document.getElementById("contact-mail");
if (el) el.innerHTML = `<a href="mailto:${addr}">${addr}</a>`;
})('<?= base64_encode($email_user) ?>', 'dejvino', 'cz');
// Interests Showcase Logic
(() => {
const slides = document.querySelectorAll('.interest-slide');
const labels = document.querySelectorAll('.interests-nav li');
if (!slides.length) return;
let currentIndex = 0;
let interval = setInterval(next, 5000);
function show(index) {
slides.forEach(s => s.classList.remove('active'));
labels.forEach(l => l.classList.remove('active'));
slides[index].classList.add('active');
labels[index].classList.add('active');
currentIndex = index;
}
function next() { show((currentIndex + 1) % slides.length); }
labels.forEach((label, i) => {
label.addEventListener('click', () => {
show(i);
clearInterval(interval);
interval = setInterval(next, 8000); // Slower auto-switch after manual interaction
});
});
})();
</script>
</body>
<!-- Cloudflare Web Analytics -->
<script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "90827cb740cd4b1db611be059f64daa9"}'></script><!-- End Cloudflare Web Analytics -->
<?php $file_mod_time = filemtime(__FILE__); ?>
<p class="page-footer">Modified: <?= date("Y-m-d", $file_mod_time) ?></p>
</body>
</html>

BIN
interests/synthwave.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

1636
style.css

File diff suppressed because it is too large Load Diff