Skip to main content
Documentation

Reusing Sections (Portability)

Lift any section into another project with a known, minimal set of dependencies.

Every section in src/components/sections/** is designed to be lifted into another project. Because the theme shares one design system, a section is never a single orphan file — it comes with a small, known “copy set”. This page documents that contract so you never have to reverse-engineer a section again.

The copy set

To reuse a section, bring these four things (each section file lists its own exact needs in a PORTABILITY comment at the very top of the file):

  1. The section file itselfsrc/components/sections/.../XxxSection.astro. Its behaviour (the inline <script>, if any) travels inside the file, so you never chase down separate JS.
  2. Any shared components it imports — usually SectionTitle and PrimaryActionButton from src/components/common/, plus the <Img> wrapper (src/components/common/Img.astro + src/lib/assets.ts) that most sections use to render optimized images. Small, dependency-light files.
  3. The theme tokens it uses — utilities like font-title, rounded-16, bg-bg-soft, primary-100/200/300. These are defined once in src/styles/global.css under @theme. Copy the block below into the target project’s Tailwind stylesheet and every token resolves.
  4. The images it references — raster images live in src/assets/images and are rendered through <Img> (optimized: srcset/format/resize/dimensions). SVG icons and a few CSS/OG assets stay in public/assets/images. The section’s header lists the exact globs (e.g. /assets/images/*.webp).
  5. Its content data — most sections declare demo content as prop defaults, and the larger datasets are centralized in src/config/ (gallery in src/config/gallery.ts, section content in src/config/sections/*.ts). Edit data there, or override via props.

Tip: open the section file and read the PORTABILITY header — it enumerates the components, tokens, assets, and behaviour for that specific section.

Design-system contract (@theme)

This is the single source of truth for the visual tokens the sections rely on. Paste it into the destination project’s global.css (Tailwind v4) and the sections render identically:

@theme {
  --color-black: #0a0a0a;
  --color-white: #fcfcfc;
  --color-border: rgba(252, 252, 252, 0.25);
  --color-border-soft: rgba(252, 252, 252, 0.15);
  --color-bg-soft: rgba(205, 167, 221, 0.05);
  --color-bg-solid: #141215;

  --color-primary-100: #dd429d;
  --color-primary-200: #b14bf4;
  --color-primary-300: #485cfb;

  --font-body: Inter, sans-serif;
  --font-title: Exo, sans-serif;

  --text-body: 20px;
  --text-body--line-height: 1.5;
  --text-h1: 72px;
  --text-h2: 52px;
  --text-h3: 32px;

  --radius-16: 16px;
  --shadow-soft: 0 20px 60px rgba(10, 10, 10, 0.35);

  /* Section animations (marquees, waves, etc.) referenced via `animate-*`. */
  --animate-company-marquee: company-marquee 26s linear infinite;
  --animate-fun-fact-marquee: fun-fact-marquee 16s linear infinite;
  --animate-works-up: works-up 18s linear infinite;
  --animate-works-down: works-down 18s linear infinite;
  --animate-gallery-left: gallery-left 32s linear infinite;
  --animate-gallery-right: gallery-right 24s linear infinite;
  --animate-usecase-cursor-tap: usecase-cursor-tap 900ms ease-in-out;
  --animate-our-story-wave: our-story-wave 1.6s ease-in-out infinite;
}

The matching @keyframes live in the same @theme block in src/styles/global.css — copy those too if the section you’re lifting uses an animate-* token (its header will say so).

No hidden layout utility

Sections no longer depend on a custom container utility. The old @utility container was inlined everywhere as mx-auto max-w-[1350px] px-[15px], so a lifted section carries its own width/centering and renders correctly even in a stock Tailwind project.

You don’t have to gather the copy-set by hand. Run:

npm run sections:export -- GallerySection
# or: npm run sections:export -- marketing/GallerySection

This writes a self-contained bundle to export/GallerySection/ containing:

  • the section file and every component it imports (Img, SectionTitle, PrimaryActionButton, …), resolved transitively,
  • any config/ data and lib/ helpers it uses,
  • the design-system stylesheet (src/styles/global.css),
  • every image the section references, and
  • a README.md with paste instructions.

Original paths are preserved, so imports and the image pipeline work as-is. To lift the section, copy the bundle’s src/ and public/ into your Astro 7 + Tailwind v4 project and import global.css once in your layout. That’s the whole job — nothing to reverse-engineer.

Manual step-by-step (if you prefer)

  1. Read the PORTABILITY header at the top of the section file.
  2. Copy the section file (and any common/ components it imports).
  3. Paste the @theme block above (plus any @keyframes for animate-* tokens used).
  4. Copy the listed public/assets/* files, or pass your own paths in via the section’s props.
  5. Render it — the section is self-styled and self-scripted.