link pills

This commit is contained in:
Dejvino 2026-05-21 12:46:30 +02:00
parent 86b5743f7a
commit 0d97902b40
2 changed files with 140 additions and 20 deletions

View File

@ -32,6 +32,34 @@ if (preg_match('/mailto:([^@]+)/', $mailto_link, $m)) {
$extra_contact_links = $cvData['contact_links'] ?? []; $extra_contact_links = $cvData['contact_links'] ?? [];
/**
* Icon SVGs for link pills
*/
$pill_icons = [
'Website' => '<svg class="pill-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>',
'Email' => '<svg class="pill-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>',
'GitLab' => '<svg class="pill-icon" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></svg>',
'GitHub' => '<svg class="pill-icon" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.166 6.839 9.489.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.604-3.369-1.34-3.369-1.34-.454-1.156-1.11-1.463-1.11-1.463-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.578 9.578 0 0 1 12 6.836a9.59 9.59 0 0 1 2.504.337c1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.578.688.48C19.138 20.163 22 16.418 22 12c0-5.523-4.477-10-10-10z"/></svg>',
'CV' => '<svg class="pill-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>',
'PDF' => '<svg class="pill-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><path d="M9 15v-2h2a1.5 1.5 0 0 1 0 3H9v-1c0-.55.45-1 1-1h1"/><line x1="9" y1="13" x2="11" y2="13"/></svg>',
'Blog' => '<svg class="pill-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>',
'Projects' => '<svg class="pill-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>',
'Code' => '<svg class="pill-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>',
];
/**
* 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;
}
/** /**
* CV Data * CV Data
*/ */
@ -140,14 +168,22 @@ $cv_skills = $cvData['skills'] ?? [];
<?php endif; ?> <?php endif; ?>
<div class="hero-row hero-contacts"> <div class="hero-row hero-contacts">
<?php foreach ($extra_contact_links as $label => $url): ?> <?php foreach ($extra_contact_links as $label => $href): ?>
<a href="<?= $url ?>" target="_blank"><?= $label ?></a> <a href="<?= $href ?>" target="_blank" class="pill contact-pill">
<?= $pill_icons[$label] ?? '' ?>
<span class="pill-label"><?= $label ?></span>
<span class="pill-url"><?= pillUrl($href) ?></span>
</a>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
<div class="hero-row hero-nav"> <div class="hero-row hero-nav">
<?php foreach ($nav_links as $label => $url): ?> <?php foreach ($nav_links as $label => $href): ?>
<a href="<?= trim($url) ?>" target="_blank"><?= $label ?></a> <a href="<?= trim($href) ?>" target="_blank" class="pill nav-pill">
<?= $pill_icons[$label] ?? '' ?>
<span class="pill-label"><?= $label ?></span>
<span class="pill-url"><?= pillUrl($href) ?></span>
</a>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
</section> </section>

116
style.css
View File

@ -203,35 +203,89 @@ body {
margin: 0; margin: 0;
line-height: 1.5; line-height: 1.5;
} }
/**
* Link pills shared base
*/
.pill {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px 6px 10px;
text-decoration: none;
font-size: 0.82rem;
line-height: 1.3;
border-radius: 6px;
border: 1px solid transparent;
transition: all 0.2s ease;
white-space: nowrap;
}
.pill-icon {
width: 16px;
height: 16px;
flex-shrink: 0;
}
.pill-label {
font-weight: 600;
}
.pill-url {
font-size: 0.72rem;
opacity: 0.5;
margin-left: 2px;
}
/**
* Contact pills gold accent
*/
.hero-contacts { .hero-contacts {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 12px; gap: 10px;
} }
.hero-contacts a {
.contact-pill {
color: var(--link-color); color: var(--link-color);
text-decoration: none; background: rgba(255, 215, 0, 0.06);
font-size: 0.9rem; border-color: rgba(255, 215, 0, 0.2);
} }
.hero-contacts a:hover {
text-decoration: underline; .contact-pill:hover {
background: rgba(255, 215, 0, 0.12);
border-color: rgba(255, 215, 0, 0.5);
box-shadow: 0 0 12px rgba(255, 215, 0, 0.15);
} }
.contact-pill .pill-url {
color: var(--link-color);
}
/**
* Nav pills cyan accent
*/
.hero-nav { .hero-nav {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 12px; gap: 10px;
padding-top: 8px; padding-top: 12px;
border-top: 1px solid rgba(0, 243, 255, 0.15); border-top: 1px solid rgba(0, 243, 255, 0.12);
} }
.hero-nav a {
.nav-pill {
color: var(--text-color); color: var(--text-color);
text-decoration: none; background: rgba(0, 243, 255, 0.04);
font-size: 0.85rem; border-color: rgba(0, 243, 255, 0.15);
opacity: 0.8;
} }
.hero-nav a:hover {
opacity: 1; .nav-pill:hover {
text-decoration: underline; background: rgba(0, 243, 255, 0.1);
border-color: rgba(0, 243, 255, 0.4);
box-shadow: 0 0 12px rgba(0, 243, 255, 0.15);
}
.nav-pill .pill-url {
color: var(--text-color);
} }
.hiring-toggle { .hiring-toggle {
@ -539,6 +593,9 @@ a { color: var(--link-color); text-decoration: none; }
.profile { flex-direction: column; text-align: center; } .profile { flex-direction: column; text-align: center; }
.hero { flex-direction: column; text-align: center; } .hero { flex-direction: column; text-align: center; }
.hero-identity { flex-direction: column; text-align: center; } .hero-identity { flex-direction: column; text-align: center; }
.hero-contacts, .hero-nav { justify-content: center; }
.pill { white-space: normal; gap: 4px 6px; padding: 5px 10px; }
.pill-url { display: inline; }
} }
/* Print mode */ /* Print mode */
@ -630,6 +687,33 @@ a { color: var(--link-color); text-decoration: none; }
} }
/* Removed duplicate flex layout for .contact .link-grid */ /* Removed duplicate flex layout for .contact .link-grid */
/* Pill links in print show label + URL clearly */
.hero-contacts, .hero-nav {
display: flex !important;
flex-wrap: wrap !important;
gap: 6px !important;
}
.pill {
display: inline-flex !important;
align-items: center !important;
gap: 4px !important;
padding: 3px 8px !important;
border: 1px solid #bbb !important;
border-radius: 3px !important;
background: #f7f7f7 !important;
color: #000 !important;
text-decoration: none !important;
font-size: 0.75rem !important;
}
.pill .pill-icon {
display: none !important;
}
.pill .pill-url {
opacity: 1 !important;
color: #333 !important;
font-size: 0.7rem !important;
}
/* CV Container hidden unless CV mode */ /* CV Container hidden unless CV mode */
/* Reset animations */ /* Reset animations */