/** Shopify CDN: Minification failed

Line 1490:0 Unexpected "}"

**/
/* ============================================================
 * BYO Builder — all selectors scoped .byo-*
 * Uses Horizon CSS tokens so the picker matches the theme.
 * ============================================================ */

/* Kill horizontal overflow caused by the full-bleed hero + tray, which use
   `margin-inline: calc(50% - 50vw)`. In real browsers `50vw` INCLUDES the
   vertical scrollbar width, so the full-bleed elements end up ~15px wider
   than the visible viewport → horizontal scroll, which pushes the header
   icons off-screen and shifts the absolutely-positioned mailing popover
   past the right edge. (Headless browsers have no scrollbar so this never
   showed in testing.) `overflow-x: clip` removes the overflow WITHOUT
   creating a scroll container, so the sticky picks tray still works.
   This CSS only loads on BYO pages, so scoping to html is safe here. */
html {
  overflow-x: clip;
}

.byo-builder {
  --byo-gap: 12px;
  --byo-gap-lg: 24px;
  --byo-radius: 4px;
  --byo-radius-button: 14px;
  --byo-border: 1px solid var(--color-border, rgba(0, 0, 0, 0.06));
  --byo-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.04);
  --byo-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.08);
  --byo-submit-height: 88px;
  /* Accent now inherits from Horizon's color scheme (--color-primary),
     which the merchant edits via Theme Editor. Default cascades to
     Heather's brand orange #FF4A06 from settings_data.json scheme-1.
     Hard-coded hex remains as a fallback in case the section is ever
     rendered outside a Horizon color scheme. */
  --byo-accent: var(--color-primary, #FF4A06);
  --byo-accent-hover: var(--color-primary-hover, #E63D00);
  --byo-accent-contrast: var(--color-background, #FFFFFF);

  /* CTA "Add to Cart" uses Horizon's primary-button (dark per Figma), brand-orange hover */
  --byo-cta-bg: var(--color-primary-button-background, #231F20);
  --byo-cta-text: var(--color-primary-button-text, #FFFFFF);
  --byo-cta-bg-hover: #FF4A06;   /* brand orange hover (was dark #3A3536) */

  padding-block: 32px 120px;
  padding-inline: 16px;
  /* 1232 - 32px of padding = 1200px of content, which is exactly the sticky
     tray's inner width (its `padding: 14px max(16px, calc(50vw - 600px))`
     resolves to a 1200px column). They used to differ by 32px, so the tray
     looked "right" and everything under it looked inset. Change these two
     together or they drift apart again. */
  max-width: 1232px;
  margin-inline: auto;
  color: var(--color-foreground, #000);
  font-family: var(--font-body--family, Inter, system-ui, sans-serif);
}

/* When a banner is present, zero out the section's top padding entirely
   so the banner sits flush against whatever is above (site header, etc.).
   The negative margin-top on .byo-builder__hero is kept as a fallback
   for stale-cache scenarios, but with padding-block-start: 0 it's a no-op. */
.byo-builder[data-has-banner="true"] {
  padding-block-start: 0;
}

/* ---------- Header (no banner) ---------- */

.byo-builder__header {
  text-align: center;
  margin-bottom: 32px;
}

.byo-builder__title {
  font-family: var(--font-heading--family, inherit);
  font-size: clamp(28px, 4vw, 48px);
  font-weight: 700;
  margin: 0 0 8px;
  letter-spacing: -0.01em;
}

.byo-builder__subtitle {
  font-size: clamp(13px, 3.5vw, 16px);
  opacity: 0.7;
  margin: 0 auto;
  max-width: 480px;
  text-wrap: balance;
  line-height: 1.4;
}

/* ---------- Hero (with banner image) ---------- */

.byo-builder__hero {
  /* Full-bleed horizontally regardless of the page-width container.
     Vertical height tier + cross-fade slide layers + position/overflow/bg
     fallback all come from the shared .adg-banner component
     (assets/adg-banner.css). Default tier is medium (~420 cap). */
  margin-inline: calc(50% - 50vw);
  margin-top: 0;
  margin-bottom: 24px;          /* a bit of breathing room before tray */
  display: flex;
  align-items: flex-end;        /* push text to bottom of banner */
  justify-content: flex-start;  /* anchor overlay LEFT — center caused the title to appear centered */
}
/* Lock the BYO product hero to 3:1 to match Joel's banner art (3840x1280),
   overriding the .adg-banner--* tier. width:auto restores true full-bleed: the
   shared .adg-banner sets width:100%, which inside a page-width section is only
   ~1088px and broke both the full-bleed banner AND the popover edge-anchor.
   Mobile floors at 280px (crops to safe zone). */
.byo-builder__hero.adg-banner { width: auto; min-height: clamp(280px, 33.333vw, 1280px); }

/* Text no longer sits directly on the banner photo (per Heather / Joel — it
   always looked heavy). Instead it lives in a semi-opaque band across the
   bottom of the banner, like the homepage tagline: image stays clean, text is
   easy to read. So no on-image gradient here. */

.byo-builder__hero-overlay {
  position: relative;
  z-index: 2;
  width: 100%;                 /* full-width band across the bottom of the banner */
  text-align: center;          /* centered to match the intro copy directly below it */
  color: var(--color-foreground, #231F20);
  /* Semi-opaque white band (matches the homepage tagline's rgba(255,255,255,.9)),
     covering the image a little so the dark text reads cleanly. */
  background: rgba(255, 255, 255, 0.92);
  padding: clamp(16px, 2.2vw, 26px) clamp(16px, 4vw, 48px) clamp(18px, 2.4vw, 28px);
}

/* (Breadcrumb removed for now — Jul. Heather's design puts it above the title;
   re-add there once the banner text treatment is settled. See byo-builder.liquid.) */

.byo-builder__title--hero {
  color: var(--color-foreground, #231F20);
  font-size: clamp(28px, 4vw, 46px);
  line-height: 1.05;
  max-width: 820px;            /* fits "Customize Your Own Wall Calendar" on ~1-2 lines */
  margin: 0 auto 6px;          /* centered block */
}

/* ---------- Mailing list popover (top-right of hero) ----------
   EXACT spec from Heather's Figma (Group 787, verified against JSON):
     367 × 178, border-radius 20
     fill: SOLID white, opacity 1.0 (NOT translucent — the 0.82 alpha was
       letting the orange hero bleed through and tint the card warm)
     shadow: blur 29, alpha 0.22
     position: she anchors it bleeding ~28px OFF the right edge of the page
       (card right edge = 1468 in a 1440 frame). right:-28px reproduces her
       exact left position (1101 ≈ her 1100) at 1440 and keeps the card
       flush-to-bleeding at every width. html{overflow-x:clip} prevents a
       scrollbar from the overhang.
     X close at top-LEFT in a 28px white circle, glyph #4C4C4C
     heading centered, Refrigerator Deluxe Bold 24px, #000
     email field ~252×52, radius 10  */
.byo-mailing-popover {
  position: absolute;
  top: 24px;
  right: -28px;   /* bleed ~28px off the right edge — matches home + BYO overview (Heather's design); html{overflow-x:clip} prevents a scrollbar */
  z-index: 2;
  width: 367px;
  height: 178px;
  max-width: calc(100vw - 16px);
  /* Solid white — opacity 1.0 per her JSON (no see-through tint) */
  background: #ffffff;
  color: var(--color-foreground, #231F20);
  border-radius: 20px;
  box-shadow: 0 4px 29px rgba(0, 0, 0, 0.22);
  padding: 0; /* inner elements absolutely positioned */
}

.byo-mailing__close {
  position: absolute;
  top: 12px;
  left: 12px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: none;
  background: #ffffff;          /* clear white circle like Heather's */
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #4C4C4C;              /* glyph color per her JSON (medium grey) */
  padding: 0;
  transition: background 120ms ease;
}
.byo-mailing__close:hover {
  background: #f2f2f2;
}
.byo-mailing__close svg { display: block; }

.byo-mailing__heading {
  position: absolute;
  top: 38px;
  left: 0;
  right: 0;
  margin: 0;
  padding: 0 24px;
  text-align: center;          /* CENTERED in the card, like Heather's */
  font-family: var(--font-heading--family, 'Oswald', sans-serif);
  font-size: 24px;             /* her JSON: 24px */
  font-weight: 700;
  letter-spacing: 0;           /* her JSON: 0 */
  line-height: 1.1;
  text-transform: uppercase;
  color: #000;                 /* her JSON: pure black */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.byo-mailing__form {
  position: absolute;
  top: 90px;
  left: 32px;                  /* equal margins → field centered in card */
  right: 32px;
  margin: 0;
}

.byo-mailing__field {
  position: relative;
  display: flex;
  align-items: stretch;
  width: 100%;
  height: 52px;
  border: 1px solid rgba(35, 31, 32, 0.22);
  border-radius: 10px;         /* rounder, matches Heather */
  overflow: hidden;
  background: #ffffff;
  transition: border-color 120ms ease;
}
.byo-mailing__field:focus-within {
  border-color: var(--byo-accent);
}

.byo-mailing__input {
  flex: 1 1 auto;
  border: none;
  outline: none;
  padding: 0 12px 0 17px;
  font: inherit;
  font-size: 14px;
  background: transparent;
  color: var(--color-foreground, #231F20);
  min-width: 0;
}
.byo-mailing__input::placeholder {
  color: rgba(35, 31, 32, 0.5);
}

.byo-mailing__submit {
  flex: 0 0 auto;
  border: none;
  background: transparent;
  cursor: pointer;
  width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-foreground, #231F20);
  transition: color 120ms ease;
}
.byo-mailing__submit:hover { color: var(--byo-accent); }

.byo-mailing__msg {
  position: absolute;
  top: 150px;
  left: 32px;
  right: 32px;
  margin: 0;
  font-size: 12px;
  text-align: center;
}
.byo-mailing__msg--ok { color: #1a7a3b; }
.byo-mailing__msg--err { color: #b00020; }

/* Hide the popover entirely on mobile. Per Heather's mobile wireframes,
   the JOIN OUR MAILING LIST signup lives in the FOOTER on mobile, not
   as a hero overlay. Forcing it on mobile crowds the hero title. */
@media (max-width: 768px) {
  .byo-mailing-popover {
    display: none !important;
  }
}

.byo-builder__subtitle--hero {
  color: #4C4C4C;
  font-size: clamp(14px, 1.4vw, 17px);
  max-width: 620px;
  margin-top: 2px;
}

/* ---------- Instructions (copied from the landing page, above the picker) ---------- */
.byo-builder__intro {
  max-width: 760px;
  margin: 0 auto clamp(20px, 3vw, 32px);
  text-align: center;
}
.byo-builder__intro-head {
  font-family: var(--font-heading--family, inherit);
  font-size: clamp(20px, 2.6vw, 26px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0;
  line-height: 1.15;
  margin: 0 0 10px;
  color: var(--color-foreground, #231F20);
}
.byo-builder__intro-body {
  font-size: 15px;
  line-height: 1.6;
  color: #4C4C4C;
}
.byo-builder__intro-body p { margin: 0; }
.byo-builder__intro-body p + p { margin-top: 10px; }

/* ---------- Picks tray ---------- */

/* Full-bleed: extends edge-to-edge of the viewport so nothing peeks through
   when sticky. Inside content is padded to align with the page's max-width. */
.byo-tray {
  position: relative;
  position: sticky;
  top: 0;
  z-index: 10;
  /* Break out of the parent's padding/max-width to span the viewport */
  margin-inline: calc(50% - 50vw);
  margin-bottom: var(--byo-gap-lg);
  /* Pad horizontally so inside content lines up with the page-width column.
     16px minimum at narrow widths; on wider screens, match the page gutter.
     Slightly more vertical padding for breathing room. */
  padding: 14px max(16px, calc(50vw - 600px)) 16px;
  border: none;
  border-radius: 0;
  background: var(--color-background, #fff);
}

/* Subtle inset bottom rule — matches the inner content width, not full-bleed */
.byo-tray::after {
  content: '';
  position: absolute;
  left: max(16px, calc(50vw - 600px));
  right: max(16px, calc(50vw - 600px));
  bottom: 0;
  height: 1px;
  background: rgba(0, 0, 0, 0.05);
  pointer-events: none;
}

/* Top line: count + Collection (left) / actions (right) per Heather's Figma */
.byo-tray__topline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.byo-tray__topline-left {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  min-width: 0;
}

.byo-tray__count {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.byo-tray__count-sep { opacity: 0.4; margin: 0 1px; }
.byo-tray__count-label {
  margin-left: 6px;
  font-weight: 400;
  opacity: 0.55;
  text-transform: lowercase;
}

/* ---------- Collection filter dropdown ---------- */
.byo-tray__collection {
  position: relative;
}

.byo-tray__collection-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-size: 14px;
  font-weight: 400;
  padding: 4px 8px;
  border: none;
  background: transparent;
  color: var(--color-foreground, #231F20);
  cursor: pointer;
  border-radius: 4px;
  transition: background 120ms ease;
}
.byo-tray__collection-btn:hover { background: rgba(0,0,0,0.04); }

.byo-tray__collection-icon {
  flex-shrink: 0;
}

.byo-tray__collection-menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 20;
  list-style: none;
  margin: 0;
  padding: 6px;
  min-width: 220px;
  background: var(--color-background, #fff);
  border: 1px solid rgba(35, 31, 32, 0.12);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}

.byo-tray__collection-opt {
  font-size: 14px;
  padding: 8px 10px;
  border-radius: 4px;
  cursor: pointer;
  color: var(--color-foreground, #231F20);
  transition: background 80ms ease;
}
.byo-tray__collection-opt:hover,
.byo-tray__collection-opt:focus {
  background: rgba(255, 74, 6, 0.08); /* light orange tint on hover */
  outline: none;
}

/* Search: full width, sits below the count + actions row */
.byo-tray__search {
  position: relative;
  display: block;
  width: 100%;
  margin-bottom: 10px;
}

.byo-tray {
  display: flex;
  flex-direction: column;
}

/* Reading order: count + actions first, search below, then the slots/strip.
   The picks-status reads as the primary thing about your in-progress work;
   search is the tool for finding more designs. */
.byo-tray__topline { order: -1; }
.byo-tray__search { order: 0; }
.byo-tray__slots-wrap { order: 1; }

.byo-tray__search-icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  opacity: 0.5;
  pointer-events: none;
}

.byo-tray__search-input {
  width: 100%;
  padding: 9px 12px 9px 34px;
  font-size: 13px;
  font-family: inherit;
  background: var(--color-background, #fff);
  color: inherit;
  border: var(--byo-border);
  border-radius: var(--byo-radius);
  outline-offset: 2px;
}
.byo-tray__search-input:focus { border-color: var(--color-foreground, #000); }

.byo-tray__btn {
  flex-shrink: 0;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 8px 14px;
  border-radius: var(--byo-radius);
  cursor: pointer;
  background: transparent;
  border: 1px solid var(--color-border, rgba(0,0,0,0.12));
  color: var(--color-foreground, #000);
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
  white-space: nowrap;
}
.byo-tray__btn:hover { background: rgba(0,0,0,0.04); border-color: var(--color-foreground, #000); }

/* Preview button: orange filled, more prominent */
.byo-tray__btn--preview {
  background: var(--byo-cta-bg);          /* black per Figma + global rule */
  color: var(--byo-cta-text);
  border-color: var(--byo-cta-bg);
}
.byo-tray__btn--preview:hover {
  background: var(--byo-accent);          /* orange hover */
  border-color: var(--byo-accent);
}

.byo-tray__btn--clear { opacity: 0.7; }
.byo-tray__btn--clear:hover { opacity: 1; }

.byo-tray__btn--toggle {
  padding: 8px 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Action buttons stay together as a unit when the toolbar wraps */
.byo-tray__actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

/* ---- Narrow screens: topline becomes two deliberate rows -----------------
   The topline holds five things (count, Design Collections, Preview, Clear,
   collapse). Below ~640px they cannot share a line: the left group wraps and
   grows tall while the action group refuses to shrink, and the two collide.
   Measured at 320px: "Design Collections" overlapped both Preview and Clear.

   So stop asking one row to do it. Row 1 is identity — how many picked, and
   which collection you are browsing. Row 2 is a full-width action bar. The
   buttons then get genuinely large tap targets instead of shrinking, which
   is better on a phone anyway. */
@media (max-width: 640px) {
  .byo-tray__topline { display: block; }

  .byo-tray__topline-left {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
  }

  .byo-tray__collection-btn {
    white-space: nowrap;          /* never let the label wrap the row taller */
    min-height: 34px;
    padding: 4px 6px;
  }

  .byo-tray__actions {
    display: flex;
    width: 100%;
    gap: 8px;
  }
  /* Preview and Clear share the row evenly; the collapse chevron keeps a
     fixed square so it stays a comfortable target and never squeezes. */
  .byo-tray__btn--preview,
  .byo-tray__btn--clear {
    flex: 1 1 0;
    min-width: 0;
    min-height: 42px;
    white-space: nowrap;
  }
  .byo-tray__btn--toggle {
    flex: 0 0 42px;
    min-height: 42px;
    justify-content: center;
  }
}

.byo-tray__toggle-icon {
  transition: transform 160ms ease;
}

.byo-tray--collapsed .byo-tray__toggle-icon {
  transform: rotate(-90deg);
}

/* Collapsed (mobile only): single horizontal scrollable strip */
@media (max-width: 767px) {
  .byo-tray--collapsed .byo-tray__slots {
    display: flex;
    grid-template-columns: none;
    gap: 6px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    padding-bottom: 0;
    /* Hide scrollbar entirely — fade indicator + swipe affordance do the job */
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
  }
  .byo-tray--collapsed .byo-tray__slots::-webkit-scrollbar {
    display: none;
  }

  .byo-tray--collapsed .byo-slot {
    flex: 0 0 76px;
    width: 76px;
    height: 76px;
    scroll-snap-align: start;
  }

  .byo-tray--collapsed .byo-slot__label {
    font-size: 12px;
  }

  /* Smaller X in the tight collapsed strip */
  .byo-tray--collapsed .byo-slot__remove {
    width: 20px;
    height: 20px;
    font-size: 12px;
    top: 2px;
    right: 2px;
  }
}

/* Desktop: collapse toggle hidden, layout always expanded regardless of class */
@media (min-width: 768px) {
  .byo-tray__btn--toggle { display: none; }
  /* Belt-and-suspenders: if .byo-tray--collapsed lingers from a mobile
     session, ignore it on desktop and render the full grid. */
  .byo-tray--collapsed .byo-tray__slots {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(48px, 1fr));
    gap: var(--byo-gap);
    overflow: visible;
  }
  .byo-tray--collapsed .byo-slot {
    flex: none;
    width: auto;
    height: auto;
  }
}

/* Right-edge fade so users see the strip is scrollable.
   Only when collapsed and only when content overflows. */
.byo-tray--collapsed .byo-tray__slots-wrap::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 4px;
  width: 28px;
  pointer-events: none;
  background: linear-gradient(to right, transparent, var(--color-background, #fff) 80%);
  opacity: 0;
  transition: opacity 120ms ease;
}
.byo-tray--collapsed.byo-tray--has-overflow .byo-tray__slots-wrap::after {
  opacity: 1;
}

/* Slots wrapper — positions the right-edge fade indicator */
.byo-tray__slots-wrap {
  position: relative;
}

/* Expanded grid: auto-fit columns so slots stretch to fill the row evenly,
   shrinking down to ~76px before wrapping (matches the collapsed-strip
   thumb size as a floor — users complained tiny thumbs looked microscopic).
   Vertical scroll kicks in if the grid grows past ~50vh so the artwork
   grid below stays accessible. */
.byo-tray__slots {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(76px, 1fr));
  gap: var(--byo-gap);
  max-height: 50vh;
  overflow-y: auto;
  overflow-x: hidden;
  /* Inner padding so the slot border doesn't kiss the scroll edge. */
  padding: 2px;
  /* Hide the vertical scrollbar visually — edge auto-scroll + fade
     indicators do the affordance work, matching the collapsed strip. */
  scrollbar-width: thin;
}

.byo-slot {
  position: relative;
  aspect-ratio: 1 / 1;
  /* Per Heather (JSON stroke #A3A4A8, weight 1): empty slots have a SOLID
     medium-grey border; only the "next" (active drop-target) slot is dashed
     [5,5]; filled slots go orange. The theme's --color-border is nearly
     invisible (0.06 alpha), so use her exact grey. */
  border: 1px solid #A3A4A8;
  border-radius: var(--byo-radius);
  overflow: hidden;
  background: transparent;
  cursor: default;
  transition: border-color 120ms ease, transform 120ms ease;
  /* Block iOS image callout / Android long-press menu so press-hold
     triggers our drag instead of the system "Save image" sheet. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* aspect-ratio fallback for Safari < 15, Firefox < 89, old Chromium.
   Uses the classic padding-bottom trick to maintain shape. */
@supports not (aspect-ratio: 1 / 1) {
  .byo-slot::before,
  .byo-card__media::before,
  .byo-preview__tile-media::before {
    content: '';
    display: block;
    padding-bottom: 100%;
  }
  .byo-preview__tile--cover .byo-preview__tile-media::before {
    padding-bottom: 75%; /* 4:3 */
  }
  .byo-slot > *,
  .byo-card__media > *,
  .byo-preview__tile-media > * {
    position: absolute;
    inset: 0;
  }
}


/* The next slot to be filled (first empty) — dashed, like Heather's active
   drop target. JS adds .byo-slot--next to exactly one slot. */
.byo-slot--next {
  border-style: dashed;
}

.byo-slot[data-byo-empty]:hover {
  border-color: var(--color-foreground, #000);
}

.byo-slot--cover {
  border-color: var(--color-foreground, #000);
  border-style: solid;
}

.byo-slot__label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 500;
  color: var(--color-foreground, #000);
  opacity: 0.4;
  letter-spacing: 0.04em;
  /* Title Case per Heather ("April", not "APRIL") — the JS already supplies
     correctly-cased month names; don't force uppercase. */
  text-transform: none;
  pointer-events: none;
}

.byo-slot--filled {
  border-style: solid;
  border-color: var(--byo-accent);
  cursor: grab;
}

.byo-slot--filled:active { cursor: grabbing; }

.byo-slot--filled .byo-slot__label { display: none; }

.byo-slot--dragging { opacity: 0.4; }

.byo-slot--drop-over {
  outline: 2px dashed var(--color-foreground, #000);
  outline-offset: 2px;
}

/* FILL AND CONTAIN — NOT PERCENTAGE CAPS.
   .byo-slot is sized by aspect-ratio, and WebKit will not resolve a percentage
   max-height against a height derived from aspect-ratio. The picked thumbnails
   therefore rendered at their natural height and were cropped by the slot's
   overflow:hidden — the art cut off at the top of every filled slot in Safari
   (Justin, 2026-08-16). Same bug and same fix as .adg-card__media img and
   .adg-pdp__stage-img; an absolute fill has no percentage to mis-resolve.
   The small inset keeps the art off the slot's border, as it was when the
   image was a centred flex item. */
.byo-slot__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 4px;
  box-sizing: border-box;
  object-fit: contain;
  display: block;
  /* Same callout suppression on the actual <img> — Safari hangs it on
     the image element, not the parent. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none; /* clicks/touches go to the slot, not the img */
}

.byo-slot--filled {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  background: #f5f5f5;
}

.byo-slot__remove {
  position: absolute;
  /* Tight to the top-right corner of the slot — "in the corner". */
  top: 2px;
  right: 2px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--byo-accent);
  color: var(--byo-accent-contrast);
  border: 2px solid var(--color-background, #fff);
  font-size: 14px;
  line-height: 1;
  display: none;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
  z-index: 2;
}

/* Reveal triggers:
   - Desktop: hover (mouse only)
   - Touch:   .byo-slot--show-remove class added by tap, auto-removed after 3s */
.byo-slot--filled:hover .byo-slot__remove,
.byo-slot--show-remove .byo-slot__remove {
  display: flex;
}

/* ---------- Browser ---------- */

.byo-browser {
  margin-bottom: var(--byo-gap-lg);
  /* A floor, so the document has its height the instant the panel swaps —
     without it the page collapses while the grid is still fetching, the
     landing scroll clamps short, and the first row ends up under the tray. */
  min-height: 70vh;
}

/* ---------- No pre-boot paint ----------
   The first frame must already look like the assembled page. Three flashes
   were reported on 2026-08-05 ("it loads what the original view would have
   been, then rearranges"), and each has one rule here:

   1. `hidden` must always WIN inside the builder. Any author display rule
      (`.byo-button { display:inline-flex }` was the culprit) beats the UA's
      [hidden] { display:none } by cascade, so the Load more button painted
      even while "hidden" — before boot, at the top of the page. */
[data-byo-root] [hidden] { display: none !important; }

/* 2. The browse area is server-rendered but which step shows is boot's
      decision (data-byo-step). Painting it before boot flashed the filter
      row, an empty grid and the status row, which boot then hid. */
[data-byo-root]:not([data-byo-step]) .byo-browser { display: none; }

/* 3. Shopify renders the tiles section as a SIBLING below the builder —
      sections cannot nest — and boot adopts it into [data-byo-tiles-slot].
      Until it lands there it must not paint at the bottom of the page;
      the jump from down there into the slot was the big rearrangement.
      This file only loads on builder pages, so the selector cannot leak
      onto the collection pages.
      :not(.byo-builder-section) is LOAD-BEARING: after adoption the tiles
      live INSIDE the builder's own section wrapper, so a bare
      :has(.adg-cats) matches the builder too and blanks the whole page —
      it did, on the first cut of this rule. */
.shopify-section:not(.byo-builder-section):has(.adg-cats) { display: none; }
[data-byo-root] [data-byo-tiles-slot] > .shopify-section:not([hidden]) { display: block; }

/* ---------- Grid ---------- */

.byo-grid {
  display: grid;
  /* Columns come from the section's "Columns (desktop)" control
     (Justin, 2026-08-03) — the same control adg-designs uses, so the picker
     and the design grids tune alike. Was a hardcoded auto-fill minmax(160px),
     which is why it silently rendered 7 across on a wide screen.
     This rule lives here rather than adg-card.css because byo-builder.css
     loads second and would otherwise win. */
  grid-template-columns: repeat(var(--adg-card-cols, 5), minmax(0, 1fr));
  gap: var(--byo-gap);
}

/* Two across on a phone at any setting — seven thumbnails on a 390px screen
   is unreadable, which is the reason the control exists at all. */
@media (max-width: 640px) {
  .byo-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.byo-card {
  display: flex;
  flex-direction: column;
  border: var(--byo-border);
  border-radius: var(--byo-radius);
  overflow: hidden;
  background: var(--color-background, #fff);
  cursor: pointer;
  transition: transform 120ms ease, box-shadow 120ms ease;
  text-align: left;
  font-family: inherit;
  color: inherit;
  padding: 0;
  /* Block iOS "Save image"/"Copy image" callout so press-hold becomes a drag. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.byo-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--byo-shadow-hover);
}

.byo-card:focus-visible {
  outline: 2px solid var(--color-foreground, #000);
  outline-offset: 2px;
}

/* Selected state: turn the card's existing 1px border orange — uniform on all
   four sides, no layout shift. (An inset box-shadow was wrong here: it paints
   BEHIND the children, so the white image area covered it on the top and sides
   and it only showed along the bottom over the transparent text area.) */
.byo-card--picked {
  border-color: var(--byo-accent);
}

.byo-card--dragging { opacity: 0.4; }
.byo-card.byo-touch-dragging { opacity: 0.4; }

/* No touch-action overrides — DragDropTouch polyfill (isPressHoldMode: true)
   only captures touch after a 400ms long-press. Quick swipes scroll natively. */

/* Floating preview that follows the finger during a touch drag */
.byo-touch-ghost {
  border-radius: var(--byo-radius);
  box-shadow: 0 10px 24px rgba(0,0,0,0.25);
  overflow: hidden;
  background: var(--color-background, #fff);
  transition: none;
  will-change: transform;
}
.byo-touch-ghost.byo-card { padding: 0; }
.byo-touch-ghost.byo-slot { padding: 0; }
.byo-touch-ghost .byo-slot__remove { display: none; }
.byo-touch-ghost .byo-card__badge { display: none; }

.byo-card__media {
  aspect-ratio: 1 / 1;
  background: #fff;          /* white, not gray — contained posters no longer sit on a gray field */
  overflow: hidden;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
}

/* Loading shimmer — added by byo-builder.js while a thumbnail is in flight
   and removed on load OR error, so a broken image never shimmers forever.
   Matches the shimmer on the collection cards (.adg-card__media.is-loading)
   so the whole store reads as one system. Inert unless JS adds the class. */
.byo-card__media.is-loading {
  background: linear-gradient(100deg, #f2f1ee 30%, #e6e4df 45%, #f2f1ee 60%);
  background-size: 300% 100%;
  animation: byo-card-shimmer 1.4s ease-in-out infinite;
}
.byo-card__media.is-loading .byo-card__img { opacity: 0; }
.byo-card__img { transition: opacity 260ms ease; }
@keyframes byo-card-shimmer {
  0%   { background-position: 100% 0; }
  100% { background-position: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  .byo-card__media.is-loading { animation: none; background: #f2f1ee; }
  .byo-card__img { transition: none; }
}

.byo-card__img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none; /* taps/touches go to the card wrapper */
}

.byo-card__badge {
  position: absolute;
  top: 8px;
  right: 8px;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;               /* pill so "×2" … "×12" don't overflow the circle */
  border-radius: 12px;
  background: var(--byo-accent);
  color: var(--byo-accent-contrast);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  display: none;
  align-items: center;
  justify-content: center;
}

.byo-card--picked .byo-card__badge { display: flex; }

/* Expand icon — opens a lightbox preview of the artwork. Always visible
   on the card so customers can preview before/after picking. Sits at the
   top-right by default. When the card is PICKED, the orange ✓ takes the
   top spot and the expand button slides down ~34px to sit just below it
   (matches Heather's Figma exactly). */
.byo-card__expand {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(35, 31, 32, 0.08);
  color: #231F20;
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  transition: transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1), background 120ms ease;
}
.byo-card__expand:hover,
.byo-card__expand:focus-visible {
  background: #ffffff;
  outline: none;
}
.byo-card__expand svg { display: block; }

/* Picked-card layout shift: ✓ stays at top (8px), expand slides to 42px
   (8px existing offset + 24px badge + 8px gap + 2px breathing) */
.byo-card--picked .byo-card__expand {
  transform: translateY(34px);
}

.byo-card__body {
  padding: 8px 10px 10px;
}

.byo-card__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.25;
  margin: 0 0 4px;
  color: var(--color-foreground, #231F20);
}

/* (Artist name removed from picker cards — products often have several artists,
   which was confusing. The name is kept in the card's aria-label for a11y.) */

/* ---------- Status & load more ---------- */

.byo-browser__status {
  margin-top: var(--byo-gap-lg);
  text-align: center;
  font-size: 14px;
  opacity: 0.7;
}

/* ---------- Submit bar ---------- */

/* Everything this rule used to declare — position, bottom, z-index,
   background, border, shadow, padding — now comes from .adg-actionbar, which
   this element also carries. This bar IS the shared action bar, so anything
   re-declared here would let the two drift apart, which is exactly the
   duplicate-arithmetic problem the shared bar exists to end.
   See adg-action-bar.css and byo-cart-form.liquid. */

.byo-submit__inner {
  display: flex;
  align-items: center;
  gap: 12px;
}

.byo-submit__summary {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}

.byo-submit__title {
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.byo-submit__price {
  font-size: 13px;
  opacity: 0.7;
}

.byo-submit__variant {
  flex-shrink: 0;
}

.byo-submit__variant select {
  font-family: inherit;
  font-size: 14px;
  padding: 8px 12px;
  border: var(--byo-border);
  border-radius: var(--byo-radius);
  background: var(--color-background, #fff);
  color: inherit;
  max-width: 180px;
}

.byo-submit .byo-button--primary {
  flex-shrink: 0;
  min-width: 140px;
}

/* Two-line Add to Cart: the destination on top, what's still needed under it.
   The button keeps one height whether or not the hint is showing, so the bar
   does not jump as the last design is picked. */
.byo-button--stacked {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  line-height: 1.15;
  min-height: 46px;
}
.byo-button__hint {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  opacity: 0.85;
}
.byo-button__hint[hidden] { display: none; }

/* Mobile: hide title (already in page header), stack variant + button,
   make Add to Cart full-width and prominent. */
@media (max-width: 640px) {
  .byo-submit__inner { flex-wrap: wrap; gap: 8px; }
  .byo-submit__summary { display: none; }
  .byo-submit__variant { flex: 1 1 auto; }
  .byo-submit__variant select { max-width: none; width: 100%; }
  .byo-submit .byo-button--primary {
    flex: 1 1 100%;
    min-height: 48px;
    font-size: 15px;
  }
}

/* ---------- Buttons ---------- */

.byo-button {
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  padding: 12px 24px;
  border-radius: var(--byo-radius-button);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
}

/* Add to Cart = dark CTA (Heather's Figma).
   Orange is reserved for selection actions (Preview, picked-card outline). */
.byo-button--primary {
  background: var(--byo-cta-bg);
  color: var(--byo-cta-text);
  border-color: var(--byo-cta-bg);
  font-weight: 700;
  letter-spacing: 0.01em;
}

.byo-button--primary:hover:not(:disabled) {
  background: var(--byo-cta-bg-hover);
  border-color: var(--byo-cta-bg-hover);
}

.byo-button--primary:disabled {
  background: #666666;          /* her JSON: solid medium grey, not faint */
  color: #ffffff;
  border-color: transparent;
  cursor: not-allowed;
}

.byo-button--secondary {
  background: transparent;
  color: var(--color-foreground, #000);
  border-color: var(--color-foreground, #000);
}

.byo-button--secondary:hover:not(:disabled) {
  background: #fafafa;
}

.byo-link {
  background: none;
  border: none;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
  padding: 0;
  font-size: 13px;
  opacity: 0.7;
}

.byo-link:hover { opacity: 1; }

/* ---------- Utility ---------- */

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}

/* ---------- Spacing for sticky submit bar ---------- */

.byo-builder { padding-bottom: var(--byo-submit-height); }

/* ---------- Preview modal ---------- */

.byo-preview {
  padding: 0;
  border: none;
  border-radius: 8px;
  max-width: min(960px, 92vw);
  width: 100%;
  max-height: 90vh;
  background: var(--color-background, #fff);
  color: var(--color-foreground, #000);
  box-shadow: 0 20px 60px rgba(0,0,0,0.25);
  font-family: var(--font-body--family, Inter, system-ui, sans-serif);
}

.byo-preview::backdrop {
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(4px); /* Safari < 18 */
  backdrop-filter: blur(4px);
}

/* Fallback for browsers without HTMLDialogElement.showModal()
   (Safari < 15.4, iOS Safari < 15.4). JS adds .byo-preview--fallback-open
   when opening, and the [open] attribute. The dialog [open] without
   showModal() renders inline by default; these styles position it
   modally and add our own backdrop. */
.byo-preview[open].byo-preview--fallback-open {
  display: block;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 9999;
  margin: 0;
}
.byo-preview--fallback-open::before {
  content: '';
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: -1;
}

.byo-preview__inner {
  display: flex;
  flex-direction: column;
  max-height: 90vh;
}

.byo-preview__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 24px;
  border-bottom: var(--byo-border);
}

.byo-preview__title {
  font-size: 18px;
  font-weight: 600;
  margin: 0;
}

.byo-preview__close {
  background: none;
  border: none;
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: inherit;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.byo-preview__close:hover { background: rgba(0,0,0,0.06); }

.byo-preview__body {
  flex: 1;
  overflow-y: auto;
  padding: 24px;
}

.byo-preview__cover-section {
  display: flex;
  justify-content: center;
  margin-bottom: 24px;
  padding-bottom: 24px;
  border-bottom: 1px dashed var(--color-border, rgba(0,0,0,0.12));
}

.byo-preview__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
@media (max-width: 720px) { .byo-preview__grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 480px) { .byo-preview__grid { grid-template-columns: repeat(2, 1fr); } }

.byo-preview__tile {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
}

.byo-preview__tile--cover {
  max-width: 320px;
  width: 100%;
}

.byo-preview__tile-media {
  aspect-ratio: 1 / 1;
  background: #f5f5f5;
  border: 1px solid var(--color-border, rgba(0,0,0,0.08));
  border-radius: var(--byo-radius);
  overflow: hidden;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.byo-preview__tile--cover .byo-preview__tile-media {
  aspect-ratio: 4 / 3;
  border: 2px solid var(--color-foreground, #000);
}

.byo-preview__tile-media img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.byo-preview__tile--empty .byo-preview__tile-media {
  border-style: dashed;
  background: transparent;
}

.byo-preview__tile-empty {
  font-size: 12px;
  font-weight: 500;
  opacity: 0.4;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.byo-preview__tile-label {
  font-size: 12px;
  font-weight: 600;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.7;
}

.byo-preview__footer {
  padding: 18px 24px;
  border-top: var(--byo-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.byo-preview__note {
  margin: 0;
  font-size: 13px;
  opacity: 0.65;
  flex: 1 1 280px;
  line-height: 1.4;
}

/* ============================================================
 * Hosted collection tiles + design grid (TODO 11c)
 *
 * WIDTH. Justin, looking at the desktop view: "why does the sticky
 * header have that nice width, and then there's these huge margins
 * that cram all the collections up so they're small". Right, and
 * two things stacked to cause it.
 *
 * The tray breaks out full-bleed and pads back to a 1200px column.
 * The tiles were inside .byo-builder's box (1168px of content) AND
 * paying their own 40px gutter on top, landing at 1088px — 112px
 * narrower a side than the tray directly above them.
 *
 * Fixed in two places: .byo-builder's max-width now yields exactly
 * 1200px of content (see above), and in here the section stops
 * paying for a second gutter. Tray, tiles and the design grid are
 * now all one width.
 *
 * Only inside the slot. The collection pages render this section
 * top-level, where its own 1400px/40px is correct and untouched.
 * ============================================================ */
/* Don't reproduce the tray's width by arithmetic — use the SAME formula it
   uses. Break out to the viewport, then pad back to the identical column.
   Matching by construction means these cannot drift apart later the way the
   1168-vs-1200 mismatch did. Same two lines as .byo-tray, deliberately. */
[data-byo-tiles-slot] .adg-cats,
.byo-browser {
  margin-inline: calc(50% - 50vw);
  padding-inline: max(16px, calc(50vw - 600px));
  max-width: none;
}

[data-byo-tiles-slot] .adg-cats {
  /* One step in a flow under the tray, not a standalone band. */
  padding-block-start: 4px;
}

/* One tile per row once two would make the artwork unreadable. Each
   tile is a 2x2 of thumbnails, so a half-width tile on a phone shows
   art at a QUARTER of half the screen — about 75px, too small to tell
   two national parks apart, which is this screen's whole job. */
@media (max-width: 600px) {
  [data-byo-tiles-slot] .adg-cats__grid { --adg-cat-cols: 1; }
}

/* The tiles section assumes it is the only thing on the page and pads
   itself off the bottom. In the slot the grid follows immediately. */
[data-byo-tiles-slot] .adg-cats { padding-block-end: 24px; }

/* The filter row moved out of this sticky tray and into .byo-browser on
   2026-08-03, where it uses the design grid's own .adg-coll__toolbar
   classes. Nothing to style here any more — that was the point. */
}
