Ryan Tseng

Ink Ridges

Heroes 60

About

Sumi-e mountain landscape background: layered ink ridges brush themselves in, far to near, with drifting mist and cloud streaks; a painted red sun blooms last, and on dark paper it is a moon. A small flock crosses now and then, and on scroll the far ridges lag while the sun sets. Every seed paints a new range. React only, no images. npx @21st-dev/cli add @ryanonline1234/ink-ridges

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Ink Ridges to your project and fits it to your theme.

Code

How Ink Ridges is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

'use client'

import { useState } from 'react'
// 21st's CLI points this import at its own copy of the component when it publishes.
import InkRidges from '@/components/ui/ink-ridges'

// Plain values only: 21st builds the preview's controls from this object.
// The moon is left to the component's default ('auto'), so dark mode shows it.
const settings = {
  layers: 4,
  seed: 7,
  horizon: 0.62,
  mist: 0.6,
  drift: 0.05,
  parallax: 0.03,
  paintIn: 2600,
  sun: true,
  sunColor: '#b5402a',
  scrollDepth: 0.35,
  glow: 0.45,
  clouds: 0.35,
  birds: 5,
  birdsEvery: 14,
  grain: 0.3,
}

export default function Demo(props: Partial<typeof settings>) {
  const s = { ...settings, ...props }
  const [bump, setBump] = useState(0)
  const seed = s.seed + bump
  return (
    <div className="w-full bg-background text-foreground">
      <InkRidges
        layers={s.layers}
        seed={seed}
        horizon={s.horizon}
        mist={s.mist}
        drift={s.drift}
        parallax={s.parallax}
        paintIn={s.paintIn}
        sun={s.sun}
        sunColor={s.sunColor}
        scrollDepth={s.scrollDepth}
        glow={s.glow}
        clouds={s.clouds}
        birds={s.birds}
        birdsEvery={s.birdsEvery}
        grain={s.grain}
        label="An ink landscape of layered mountain ridges in mist, painted by code"
        className="h-[82svh] min-h-[520px] w-full bg-background"
      >
        <div className="max-w-xl p-6 md:p-10">
          <p className="font-mono text-[11px] uppercase tracking-[0.18em] text-muted-foreground">Ink ridges · seed {seed}</p>
          <h1 className="mt-4 font-serif text-5xl font-normal leading-[0.98] tracking-[-0.02em] md:text-7xl">
            Mountains,
            <br />
            painted in place.
          </h1>
          <p className="mt-5 max-w-sm text-sm text-muted-foreground">
            Every seed paints a different range. Ink thins toward each foot, mist drifts between the ridges, now and then a flock crosses, and the sun sets as you scroll on.
          </p>
          <button
            type="button"
            id="paint-another-range"
            onClick={() => setBump((b) => b + 1)}
            className="mt-6 rounded-full border border-foreground/25 bg-background/70 px-4 py-2 font-mono text-[11px] uppercase tracking-[0.16em] backdrop-blur-sm transition-colors duration-150 hover:bg-foreground hover:text-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
          >
            Paint another range
          </button>
        </div>
      </InkRidges>
      <section className="mx-auto flex min-h-[120svh] max-w-3xl flex-col justify-center px-6 py-24 md:px-10">
        <h2 className="font-serif text-3xl leading-tight">A range, not a picture.</h2>
        <p className="mt-4 text-sm text-muted-foreground">
          Nothing here is an image. Each ridge is a line of noise brushed in from the left, far ridge first; the ink thins toward its foot, and
          mist lifts out of it and drifts. The landscape draws only while something moves, takes the paper and ink from your theme, and under
          prefers-reduced-motion it is one finished, still frame.
        </p>
      </section>
    </div>
  )
}

More by Ryan Tseng

View all
  • Ink Hero

    Ink Hero

    76
  • Ink Headline

    Ink Headline

    39
  • Ink Reveal

    Ink Reveal

    19
  • Ease Atlas

    Ease Atlas

More in Heroes

View all
  • SaaS Template

    SaaS Template

    2.4K
  • Hero

    Hero

    1.2K
  • Centered Hero with Image Fan

    Centered Hero with Image Fan

    924
  • Responsive Hero Banner

    Responsive Hero Banner

    2K
  • Hero Section 6

    Hero Section 6

    881
  • Hero Golden Spiral

    Hero Golden Spiral

    101
  • Home Section

    Home Section

    65
  • Minimalist Hero Fashion

    Minimalist Hero Fashion

    284