feat: framed EARTH WALKER / DESIGN wordmark, themed via currentColor
Carries forward the original site's wordmark — heavier "EARTH WALKER"
paired with lighter "DESIGN", contained in a thin rectangular frame —
adapted to our type system (Fraunces semibold + light) rather than
re-importing the original slab serif. Because everything is rendered
in currentColor, the frame and both words invert automatically against
the dark hero overlay, the dark theme, and any of the four palettes.
Wordmark.vue takes a size prop ('sm' | 'md' | 'lg') driving type
scale, frame padding, and letter-spacing. Replaces the plain-text
brand in:
- SiteHeader logo slot (sm)
- Mobile Sheet drawer header (sm)
- SiteFooter brand block (sm)
- HomeView hero overlay above the headline (md)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c6ec34f5c3
commit
576b8559d7
4 changed files with 58 additions and 11 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RouterLink } from 'vue-router'
|
import { RouterLink } from 'vue-router'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import Wordmark from './Wordmark.vue'
|
||||||
|
|
||||||
const { t } = useI18n({ useScope: 'global' })
|
const { t } = useI18n({ useScope: 'global' })
|
||||||
const year = new Date().getFullYear()
|
const year = new Date().getFullYear()
|
||||||
|
|
@ -11,8 +12,8 @@ const year = new Date().getFullYear()
|
||||||
<div
|
<div
|
||||||
class="mx-auto flex max-w-[1400px] flex-col items-start justify-between gap-6 px-6 py-12 md:flex-row md:items-center md:px-10"
|
class="mx-auto flex max-w-[1400px] flex-col items-start justify-between gap-6 px-6 py-12 md:flex-row md:items-center md:px-10"
|
||||||
>
|
>
|
||||||
<div class="space-y-1">
|
<div class="space-y-3">
|
||||||
<p class="font-serif text-base tracking-[0.18em] uppercase">{{ t('brand') }}</p>
|
<Wordmark size="sm" class="text-foreground" />
|
||||||
<p class="text-muted-foreground text-xs">{{ t('footer.tagline') }}</p>
|
<p class="text-muted-foreground text-xs">{{ t('footer.tagline') }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-8">
|
<div class="flex items-center gap-8">
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import {
|
||||||
} from '@/components/ui/sheet'
|
} from '@/components/ui/sheet'
|
||||||
import ThemeToggle from './ThemeToggle.vue'
|
import ThemeToggle from './ThemeToggle.vue'
|
||||||
import LocaleSwitcher from './LocaleSwitcher.vue'
|
import LocaleSwitcher from './LocaleSwitcher.vue'
|
||||||
|
import Wordmark from './Wordmark.vue'
|
||||||
|
|
||||||
const { t } = useI18n({ useScope: 'global' })
|
const { t } = useI18n({ useScope: 'global' })
|
||||||
|
|
||||||
|
|
@ -32,9 +33,10 @@ const mobileOpen = ref(false)
|
||||||
>
|
>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
to="/"
|
to="/"
|
||||||
class="text-foreground font-serif text-lg tracking-[0.18em] uppercase"
|
class="text-foreground"
|
||||||
|
:aria-label="t('brand')"
|
||||||
>
|
>
|
||||||
{{ t('brand') }}
|
<Wordmark size="sm" />
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
||||||
<nav class="hidden items-center gap-8 md:flex">
|
<nav class="hidden items-center gap-8 md:flex">
|
||||||
|
|
@ -63,9 +65,8 @@ const mobileOpen = ref(false)
|
||||||
</SheetTrigger>
|
</SheetTrigger>
|
||||||
<SheetContent side="right" class="w-full sm:max-w-sm">
|
<SheetContent side="right" class="w-full sm:max-w-sm">
|
||||||
<SheetHeader>
|
<SheetHeader>
|
||||||
<SheetTitle class="font-serif tracking-[0.18em] uppercase">
|
<SheetTitle class="sr-only">{{ t('brand') }}</SheetTitle>
|
||||||
{{ t('brand') }}
|
<Wordmark size="sm" class="text-foreground" />
|
||||||
</SheetTitle>
|
|
||||||
</SheetHeader>
|
</SheetHeader>
|
||||||
<nav class="mt-10 flex flex-col gap-6 px-4">
|
<nav class="mt-10 flex flex-col gap-6 px-4">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
|
|
|
||||||
46
src/components/layout/Wordmark.vue
Normal file
46
src/components/layout/Wordmark.vue
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
type Size = 'sm' | 'md' | 'lg'
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
/** Visual size — controls type scale + frame padding. */
|
||||||
|
size?: Size
|
||||||
|
}>(),
|
||||||
|
{ size: 'md' },
|
||||||
|
)
|
||||||
|
|
||||||
|
const frameClasses: Record<Size, string> = {
|
||||||
|
sm: 'px-2.5 py-1.5 gap-2',
|
||||||
|
md: 'px-4 py-2.5 gap-3',
|
||||||
|
lg: 'px-6 py-3.5 gap-4',
|
||||||
|
}
|
||||||
|
|
||||||
|
const earthClasses: Record<Size, string> = {
|
||||||
|
sm: 'text-[0.7rem] tracking-[0.28em]',
|
||||||
|
md: 'text-sm tracking-[0.32em] md:text-base',
|
||||||
|
lg: 'text-base tracking-[0.34em] md:text-xl',
|
||||||
|
}
|
||||||
|
|
||||||
|
const designClasses: Record<Size, string> = {
|
||||||
|
sm: 'text-[0.55rem] tracking-[0.28em]',
|
||||||
|
md: 'text-[0.7rem] tracking-[0.32em] md:text-xs',
|
||||||
|
lg: 'text-xs tracking-[0.34em] md:text-sm',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span
|
||||||
|
:class="[
|
||||||
|
'inline-flex items-baseline border border-current uppercase',
|
||||||
|
frameClasses[props.size],
|
||||||
|
]"
|
||||||
|
aria-label="Earth Walker Design"
|
||||||
|
>
|
||||||
|
<span :class="['font-serif font-semibold', earthClasses[props.size]]">
|
||||||
|
Earth Walker
|
||||||
|
</span>
|
||||||
|
<span :class="['font-serif font-light opacity-90', designClasses[props.size]]">
|
||||||
|
Design
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
@ -4,6 +4,7 @@ import { RouterLink } from 'vue-router'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { AspectRatio } from '@/components/ui/aspect-ratio'
|
import { AspectRatio } from '@/components/ui/aspect-ratio'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
|
import Wordmark from '@/components/layout/Wordmark.vue'
|
||||||
import { projects } from '@/data/projects'
|
import { projects } from '@/data/projects'
|
||||||
|
|
||||||
const { t } = useI18n({ useScope: 'global' })
|
const { t } = useI18n({ useScope: 'global' })
|
||||||
|
|
@ -34,11 +35,9 @@ const projectCards = computed(() =>
|
||||||
<div
|
<div
|
||||||
class="absolute right-0 bottom-14 left-0 mx-auto max-w-[1400px] px-6 text-white md:bottom-20 md:px-10"
|
class="absolute right-0 bottom-14 left-0 mx-auto max-w-[1400px] px-6 text-white md:bottom-20 md:px-10"
|
||||||
>
|
>
|
||||||
<p class="text-xs uppercase tracking-[0.22em] text-white/80">
|
<Wordmark size="md" class="text-white/95" />
|
||||||
{{ t('home.hero.eyebrow') }}
|
|
||||||
</p>
|
|
||||||
<h1
|
<h1
|
||||||
class="mt-4 max-w-3xl font-serif text-4xl font-light leading-[1.05] tracking-tight md:text-6xl lg:text-7xl"
|
class="mt-6 max-w-3xl font-serif text-4xl font-light leading-[1.05] tracking-tight md:text-6xl lg:text-7xl"
|
||||||
>
|
>
|
||||||
{{ t('home.hero.headline') }}<br />{{ t('home.hero.headline2') }}
|
{{ t('home.hero.headline') }}<br />{{ t('home.hero.headline2') }}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue