Skip to content

Design Guidelines and Styling System (Polaris + Tailwind Plan)

This document defines the rollout plan for using Tailwind CSS with Shopify Polaris in the embedded admin app.

Goal: modern, stylish UI updates without breaking Shopify-native behavior.


  1. Keep Polaris as the base component system.
  2. Use Tailwind for layout, spacing, typography, and utility wrappers.
  3. Improve visual consistency with a reusable styling system.
  4. Gradually reduce brittle global CSS overrides.

  • Polaris owns component behavior/accessibility.
  • Tailwind owns visual rhythm and composition.
  • Prefer incremental migration, not a big-bang rewrite.
  • Preserve embedded Shopify UX patterns.

  • Admin routes under app/routes/app.*.
  • Shared design primitives (cards, page sections, headings, button groups).
  • Form density, spacing, typography, and responsive layout.
  • Replacing Polaris with another UI framework.
  • Rebuilding all existing pages at once.
  • Styling storefront theme extension with this system.

  1. Layer A: Polaris baseline
    • Keep existing Polaris components and App Bridge integration.
  2. Layer B: Tailwind utilities
    • Add utility classes for spacing, layout, and typography.
  3. Layer C: Small semantic utility classes
    • Define reusable app classes (e.g. section wrappers) using @apply.

Create app-level tokens in Tailwind theme that align with Polaris feel:

  • Spacing scale for form/card rhythm.
  • Neutral + brand palette for accents only.
  • Border radius and shadow scale for modern card/button style.
  • Font stack aligned with current brand font direction.

  • Capture current screenshots of key pages:
    • Dashboard, Settings, Appearance, Billing, AI Chats.
  • Define acceptance criteria:
    • No regression in save flows, no layout break in embedded iframe, no accessibility regressions.
  • Install Tailwind and configure scanning for:
    • app/**/*.{js,jsx,ts,tsx}.
  • Add base stylesheet entry for Tailwind.
  • Keep current app/theme-overrides.css active initially.

Create reusable semantic classes (example names):

  • .app-page-shell
  • .app-section
  • .app-section-title
  • .app-section-subtitle
  • .app-form-grid
  • .app-actions-row

Use these in 1-2 routes first (app._index.jsx, app.appearance.jsx).

Apply Tailwind around Polaris form components:

  • Better vertical rhythm (consistent gaps).
  • Cleaner two-column layouts with responsive fallback.
  • More modern section structure and spacing.

Prioritize:

  1. app.settings.jsx
  2. app.appearance.jsx
  3. app.billing.jsx
  • Remove or reduce brittle selectors in app/theme-overrides.css (especially wildcard class selectors) after equivalent Tailwind primitives are in use.
  • Keep only high-value global rules that truly need to be global.
  • Verify all breakpoints in Shopify embedded context.
  • Check keyboard navigation and focus visibility.
  • Validate visual consistency across all major routes.

  1. Dashboard (app._index.jsx)
    • Card grid rhythm, section spacing, quick links grouping.
  2. Appearance (app.appearance.jsx)
    • Form spacing and grouped settings hierarchy.
  3. Settings (app.settings.jsx)
    • Two-column contact layout polish and consistent field spacing.
  4. Billing (app.billing.jsx)
    • Dense content organization, table spacing, action grouping.
  5. AI Chats (app.chat-logs.jsx)
    • Message table readability and collapsible spacing.

  • Faster UI iteration using utilities.
  • Cleaner and more predictable layout control.
  • Better visual consistency between pages.
  • Lower maintenance risk versus heavy global CSS overrides.

  1. Risk: Style conflicts between Polaris and Tailwind.

    • Mitigation: Keep Tailwind mostly on wrappers/layout; avoid fighting Polaris internals directly.
  2. Risk: Inconsistent class usage across routes.

    • Mitigation: Use semantic primitive classes and document examples.
  3. Risk: Regressions in embedded layout.

    • Mitigation: Test each migrated page inside Shopify admin before moving to next phase.

  • Tailwind integrated and active.
  • Core routes migrated to shared styling primitives.
  • Visual style is modern and consistent.
  • No functional regressions in save flows/navigation.
  • app/theme-overrides.css simplified to minimal required global rules.

After approving this plan, implement Phase 1 + Phase 2 first, then migrate Dashboard and Appearance before touching the other routes.


11) Class Naming System (Empty Style Hooks)

Section titled “11) Class Naming System (Empty Style Hooks)”

Use the class names below as stable hooks so you can style each UI element later (font size, border, text color, background color, radius, spacing, shadows).

These hooks are intended for app/theme-overrides.css.

  • .app-page-shell
  • .app-page-header
  • .app-page-title
  • .app-page-subtitle
  • .app-section
  • .app-section-title
  • .app-section-subtitle
  • .app-grid
  • .app-grid-col
  • .app-stack
  • .app-inline
  • .app-actions-row
  • .app-card
  • .app-card-header
  • .app-card-title
  • .app-card-subtitle
  • .app-card-body
  • .app-card-footer
  • .app-form
  • .app-form-grid
  • .app-form-row
  • .app-form-group
  • .app-form-label
  • .app-form-help
  • .app-form-error
  • .app-input
  • .app-textarea
  • .app-select
  • .app-checkbox
  • .app-btn
  • .app-btn-primary
  • .app-btn-secondary
  • .app-btn-ghost
  • .app-btn-danger
  • .app-btn-sm
  • .app-btn-md
  • .app-btn-lg
  • .app-table-wrap
  • .app-table
  • .app-table-head
  • .app-table-row
  • .app-table-cell
  • .app-badge
  • .app-empty-state
  • .app-tone-info
  • .app-tone-success
  • .app-tone-warning
  • .app-tone-danger
  • .app-tone-muted
  • .app-font-xs, .app-font-sm, .app-font-md, .app-font-lg, .app-font-xl
  • .app-text-primary, .app-text-secondary, .app-text-muted, .app-text-inverse
  • .app-bg-primary, .app-bg-secondary, .app-bg-muted, .app-bg-surface
  • .app-border, .app-border-strong, .app-border-muted
  • .app-radius-sm, .app-radius-md, .app-radius-lg, .app-radius-xl

Add and maintain the hook implementations in:

  • app/theme-overrides.css

Recommended approach:

  1. Keep these class hooks mostly on wrappers around Polaris components.
  2. Avoid deep Polaris internal selectors unless absolutely necessary.
  3. Move repeated one-off styles into these shared hooks.