Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,33 @@ migrates `[Unreleased]` into that file and empties this one — see
diagonal stripes and the subtitle retypes like the titles. Still under
`prefers-reduced-motion`.

- **A journey page, `/experience`**
([#78](https://github.com/kbrdn1/kbrdn.dev/issues/78)). Laid out like an
editorial spread (after isrod.eu): an intro, a strip of every role and
degree, then one spread each, the story on the left and the stack and
missions on the right, with "show more". Then the open source work, every
item linked to its pull request or issue: the projects I maintain (gwm,
vellum, LazyCurl, herdr-plugin-gwm, claude-crosstalk, kbrdn-docs), the
contributions (winget, aqua-registry and awesome-ratatui merged, nixpkgs in
review) and the bugs reported upstream. On the home page, the Parcours
accordions give way to a one-line-per-role teaser linking to it.

- **An apps page, `/apps`**
([#79](https://github.com/kbrdn1/kbrdn.dev/issues/79)). gwm (available),
vellum (in development) and LazyCurl (archived), each with its features and
licence, links to its site, repository and releases, and for gwm the install
commands of its README. The latest release is read from GitHub instead of
written down.

### Changed

- **The navigation leads to pages**
([#80](https://github.com/kbrdn1/kbrdn.dev/issues/80)). Journey, Apps and
Blog, on every page and on mobile, instead of the home page's anchors; one
list shared by the header, the blog header and the footer, with the current
page marked. On wide screens (1700px and up), the home page gets a table of
contents in the margin, like an article's, following the section being read.

- **A new logo**
([#74](https://github.com/kbrdn1/kbrdn.dev/issues/74)). A K drawn from a
rising bar and two orange pieces, redrawn as SVG on a 45° grid, replaces the
Expand Down
13 changes: 0 additions & 13 deletions app/assets/css/components.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,6 @@
background-color: var(--color-primary-500);
}

/* Accordion +/- icon animation */
.accordion-icon-bar {
transition: transform 300ms ease !important;
}

.accordion-icon-bar.is-collapsed {
transform: rotate(90deg);
}

.accordion-icon-bar.is-expanded {
transform: rotate(0deg);
}

/* Disabled button with subtle diagonal striped background */
.btn-disabled-striped {
background-image: repeating-linear-gradient(
Expand Down
19 changes: 0 additions & 19 deletions app/assets/css/transitions.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,6 @@
Animations & Transitions
═══════════════════════════════════════════════════ */

/* Accordion animation */
.accordion-wrapper {
display: grid;
grid-template-rows: 0fr;
opacity: 0;
transition:
grid-template-rows 400ms cubic-bezier(0.4, 0, 0.2, 1),
opacity 300ms ease !important;
}

.accordion-wrapper.is-open {
grid-template-rows: 1fr;
opacity: 1;
}

.accordion-wrapper > .accordion-inner {
overflow: hidden;
}

/* Nav entrance animation */
@keyframes nav-fade-in {
from {
Expand Down
99 changes: 99 additions & 0 deletions app/components/experience/Spread.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<script setup lang="ts">
// One role or degree on /experience, laid out like an editorial spread (after
// isrod.eu/fr/experience): the story on the left, a rail on the right with the stack and
// the first missions; "Show more" unfolds the rest.
import { useI18n } from '#imports'

const props = withDefaults(
defineProps<{
id: string
index: number
title: string
meta: string
summary: string
logo?: string
stack: string[]
itemsLabel: string
items: string[]
/** Missions shown before "Show more". */
preview?: number
}>(),
{ logo: undefined, preview: 2 },
)

const { t } = useI18n()
const open = ref(false)
const hasMore = computed(() => props.items.length > props.preview)
const shown = computed(() => (open.value ? props.items : props.items.slice(0, props.preview)))
</script>

<template>
<article
:id="id"
class="grid scroll-mt-24 gap-8 border-t border-neutral-200 py-10 md:grid-cols-12 dark:border-neutral-800"
>
<header class="md:col-span-7">
<span class="block font-mono text-[11px] tracking-widest text-neutral-500">
{{ String(index).padStart(2, '0') }}
</span>
<div class="mt-2 flex items-center gap-3">
<NuxtImg
v-if="logo"
:src="logo"
alt=""
width="36"
height="36"
class="size-9 shrink-0 object-contain"
/>
<h3 class="text-2xl font-semibold text-neutral-900 sm:text-3xl dark:text-neutral-100">
<UiScrambleText :text="title" />
</h3>
</div>
<p class="mt-3 font-mono text-xs uppercase tracking-wider text-primary-500">{{ meta }}</p>
<p class="mt-5 max-w-xl text-sm leading-relaxed text-neutral-600 dark:text-neutral-400">
{{ summary }}
</p>
<button
v-if="hasMore"
type="button"
:aria-expanded="open"
:aria-controls="`${id}-items`"
class="relative isolate mt-6 inline-flex items-center gap-2 overflow-hidden border border-neutral-300 px-3 py-1.5 font-mono text-xs uppercase tracking-wider text-neutral-700 transition-colors hover:border-primary-500/60 hover:text-primary-500 dark:border-neutral-700 dark:text-neutral-300"
@click="open = !open"
>
<UiPixelCanvas />
{{ open ? t('experiencePage.less') : t('experiencePage.more') }}
<span aria-hidden="true">{{ open ? '−' : '+' }}</span>
</button>
</header>

<aside
class="space-y-6 border-neutral-200 md:col-span-5 md:border-l md:pl-8 dark:border-neutral-800"
>
<div>
<h4 class="font-mono text-[11px] uppercase tracking-widest text-neutral-500">
{{ t('experiencePage.stack') }}
</h4>
<p
class="mt-2 font-mono text-xs uppercase leading-relaxed tracking-wider text-neutral-700 dark:text-neutral-300"
>
{{ stack.join(' · ') }}
</p>
</div>
<div>
<h4 class="font-mono text-[11px] uppercase tracking-widest text-neutral-500">
{{ itemsLabel }}
</h4>
<ul
:id="`${id}-items`"
class="mt-2 space-y-2 text-sm leading-relaxed text-neutral-600 dark:text-neutral-400"
>
<li v-for="item in shown" :key="item" class="flex gap-2">
<span class="mt-2 size-1.5 shrink-0 bg-primary-500" aria-hidden="true" />
<span>{{ item }}</span>
</li>
</ul>
</div>
</aside>
</article>
</template>
Loading
Loading