import { DEVICES, type DeviceName } from '../ViewMode'; /** * The site's horizontal gutter: how far the content sits from the edge of the window. * * ── One setting, not one per band ── * * The header row, the content column and the footer's inner block all share the site's measure, and all * three want the same space at the edges. That is what makes this a GUTTER rather than three paddings * that happen to agree — and setting it once is the only arrangement in which they cannot drift. * * A section's own padding still exists and composes on top of this. This is the floor everything starts * from; `PaddingTab` is the per-band control, and it stays for the pages. * * ── The device toggle picks the width ── * * Same as everywhere else in this panel: Mobile writes `base`, Tablet `md`, Desktop `lg`, and they * cascade — so one gutter at every width is one choice rather than three. */ export type Gutter = Partial>; const BREAKPOINT: Record = { mobile: 'base', tablet: 'md', desktop: 'lg' }; /** What this breakpoint falls back to: the nearest smaller one that has a value. */ const inherited = (gutter: Gutter, breakpoint: 'base' | 'md' | 'lg'): number | null => { const below = { base: [], md: ['base'], lg: ['md', 'base'] } as const; for (const smaller of below[breakpoint]) { const step = gutter[smaller]; if (typeof step === 'number') return step; } return null; }; export const GutterTab = ({ gutter, device, steps, onChange, }: { gutter: Gutter; device: DeviceName; steps: number[]; onChange: (gutter: Gutter) => void; }) => { const breakpoint = BREAKPOINT[device]; const own = gutter[breakpoint]; const from = inherited(gutter, breakpoint); const set = (value: string) => { const next = { ...gutter }; // Removed rather than stored as null: an absence is what "inherit" means, and storing a marker for // it would leave two ways to say the same thing. if (value === '') delete next[breakpoint]; else next[breakpoint] = Number(value); onChange(next); }; return (

Horizontal padding

The space between the content and the edge of the window {/* Which width is being set, said here because the device buttons are at the top of the panel and the effect of pressing one is not obvious from down here. */} editing {DEVICES[device].label.toLowerCase()} — {breakpoint}
Applies to the header, the page and the footer
); };