/* Centered under the centered .category-title the products.index chain gives
   this page.

   Deliberately not a positioned ancestor: Coloris appends its panel to
   document.body and positions it in document coordinates, so a containing block
   here would shift the panel by this form's offset. */
.color-search-form {
  /* Mirrors .clr-picker's width in 22_coloris.css so the field and the panel
     that drops out of it line up edge to edge. Keep the two in step: Coloris
     anchors the panel to the field's left edge, and only falls back to
     right-aligning it when the panel would overflow the viewport — with equal
     widths both branches land in the same place. */
  --color-search-field-width: 200px;

  /* Was capped at 360px, which fit a field and one button. The row carries two
     facet dropdowns as well now, so it sizes to its content and centers
     itself. */
  width: fit-content;
  max-width: 100%;
  margin: 0 auto var(--space-6);
}

.color-search-controls {
  display: flex;
  align-items: stretch;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* Coloris wraps the input in .clr-field at connect() time; making that wrapper
   a flex box keeps it the same height as the input it now owns. */
.color-search-controls .clr-field {
  flex: 0 0 auto;
  display: flex;
}

.color-search-controls .clr-field button {
  display: none;
}

/* The block of color itself: the controller writes the chosen hex into this
   element's background-color, and white here is the color-less state behind the
   placeholder.

   Top padding is the optical-center nudge .account-button .label gets from a
   transform in 04_components.css: MaharamNeue's ascent and descent (800 and
   -300 against a 750 cap height) leave the cap band 0.125em above the middle of
   the line box, so centered text reads high. An input has no inner element to
   translate, so the correction is asymmetric padding — the browser centers the
   text in what is left of the content box, which halves the offset, hence 4px
   to move 16px type down the 2px it needs. */
.color-search-controls input[type="text"] {
  width: var(--color-search-field-width);
  height: 40px;
  padding: 4px var(--space-3) 0;
  border: 1px solid var(--color-gray-8);
  background-color: var(--color-white);
  color: transparent;
  caret-color: transparent;
  cursor: pointer;
  user-select: none;
  font-family: var(--font-stack);
  font-size: var(--font-size-4);
  transition: border-color var(--transition-fast);
}

.color-search-controls input[type="text"]::selection {
  background-color: transparent;
}

.color-search-controls input[type="text"]::placeholder {
  color: var(--color-gray-16);
}

.color-search-controls input[type="text"]:focus {
  outline: none;
  border-color: var(--color-black);
}

/* .account-button is the right size here, but its neutral white fill belongs to
   the two facet dropdowns beside it — this is the button that runs the search,
   so it takes .cta-primary's coloring instead: primary fill, white label.

   Scoped to the submit rather than applied to .account-button: the facet
   summaries carry that class too, and a row of three orange pills would say
   nothing about which one submits.

   The border goes with the fill. .cta has none, and .account-button's gray one
   left a visible ring around the color. */
.color-search-controls button[type="submit"] {
  border-color: var(--color-primary);
  background-color: var(--color-primary);
  color: var(--color-white);

  &:hover {
    border-color: var(--color-primary-hover);
    background-color: var(--color-primary-hover);
  }
}

/* CATEGORY / PATTERN DROPDOWNS */

/* The containing block for this dropdown's panel. Safe despite the warning at
   the top of this file: only a panel's own ancestors form its containing block,
   and Coloris' panel is appended to document.body, not in here. */
.color-facet {
  position: relative;
}

/* <summary> defaults to display: list-item. .account-button's inline-flex
   already suppresses the Firefox marker; this drops WebKit's. */
.color-facet-toggle {
  list-style: none;
  padding-inline: var(--space-4);
  font-weight: 400;
  user-select: none;
}

.color-facet-toggle::-webkit-details-marker {
  display: none;
}

.color-facet[open] > .color-facet-toggle {
  border-color: var(--color-black);
}

/* .account-button lays its children out with a gap, so an unselected facet's
   empty count span would still push the chevron over. */
.color-facet-count:empty {
  display: none;
}

.color-facet-icon {
  width: 7px;
  height: 7px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform var(--transition-fast);
}

.color-facet[open] > .color-facet-toggle .color-facet-icon {
  transform: translateY(2px) rotate(-135deg);
}

/* Above the swatch wall, which lifts a hovered item to 20, and below Coloris'
   panel at 1000 in 21_coloris.css — so opening the color picker over a
   dropdown reads the right way round.

   width: max-content so "Maharam Digital Projects" sets the width instead of
   wrapping; min-width so a short list is never narrower than its own button. */
.color-facet-panel {
  position: absolute;
  top: calc(100% + var(--space-2));
  z-index: 30;
  width: max-content;
  min-width: 100%;
  max-height: 60vh;
  overflow-y: auto;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-gray-8);
  background-color: var(--color-white);
  box-shadow: 0 2px 24px rgba(0, 0, 0, 0.18);
  text-align: left;
}

.color-facet-panel--start {
  left: 0;
}

.color-facet-panel--end {
  right: 0;
}

.color-facet-option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 5px 0;
  cursor: pointer;
  font-size: var(--font-size-3);
  line-height: 1.35;
  white-space: nowrap;
}

.color-facet-option:hover {
  color: var(--color-primary);
}

/* products.css hides the native box on the products index (.facet-label input
   { opacity: 0 }) because the selections tray shows the state as chips
   instead. There is no tray here, so the box has to carry the state itself.
   These are .color-facet-* class names precisely so that rule cannot reach
   them. */
.color-facet-option input[type="checkbox"] {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  margin: 0;
  accent-color: var(--color-black);
  cursor: pointer;
}

/* COLOR SUGGESTIONS */

.color-harmony-groups {
  display: grid;
  gap: var(--space-2);
}

.color-harmony-group {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* "Complementary" is the longest of the four labels; sizing the column in ems
   holds the swatch rows in line without hard-coding a pixel width that a font
   change would break. */
.color-harmony-label {
  flex: 0 0 auto;
  min-width: 8em;
  color: var(--color-gray-16);
  font-size: var(--font-size-2);
}

.color-harmony-swatches {
  display: flex;
  gap: var(--space-2);
}

/* Round, matching the swatch buttons Coloris draws in the picker next to this,
   so the two read as the same kind of thing. The inset ring keeps a pale
   suggestion from vanishing into the white panel. */
.color-harmony-swatch {
  display: block;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.15);
  transition: transform var(--transition-fast);
}

.color-harmony-swatch:hover {
  transform: scale(1.15);
}

.color-harmony-empty {
  max-width: 24ch;
  color: var(--color-gray-16);
  font-size: var(--font-size-2);
}

.color-harmony-rule {
  margin: var(--space-3) 0;
  border: 0;
  border-top: 1px solid var(--color-gray-4);
}

/* Ten circles on one line would set the panel's width, since the panel sizes
   to max-content and would therefore never wrap on its own. Capping the row at
   five folds them into two tidy rows and leaves the width to the schemes
   above. */
.color-harmony-swatches--recent {
  flex-wrap: wrap;
  max-width: calc((22px * 5) + (var(--space-2) * 4));
}

/* The newest recent color is the one currently on screen. The ring says so,
   rather than leaving a circle that looks like a stray duplicate. */
.color-harmony-swatch.is-current {
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.15),
    0 0 0 2px var(--color-black);
}

/* IMAGE COLOR EXTRACTION */

/* The one panel that cannot size to max-content: an image is as wide as it is,
   so the shared rule would let a landscape photo set the panel's width and
   push it off the screen. 17rem is picked to fit the palette — eight 22px
   circles and seven --space-2 gaps come to 232px, inside the 240px this leaves
   between the panel's own padding.

   Deliberately declared before the media query below, which sets
   .color-facet-panel to width: 100% at equal specificity. Source order is what
   lets that override keep winning on a stacked row. */
.color-extract-panel {
  width: 17rem;
}

/* The whole panel body is the target, not just the empty box, so a second
   image can be dropped straight onto the first to replace it. The dashed
   border is only drawn in the empty state, where it is an invitation; over a
   photo it would just be a box. Reserved as transparent either way, so the
   drag highlight does not reflow the panel. */
.color-extract-zone {
  display: grid;
  justify-items: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-3);
  border: 1px dashed transparent;
  transition:
    border-color var(--transition-fast),
    background-color var(--transition-fast);
}

.color-extract-zone:not(.is-loaded) {
  border-color: var(--color-gray-8);
}

.color-extract-zone.is-loaded {
  padding: 0;
}

.color-extract-zone.is-dragging {
  border-color: var(--color-primary);
  background-color: var(--color-gray-2);
}

.color-extract-prompt {
  color: var(--color-gray-16);
  font-size: var(--font-size-2);
  text-align: center;
}

/* The keyboard path to the file dialog, since the input itself is out of the
   tab order — see the note in the partial. Sized down from .account-button:
   these sit inside a panel, not in the control row. */
.color-extract-browse,
.color-extract-remove {
  height: 28px;
  /* Top padding is the same optical-center nudge the hex field above gets, and
     works the same way: a button centers its bare text in the content box, so
     3px off the top moves 12px type down the 1.5px MaharamNeue's metrics owe
     it. Bare text rather than a .label span because these are built for a
     panel, not for the control row. */
  padding: 3px var(--space-3) 0;
  border: 1px solid var(--color-gray-8);
  border-radius: var(--radius-round);
  background-color: var(--color-white);
  color: var(--color-black);
  font-family: var(--font-stack);
  font-size: var(--font-size-2);
  cursor: pointer;
  transition:
    border-color var(--transition-fast),
    color var(--transition-fast);

  &:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
  }

  &:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
  }
}

/* One state at a time: prompt and browse button before an image, preview and
   remove button after it. The controller only ever toggles .is-loaded. */
.color-extract-zone.is-loaded .color-extract-prompt,
.color-extract-zone.is-loaded .color-extract-browse,
.color-extract-preview,
.color-extract-remove {
  display: none;
}

.color-extract-zone.is-loaded .color-extract-preview,
.color-extract-zone.is-loaded .color-extract-remove {
  display: block;
}

/* Capped well under the panel's own max-height: 60vh, so the palette and the
   button below it are on screen without scrolling. contain rather than cover —
   a crop would hide part of what the colors were taken from. */
.color-extract-preview {
  width: 100%;
  max-height: 180px;
  object-fit: contain;
  background-color: var(--color-gray-2);
}

.color-extract-palette {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
}

/* Nothing extracted yet, or nothing extractable — the zone's grid gap would
   otherwise leave a hole between the preview and the button. */
.color-extract-palette:empty {
  display: none;
}

/* Carries .color-harmony-swatch too, so an extracted color is the same circle,
   ring and hover as a suggested one. This adds only the cursor, which the
   harmony swatches get from being anchors with an href at parse time; these
   are built by script. */
.color-extract-swatch {
  cursor: pointer;
}

.color-extract-status {
  margin-top: var(--space-3);
  color: var(--color-gray-16);
  font-size: var(--font-size-2);
  text-align: center;
}

.color-extract-status:empty {
  display: none;
}

/* SEARCH BREADTH */

/* Sized rather than max-content, which would collapse to the width of the two
   end labels and leave a stub of a track. Before the media query, which
   overrides it at equal specificity. */
.color-breadth-panel {
  /* The thumb's diameter, named because three things depend on it: the thumb
     itself, the -webkit thumb's centering offset, and the inset that lines the
     numbered scale up with where the thumb can actually sit. */
  --breadth-thumb: 16px;
  --breadth-track: 7px;

  width: 16rem;

  /* A <label> is inline, so the range would share its line. */
  .color-breadth-heading {
    display: block;
    margin-bottom: var(--space-2);
    font-size: var(--font-size-3);
  }

  .color-breadth-range {
    display: block;
    width: 100%;
    margin: 0;
    appearance: none;
    background-color: transparent;
    cursor: pointer;

    &::-webkit-slider-runnable-track {
      height: var(--breadth-track);
      border-radius: calc(var(--breadth-track) / 2);
      background-color: var(--color-gray-8);
    }

    /* Firefox fills the segment before the thumb through a track of its own */
    &::-moz-range-track,
    &::-moz-range-progress {
      height: var(--breadth-track);
      border-radius: calc(var(--breadth-track) / 2);
      background-color: var(--color-gray-8);
    }

    /* The negative margin centers the thumb on the track */
    &::-webkit-slider-thumb {
      appearance: none;
      width: var(--breadth-thumb);
      height: var(--breadth-thumb);
      margin-top: calc((var(--breadth-track) - var(--breadth-thumb)) / 2);
      border-radius: 50%;
      background-color: var(--color-black);
    }

    &::-moz-range-thumb {
      width: var(--breadth-thumb);
      height: var(--breadth-thumb);
      border: 0;
      border-radius: 50%;
      background-color: var(--color-black);
    }

    &:focus-visible {
      outline: 2px solid var(--color-primary);
      outline-offset: 2px;
    }
  }

  .color-breadth-scale {
    position: relative;
    height: 1.9em;
    margin: 2px calc(var(--breadth-thumb) / 2) 0;
    color: var(--color-gray-16);
    font-size: var(--font-size-2);

    span {
      position: absolute;
      padding: 4px 8px;
      transform: translateX(-50%);
      cursor: pointer;

      &:hover {
        color: var(--color-black);
      }
    }
  }

  .color-breadth-ends {
    display: flex;
    justify-content: space-between;
    color: var(--color-gray-16);
    font-size: var(--font-size-2);
  }
}

/* Below the wrap point the row stacks, and a panel anchored to one edge of a
   full-width button would hang off the screen. */
@media (max-width: 32rem) {

  .color-facet {
    flex: 1 1 100%;
  }

  .color-facet-panel {
    left: 0;
    right: auto;
    width: 100%;
  }

}

/* .sorting-wrapper is space-between so the products index can sit a sort
   dropdown opposite the pagination. This page has no sort control, so the lone
   pagination block would fall to the left without this. */
.color-search .sorting-wrapper {
  justify-content: flex-end;
}

/* SWATCH WALL */

/* auto-fill rather than a fixed column count: the swatch is a fixed size, so
   the number that fits is a property of the viewport, not of the design. */
.color-swatch-grid {
  --swatch-size: 138px;
  --swatch-gap: 6px;
  --swatch-card-width: 300px;
  display: grid;
  grid-template-columns: repeat(auto-fill, var(--swatch-size));
  justify-content: space-between;
  gap: var(--swatch-gap);
  margin-bottom: var(--space-6);
}

.color-swatch-item {
  position: relative;
  width: var(--swatch-size);
  height: var(--swatch-size);
}

/* Siblings are painted in document order, so a later swatch would cover an
   earlier one's card. Raising the whole item — not just the card — lifts it
   clear of the ones after it. */
.color-swatch-item:hover,
.color-swatch-item:focus-within {
  z-index: 20;
}

.color-swatch-link {
  display: block;
}

.color-swatch {
  display: block;
  width: var(--swatch-size);
  height: var(--swatch-size);
  object-fit: cover;
  background-color: var(--color-gray-2);
}

/* Centred on its swatch, then nudged back inside the viewport at the edges by
   swatch_preview_controller.js via the two shift properties.

   visibility rather than display, so the controller can measure the card
   before it is shown. pointer-events: none matters just as much — at 300px the
   hidden card covers its neighbours, and would otherwise swallow hovers meant
   for them. */
.color-swatch-detail {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--swatch-card-width);
  transform:
    translate(-50%, -50%)
    translate(var(--swatch-shift-x, 0px), var(--swatch-shift-y, 0px));
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 150ms ease, visibility 0s linear 150ms;
}

.color-swatch-detail .card {
  box-shadow: 0 2px 24px rgba(0, 0, 0, 0.22);
}

/* Guarded on a real pointer: on touch there is no hover to leave, so the card
   would stick open over the neighbours it covers. Tapping the swatch follows
   its link instead, which is where the card would have led anyway. */
@media (hover: hover) {

  .color-swatch-item:hover .color-swatch-detail,
  .color-swatch-item:focus-within .color-swatch-detail {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    /* Held back long enough that dragging across the wall does not strobe. */
    transition: opacity 200ms ease 250ms, visibility 0s linear 250ms;
  }

}
