Why section/column need a text_align option separate from content alignment (and why special_heading keeps its master alignment)
The question: When a converted <div class="text-center max-w-2xl mx-auto"><h2>…</h2><p>…</p></div>
comes out left-aligned, where does alignment belong? Should we add text_align to the column/section —
and if we do, is special_heading's master Alignment option now redundant and safe to remove?
Context
The deterministic Site Converter decomposes a source band into native shortcodes. A common source
pattern centers a heading intro on an intermediate wrapper — text-center max-w-2xl mx-auto — that
holds the <h2> and its subtitle <p>. The heading recognizer captured the h2's own classes
(text-3xl md:text-4xl font-bold), which carry no alignment, so the wrapper's text-center was dropped
and the heading rendered left. special_heading already has an alignment option and the mapper already
knew how to translate text-center/max-w-*/mx-auto — the classes just never reached it.
That surfaced the real question about layering. The column shortcode has a content alignment
(content_h/content_v) option, but that is flexbox cross/main-axis alignment (align-items /
justify-content) — it positions block children, it does not set text-align. text-align is a
separate, inherited CSS property. So a text-center wrapper holding mixed children (heading +
paragraph + buttons + stats) that decompose into sibling shortcodes could not be faithfully centered by
any existing option: special_heading can only center itself, and the column's content-alignment is the
wrong axis.
Options considered
- Only fix the heading (read the wrapper's classes into
special_heading's alignment). Fixes the reported case, but a centered wrapper with mixed content still can't center its non-heading siblings. - Add container-level
text_alignand REMOVEspecial_heading's master alignment (treat the container as the single source of truth). Tempting — feels less redundant — but the master alignment is the only way to center one heading inside an otherwise-left column without moving its siblings, and removing a shipped option breaks stored values, presets, and Theme-Builder templates (needs a migration) for no real gain. - Add container-level
text_alignAND keep all the heading alignments, defaulting every level to Inherit so they cascade. (Chosen.)
Decision
- Add a
text_alignoption tosectionandcolumn, reusing the exactspecial_headingalignment image-picker (Inherit / left / center / right swatches) for a consistent UI. Default''= Inherit (emits nothing) → purely additive, no migration, existing presets stay valid. - Keep
special_heading's master Alignment and the per-element (Overline/Title/Subtitle) alignments. - Fix the heading wrapper-inheritance in the converter so an intermediate
text-center/max-w-* mx-autowrapper's alignment + measure cascade onto the heading it flattens. - The converter maps a source wrapper's
text-*to the nearest container'stext_alignand leaves the heading master on Inherit, so headings cascade from the container.
Alignment is therefore a four-level Inherit cascade, each level overriding the one above:
Section text_align → Column text_align → Heading master Alignment → Overline/Title/Subtitle
Why
text_alignand content-alignment are different axes. Flexboxalign-items/justify-contentcannot express inherited text centering; a mixed-content centered wrapper genuinely needs a container-leveltext_align. It's also a legitimately useful native option beyond the converter.- The master Alignment is an override, not a redundancy. Container
text_aligncenters everything in the container; the heading master lets one heading differ from its container without touching siblings. Because it defaults to Inherit andtext-aligninherits, a heading in a centered column auto-centers with the master untouched — and the master is still there when someone wants the override. - Removing a shipped option is a breaking change (stored values, Preset Library, Theme-Builder templates, a schema migration) for no benefit, since the option isn't actually redundant.
- Consistency: the section/column picker reuses the special_heading swatches, so the whole alignment system looks and behaves the same everywhere.
A related cleanup shipped alongside: the converter no longer dumps inert Tailwind utility classes
(text-3xl, font-bold, mangled md:text-4xl / text-foreground/70) onto native heading parts — their
visual intent already rides the per-node computed base — while semantic accent utilities (text-primary)
and genuinely custom classes are preserved.
