/* frontend/css/design-builder.css */

/* Shape rail: a tight vertical column of icon-only tiles to the LEFT of the
   preview. Was a minmax(4.5rem) grid, which floated each 3rem icon in an
   oversized cell — the "white space around the circle/square". A flex column
   sized to its icons removes that dead space. */
.shape-selector {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  margin: 0;
  padding: 0.375rem;
  background: var(--color-bg-secondary, #f5f5f5);
  border-radius: 0.5rem;
}

/* Keep the rail at its natural icon width in the flex row so the preview
   (flex-1) takes the remaining space and the rail never stretches/squashes. */
.shape-rail {
  flex: none;
}

.shape-selector-item {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Click-to-select tile, not a drag handle — a pointer is the correct
     affordance. `grab` is reserved for the actual pan surface (the crop
     canvas), which sets it via canvas style in photo-upload.js (#72). */
  cursor: pointer;
  padding: 0.25rem;
  transition: transform 0.15s ease;
}

/* Hover/selection feedback follows the SHAPE, not the rectangular tile (no
   boxy "focus-ring" look). Hover nudges the icon up in scale; the active shape
   gets a blue outline traced around its silhouette via stacked drop-shadows.
   drop-shadow follows the element's clipped alpha, so the ring hugs the
   circle/hex/triangle/etc. exactly; the four offsets compound (each applies to
   the previous result) to fill the corners into a continuous ~2px outline. */
.shape-selector-item:hover .shape-preview {
  transform: scale(1.06);
}

/* Selected shape: keep the dark legibility edge (CSS filter REPLACES, it does
   not merge — so the base .shape-preview filter is lost here and must be
   repeated) and add a thicker brand-blue ring just outside it. Dark inner edge
   keeps the silhouette visible on light images; blue outer ring signals select. */
[data-shape-btn].active .shape-preview {
  filter:
    drop-shadow(1.5px 0 0 rgba(15, 23, 42, 0.8))
    drop-shadow(-1.5px 0 0 rgba(15, 23, 42, 0.8))
    drop-shadow(0 1.5px 0 rgba(15, 23, 42, 0.8))
    drop-shadow(0 -1.5px 0 rgba(15, 23, 42, 0.8))
    drop-shadow(2.5px 0 0 var(--color-brand, #3b82f6))
    drop-shadow(-2.5px 0 0 var(--color-brand, #3b82f6))
    drop-shadow(0 2.5px 0 var(--color-brand, #3b82f6))
    drop-shadow(0 -2.5px 0 var(--color-brand, #3b82f6));
}

.shape-preview {
  position: relative;
  width: 3rem;
  height: 3rem;
  /* No box frame: the clipped fill IS the shape. A white bg + grey border
     drew a square box around the circle/hex (the "inner box" + merff, #61
     follow-up). The tile carries selection state instead. */
  background: transparent;
  /* No overflow:hidden — the active shape's drop-shadow outline must paint just
     outside the silhouette (the surrounding tile padding absorbs it). The image
     is constrained by its clip-path, not by this box. */
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
  transition: transform 0.15s ease;
  /* ALWAYS trace the silhouette with a dark outline so every shape is legible
     against any image — even a light/cream one. The drop-shadow MUST live on
     this (un-clipped) wrapper, NOT on .shape-preview-fill: a clip-path clips the
     element's filter output too, so a shadow on the clipped fill is eaten by its
     own clip and never shows. Here the wrapper's filter follows the clipped
     child's alpha and paints the outline just outside it; the four 0-blur shadows
     compound into a continuous ~2px edge. */
  filter:
    drop-shadow(1.5px 0 0 rgba(15, 23, 42, 0.8))
    drop-shadow(-1.5px 0 0 rgba(15, 23, 42, 0.8))
    drop-shadow(0 1.5px 0 rgba(15, 23, 42, 0.8))
    drop-shadow(0 -1.5px 0 rgba(15, 23, 42, 0.8));
}

.shape-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The fill layer carries the clip-path + the cropped image (or a gradient
   placeholder before upload). design-builder.js sets its background. */
.shape-preview-fill {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

/* The crop stage doubles as the shaped preview (#77): design-builder.js sets
   its clip-path from the selected shape so crop/zoom happen inside the shape.
   A short transition smooths swaps where the browser can interpolate.
   contain:paint clips all descendant compositing layers (including CSS filter
   on the canvas) to this element's border-box, preventing filter bleed
   outside the clip-path at shape boundaries. */
[data-shape-preview-stage] {
  transition: clip-path 0.2s ease;
  contain: paint;
}

/* Labels are visually hidden in the rail (the silhouette is the affordance) but
   kept in the DOM so screen readers still announce each shape. */
.shape-label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.shape-count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  height: 1.5rem;
  padding: 0 0.375rem;
  background: var(--color-brand, #3b82f6);
  color: white;
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: 0.75rem;
}

.shape-count-badge.hidden {
  display: none;
}

.design-summary {
  padding: 1rem;
  background: var(--color-bg-tertiary, #f9fafb);
  border-radius: 0.5rem;
  margin: 1rem 0;
}

.design-summary-items {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.design-summary-item {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.5rem 0.75rem;
  background: white;
  border: 1px solid #e5e5e5;
  border-radius: 0.375rem;
  font-size: 0.875rem;
}

.design-summary-item img {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 0.25rem;
}

.button-group {
  display: flex;
  gap: 0.75rem;
  margin-top: 1rem;
}

.button-group button {
  flex: 1;
  padding: 0.75rem 1rem;
  border: none;
  border-radius: 0.375rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.btn-add-cart {
  background: var(--color-brand, #3b82f6);
  color: white;
}

.btn-add-cart:hover {
  background: var(--color-brand-dark, #2563eb);
}

.btn-add-cart:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-clear {
  background: var(--color-bg-secondary, #e5e7eb);
  color: var(--color-text, #1f2937);
}

.btn-clear:hover {
  background: var(--color-bg-tertiary, #d1d5db);
}

/* Save design (#84): a secondary action next to Add to Cart. Outlined rather
   than filled so the primary add-to-cart action stays visually dominant. */
.btn-save-design {
  background: transparent;
  color: var(--color-brand, #3b82f6);
  box-shadow: inset 0 0 0 1px var(--color-brand, #3b82f6);
}

.btn-save-design:hover {
  background: rgba(59, 130, 246, 0.08);
}

.btn-save-design:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Resume-link panel (#84): revealed after a successful Save. Holds the
   shareable ?resume=<hash> URL in a read-only field plus a Copy button. */
.design-resume {
  margin-top: 1rem;
  padding: 0.75rem;
  background: white;
  border: 1px solid #e5e5e5;
  border-radius: 0.375rem;
}

.design-resume-label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-text, #1f2937);
  margin-bottom: 0.375rem;
}

.design-resume-row {
  display: flex;
  gap: 0.5rem;
}

.design-resume-url {
  flex: 1;
  min-width: 0;
  padding: 0.5rem 0.625rem;
  font-size: 0.8125rem;
  border: 1px solid #d1d5db;
  border-radius: 0.375rem;
  background: var(--color-bg-secondary, #f5f5f5);
  color: var(--color-text, #1f2937);
}

.btn-resume-copy {
  flex: 0 0 auto;
  padding: 0.5rem 0.875rem;
  border: none;
  border-radius: 0.375rem;
  font-weight: 500;
  cursor: pointer;
  background: var(--color-brand, #3b82f6);
  color: white;
  transition: background 0.2s ease;
}

.btn-resume-copy:hover {
  background: var(--color-brand-dark, #2563eb);
}

.whoosh-animation {
  animation: whoosh 0.6s ease-out;
}

@keyframes whoosh {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: scale(0.5) translateY(-2rem);
  }
}

/* Mobile: tighten the shape picker so tiles don't waste vertical space on a
   phone. Smaller tiles, smaller previews, smaller gaps (#61 follow-up). */
@media (max-width: 480px) {
  /* The rail stays on the LEFT on phones (chosen behaviour); shrink the icons
     and padding so it stays a thin column beside a still-usable preview. */
  .shape-selector {
    padding: 0.25rem;
    gap: 0.375rem;
  }

  .shape-selector-item {
    padding: 0.2rem;
  }

  .shape-preview {
    width: 2.25rem;
    height: 2.25rem;
  }

  .button-group {
    flex-direction: column;
  }

  /* The zoom slider replaced the −/+ buttons and is now the primary crop touch
     control on a phone; give it a ~44px-tall hit area (the native range track is
     only a couple of pixels). Keyed off the stable JS data hook (#96). */
  [data-photo-upload-zoom-slider] {
    min-height: 2.75rem;
  }

  /* Give the shaped crop stage maximum room on small screens: the wrapper's
     max-w-xs (20rem) can be cramped on mid-size phones, so let the builder
     use the full column width. */
  [data-photo-upload] {
    max-width: 100%;
  }
}
