/* Zestia public theme contract
   Loaded after every legacy/customer stylesheet.  Its job is deliberately
   narrow: public surfaces must consume the selected theme tokens instead of
   falling back to an accidental white canvas.  Light palettes remain light;
   dark palettes remain dark. */

html {
  color: var(--zsf-text, var(--text, #f7f4ef));
  background: var(--zsf-page-bg-deep, var(--bg-deep, #050505));
}

body.app-body.storefront-shell {
  color: var(--zsf-text, var(--text, #f7f4ef));
  background-color: var(--zsf-page-bg, var(--bg, #050505));
  background-image:
    radial-gradient(circle at 6% 10%, color-mix(in srgb, var(--brand, #c93a24) 10%, transparent), transparent 34rem),
    radial-gradient(circle at 94% 22%, color-mix(in srgb, var(--accent, #d8aa58) 7%, transparent), transparent 32rem);
}

body.app-body.storefront-shell :where(
  .storefront-surface,
  .content,
  .auth-shell,
  .account-shell,
  .cart-layout,
  .product-page,
  .local-landing,
  .legal-shell,
  .sitemap-shell
) {
  color: var(--zsf-text, var(--text, #f7f4ef));
}

/* Shared panels used by the 25 public surfaces in the storefront contract. */
body.app-body.storefront-shell :where(
  .card,
  .auth-card,
  .auth-visual,
  .account-section,
  .address-card,
  .order-card,
  .order-head-card,
  .cart-panel,
  .checkout-panel,
  .checkout-final-card,
  .checkout-totals-card,
  .cart-complete-order__card,
  .menu-header,
  .storefront-catalog-tools,
  .menu-section,
  .main-menu,
  .mini-cart,
  .product-page__summary,
  .product-page__details,
  .product-customizer,
  .fulfillment-panel,
  .local-landing__hero,
  .local-landing__section,
  .legal-card,
  .sitemap-card,
  .empty-state
) {
  color: var(--zsf-text, var(--text, #f7f4ef));
  background-color: var(--zsf-surface, var(--surface, #121212));
  border-color: var(--zsf-line, var(--border, #2a2a2a));
}

body.app-body.storefront-shell :where(
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
  select,
  textarea
) {
  color: var(--zsf-text, var(--text, #f7f4ef));
  background-color: var(--zsf-surface-raised, var(--surface, #121212));
  border-color: var(--zsf-line, var(--border, #2a2a2a));
  -webkit-text-fill-color: currentColor;
}

body.app-body.storefront-shell :where(input, textarea)::placeholder {
  color: var(--zsf-text-muted, var(--muted, #b1b1b1));
  opacity: .88;
}

body.app-body.storefront-shell :where(select option) {
  color: var(--zsf-text, var(--text, #f7f4ef));
  background: var(--zsf-surface, var(--surface, #121212));
}

body.app-body.storefront-shell :where(
  .site-header,
  .site-footer,
  .customer-cart-drawer__panel,
  .customer-mobile-dock
) {
  color: var(--zsf-text, var(--text, #f7f4ef));
  border-color: var(--zsf-line, var(--border, #2a2a2a));
}

body.app-body.storefront-shell :where(
  .muted,
  .detail-label,
  .auth-card__switch,
  .account-section__head p,
  .legal-card p,
  .sitemap-card p
) {
  color: var(--zsf-text-muted, var(--muted, #b1b1b1));
}

/* White is still valid when it is an intentional high-contrast action.  The
   surface behind it, however, always comes from the selected palette. */
body.app-body.storefront-shell .store-context-bar__cta,
body.app-body.storefront-shell .store-context-choice.is-active,
body.app-body.storefront-shell .customer-mobile-dock a[aria-current="page"],
body.app-body.storefront-shell .customer-mobile-dock__cart strong {
  color: var(--zsf-page-bg-deep, var(--bg-deep, #080808));
  background: var(--zsf-text, var(--text, #ffffff));
  -webkit-text-fill-color: currentColor;
}

body.app-body.storefront-shell :where(a, button, input, select, textarea):focus-visible {
  outline-color: var(--zsf-focus, var(--accent, #d8aa58));
}

/* The mobile dock is fixed above the safe area. Reserve that complete footprint
   in the final shell layer so every structural pack, including account/auth,
   can scroll its last content and footer fully above the dock. */
@media (max-width: 820px) {
  body.app-body.storefront-shell {
    --zsf-mobile-dock-reserved-space: calc(
      112px + env(safe-area-inset-bottom, 0px)
    );
    padding-bottom: var(--zsf-mobile-dock-reserved-space) !important;
    scroll-padding-bottom: var(--zsf-mobile-dock-reserved-space);
  }

  body.app-body.storefront-shell :where(.content, .site-footer) {
    padding-bottom: var(--zsf-mobile-dock-reserved-space) !important;
    scroll-padding-bottom: var(--zsf-mobile-dock-reserved-space);
  }
}

@media (prefers-reduced-motion: reduce) {
  body.app-body.storefront-shell {
    background-attachment: initial;
  }
}

/* Thermal media has one photographic layer only. The canvas contributes
   frost/condensation, never a second blurred copy of the product. */
body.app-body.storefront-shell.theme-pizza_solas
  :is(.product-media, .product-page__media).zestia-thermal-media::before {
  content: none !important;
  background-image: none !important;
  filter: none !important;
  transform: none !important;
}

/* The image and its thermal mask must use the same fit and the same box at
   every breakpoint. A padding mismatch makes the frost look like a duplicate
   can, so thermal geometry is centralized in this final contract layer. */
body.app-body.storefront-shell
  .zestia-thermal-media[data-zestia-thermal-fit="cover"]
  > :where(.product-image, .product-page__image) {
  object-fit: cover !important;
  object-position: center !important;
  padding: 0 !important;
}

body.app-body.storefront-shell
  .zestia-thermal-media[data-zestia-thermal-fit="contain"]
  > :where(.product-image, .product-page__image) {
  object-fit: contain !important;
  object-position: center !important;
  padding: 0 !important;
}

body.app-body.storefront-shell
  .zestia-thermal-media[data-zestia-thermal-fit]
  > :where(.product-image, .product-page__image) {
  display: block !important;
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
}
