/* Kit Builder — storefront styles (Direction A: refined, theme-friendly)
 *
 * Tokens inherit from theme CSS variables where available (Dawn: --color-foreground,
 * --color-background, --inputs-radius, --buttons-radius, --color-button,
 * --color-button-text, --color-shadow, --popup-corner-radius). Falls back to a
 * neutral monochrome palette so non-Dawn themes still look clean.
 */

/* Scope the tokens to our three roots: the panel itself and the two
   portalled overlays (drawer + quickview live under document.body, so
   they're outside .rpkb-builder's cascade). */
.rpkb-builder,
.rpkb-drawer,
.rpkb-quickview {
  --kb-fg: var(--color-foreground, 17, 17, 17);
  --kb-bg: var(--color-background, 255, 255, 255);
  --kb-shadow: var(--color-shadow, 0, 0, 0);
  /* Design tokens for card containment — values from the Kit Builder
     design bundle (Direction A). Solid neutrals so cards read the same
     against any theme background. Themes that need to override can
     point these at their own tokens. */
  /* Slightly darker than design's #e4e4e4 — Concept and other near-white
     themes wash out a 1px #e4e4e4 against their product-page bg. #d6d6d6
     reads as a clear card edge without becoming heavy. */
  --kb-line: 214, 214, 214;  /* #d6d6d6 — card borders, dividers */
  --kb-soft: 241, 241, 241;  /* #f1f1f1 — image bg, soft surfaces */
  /* Card radius — pick up the theme's card-radius token if it exposes
     one, otherwise fall back to 10px from the design. Merchants can
     still override via the "Card corners" admin setting below. */
  --kb-radius: var(--rounded-card, 10px);
  --kb-radius-btn: var(--buttons-radius, var(--rounded-button, 6px));
  --kb-radius-popup: var(--popup-corner-radius, var(--rounded-block, 12px));
}

/* ══ Merchant style settings (from the Style editor page) ══════════════ */

/* Card corners */
.rpkb-builder[data-kb-radius="none"] { --kb-radius: 0; }
.rpkb-builder[data-kb-radius="small"] { --kb-radius: 4px; }
.rpkb-builder[data-kb-radius="medium"] { --kb-radius: 10px; }
.rpkb-builder[data-kb-radius="large"] { --kb-radius: 16px; }

/* Density — compact reduces vertical padding everywhere */
.rpkb-builder[data-kb-density="compact"] .rpkb-component__info { padding: 8px 10px 10px; }
.rpkb-builder[data-kb-density="compact"] .rpkb-component__picker { padding: 8px 10px 10px; }
.rpkb-builder[data-kb-density="compact"] .rpkb-component__modal-trigger { padding: 4px 10px 8px; }
.rpkb-builder[data-kb-density="compact"] .rpkb-component__title { font-size: 13px; }
.rpkb-builder[data-kb-density="compact"] .rpkb-component__price { font-size: 13px; }
.rpkb-builder[data-kb-density="compact"] .rpkb-builder__group { margin-bottom: 20px; }

/* Grid columns — default 2, optional 3 on desktop */
.rpkb-builder[data-kb-columns="3"] .rpkb-builder__group-items--grid {
  grid-template-columns: repeat(3, 1fr);
}
/* Mobile always collapses to 2 */
@media screen and (max-width: 749px) {
  .rpkb-builder[data-kb-columns="3"] .rpkb-builder__group-items--grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Image aspect (grid only — list keeps its 76px square thumb) */
.rpkb-builder[data-kb-image-aspect="4:3"] .rpkb-builder__group-items--grid .rpkb-component__image {
  aspect-ratio: 4 / 3;
}
.rpkb-builder[data-kb-image-aspect="3:4"] .rpkb-builder__group-items--grid .rpkb-component__image {
  aspect-ratio: 3 / 4;
}

/* Selected state emphasis */
.rpkb-builder[data-kb-selected-style="clear"] .rpkb-component--selected,
.rpkb-builder[data-kb-selected-style="clear"] .rpkb-component.rpkb-component--selected {
  border-color: rgb(var(--kb-fg));
  border-width: 1px;
  box-shadow: none;
}
.rpkb-builder[data-kb-selected-style="bold"] .rpkb-component--selected,
.rpkb-builder[data-kb-selected-style="bold"] .rpkb-component.rpkb-component--selected {
  border-color: rgb(var(--kb-fg));
  border-width: 2px;
  box-shadow: 0 4px 18px -8px rgba(var(--kb-fg), 0.22);
}
/* In bold mode the card grows 1px — nudge the body padding to compensate */
.rpkb-builder[data-kb-selected-style="bold"] .rpkb-component--selected .rpkb-component__info {
  padding-top: 11px;
}

/* "Subtle" affordance (default): the dark border alone communicates
   selection on grid cards — hide the on-image checkmark badge. Matches
   the Direction A design at affordance:"subtle". List layout keeps its
   own inline side-mark (mark--side) which is governed elsewhere. */
.rpkb-builder:not([data-kb-selected-style="clear"]):not([data-kb-selected-style="bold"])
  .rpkb-builder__group-items--grid
  .rpkb-component__mark:not(.rpkb-component__mark--side) {
  display: none;
}

/* Toggle flags */
.rpkb-builder[data-kb-no-tags] .rpkb-component__badges { display: none; }
.rpkb-builder[data-kb-no-details] .rpkb-component__details { display: none; }

/* ══ Theme preset: Concept ════════════════════════════════════════════
   Reserved for Concept-theme-specific tweaks. The merchant explicitly
   opts in via the block's "Theme preset" select; the wrapper gains
   data-kb-theme="concept" and any rules below take effect.

   Currently this is a no-op visually — our default rendering matches
   the Direction A design (monochrome, subtle, refined) the user signed
   off on, so Concept-preset users get the same look as everyone else.
   The hook stays so future Concept-specific refinements (e.g. picking
   up Concept-only design tokens) can land without re-plumbing the
   schema or render branch. */

/* End of Concept preset block. */


/* Border thickness (0 / 1 / 2 px) */
.rpkb-builder[data-kb-border="0"] .rpkb-component { border-width: 0; }
.rpkb-builder[data-kb-border="2"] .rpkb-component { border-width: 2px; }
/* With no border we lean on the card tint to delineate shape */
.rpkb-builder[data-kb-border="0"] .rpkb-component {
  background: rgba(var(--kb-fg), 0.04);
}

/* Card background fill */
.rpkb-builder[data-kb-bg="soft"] .rpkb-component {
  background: rgba(var(--kb-fg), 0.04);
}

.rpkb-builder {
  font-family: inherit;
  color: rgb(var(--kb-fg));
  -webkit-font-smoothing: antialiased;
  margin: 1.5rem 0;
}

.rpkb-builder__heading,
.rpkb-builder__subtext { display: none; }

/* ── Group ────────────────────────────────────────────────────────────── */
.rpkb-builder__group { margin-bottom: 32px; }
.rpkb-builder__group:last-child { margin-bottom: 16px; }

.rpkb-builder__group-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.rpkb-builder__group-name {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.2;
  color: rgb(var(--kb-fg));
}
.rpkb-builder__group-meta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.rpkb-builder__group-ok {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: rgb(var(--kb-fg));
  color: rgb(var(--kb-bg));
  flex-shrink: 0;
}
.rpkb-builder__group-ok svg { display: block; }
.rpkb-builder__group-mode {
  font-size: 12px;
  color: rgba(var(--kb-fg), 0.55);
  font-style: italic;
}

/* ── Layout wrappers ─────────────────────────────────────────────────── */
.rpkb-builder__group-items { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.rpkb-builder__group-items--grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.rpkb-builder__group-items--list { display: flex; flex-direction: column; gap: 8px; }

/* ── Card (shared) ───────────────────────────────────────────────────── */
.rpkb-component {
  position: relative;
  border: 1px solid rgb(var(--kb-line));
  border-radius: var(--kb-radius);
  background: rgb(var(--kb-bg));
  /* Subtle elevation so the card edge reads even on themes whose
     product-page bg is close to white (Concept etc.). */
  box-shadow: 0 1px 2px rgba(var(--kb-shadow), 0.04);
  cursor: pointer;
  overflow: hidden;
  transition: border-color 0.15s, box-shadow 0.15s;
  display: flex;
  flex-direction: column;
}
.rpkb-component:hover {
  border-color: rgba(var(--kb-fg), 0.35);
  box-shadow: 0 2px 8px rgba(var(--kb-shadow), 0.06);
}
.rpkb-component--selected,
.rpkb-component.rpkb-component--selected {
  /* Subtle affordance: 70% opacity foreground, no inset shadow.
     The darkened border is the only selection cue — no checkmark. */
  border-color: rgba(var(--kb-fg), 0.7);
}
.rpkb-component--selected:hover,
.rpkb-component.rpkb-component--selected:hover {
  border-color: rgba(var(--kb-fg), 0.7);
}
.rpkb-component:focus-visible { outline: 2px solid rgb(var(--kb-fg)); outline-offset: 2px; }

/* visually hidden selection inputs. Concept theme's
   `input[type=checkbox]:not(.switch)` rule wins on specificity (0,2,1
   vs our 0,1,0) and forces `flex: 0 0 auto; width: 20px` on the input —
   which then takes up a 20px row at the top of our flex card. We need
   !important on the layout properties to neutralise that, and
   appearance: none so themes can't paint a native checkbox over the
   1px clipped square. */
.rpkb-component__select {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  flex: 0 0 auto !important;
  appearance: none !important;
  -webkit-appearance: none !important;
  opacity: 0 !important;
  pointer-events: none !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  background: transparent !important;
}

/* Image + checkmark pill */
.rpkb-component__image {
  position: relative;
  aspect-ratio: 1;
  overflow: hidden;
  background: rgb(var(--kb-soft));
}
.rpkb-component__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.3s ease;
}
.rpkb-component:hover .rpkb-component__image img { transform: scale(1.03); }
.rpkb-component__image-placeholder {
  width: 100%; height: 100%; background: rgba(var(--kb-fg), 0.06);
}

.rpkb-component__mark {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgb(var(--kb-bg));
  border: 1.5px solid rgba(var(--kb-fg), 0.2);
  color: rgb(var(--kb-bg));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, border-color 0.15s, transform 0.2s;
}
.rpkb-component__mark svg { display: block; }
.rpkb-component--selected .rpkb-component__mark {
  background: rgb(var(--kb-fg));
  border-color: rgb(var(--kb-fg));
  color: rgb(var(--kb-bg));
  transform: scale(1.05);
}

/* Body */
.rpkb-component__info {
  padding: 12px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.rpkb-component__title {
  font-size: 14px;
  font-weight: 500;
  color: rgb(var(--kb-fg));
  line-height: 1.3;
}
/* Sold-out component state. The click handler also refuses selection. */
.rpkb-component.rpkb-component--unavailable {
  opacity: 0.55;
  cursor: not-allowed;
}
.rpkb-component.rpkb-component--unavailable .rpkb-component__title,
.rpkb-component.rpkb-component--unavailable .rpkb-component__price,
.rpkb-component.rpkb-component--unavailable .rpkb-component__pricepill {
  text-decoration: line-through;
  color: rgba(var(--kb-fg), 0.55);
}
.rpkb-component.rpkb-component--unavailable:hover {
  border-color: rgba(var(--kb-fg), 0.15);
}
.rpkb-component__soldout {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgb(var(--kb-bg));
  background: rgba(var(--kb-fg), 0.8);
  padding: 2px 8px;
  border-radius: 999px;
  width: fit-content;
}
.rpkb-component__price {
  font-size: 14px;
  font-weight: 600;
  color: rgb(var(--kb-fg));
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.rpkb-component__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 2px;
}
.rpkb-component__badge {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgb(var(--kb-soft));
  color: rgba(var(--kb-fg), 0.65);
}

/* "More details" link */
.rpkb-component__details {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin-top: 4px;
  font-family: inherit;
  font-size: 11.5px;
  color: rgba(var(--kb-fg), 0.6);
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: rgba(var(--kb-fg), 0.2);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color 0.12s, text-decoration-color 0.12s;
  display: inline-block;
  align-self: flex-start;
  line-height: 1.4;
}
.rpkb-component__details:hover {
  color: rgb(var(--kb-fg));
  text-decoration-color: rgb(var(--kb-fg));
}

/* Fallback message (product load failed) */
.rpkb-component__fallback {
  padding: 10px 14px;
  font-size: 12px;
  font-style: italic;
  color: rgba(var(--kb-fg), 0.55);
}

/* ── List layout specifics ──────────────────────────────────────────── */
.rpkb-builder__group-items--list .rpkb-component { flex-direction: row; flex-wrap: wrap; padding: 0; align-items: stretch; }

.rpkb-builder__group-items--list .rpkb-component__image {
  flex: 0 0 76px;
  width: 76px;
  min-height: 76px;
  aspect-ratio: 1;
  align-self: stretch;
  border-right: 1px solid rgba(var(--kb-fg), 0.1);
  border-top-left-radius: var(--kb-radius);
  border-bottom-left-radius: var(--kb-radius);
}
.rpkb-builder__group-items--list .rpkb-component--selected .rpkb-component__image {
  /* When the card gets a dark outer border, drop the internal right-divider
     so there isn't a second line fighting it. */
  border-right-color: transparent;
}
/* In list layout the check moves to the right side (next to the price),
   so hide the image-mark and show the side-mark instead. */
.rpkb-builder__group-items--list .rpkb-component__image .rpkb-component__mark:not(.rpkb-component__mark--side) {
  display: none;
}

.rpkb-builder__group-items--list .rpkb-component__info {
  flex: 1 1 auto;
  min-width: 0;
  padding: 12px 14px;
  justify-content: center;
  gap: 4px;
}
.rpkb-builder__group-items--list .rpkb-component__title { font-size: 14px; }
/* Price lives in .rpkb-component__priceside for list layout (hidden inside info) */
.rpkb-builder__group-items--list .rpkb-component__info .rpkb-component__price { display: none; }

/* Right-side priceside column with check + price pill */
.rpkb-component__priceside {
  display: none; /* grid hides this — only list shows it */
}
.rpkb-builder__group-items--list .rpkb-component__priceside {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  padding: 10px 14px 10px 8px;
  gap: 6px;
  min-width: 0;
  flex-shrink: 0;
  align-self: center;
}
.rpkb-component__pricepill {
  font-size: 14px;
  font-weight: 600;
  color: rgb(var(--kb-fg));
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.rpkb-component__mark--side {
  /* Override the absolute-positioned mark on the image — this one is inline,
     sits above the price pill, borders only (no fill) until selected. */
  position: static;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgb(var(--kb-bg));
  border: 1px solid rgba(var(--kb-fg), 0.3);
  color: transparent;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  flex-shrink: 0;
}
.rpkb-component--selected .rpkb-component__mark--side {
  background: rgb(var(--kb-fg));
  border-color: rgb(var(--kb-fg));
  color: rgb(var(--kb-bg));
}

/* Picker / modal trigger / qty flow onto a full-width row in list */
.rpkb-builder__group-items--list .rpkb-component__picker,
.rpkb-builder__group-items--list .rpkb-component__modal-trigger,
.rpkb-builder__group-items--list .rpkb-component__qty {
  flex: 0 0 100%;
  width: 100%;
  border-top: 1px solid rgba(var(--kb-fg), 0.1);
}

/* ── Inline picker (chips) ───────────────────────────────────────────── */
.rpkb-component__picker {
  border-top: 1px solid rgba(var(--kb-fg), 0.1);
  padding: 12px 14px 14px;
  background: rgba(var(--kb-fg), 0.02);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.rpkb-component--selected .rpkb-component__picker {
  border-top-color: rgb(var(--kb-fg));
}

/* "Includes" list — surfaces the BOM contents under a parent component
   card so the customer can see exactly what they're committing to, with
   a small per-row availability flag. Sold-out rows are dimmed and the
   stock badge flips tone. */
.rpkb-component__includes {
  border-top: 1px solid rgba(var(--kb-fg), 0.1);
  padding: 10px 14px 12px;
  background: rgba(var(--kb-fg), 0.02);
  font-size: 13px;
  line-height: 1.4;
}
.rpkb-component--selected .rpkb-component__includes {
  border-top-color: rgba(var(--kb-fg), 0.18);
}
.rpkb-component__includes-title {
  font-size: 11px;
  font-weight: 600;
  color: rgba(var(--kb-fg), 0.65);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 6px;
}
.rpkb-component__includes-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.rpkb-component__includes-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.rpkb-component__includes-qty {
  font-weight: 600;
  flex-shrink: 0;
}
.rpkb-component__includes-title-text { flex: 0 1 auto; }
.rpkb-component__includes-variant {
  color: rgba(var(--kb-fg), 0.55);
}
.rpkb-component__includes-stock {
  margin-left: auto;
  font-size: 11px;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 999px;
  background: rgba(var(--kb-fg), 0.08);
  color: rgba(var(--kb-fg), 0.7);
}
.rpkb-component__includes-row--soldout {
  color: rgba(var(--kb-fg), 0.45);
}
.rpkb-component__includes-row--soldout .rpkb-component__includes-stock {
  background: rgba(220, 38, 38, 0.12);
  color: rgb(185, 28, 28);
}

.rpkb-component__option { display: flex; flex-direction: column; gap: 7px; }
.rpkb-component__option-label {
  font-size: 12px;
  font-weight: 500;
  color: rgba(var(--kb-fg), 0.7);
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.2;
}
.rpkb-component__option-values { display: flex; flex-wrap: wrap; gap: 5px; }

/* Note: Concept theme aggressively resets `button { border: 0 }` with
   higher specificity than our class-only rule. Use `border` + a
   matching `box-shadow: inset` as a belt-and-braces so the chip outline
   reads even when a theme strips the native border. The shadow takes
   no layout space (it's just a paint), so swapping it in/out for the
   selected state keeps the chip from jumping by a pixel. */
.rpkb-component__option-btn {
  appearance: none;
  font-family: inherit;
  padding: 6px 11px;
  font-size: 12.5px;
  font-weight: 500;
  /* Match the unselected card border. !important is load-bearing on
     Concept (and a few other themes) whose `button { border: 0 }`
     reset has higher specificity than this class rule. */
  border: 1px solid rgb(var(--kb-line)) !important;
  background: rgb(var(--kb-bg));
  color: rgb(var(--kb-fg));
  border-radius: var(--kb-radius-btn);
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s, color 0.12s, box-shadow 0.12s;
  line-height: 1.2;
  min-height: 30px;
  letter-spacing: 0;
  text-transform: none;
}
.rpkb-component__option-btn:hover,
.rpkb-component__option-btn:focus-visible {
  border-color: rgba(var(--kb-fg), 0.4) !important;
  outline: none;
}
.rpkb-component__option-btn.rpkb-component__option-btn--selected,
.rpkb-component__option-btn.rpkb-component__option-btn--selected:hover,
.rpkb-component__option-btn.rpkb-component__option-btn--selected:focus-visible {
  background: rgb(var(--kb-fg));
  border-color: rgb(var(--kb-fg)) !important;
  color: rgb(var(--kb-bg));
}
/* Sold-out option value: strikethrough + dimmed, non-interactive cursor.
   Click is blocked in the JS handler via aria-disabled. */
.rpkb-component__option-btn.rpkb-component__option-btn--unavailable,
.rpkb-component__option-btn.rpkb-component__option-btn--unavailable:hover,
.rpkb-component__option-btn.rpkb-component__option-btn--unavailable:focus-visible {
  color: rgba(var(--kb-fg), 0.4);
  border-color: rgba(var(--kb-fg), 0.1);
  background: transparent;
  text-decoration: line-through;
  cursor: not-allowed;
}

/* ── Modal trigger row (when variantSelection = modal) ──────────────── */
.rpkb-component__modal-trigger {
  border-top: 1px solid rgba(var(--kb-fg), 0.1);
  padding: 0;
  background: rgba(var(--kb-fg), 0.02);
}
.rpkb-component--selected .rpkb-component__modal-trigger {
  border-top-color: rgba(var(--kb-fg), 0.15);
}

/* Variant summary as clickable link (both grid + list modal modes) */
.rpkb-component__choose-options-btn {
  appearance: none;
  font-family: inherit;
  width: 100%;
  padding: 9px 14px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  cursor: pointer;
  font-size: 12.5px;
  color: rgba(var(--kb-fg), 0.85);
  text-align: left;
  line-height: 1.3;
  transition: color 0.12s, background 0.12s;
  min-height: 36px;
  white-space: normal;
}
.rpkb-component__choose-options-btn:hover,
.rpkb-component__choose-options-btn:focus-visible {
  color: rgb(var(--kb-fg));
  background: rgba(var(--kb-fg), 0.04);
  outline: none;
}
.rpkb-component__selection-summary {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex: 1;
  text-decoration: underline;
  text-decoration-color: rgba(var(--kb-fg), 0.25);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  font-size: 12.5px;
  color: inherit;
}
.rpkb-component__choose-options-btn:hover .rpkb-component__selection-summary {
  text-decoration-color: rgb(var(--kb-fg));
}
.rpkb-component__choose-options-btn svg { flex-shrink: 0; opacity: 0.55; }

/* ── Quantity stepper (inline in card or inside drawer) ─────────────── */
.rpkb-component__qty {
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  border-top: 1px solid rgba(var(--kb-fg), 0.1);
  background: rgba(var(--kb-fg), 0.02);
}
.rpkb-component__qty-label {
  font-size: 12px;
  color: rgba(var(--kb-fg), 0.6);
}
.rpkb-component__qty-stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid rgba(var(--kb-fg), 0.2);
  border-radius: var(--kb-radius-btn);
  overflow: hidden;
}
.rpkb-component__qty-btn {
  appearance: none;
  border: 0;
  background: transparent;
  width: 32px;
  height: 32px;
  font-size: 14px;
  cursor: pointer;
  color: rgb(var(--kb-fg));
  font-family: inherit;
}
.rpkb-component__qty-btn:hover { background: rgba(var(--kb-fg), 0.06); }
.rpkb-component__qty-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.rpkb-component__qty-input {
  width: 44px;
  height: 32px;
  border: none;
  border-left: 1px solid rgba(var(--kb-fg), 0.2);
  border-right: 1px solid rgba(var(--kb-fg), 0.2);
  text-align: center;
  font-size: 13px;
  font-weight: 500;
  background: transparent;
  color: rgb(var(--kb-fg));
  font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
}
.rpkb-component__qty-input:focus {
  outline: 2px solid rgba(var(--kb-fg), 0.4);
  outline-offset: -2px;
  background: rgba(var(--kb-fg), 0.03);
}
.rpkb-component__qty-input::-webkit-inner-spin-button,
.rpkb-component__qty-input::-webkit-outer-spin-button { -webkit-appearance: none; }
/* Multiplier hint (e.g. "× 4 = 4 per kit") — shown when quantityMultiplier > 1.
   Pushed to its own line on narrow cards, inline on wider containers. */
.rpkb-component__qty-hint {
  font-size: 11px;
  color: rgba(var(--kb-fg), 0.55);
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ── Kit total + Add-to-cart fallback ───────────────────────────────── */
.rpkb-builder__total {
  margin-top: 16px;
  padding: 14px 0 0;
  border-top: 1px solid rgba(var(--kb-fg), 0.1);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.rpkb-builder__total-label {
  font-size: 14px;
  color: rgba(var(--kb-fg), 0.7);
}
.rpkb-builder__total-price {
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Fallback "Add kit to cart" (only when theme form isn't hooked) */
.rpkb-builder__add-btn { margin-top: 12px; width: 100%; }
.rpkb-builder__add-btn:not(.button) {
  appearance: none;
  height: 46px;
  border: 1px solid rgb(var(--kb-fg));
  background: rgb(var(--kb-bg));
  color: rgb(var(--kb-fg));
  font-size: 14px;
  font-weight: 600;
  border-radius: var(--kb-radius-btn);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  font-family: inherit;
  text-transform: none;
  letter-spacing: 0;
}
.rpkb-builder__add-btn:not(.button):hover {
  background: rgb(var(--kb-fg));
  color: rgb(var(--kb-bg));
}
.rpkb-builder__add-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* ── Error message ─────────────────────────────────────────────────── */
.rpkb-builder__error {
  margin-top: 12px;
  padding: 10px 14px;
  background: rgba(185, 28, 28, 0.06);
  border: 1px solid rgba(185, 28, 28, 0.3);
  border-radius: var(--kb-radius-btn);
  color: #b91c1c;
  font-size: 13px;
}

/* ── Empty state (design mode) ──────────────────────────────────────── */
.rpkb-builder-empty {
  padding: 1.5rem;
  border: 2px dashed rgba(var(--kb-fg), 0.12);
  border-radius: var(--kb-radius);
  text-align: center;
  color: rgba(var(--kb-fg), 0.45);
}

/* ══════════════════════════════════════════════════════════════════════
 * Drawer (modal variant picker)
 * ══════════════════════════════════════════════════════════════════════ */

.rpkb-drawer {
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  /* Clip the off-screen panel — closed drawers stay mounted (so the
     open/close transition can play) and their panel sits at translateX
     /translateY(100%) just outside the viewport. Without overflow:hidden
     this would extend the page's scroll area on some themes. */
  overflow: hidden;
  /* Closed drawers are visually offscreen but still in the layout tree.
     Hide them from assistive tech via aria-hidden (set in JS) and from
     pointer hit-testing via the pointer-events rule above. We avoid
     `display:none`/`visibility:hidden` so the CSS transition has a state
     to animate from when the drawer opens. */
}
.rpkb-drawer--open { pointer-events: auto; }
/* Legacy: some flows may still set [hidden] (e.g. when the drawer DOM is
   garbage-collected before it animates). Keep the rule so it works. */
.rpkb-drawer[hidden] { display: none; }

.rpkb-drawer__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(var(--color-shadow, 0, 0, 0), 0.45);
  opacity: 0;
  transition: opacity 0.32s ease;
}
.rpkb-drawer--open .rpkb-drawer__backdrop { opacity: 1; }

.rpkb-drawer__panel {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  /* Wide enough on desktop to fit the bespoke 2-column body (image
     left + options right). Caps at 92vw so it never overflows the
     viewport on tablet sizes. Mobile collapses to a bottom sheet via
     the media query at the foot of this file. */
  width: min(640px, 92vw);
  background: rgb(var(--color-background, 255, 255, 255));
  color: rgb(var(--color-foreground, 17, 17, 17));
  display: flex;
  flex-direction: column;
  box-shadow: -8px 0 32px rgba(var(--color-shadow, 0, 0, 0), 0.14);
  transform: translateX(100%);
  transition: transform 0.42s cubic-bezier(0.22, 0.7, 0.3, 1);
}
.rpkb-drawer--open .rpkb-drawer__panel { transform: translateX(0); }

.rpkb-drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 22px;
  border-bottom: 1px solid rgba(var(--color-foreground, 17, 17, 17), 0.1);
  flex-shrink: 0;
}
.rpkb-drawer__title {
  margin: 0;
  font-size: 16px;
  line-height: 1.3;
  font-weight: 600;
  color: rgb(var(--color-foreground, 17, 17, 17));
  letter-spacing: 0;
  text-transform: none;
}
.rpkb-drawer__close {
  appearance: none;
  border: 0;
  background: transparent;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  color: rgba(var(--color-foreground, 17, 17, 17), 0.6);
  padding: 4px 8px;
}
.rpkb-drawer__close:hover { color: rgba(var(--color-foreground, 17, 17, 17), 0.9); }

.rpkb-drawer__body {
  flex: 1;
  overflow-y: auto;
  padding: 22px;
}

/* 2-column body layout — bespoke mirrors product image alongside the
   options. Stacks vertically on narrow viewports (see mobile rules
   further down). */
.rpkb-drawer__layout {
  display: flex;
  flex-direction: column;
  gap: 22px;
}
@media screen and (min-width: 640px) {
  .rpkb-drawer__layout {
    flex-direction: row;
    align-items: flex-start;
    gap: 24px;
  }
  .rpkb-drawer__media {
    flex: 0 0 45%;
    position: sticky;
    top: 0;
  }
  .rpkb-drawer__options {
    flex: 1;
    min-width: 0;
  }
}
.rpkb-drawer__media {
  border-radius: var(--kb-radius);
  overflow: hidden;
  background: rgb(var(--kb-soft));
  aspect-ratio: 1;
}
.rpkb-drawer__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.rpkb-drawer__options {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* "View full product details ↗" link — quiet underlined link, with a
   small external-link icon sitting half a px above the baseline. */
.rpkb-drawer__product-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: rgba(var(--color-foreground, 17, 17, 17), 0.6);
  text-decoration: underline;
  text-decoration-color: rgba(var(--color-foreground, 17, 17, 17), 0.2);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  align-self: flex-start;
  transition: color 0.12s, text-decoration-color 0.12s;
}
.rpkb-drawer__product-link:hover {
  color: rgb(var(--color-foreground, 17, 17, 17));
  text-decoration-color: rgb(var(--color-foreground, 17, 17, 17));
}

/* In the drawer, option chips have room to breathe → bigger touch targets */
.rpkb-drawer__body .rpkb-component__picker {
  border-top: 0;
  padding: 0;
  background: transparent;
}
.rpkb-drawer__body .rpkb-component__option-label {
  font-size: 12px;
  font-weight: 600;
  color: rgba(var(--color-foreground, 17, 17, 17), 0.6);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 8px;
}
.rpkb-drawer__body .rpkb-component__option-btn {
  padding: 8px 14px;
  font-size: 13px;
  min-height: 40px;
}
.rpkb-drawer__body .rpkb-component__qty {
  border-top: 0;
  padding: 0;
  background: transparent;
}

.rpkb-drawer__footer {
  padding: 16px 22px;
  border-top: 1px solid rgba(var(--color-foreground, 17, 17, 17), 0.1);
  flex-shrink: 0;
}
.rpkb-drawer__done-btn { width: 100%; }
.rpkb-drawer__done-btn:not(.button) {
  appearance: none;
  width: 100%;
  height: 44px;
  border: 0;
  border-radius: var(--buttons-radius, 6px);
  background: rgb(var(--color-button, 0, 0, 0));
  color: rgb(var(--color-button-text, 255, 255, 255));
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  text-transform: none;
  letter-spacing: 0;
  transition: opacity 0.12s;
}
.rpkb-drawer__done-btn:not(.button):hover,
.rpkb-drawer__done-btn:not(.button):focus-visible {
  opacity: 0.88;
  outline: none;
}

@media screen and (max-width: 749px) {
  .rpkb-drawer__panel {
    right: 0;
    left: 0;
    top: auto;
    bottom: 0;
    width: 100%;
    height: auto;
    max-height: 90vh;
    border-top-left-radius: var(--popup-corner-radius, 16px);
    border-top-right-radius: var(--popup-corner-radius, 16px);
    transform: translateY(100%);
  }
  .rpkb-drawer--open .rpkb-drawer__panel { transform: translateY(0); }
  .rpkb-drawer__body { max-height: calc(90vh - 8rem); }
}

/* ══════════════════════════════════════════════════════════════════════
 * Quickview modal (product detail peek)
 * ══════════════════════════════════════════════════════════════════════ */

.rpkb-quickview {
  position: fixed;
  inset: 0;
  z-index: 10000;
  pointer-events: none;
}
.rpkb-quickview--open { pointer-events: auto; }
.rpkb-quickview[hidden] { display: none; }

.rpkb-quickview__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(var(--color-shadow, 0, 0, 0), 0.5);
  opacity: 0;
  transition: opacity 0.2s;
}
.rpkb-quickview--open .rpkb-quickview__backdrop { opacity: 1; }

.rpkb-quickview__panel {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -48%) scale(0.97);
  width: min(440px, 94vw);
  max-height: 92vh;
  background: rgb(var(--color-background, 255, 255, 255));
  color: rgb(var(--color-foreground, 17, 17, 17));
  border-radius: var(--popup-corner-radius, 12px);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 60px rgba(var(--color-shadow, 0, 0, 0), 0.28);
  opacity: 0;
  transition: opacity 0.22s, transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.rpkb-quickview--open .rpkb-quickview__panel {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.rpkb-quickview__close {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.85);
  border: 0;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #1a1a1a;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.rpkb-quickview__close:hover { background: #fff; }

.rpkb-quickview__media {
  aspect-ratio: 4 / 3;
  background: rgba(var(--color-foreground, 17, 17, 17), 0.04);
  overflow: hidden;
  flex-shrink: 0;
}
.rpkb-quickview__media img { width: 100%; height: 100%; object-fit: cover; display: block; }

.rpkb-quickview__body {
  padding: 20px 22px 22px;
  overflow-y: auto;
  flex: 1;
}
.rpkb-quickview__eyebrow {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(var(--color-foreground, 17, 17, 17), 0.5);
  margin-bottom: 6px;
}
.rpkb-quickview__title {
  font-size: 22px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 0 0 4px;
  color: rgb(var(--color-foreground, 17, 17, 17));
}
.rpkb-quickview__price {
  font-size: 15px;
  font-weight: 600;
  margin-bottom: 14px;
  font-variant-numeric: tabular-nums;
}
.rpkb-quickview__desc {
  font-size: 13.5px;
  line-height: 1.55;
  color: rgba(var(--color-foreground, 17, 17, 17), 0.75);
  margin: 0 0 18px;
}
.rpkb-quickview__actions { display: flex; gap: 10px; }
/* Quickview "Add to kit" CTA. Use --kb-fg / --kb-bg explicitly rather
   than --color-button / --color-button-text — some themes (Concept
   variants) resolve --color-button-text to a dark value which produces
   dark text on the dark button. !important on color guards against
   theme button-text overrides. */
.rpkb-quickview__add {
  flex: 1;
  appearance: none;
  font-family: inherit;
  height: 44px;
  border: 0;
  border-radius: var(--buttons-radius, 6px);
  background: rgb(var(--kb-fg));
  color: rgb(var(--kb-bg)) !important;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.12s;
  text-transform: none;
  letter-spacing: 0;
}
.rpkb-quickview__add:hover { opacity: 0.88; }
.rpkb-quickview__add:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ── Mobile tweaks ───────────────────────────────────────────────────── */
@media screen and (max-width: 749px) {
  /* Grid layout becomes a horizontal scroll-snap carousel on mobile —
     mirrors the bespoke kit-builder's slider-element behavior. ~80% of
     the panel width per card so the next card peeks into view as an
     affordance for scrolling. Pulled out to the panel edges with
     negative margin so the leftmost card aligns flush with the heading
     and the scroll-padding pins snap to the same edge. */
  .rpkb-builder__group-items,
  .rpkb-builder__group-items--grid {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: visible;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: 0;
    -webkit-overflow-scrolling: touch;
    gap: 12px;
    margin-inline: 0;
    /* Hide the native horizontal scrollbar — the peek of the next card
       is the affordance; a scrollbar adds noise. */
    scrollbar-width: none;
  }
  .rpkb-builder__group-items::-webkit-scrollbar,
  .rpkb-builder__group-items--grid::-webkit-scrollbar { display: none; }

  .rpkb-builder__group-items > .rpkb-component,
  .rpkb-builder__group-items--grid > .rpkb-component {
    flex: 0 0 80%;
    min-width: 0;
    scroll-snap-align: start;
  }
  /* When there's only one card in the group, let it span full width
     (no peek needed if there's nothing to peek at). */
  .rpkb-builder__group-items--grid > .rpkb-component:only-child,
  .rpkb-builder__group-items > .rpkb-component:only-child {
    flex-basis: 100%;
  }

  .rpkb-component__info { padding: 10px 12px 12px; }
  .rpkb-component__title { font-size: 13.5px; }
  .rpkb-component__price { font-size: 13.5px; }

  /* List layout stays as a vertical stack — only grid gets the
     horizontal carousel. */
  .rpkb-builder__group-items--list {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    overflow: visible;
    scroll-snap-type: none;
    gap: 8px;
    margin-inline: 0;
  }
  .rpkb-builder__group-items--list > .rpkb-component { flex-basis: auto; }
  .rpkb-builder__group-items--list .rpkb-component__image { flex: 0 0 72px; width: 72px; min-height: 72px; }
  .rpkb-builder__group-items--list .rpkb-component__info { padding: 10px 12px; }
  .rpkb-builder__group-items--list .rpkb-component__title { font-size: 14px; }
}

/* ── "What's included" section ───────────────────────────────────── */

.kit-included {
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid rgba(var(--color-foreground, 17, 17, 17), 0.12);
  border-radius: 6px;
  background: rgba(var(--color-foreground, 17, 17, 17), 0.03);
}
.kit-included__heading {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: rgba(var(--color-foreground, 17, 17, 17), 0.7);
}
.kit-included__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.kit-included__item {
  display: flex;
  align-items: center;
  gap: 10px;
}
.kit-included__image {
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  object-fit: cover;
  border-radius: 4px;
  background: rgba(var(--color-foreground, 17, 17, 17), 0.06);
}
.kit-included__image--empty {
  border: 1px dashed rgba(var(--color-foreground, 17, 17, 17), 0.18);
}
.kit-included__body {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 0;
}
.kit-included__title {
  font-size: 14px;
  font-weight: 500;
  color: rgb(var(--color-foreground, 17, 17, 17));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kit-included__qty {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: rgba(var(--color-foreground, 17, 17, 17), 0.65);
}
.kit-included__badge {
  margin-left: auto;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: rgb(180, 35, 24);
  background: rgba(180, 35, 24, 0.1);
  border-radius: 999px;
}
.kit-included__item--unavailable .kit-included__title,
.kit-included__item--unavailable .kit-included__qty {
  color: rgba(var(--color-foreground, 17, 17, 17), 0.45);
}

/* ══ Skeleton loader ═══════════════════════════════════════════════════
   Inline placeholder rendered by the Liquid block before JS hydrates.
   Mirrors the rpkb-component grid so the layout shift on swap is
   minimal. The shimmer is a translating linear-gradient bg — no JS,
   no DOM mutation, no reflow, just a transformed pseudo-element. */
.rpkb-builder__skeleton {
  padding: 4px 0;
}
.rpkb-builder__skeleton-header {
  height: 18px;
  width: 40%;
  max-width: 240px;
  border-radius: 4px;
  margin: 0 0 16px;
  background: rgba(var(--kb-fg), 0.08);
  position: relative;
  overflow: hidden;
}
.rpkb-builder__skeleton-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.rpkb-builder__skeleton-card {
  border: 1px solid rgb(var(--kb-line));
  border-radius: var(--kb-radius);
  background: rgb(var(--kb-bg));
  box-shadow: 0 1px 2px rgba(var(--kb-shadow), 0.04);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.rpkb-builder__skeleton-image {
  aspect-ratio: 1;
  background: rgba(var(--kb-fg), 0.06);
  position: relative;
  overflow: hidden;
}
.rpkb-builder__skeleton-line {
  height: 12px;
  border-radius: 4px;
  background: rgba(var(--kb-fg), 0.08);
  margin: 10px 12px 0;
  position: relative;
  overflow: hidden;
}
.rpkb-builder__skeleton-line--title {
  width: 70%;
  height: 14px;
  margin-top: 12px;
}
.rpkb-builder__skeleton-line--price {
  width: 40%;
  height: 12px;
  margin-bottom: 14px;
}

/* Shimmer — single keyframe shared by every placeholder element. The
   gradient is wider than the element so the highlight sweeps through
   instead of fading in/out. respects prefers-reduced-motion. */
.rpkb-builder__skeleton-header::after,
.rpkb-builder__skeleton-image::after,
.rpkb-builder__skeleton-line::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(var(--kb-bg), 0.55) 50%,
    transparent 100%
  );
  transform: translateX(-100%);
  animation: rpkb-skeleton-shimmer 1.4s ease-in-out infinite;
}
@keyframes rpkb-skeleton-shimmer {
  100% { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
  .rpkb-builder__skeleton-header::after,
  .rpkb-builder__skeleton-image::after,
  .rpkb-builder__skeleton-line::after {
    animation: none;
  }
}
