Workspace / component / backgrounds

Editorial Grid Background

Visible column guides and a baseline grid, like a design file with the overlays left on. Columns are responsive and honest to the container.

Workspacecomponentbackgrounds

paxfx add blocks/component-backgrounds-editorial-gridlocal only

Tier: low. Reduced motion: Fully static surface.

"use client";

import type { ReactNode } from "react";
import { cn } from "@pax-sh/blocks";

export interface EditorialGridBackgroundProps {
  /** Number of column guides. */
  columns?: number;
  /** Gutter between columns in px. */
  gutter?: number;
  /** Outer margin around the column guides in px. */
  margin?: number;
  /** Baseline grid spacing in px. */
  baseline?: number;
  className?: string;
  children?: ReactNode;
}

/**
 * Visible column guides and a baseline grid, like a design file with the
 * overlays left on. Columns are real 1fr grid tracks, so they stay honest to
 * the container at every width. Fully static surface.
 */
export function EditorialGridBackground({
  columns = 12,
  gutter = 16,
  margin = 24,
  baseline = 8,
  className,
  children,
}: EditorialGridBackgroundProps) {
  return (
    <div
      className={cn(
        "relative isolate overflow-hidden rounded-2xl border border-[var(--pax-border,rgba(18,17,15,0.12))]",
        "bg-[var(--pax-paper,#f6f2ea)] text-[var(--pax-ink,#12110f)]",
        className,
      )}
      data-pax-asset="component-backgrounds-editorial-grid"
    >
      <div
        aria-hidden="true"
        className="pointer-events-none absolute inset-0 opacity-60"
        style={{
          backgroundImage: `repeating-linear-gradient(to bottom, var(--pax-border,rgba(18,17,15,0.12)) 0 1px, transparent 1px ${baseline}px)`,
        }}
      />
      <div
        aria-hidden="true"
        className="pointer-events-none absolute grid"
        style={{
          inset: margin,
          gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
          columnGap: gutter,
          boxShadow: "0 0 0 1px var(--pax-border,rgba(18,17,15,0.12))",
        }}
      >
        {Array.from({ length: columns }, (_, i) => (
          <div
            key={i}
            className="h-full"
            style={{
              background: "color-mix(in srgb, var(--pax-acid,#c8ff00) 9%, transparent)",
              borderLeft: "1px solid var(--pax-border,rgba(18,17,15,0.12))",
              borderRight: "1px solid var(--pax-border,rgba(18,17,15,0.12))",
            }}
          />
        ))}
      </div>
      <div className="relative z-[1]">{children}</div>
    </div>
  );
}