/*
 * The size chooser and the preview modal.
 *
 * The personalization's own controls are not styled here: each vendor's runtime
 * draws them from its own stylesheet (inc/vendor.php). What is left is the markup
 * this theme prints — the size pills, the preview modal, and the rule that hides a
 * vendor's own dialog while a render is taken from it.
 */

/* ---------- personalizer ---------- */

.gs-personalizer {
  /* Measured on the reference's own personalizer. */
  --gs-ink: rgb(0, 0, 0);
}

.gs-personalizer * { box-sizing: border-box; }

/* A refusal the personalizer raises is a field-level error, not WooCommerce's
   page-level notice bar: one red line at the form's own size, with a 16px mark,
   no ground and no border (1.0.139). The rule and its reason live in
   `DESIGN.md` §Notice and `NOTICES.md`; the cart's and checkout's notices keep
   the bar in `woo.css`. */
.gs-inline-error {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  max-width: 100%;
  margin: 0 0 12px;
  color: rgb(var(--danger));
  font-size: 14px;
  font-weight: 500;
  line-height: 1.5;
}
.gs-inline-error__icon {
  display: block;
  flex: 0 0 16px;
  width: 16px;
  height: 16px;
  margin-top: 1px;
}
.gs-inline-error__text { min-width: 0; }
.gs-inline-error__text p { margin: 0; overflow-wrap: anywhere; }
.gs-inline-error__text p + p { margin-top: 4px; }

/* The size chooser on a sized product: the reference's variant pills — the same
   measured family as the reference's own selector (2026-10-14): its
   `.form__label` for the legend, its `variant-label` for the options. */
.gs-size { border: 0; margin: 0 0 14px; padding: 0; }
.gs-size legend { margin: 0 0 8px; padding: 0 2px 0 0; font-size: 1.7rem; font-weight: 700; letter-spacing: .48px; line-height: 1.4167; color: var(--muted); }
.gs-size-option { position: relative; display: inline-flex; align-items: center; height: 44px; margin: 0 12px 8px 0; padding: 0 24px; border: 1px solid var(--muted); border-radius: 4px; background: rgb(var(--color-background)); color: rgb(var(--color-foreground)); font-size: 1.5rem; font-weight: 400; letter-spacing: .1rem; cursor: pointer; }
.gs-size-option input { position: absolute; opacity: 0; pointer-events: none; }
.gs-size-option:has(input:checked) { background: rgb(var(--color-foreground)); color: rgb(var(--color-background)); }
.gs-size-option:has(input:focus-visible) { outline: 2px solid rgb(var(--color-foreground)); outline-offset: 2px; }

/* The preview modal. */
.gs-personalizer .gs-modal {
  position: fixed; inset: 0; background: rgba(0, 0, 0, .55);
  display: flex; align-items: center; justify-content: center; padding: 24px; z-index: 200;
}
.gs-personalizer .gs-modal[hidden] { display: none; }
.gs-personalizer .gs-modal img {
  display: block; width: 100%; height: auto; max-width: 620px;
  background: rgb(var(--color-background)); border-radius: var(--radius-plate); letter-spacing: normal;
}
/* The preview overlay's close key. Kept circular: it sits on a
   rgba(0,0,0,.55) scrim, where a circular dismiss is the convention and a 4px
   corner would read as a stray box. This is the second written exception to the
   button scale — see the list in style.css. */
.gs-personalizer .gs-modal-close {
  position: absolute; top: 18px; right: 18px;
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 50%;
  border: 0; background: rgb(var(--color-background)); color: var(--gs-ink); font-size: 22px; line-height: 1; cursor: pointer;
}

/* While the shop takes a render off a vendor's own preview dialog, that dialog
   must not be seen: the shop opens its own modal instead, and two modals racing
   would show the vendor's first. Both the vendor's scrim and its panel are body
   children marked data-state="open" and nothing else on the page is, so the
   capture window is one class on <html> (assets/js/vendor-customix.js). */
html.gs-capturing > body > [data-state="open"] { visibility: hidden !important; }

/* Two of the Teeinblue runtime's own blocks have no config switch: it draws the product's
   price row and a Material/Size picker because on its own storefront it *is* the product
   page. This shop draws both — its own price with the compare-at and the saving chip, and
   its own size pills — so the runtime's copies are taken out here rather than shown twice
   (the rest of its storefront chrome is switched off in `gs_teeinblue_config_overrides()`,
   inc/vendor.php). Its option form and its fields stay; its own add-to-cart row goes, because
   the shop's own buy row is the one the shopper uses (the click on it is taken either way).
   The runtime builds its form inside the shop's own `form.cart`, under `#tee-artwork-form`,
   so the path is the shop's form and the runtime's wrapper — measured on the dev site. */
form.cart > #tee-artwork-form > .tee-product-price,
form.cart > #tee-artwork-form > .tee-variants,
form.cart > #tee-artwork-form .tee-form-atc-wrapper { display: none !important; }

/* The runtime's stylesheet hides **every sibling that follows its own form wrapper** —
   `.teeinblue-enabled:not(.teeinblue-platform-product-enabled) .tee-customization-wrapper ~ *`
   — because on its storefront whatever follows is the theme's duplicate of its own controls.
   Here the sibling after it is the shop's preview/add-to-cart row, which the shopper needs
   (measured: with the runtime's rule in force the product page had **no buy row at all**).
   Taken back with a heavier selector rather than by moving our markup, because the runtime
   inserts its own wrapper as the form's first child whatever the markup order. The size
   fieldset is the one element that *is* moved instead — `main.js` re-prepends it above the
   runtime's block, which is where the shopper's first decision belongs — so it is not here. */
body.teeinblue-enabled form.cart .tee-customization-wrapper ~ .personalizer-actions { display: flex !important; }
