Skip to content

Figma transformer: responsive emission — consume sibling-groups → emit @media #247

Description

@chubes4

Problem

The Figma transformer renders a single fixed-width canvas, not a responsive website. The root wrapper is .figma-root{position:relative;min-width:100%;width:max-content} (fixed canvas width → horizontal scroll on narrow viewports) and there are zero @media queries package-wide. Auto-layout frames map to real flexbox and FILL/HUG sizing is honored, so output is faithful at the design's native width — but it does not reflow.

To date, 35 merged figma PRs are all single-width fidelity/diagnostics work. Responsive emission has never been attempted.

What exists already

Detection of responsive frame sets now lands in ScenegraphFrameInspector (PR landing the cook/figma-selection-responsive branch):

  • deviceHint() — classifies a frame mobile/tablet/desktop by name regex + width thresholds (<700 / 700–1100 / ≥1100).
  • siblingGroupKey() + responsiveSiblings() — groups frames that represent one page at multiple widths.
  • normalizedPageName() / nameSimilarity() — strip desktop/mobile/copy/v2/variant suffixes so siblings match by base name.

This is detection only. device_hint / sibling_group_key / responsive_siblings are consumed by nothing — neither ScenegraphPagePlanner nor StaticHtmlEmitter reads them.

Scope

  1. PagePlanner — collapse a responsive sibling-group into a single page with N breakpoint variants (instead of one page per frame).
  2. StaticHtmlEmitter — diff per-breakpoint styles and emit @media blocks; share the existing flex/FILL/HUG machinery across breakpoints rather than re-deriving layout.
  3. Fluid root — replace width:max-content with a centered max-width container for FILL roots; clear the fixed_root_width_count diagnostic smell.
  4. Per-breakpoint parity — extend the parity contract so each breakpoint is verified against its corresponding source frame. Responsiveness is unfalsifiable while parity is measured at a single viewport.

Acceptance

  • A Figma file with desktop/tablet/mobile frames of the same page produces one HTML page with @media breakpoints that match each source frame.
  • Parity report records a pass/fail per breakpoint against its source frame.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions