feat: surface availability and operations evidence

This commit is contained in:
2026-09-04 20:34:19 +03:00
parent 3509f5fbdf
commit 55158d490e
13 changed files with 147 additions and 22 deletions

View File

@@ -224,7 +224,7 @@ onUnmounted(() => removePageListeners());
</header>
<main id="portfolio-content" class="portfolio-main" tabindex="-1">
<HeroJourney :identity="content.identity" @explore="navigation.onSectionLinkClick" />
<HeroJourney :identity="content.identity" :email="content.contact.email" @explore="navigation.onSectionLinkClick" />
<PortfolioSection id="profile" :layout="sectionLayouts.profile" :heading="sectionLabel('profile')">
<p>{{ content.profile.introduction }}</p>

View File

@@ -9,14 +9,14 @@ defineProps<{
<template>
<div class="contact-destination">
<p class="contact-destination__copy">Thanks for making the trip. The road's open if you'd like to build something together.</p>
<a class="contact-link" :href="`mailto:${contact.email}`">Start a conversation</a>
<p class="contact-destination__copy">{{ contact.introduction }}</p>
<a class="contact-link" :href="`mailto:${contact.email}`">Email Luca</a>
<p class="contact-destination__email">{{ contact.email }}</p>
<p class="contact-destination__cv">{{ contact.cvMessage }}</p>
</div>
<ul class="contact-social">
<li v-for="link in contact.social" :key="link.service">
<a class="contact-social-link" :href="link.url" target="_blank" rel="noopener noreferrer">
<a class="contact-social-link" :href="link.url" target="_blank" rel="me noopener noreferrer">
<BrandIcon :label="link.service" />
<span>{{ link.service }}</span>
</a>

View File

@@ -3,6 +3,7 @@ import type { PortfolioContent } from '@/content/types';
defineProps<{
identity: Readonly<PortfolioContent['identity']>;
email: string;
}>();
const emit = defineEmits<{
@@ -16,7 +17,11 @@ const emit = defineEmits<{
<h1 id="start-heading" tabindex="-1">{{ identity.name }}</h1>
<p class="hero-journey__role">{{ identity.role }}</p>
<p class="hero-journey__value">{{ identity.valueProposition }}</p>
<a class="hero-journey__action" href="#selected-builds" @click="emit('explore', $event)">Explore work</a>
<p class="hero-journey__availability">{{ identity.availability }}</p>
<div class="hero-journey__actions">
<a class="hero-journey__action hero-journey__action--primary" :href="`mailto:${email}`">Email Luca</a>
<a class="hero-journey__action" href="#selected-builds" @click="emit('explore', $event)">Explore work</a>
</div>
</div>
<p class="print-portfolio-label" aria-hidden="true">Portfolio</p>
</section>

View File

@@ -1,4 +1,5 @@
<script setup lang="ts">
import OperationsProof from './OperationsProof.vue';
import type { InfrastructureCaseStudy } from "@/content/types";
defineProps<{ infrastructure: Readonly<InfrastructureCaseStudy> }>();
@@ -118,5 +119,6 @@ defineProps<{ infrastructure: Readonly<InfrastructureCaseStudy> }>();
>: {{ band.summary }}
</li>
</ul>
<OperationsProof id="nextcloud-migration" :operation="infrastructure.featuredOperation" />
</article>
</template>

View File

@@ -0,0 +1,16 @@
<script setup lang="ts">
import type { FeaturedOperation } from '@/content/types';
defineProps<{ id: string; operation: Readonly<FeaturedOperation> }>();
</script>
<template>
<section class="operations-proof" data-featured-operation :aria-labelledby="`${id}-heading`">
<h4 :id="`${id}-heading`">{{ operation.title }}</h4>
<p>{{ operation.context }}</p>
<ol>
<li v-for="action in operation.actions" :key="action">{{ action }}</li>
</ol>
<p class="operations-proof__outcome"><strong>Outcome:</strong> {{ operation.outcome }}</p>
</section>
</template>