* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background-color: #f6f6f7;
}

#root {
  min-height: 100vh;
}

/* Custom styles for better app appearance */
.Polaris-Page {
  background-color: #f6f6f7;
}

.Polaris-Card {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

/*
 * The option-set editor: a step-picker rail, the selected step's own form, and
 * the live preview. A plain grid rather than Polaris's `<Layout>`, which only
 * really has a two-column recipe (`variant="oneThird"`) and has nothing built
 * for a third, narrower rail.
 *
 * A CSS grid's row stretches to its tallest column by default (unlike
 * `<Layout>`, which top-aligns each one to its own content height), so the
 * sticky rail and preview simply get the full travel of the taller middle
 * column for free — no stretch override to maintain here.
 */
.kz-editor-grid {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr) 340px;
  gap: var(--p-space-400, 16px);
  align-items: start;
  margin-bottom: var(--p-space-400, 16px);
}

[data-kz-nav],
[data-kz-preview] {
  position: sticky;
  top: var(--p-space-400, 16px);
}

/* Below this the three columns stack full width, in source order (rail, then
   form, then preview) — and neither side column can sensibly stay pinned above
   content it no longer sits beside. */
@media (max-width: 48em) {
  .kz-editor-grid {
    grid-template-columns: 1fr;
  }

  [data-kz-nav],
  [data-kz-preview] {
    position: static;
  }
}

/* Loading animation */
@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.loading-spinner {
  animation: spin 1s linear infinite;
}

/* Widen the quote detail modal.
   Polaris caps a `size="large"` modal at 61.25rem (980px), which is narrower than
   this one needs: it puts up to four preview composites beside a details column, and
   at 980px the pictures shrink below the size a merchant can price a job from.
   Scoped with :has() to the quote modal alone — a width that suits a two-column
   layout full of images would be wrong for a confirm dialog, and Polaris gives the
   Modal no className to target instead. `min()` keeps it inside a narrow viewport,
   where the cap is the screen rather than the design. */
.Polaris-Modal-Dialog__Modal:has([data-quote-detail]) {
  max-width: min(78rem, calc(100vw - 3rem));
}
