marketing footer-1

Footer 1 — 4-column site footer

Minimal 4-column site footer with nav columns, hairline meta strip, and 特定商取引法 link slot. shadcn-baseline — no Mincho, no card, no shadow.

無料MITv1.1.0

ライブプレビュー

viewport: responsive

コード · components/blocks/footer-1.tsx

import Link from "next/link";

/**
 * Shoji footer-1 — minimal 4-column footer.
 *
 * Surface B (Blocks) contract — design-spec §4.5:
 *   - shadcn semantic tokens only (bg-background, text-foreground, border, text-muted-foreground)
 *   - Tailwind default scale — no Shoji-specific utilities
 *   - No wordmark, no Mincho — branding stays on Surface A (LP)
 *   - JP feature: 特定商取引法 link surfaced (compliance pattern)
 */
export function Footer1() {
  return (
    <footer
      role="contentinfo"
      className="bg-background text-foreground border-t border-border"
    >
      <div className="mx-auto w-full max-w-6xl px-6 py-16 lg:py-20">
        <div className="grid grid-cols-2 gap-12 md:grid-cols-4">
          <div className="col-span-2 flex flex-col gap-4 md:col-span-1">
            <p className="text-base font-semibold tracking-tight">
              Your Brand
            </p>
            <p className="max-w-xs text-sm leading-[1.75] text-muted-foreground">
              プロダクトの一行説明をここに。
              <br />
              Replace with your own tagline.
            </p>
          </div>

          <FooterColumn
            title="Product"
            items={[
              { href: "/features", label: "Features" },
              { href: "/pricing", label: "Pricing" },
              { href: "/changelog", label: "Changelog" },
              { href: "/roadmap", label: "Roadmap" },
            ]}
          />
          <FooterColumn
            title="Resources"
            items={[
              { href: "/docs", label: "Documentation" },
              { href: "/support", label: "サポート" },
              { href: "/blog", label: "Blog" },
              {
                href: "https://github.com/your-org",
                label: "GitHub",
                external: true,
              },
            ]}
          />
          <FooterColumn
            title="Company"
            items={[
              { href: "/about", label: "About" },
              { href: "/contact", label: "Contact" },
              { href: "/terms", label: "利用規約" },
              { href: "/privacy", label: "プライバシーポリシー" },
              {
                href: "/specified-commercial-transactions",
                label: "特定商取引法に基づく表記",
              },
            ]}
          />
        </div>

        <hr className="mt-16 border-t border-border" />

        <div className="mt-8 flex flex-col items-start justify-between gap-4 text-xs text-muted-foreground sm:flex-row sm:items-center">
          <p className="font-mono">© 2026 Your Brand · Made in Japan</p>
          <ul className="flex items-center gap-6 font-mono">
            <li>v1.0.0</li>
            <li aria-hidden>·</li>
            <li>
              <Link
                href="/changelog"
                className="hover:text-foreground transition-colors"
              >
                Changelog →
              </Link>
            </li>
          </ul>
        </div>
      </div>
    </footer>
  );
}

function FooterColumn({
  title,
  items,
}: {
  title: string;
  items: Array<{ href: string; label: string; external?: boolean }>;
}) {
  return (
    <div className="flex flex-col gap-4">
      <p className="text-xs font-mono uppercase tracking-[0.18em] text-muted-foreground">
        {title}
      </p>
      <ul className="flex flex-col gap-2 text-sm leading-[1.75]">
        {items.map((item) => (
          <li key={item.href}>
            <Link
              href={item.href}
              className="inline-flex items-center gap-1 hover:text-muted-foreground transition-colors"
              {...(item.external
                ? { target: "_blank", rel: "noopener noreferrer" }
                : {})}
            >
              {item.label}
              {item.external && (
                <span aria-hidden className="text-[0.6rem] opacity-60">
                  ↗
                </span>
              )}
            </Link>
          </li>
        ))}
      </ul>
    </div>
  );
}

AI prompt · MDX

shoji_block: footer-1
---
shoji_block: footer-1
shoji_version: 1.1.0
category: marketing
license: MIT
dependencies: ["next"]
shadcn_primitives: []
ja_specific: false
---

# footer-1

> Shoji block for AI agents. Paste this entire file to your AI;
> it will scaffold a 4-column site footer with a 特商法 link slot for JP compliance.

## Component

```tsx
import Link from "next/link";

export function Footer1() {
  return (
    <footer
      role="contentinfo"
      className="bg-background text-foreground border-t border-border"
    >
      <div className="mx-auto w-full max-w-6xl px-6 py-16 lg:py-20">
        <div className="grid grid-cols-2 gap-12 md:grid-cols-4">
          <div className="col-span-2 flex flex-col gap-4 md:col-span-1">
            <p className="text-base font-semibold tracking-tight">Your Brand</p>
            <p className="max-w-xs text-sm leading-[1.75] text-muted-foreground">
              プロダクトの一行説明をここに。
              <br />
              Replace with your own tagline.
            </p>
          </div>

          <FooterColumn
            title="Product"
            items={[
              { href: "/features", label: "Features" },
              { href: "/pricing", label: "Pricing" },
              { href: "/changelog", label: "Changelog" },
              { href: "/roadmap", label: "Roadmap" },
            ]}
          />
          <FooterColumn
            title="Resources"
            items={[
              { href: "/docs", label: "Documentation" },
              { href: "/support", label: "サポート" },
              { href: "/blog", label: "Blog" },
              { href: "https://github.com/your-org", label: "GitHub", external: true },
            ]}
          />
          <FooterColumn
            title="Company"
            items={[
              { href: "/about", label: "About" },
              { href: "/contact", label: "Contact" },
              { href: "/terms", label: "利用規約" },
              { href: "/privacy", label: "プライバシーポリシー" },
              { href: "/specified-commercial-transactions", label: "特定商取引法に基づく表記" },
            ]}
          />
        </div>

        <hr className="mt-16 border-t border-border" />

        <div className="mt-8 flex flex-col items-start justify-between gap-4 text-xs text-muted-foreground sm:flex-row sm:items-center">
          <p className="font-mono">© 2026 Your Brand · Made in Japan</p>
          <ul className="flex items-center gap-6 font-mono">
            <li>v1.0.0</li>
            <li aria-hidden>·</li>
            <li>
              <Link href="/changelog" className="hover:text-foreground transition-colors">
                Changelog →
              </Link>
            </li>
          </ul>
        </div>
      </div>
    </footer>
  );
}

function FooterColumn({
  title,
  items,
}: {
  title: string;
  items: Array<{ href: string; label: string; external?: boolean }>;
}) {
  return (
    <div className="flex flex-col gap-4">
      <p className="text-xs font-mono uppercase tracking-[0.18em] text-muted-foreground">
        {title}
      </p>
      <ul className="flex flex-col gap-2 text-sm leading-[1.75]">
        {items.map((item) => (
          <li key={item.href}>
            <Link
              href={item.href}
              className="inline-flex items-center gap-1 hover:text-muted-foreground transition-colors"
              {...(item.external ? { target: "_blank", rel: "noopener noreferrer" } : {})}
            >
              {item.label}
              {item.external && (
                <span aria-hidden className="text-[0.6rem] opacity-60">↗</span>
              )}
            </Link>
          </li>
        ))}
      </ul>
    </div>
  );
}
```

## Usage

```tsx
import { Footer1 } from "@/components/blocks/footer-1";

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <main>{children}</main>
      <Footer1 />
    </>
  );
}
```

## Block contract (Two-surfaces — design-spec §4.5)

This is a **Surface B block** — drops into any shadcn theme without modification.

- shadcn semantic tokens only (`bg-background`, `text-foreground`, `border-border`, `text-muted-foreground`)
- Tailwind defaults — no Mincho wordmark, no `font-mincho`, no 5-color tokens
- Replace `Your Brand` with your own wordmark; keep typography neutral

## Customization hints

- **Wordmark**: replace the `Your Brand` text with your own logo or component. Shoji does not impose a font here.
- **Column count**: 4 → 2 → 1 responsive. Adjust `md:grid-cols-N` and the wordmark column's `col-span-{2,1}` together.
- **特商法表記**: required for any JP commercial offering. Wire `/specified-commercial-transactions` to a real page.
- **External link icon**: `↗` is `aria-hidden`; the `target="_blank"` machinery does the SR work.

## A11y

- Top-level element is `<footer role="contentinfo">` — landmark for assistive tech.
- All links use Next `<Link>` — focus ring inherited from your global styles.
- External links: `target="_blank" rel="noopener noreferrer"`. `↗` icon is `aria-hidden`.
- Decorative `·` separators use `aria-hidden`.
- Body uses `leading-[1.75]` for JP-friendly tap-target spacing.

## Why this is a Shoji block

- **JP-compliant out of the box.** `特定商取引法に基づく表記` link slot is wired in by default — most US/EU footer templates leave this gap.
- **No theming opinions.** No Mincho, no Shoji palette — your shadcn theme drives everything.
- **AI agent ready.** Single-paste MDX with all a11y, link, and JP-compliance context inline.

依存パッケージ · npm

  • 外部依存なし。