Localized Precision: Orchestrating Micro Alignment

While CSS Grid governs the "Macro" skeleton of the page, the Espalier system utilizes Flexbox for the surgical, one-dimensional alignment of items within components. We treat Flexbox as a "Content-Out" engine: a tool where the inherent size of the content—such as the label of a button or the width of an icon—informs its own spatial distribution.

By limiting Flexbox to localized, component-level challenges, we maintain a defensible architecture that prioritizes structural predictability without sacrificing internal flexibility.

The Division of Labor: Why Micro?

From a Startup Strategist’s perspective, over-using Flexbox for page-level layout creates technical debt. Flexbox is fundamentally linear; when forced to manage two dimensions, it requires deeply nested wrappers that obfuscate the DOM.

In Espalier, Flexbox is reserved for:

  1. Linear Components: Toolbars, navigation bars, and breadcrumbs.
  2. Alignment-Heavy Units: Centering content within a card or aligning labels with input fields.
  3. Dynamic Wrapping: Tag lists or carousels where the number of items is unknown.

Intrinsic Responsiveness: The Wrap-and-Grow Pattern

One of the "killer features" of Flexbox in our system is its ability to adapt to available space without media queries. By pairing flex-wrap with flex-grow, we enable components to stack and shift naturally.

/* The 'Every Layout' Stack pattern */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-size-small);
  align-items: center;
}

.toolbar-primary-action {
  /* Grow to fill space on mobile, but base size is content-driven */
  flex: 1 0 auto;
}

This pattern ensures that a search bar and a button group can sit side-by-side on a desktop but stack perfectly on a mobile device, purely through the interaction of content-width and container constraints.

Alignment Consistency: Main vs. Cross Axes

To ensure visual harmony, we utilize standardized alignment roles across all components:

Engine Role Property Strategic Intent
Distribution justify-content Manages the spacing between items (e.g., space-between for headers).
Cross-Alignment align-items Ensures vertical consistency (e.g., baseline for text/icon pairings).
Gap Management gap Utilizes our fluid spacing tokens to maintain vertical rhythm.

Challenge the Assumption: "Grid for Everything"

While Espalier is a "Grid-First" system, a common mistake is attempting to force one-dimensional lists into a Grid. We challenge this. Using Grid for a simple row of buttons adds unnecessary overhead and makes "intrinsic" wrapping significantly harder to maintain.

For a defensible architecture, use Grid for the Scaffolding and Flexbox for the Furniture.

Strategic Implementation in Lit

We utilize Lit’s directive system to apply these micro-alignment rules reactively, ensuring that components like esp-button-group remain flexible for the consumer.

render() {
  const alignmentStyles = {
    justifyContent: this.centered? 'center' : 'flex-start',
    flexDirection: this.vertical? 'column' : 'row'
  };

  return html`
    <div class="micro-trellis" style=${styleMap(alignmentStyles)}>
      <slot></slot>
    </div>
  `;
}

Where does this show?