fix: storybook font rendering and shared fonts module #1

Merged
ilia merged 74 commits from feat/portfolio-setup into main 2026-05-18 18:45:22 +00:00
Owner

Protfolio project.
Set up for ISR.

Protfolio project. Set up for ISR.
ilia added 74 commits 2026-05-18 18:45:02 +00:00
- app/[[...slug]]/page.tsx replaces app/page.tsx; activeSlug from URL params
- SidebarNav and MobileNav removed from main layout (sections accordion is the nav)
- next.config.ts: output:export controlled by STATIC_EXPORT env var instead of NODE_ENV
- package.json: yarn build is standard Next.js build; yarn export is STATIC_EXPORT=true
- Mock API route: force-static + generateStaticParams for output:export compatibility
Replace ochre-clay, carbon-black, burnt-oxide, slate-indigo with clean
two-color system: --cream (#f4f0e8) and --blue (#041cf3). Update every
component, utility class, and test assertion.
Remove slug field from PageContentRecord (intro/bio collections have none).
Remove number field from SectionRecord (not stored in PocketBase); derive
zero-padded display number from the order field at render time.
Global a { border-bottom } was leaking onto the inactive section
nav links. Override with border-b-0 hover:border-b-0.
Add html-react-parser-backed RichText component that converts HTML
strings from PocketBase rich-text fields into React elements without
dangerouslySetInnerHTML. Replace raw <p> render in IntroSection and
BioSection, and drop the invalid slug filters those collections lacked.
Wraps children in React's ViewTransition (canary API) when available,
falling back to Fragment in environments where ViewTransition is undefined
(test env, stable react-dom). Add react/canary to tsconfig types to
expose the ViewTransition component type.
Enable experimental.viewTransition in Next.js config. Wrap active section
in ViewTransitionWrapper so the browser cross-fades between sections on
navigation. Replace animate-fadeIn keyframe with @starting-style + CSS
transition for the initial render enter animation.
hover:opacity-60 on Link and opacity-30/group-hover:opacity-50 on h2
were multiplying (0.6 × 0.5 = 0.30 = base), making hover invisible.
Removed opacity from Link, consolidated to h2 only: opacity-30 base,
group-hover:opacity-60 on hover.
Add animation tokens to :root (--ease-spring, --ease-decelerate,
--ease-default, --duration-fast/normal/slow/spring). Apply spring easing
to section title enter. Add separate section-body transition: fast
blur-out exit (100ms), clean slide-in enter (350ms) delayed by 200ms so
content appears after the title animation completes.
- Expand brutal shadow scale: xs (1px) through 2xl (12px)
- Add --ease-micro cubic-bezier for fast micro-interactions
- Tune --duration-normal 200ms→150ms, --duration-spring 380ms→220ms
- Add --section-content-width and register as --container-section in @theme inline
- Register all brutal shadow tokens in @theme inline for Tailwind utility generation
- Add .btn-transition utility (transform-only, shadow snaps instantly)
- Add .rich-text editorial typography class with magazine-quality settings
- Remove section-body blur-out/slide-in view transition animations
Variants now use brutal shadow tokens. On hover the button translates
up-left (−0.5px), on active down-right (+0.5px). Only transform animates
(130ms ease-out); shadow snaps instantly so the eye reads button movement
not shadow resize. Primary keeps rgba alpha shadow; secondary/outline use
solid brutal tokens.
Always wraps content in .rich-text: max-width 65ch, onum figures,
hanging punctuation, pretty text-wrap, auto hyphens, 1.65 line-height,
and 1.2em paragraph spacing. className prop merges additonal classes.
ExperienceCard description switches from a plain <p> to RichText so
rich-text HTML from PocketBase renders correctly. BioSection and
IntroSection drop the prose class overrides — RichText handles
typography consistently.
Adds max-w-section (56rem via --container-section token) to the
experience, projects, and skills section wrappers for consistent
readable line length across all content areas.
Replace inline var(--blue) arbitrary shadow values with typed theme
tokens (shadow-brutal-xl, shadow-brutal-2xl). Remove translate on
ProjectCard hover — shadow-only interaction is less distracting in
a dense grid layout.
Sidebar: period badge, company, stack tags.
Main: role title and rich-text description.
Discriminated union types (AsButton | AsAnchor), isAnchorProps type guard
eliminates all 'as' casts. as const satisfies for VARIANTS/SIZES lookup
tables. brutal-border replaces border-[3px] in ghost variant.
Moved from ProjectsSection inline function to shared/lib/utils.
Accepts optional baseUrl for testability without env mocking.
Renders Next.js Link for internal routes, plain anchor with
target="_blank" rel="noopener noreferrer" when external prop is set.
Models PocketBase relations: SiteSettings → contacts → ContactsRecord
→ socials[] → SocialRecord. expand fields typed as optional resolved
records for use with PocketBase expand query param.
Fetches CV file, email and social links via expand=contacts,contacts.socials.
CV rendered as polymorphic Button with download attr; socials and email
rendered as Link components.
not-found.tsx renders oversized Fraunces heading with a back link.
Body gets flex flex-col min-h-screen so main can flex-1 to fill
available height without pushing the footer off screen.
Drops static export (STATIC_EXPORT env var) in favour of standalone
for ISR. Images remotePatterns reads PB_HOSTNAME/PB_PORT env vars so
Docker internal hostname works without hardcoding.
PB_URL falls back through PB_URL → NEXT_PUBLIC_PB_URL → localhost so
internal Docker hostname is used server-side without leaking into the
client bundle. cache: force-cache replaced with next: { tags, revalidate }
for ISR tag-based invalidation.
Each getCollection/getFirstRecord call now passes the collection name
as a cache tag so revalidateTag can target individual collections.
POST with x-revalidate-secret header and { tag } body calls
revalidateTag to purge a collection from the Next.js data cache.
Guarded by REVALIDATE_SECRET env var.
ilia merged commit cd9da6dd26 into main 2026-05-18 18:45:22 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ilia/portfolio#1