Proof footer

Inverse color band that reprises testing, ingredients, dispatch, and guarantee, then ends on a clipped wordmark.

blockproofanytrust
$npx shadcn@latest add @storekit/footer-proof
footer-proof

Live and interactive. Switch the brand in the frame header to see the same source under another token file.

Installation

$npx shadcn@latest add @storekit/footer-proof
$pnpm dlx shadcn@latest add @storekit/footer-proof
$yarn dlx shadcn@latest add @storekit/footer-proof
$bunx --bun shadcn@latest add @storekit/footer-proof

Source

components/storekit/footer/footer-proof.tsx
127 lines
"use client"

import { useEffect, useRef } from "react"
import { BadgeCheck, FileCheck2, PackageCheck, ShieldCheck } from "lucide-react"
import { cn } from "@/components/storekit/lib/cn"

/* Inverted band footer (ink fill, paper text: dark on light brands, light on
   dark brands) that reprises the store's trust claims before the link columns,
   then ends on an oversized wordmark clipped by the bottom edge. Trust points
   read as a quiet ledger, not a stat banner. The only client code shrinks the
   wordmark when a wide display face would overflow the width. */

type Point = { title: string; note: string; icon?: "tested" | "ingredients" | "dispatch" | "guarantee" }
type Column = { title: string; links: { label: string; href: string }[] }

const ring =
  "outline-none focus-visible:ring-2 focus-visible:ring-sk-paper focus-visible:ring-offset-2 focus-visible:ring-offset-sk-ink"

const ICONS = { tested: BadgeCheck, ingredients: FileCheck2, dispatch: PackageCheck, guarantee: ShieldCheck }

export function FooterProof({
  brandName = "Morrow",
  points = [
    { title: "Third-party tested", note: "Results published for every batch", icon: "tested" },
    { title: "Clean ingredients", note: "No fillers, no artificial colors", icon: "ingredients" },
    { title: "24h dispatch", note: "Orders before 2pm, same day", icon: "dispatch" },
    { title: "30-day guarantee", note: "Even if the pouch is empty", icon: "guarantee" },
  ],
  columns = [
    { title: "Shop", links: [{ label: "All products", href: "#shop" }, { label: "Powders", href: "#powders" }, { label: "Drinks", href: "#drinks" }] },
    { title: "Proof", links: [{ label: "Lab results", href: "#lab-results" }, { label: "Ingredients", href: "#ingredients" }, { label: "Quality", href: "#quality" }] },
    { title: "Support", links: [{ label: "Shipping", href: "#shipping" }, { label: "Returns", href: "#returns" }, { label: "Contact", href: "#contact" }] },
  ],
  legal = "These statements have not been evaluated by the FDA. This product is not intended to diagnose, treat, cure, or prevent any disease.",
  className,
}: {
  brandName?: string
  points?: Point[]
  columns?: Column[]
  legal?: string
  className?: string
}) {
  return (
    <footer data-sk-section="footer" data-sk-variant="footer-proof" className={cn("relative overflow-hidden bg-sk-ink text-sk-paper", className)}>
      <div className="mx-auto max-w-6xl px-4 pt-14 sm:px-8">
        <ul className="grid grid-cols-1 gap-px overflow-hidden rounded-sk-card border border-sk-paper/10 bg-sk-paper/10 sm:grid-cols-2 lg:grid-cols-4">
          {points.map((p) => {
            const Icon = ICONS[p.icon ?? "tested"]
            return (
              <li key={p.title} className="flex items-start gap-3 bg-sk-ink p-5">
                <Icon size={18} aria-hidden className="mt-0.5 shrink-0 text-sk-paper/60" />
                <div>
                  <p className="text-[15px] font-semibold">{p.title}</p>
                  <p className="mt-1 text-[13px] leading-[1.5] text-sk-paper/60">{p.note}</p>
                </div>
              </li>
            )
          })}
        </ul>

        <div className="grid grid-cols-2 gap-x-6 gap-y-10 py-14 sm:grid-cols-3 md:grid-cols-[1.5fr_1fr_1fr_1fr]">
          <div className="col-span-2 max-w-xs sm:col-span-3 md:col-span-1">
            <p className="font-sk-display text-xl font-semibold leading-[1.1] tracking-[-0.02em] text-balance">Every batch tested. Every result published.</p>
            <p className="mt-3 text-[13px] leading-[1.5] text-sk-paper/60">{legal}</p>
          </div>
          {columns.map((c) => (
            <nav key={c.title} aria-label={c.title}>
              <p className="font-sk-mono text-[11px] uppercase tracking-[0.14em] text-sk-paper/50">{c.title}</p>
              <ul className="mt-3 grid">
                {c.links.map((l) => (
                  <li key={l.href}>
                    <a href={l.href} className={cn("inline-flex min-h-10 items-center rounded-sk-btn text-[13px] text-sk-paper/70 transition-colors duration-200 hover:text-sk-paper", ring)}>
                      {l.label}
                    </a>
                  </li>
                ))}
              </ul>
            </nav>
          ))}
        </div>

        <div className="flex flex-wrap items-center justify-between gap-2 border-t border-sk-paper/10 py-5 text-[13px] text-sk-paper/50">
          <p>&copy; {new Date().getFullYear()} {brandName}</p>
          <p className="font-sk-mono text-[11px] uppercase tracking-[0.14em]">Made in the USA</p>
        </div>
      </div>

      <Wordmark name={brandName} />
    </footer>
  )
}

/** Oversized wordmark sized by container width, then shrunk to fit if the
    style pack's display face is wider than the estimate. */
function Wordmark({ name }: { name: string }) {
  const box = useRef<HTMLDivElement>(null)
  const text = useRef<HTMLSpanElement>(null)
  useEffect(() => {
    const b = box.current
    const t = text.current
    if (!b || !t) return
    const fit = () => {
      t.style.transform = ""
      const avail = b.clientWidth - 16
      const w = t.scrollWidth
      if (w > avail && w > 0) t.style.transform = `scale(${avail / w})`
    }
    fit()
    const ro = new ResizeObserver(fit)
    ro.observe(b)
    document.fonts?.ready.then(fit).catch(() => {})
    return () => ro.disconnect()
  }, [name])
  return (
    <div ref={box} aria-hidden className="pointer-events-none flex select-none justify-center overflow-hidden px-2 [container-type:inline-size]">
      <span
        ref={text}
        className="-mb-[0.18em] block origin-bottom whitespace-nowrap font-sk-display font-semibold leading-[0.8] text-sk-paper/10"
        // Inline tracking beats the style pack's display tracking.
        style={{ fontSize: `min(240px, calc(100cqw / ${Math.max(4, name.length * 0.55).toFixed(2)}))`, letterSpacing: "-0.04em" }}
      >
        {name}
      </span>
    </div>
  )
}

Usage

Import from "@/components/storekit/footer/footer-proof" and pass your product data. The demo above exercises the full prop surface with sample values.

Proof footer, StoreKit