بلاک‌ها · بخش‌های صفحه

فوتر با اسمِ درشت

پیش‌نمایش تمام‌صفحه

بخشِ فوترِ تیره: تیتر، عضویتِ خبرنامه، برند و سه ستونِ لینک، و اسمِ برند با گرادیانِ نقره‌ای که پایینِ کارت نیمه‌بریده می‌نشیند.

۱. نصب کامپوننت‌ها

این بلاک از ۴ آیتم دیگ استفاده می‌کند: buttoncontrol-sizeiconsinput

پکیج‌منیجر پیش‌فرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/input.json
pnpm dlx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/input.json
yarn dlx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/input.json
bunx --bun digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/input.json

۲. کد صفحه

کد را در app/<route>/page.tsx بگذارید و متن‌ها، داده و هندلرها را با محصول خودتان عوض کنید.

footer-wordmark.tsx
"use client"

import * as React from "react"

import { CheckCircleIcon, SparklesIcon } from "@/components/icons"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { Input } from "@/components/ui/input"

const COLUMNS = [
  { title: "محصول", links: ["چطور کار می‌کند", "تعرفه", "امنیت", "اپِ موبایل"] },
  { title: "یادگیری", links: ["مرکزِ راهنما", "وضعیتِ سرویس", "مستنداتِ API", "انجمن"] },
  { title: "شرکت", links: ["درباره ما", "فرصت‌های شغلی", "حریمِ خصوصی", "مرکزِ اعتماد"] },
]

/**
 * فوترِ پایانی با اسمِ درشتِ برند: کارتِ تیره با درخششِ سبزِ محو، تیترِ «رشدِ آنچه ساخته‌اید»،
 * عضویتِ خبرنامهٔ ماهانه با دکمهٔ سبزِ روشن، برند و سه ستونِ لینک؛ اسمِ برند با گرادیانِ
 * نقره‌ای پایینِ کارت نیمه‌بریده می‌نشیند. همیشه تیره است.
 */
export default function FooterWordmarkBlock() {
  const [state, setState] = React.useState<"idle" | "error" | "done">("idle")

  return (
    <ControlSizeProvider size="xl" asChild>
      <footer className="w-full bg-[var(--dig-graphite-950)] p-3 sm:p-6">
        <div className="relative isolate mx-auto flex w-full max-w-6xl flex-col gap-12 overflow-hidden rounded-xl border border-[var(--dig-graphite-800)] bg-[radial-gradient(ellipse_at_50%_110%,var(--dig-green-800),var(--dig-graphite-950)_60%)] px-5 pt-10 text-[var(--dig-white)] sm:px-10 sm:pt-14">
          <div className="grid grid-cols-1 gap-10 lg:grid-cols-[1fr_24rem]">
            <div className="flex flex-col items-start gap-4">
              <span className="flex items-center gap-2 rounded-full bg-[var(--dig-graphite-800)] px-3 py-1 text-xs font-semibold">
                <span aria-hidden className="size-1.5 rounded-full bg-[var(--dig-green-300)]" />
                شروعِ کار
              </span>
              <h2 className="text-3xl leading-snug font-black sm:text-4xl">
                رشدِ آنچه <span className="text-[var(--dig-green-300)]">ساخته‌اید</span>
              </h2>
              <p className="text-[var(--dig-neutral-400)]">همه‌چیز در یک جا؛ و همه‌چیز همان‌طور که باید.</p>
            </div>
            <div className="flex flex-col gap-2">
              <span className="font-bold">خلاصهٔ ماهانهٔ بازار</span>
              {state === "done" ? (
                <p role="status" className="flex items-center gap-2 text-[var(--dig-green-300)]">
                  <CheckCircleIcon aria-hidden className="size-5" />
                  عضو شدید؛ اولین شماره اولِ ماه می‌رسد.
                </p>
              ) : (
                <form
                  noValidate
                  onSubmit={(event) => {
                    event.preventDefault()
                    const email = String(new FormData(event.currentTarget).get("email"))
                    setState(/^\S+@\S+\.\S+$/.test(email) ? "done" : "error")
                  }}
                  className="flex gap-2"
                >
                  <Input
                    name="email"
                    type="email"
                    dir="ltr"
                    aria-label="ایمیل"
                    placeholder="name@mail.com"
                    aria-invalid={state === "error"}
                    className="flex-1 border-[var(--dig-graphite-700)] bg-[var(--dig-graphite-900)] text-[var(--dig-white)] placeholder:text-[var(--dig-neutral-500)]"
                  />
                  <Button type="submit" className="[--primary-foreground:var(--dig-graphite-950)] [--primary:var(--dig-green-300)] hover:[--primary:var(--dig-green-200)]">
                    عضویت
                  </Button>
                </form>
              )}
              {state === "error" ? (
                <p role="alert" className="text-sm text-[var(--dig-red-300)]">
                  ایمیل را کامل بنویسید.
                </p>
              ) : (
                <p className="text-xs text-[var(--dig-neutral-500)]">
                  با عضویت <a href="#" className="underline">حریمِ خصوصی</a> را می‌پذیرید.
                </p>
              )}
            </div>
          </div>

          <div className="grid grid-cols-2 gap-8 border-t border-[var(--dig-graphite-800)] pt-10 md:grid-cols-[1.5fr_1fr_1fr_1fr]">
            <div className="col-span-2 flex flex-col gap-3 md:col-span-1">
              <span className="flex items-center gap-2 text-lg font-black">
                <span aria-hidden className="flex size-8 items-center justify-center rounded-lg bg-[var(--dig-green-300)] text-[var(--dig-graphite-950)]">
                  <SparklesIcon className="size-4" />
                </span>
                کوهسار
              </span>
              <p className="max-w-60 text-sm leading-6 text-[var(--dig-neutral-400)]">پیگیریِ دارایی‌ها، سرمایه‌گذاری و رشدِ مالی در یک جا.</p>
            </div>
            {COLUMNS.map((column) => (
              <nav key={column.title} aria-label={column.title} className="flex flex-col gap-3 text-sm">
                <span className="text-[var(--dig-neutral-500)]">{column.title}</span>
                {column.links.map((link) => (
                  <a key={link} href="#" className="text-[var(--dig-neutral-300)] hover:text-[var(--dig-white)]">
                    {link}
                  </a>
                ))}
              </nav>
            ))}
          </div>

          <div className="flex flex-wrap justify-between gap-2 text-xs text-[var(--dig-neutral-500)]">
            <span>© ۱۴۰۵ کوهسار. همهٔ حقوق محفوظ است.</span>
            <a href="#" className="hover:text-[var(--dig-white)]">
              شرایطِ استفاده
            </a>
          </div>

          <span aria-hidden className="-mb-[0.32em] block bg-[linear-gradient(180deg,var(--dig-neutral-100),var(--dig-neutral-500)_70%,transparent)] bg-clip-text text-center text-[clamp(5rem,22vw,16rem)] leading-[0.9] font-black text-transparent select-none">
            کوهسار
          </span>
        </div>
      </footer>
    </ControlSizeProvider>
  )
}