.color-search {

  .color-search-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-6);
    margin-bottom: var(--space-4);

    h1.category-title {
      margin-bottom: 0;
      text-align: left;
      white-space: nowrap;
    }

    /* Below the wrap point each explore link is a full-width row of its own, so
       the title takes a line above them instead. */
    @media (max-width: 32rem) {
      display: block;

      .color-explore {
        width: 100%;
        margin-top: var(--space-3);
      }
    }
  }

  .color-explore {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-6);
    width: fit-content;
    max-width: 100%;

    .color-facet-toggle {
      display: flex;
      align-items: center;
      gap: var(--space-2);
      color: var(--color-black);
      font-size: var(--font-size-4);
      cursor: pointer;
      transition: color var(--transition-fast);

      /* MaharamNeue sits high, so icon needs to be bumped up. */
      .icon {
        stroke: currentColor;
        transform: translateY(-2px);
      }

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

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

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

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

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

      &.current {
        padding-bottom: var(--space-2);
        border-bottom: 1px solid var(--color-gray-4);
      }
    }

    .color-harmony-label {
      flex: 0 0 auto;
      /* 8em fits "Complementary" without pinning a width a font change would
         break. */
      min-width: 8em;
      color: var(--color-gray-16);
      font-size: var(--font-size-2);
    }

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

      /* The panel sizes to max-content, so ten in a row would set its width. */
      &.recent {
        flex-wrap: wrap;
        max-width: calc((22px * 5) + (var(--space-2) * 4));
      }
    }

    .color-harmony-swatch {
      display: block;
      width: 22px;
      height: 22px;
      padding: 0;
      border: 0;
      border-radius: 50%;
      /* Keeps a pale swatch off the white panel. */
      box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.15);
      cursor: pointer;
      transition: transform var(--transition-fast);

      &:hover {
        transform: scale(1.15);
      }

      /* The color the results on screen are for. */
      &.is-current {
        box-shadow:
          inset 0 0 0 1px rgba(0, 0, 0, 0.15),
          0 0 0 2px var(--color-black);
      }
    }

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

    /* Fixed rather than max-content: an image is as wide as it is, and would
       otherwise set the panel's width. */
    .color-extract-panel {
      width: 17rem;

      @media (max-width: 32rem) {
        width: 100%;
      }
    }

    /* The whole body is the drop target, so a second image replaces the first.
       The border is reserved 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);

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

      &.is-loaded {
        padding: 0;
      }

      &.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;
    }

    .color-extract-browse,
    .color-extract-remove {
      height: 28px;
      /* Optical-center nudge: MaharamNeue sits high in its em box, and a
         bare-text button has no .label span to translate. */
      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; 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;
    }

    /* contain, not cover: a crop would hide part of what the colors came 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);

      /* Otherwise the zone's grid gap leaves a hole below the preview. */
      &:empty {
        display: none;
      }
    }

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

      &:empty {
        display: none;
      }
    }
  }

  .color-palette {
    /* Each swatch is `flex: 1 1 0`, which divides the strip evenly however many
       colors it holds — and lets the controller animate one swatch's flex-grow
       between 0 and 1 to make the others re-divide with it, without measuring. */
    --color-palette-height: 125px;
    --color-palette-button: 26px;

    position: relative;
    height: var(--color-palette-height);
    margin-bottom: var(--space-4);
    border: 1px dashed var(--color-gray-8);
    overflow: hidden;

    @media (max-width: 32rem) {
      --color-palette-height: 120px;
    }

    /* Kept rather than removed, so the strip does not shift when its first color
       lands. */
    &:has(.color-palette-swatch) {
      border-color: transparent;
    }

    /* An inset ring rather than the border, which is transparent as soon as the
       strip holds a color. */
    &.is-dragging {
      box-shadow: inset 0 0 0 2px var(--color-black);
    }

    .color-palette-swatches {
      display: flex;
      height: 100%;
      margin: 0;
      padding: 0;
      list-style: none;
    }

    .color-palette-swatch {
      flex: 1 1 0;
      min-width: 0;
      position: relative;
      overflow: hidden;
      cursor: pointer;

      /* The one the search field is holding. An inset outline rather than a
         border, which would throw off width measurements. */
      &.selected {
        outline: 2px solid var(--color-black);
        outline-offset: -2px;
      }

      /* Still painted while it collapses, but no longer part of the palette. */
      &.is-leaving {
        pointer-events: none;

        .color-palette-remove {
          opacity: 0;
          pointer-events: none;
        }
      }

      &.is-dragged {
        opacity: 0.5;
      }
    }

    /* The whole empty strip is the button that opens the picker — the one way
       in to a first color, since every other way is a drag. */
    .color-palette-empty {
      position: absolute;
      inset: 0;
      display: grid;
      place-items: center;
      width: 100%;
      margin: 0;
      padding: 0;
      border: 0;
      background: none;
      color: var(--color-gray-16);
      font-family: var(--font-stack);
      font-size: var(--font-size-2);
      cursor: pointer;
      transition: color var(--transition-fast);

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

      /* The controller hides it with the attribute, which the display above
         would otherwise win against. */
      &[hidden] {
        display: none;
      }
    }

    /* Translucent white because it sits over whatever colors the visitor has
       collected. */
    .color-palette-status {
      position: absolute;
      right: var(--space-3);
      bottom: var(--space-3);
      margin: 0;
      padding: 5px var(--space-3) 3px;
      border-radius: 12px;
      background-color: rgba(255, 255, 255, 0.85);
      color: var(--color-black);
      font-size: var(--font-size-2);

      &:empty {
        display: none;
      }
    }

    /* In the corner rather than centered: the swatch itself is a button, and a
       target in the middle would swallow clicks meant for the color. */
    .color-palette-remove {
      position: absolute;
      top: var(--space-2);
      right: var(--space-2);
      display: grid;
      place-items: center;
      width: var(--color-palette-button);
      height: var(--color-palette-button);
      padding: 0;
      border: 0;
      border-radius: 50%;
      background-color: rgba(255, 255, 255, 0.85);
      cursor: pointer;
      transition:
        opacity var(--transition-fast),
        background-color var(--transition-fast);

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

    .color-palette-glyph {
      position: relative;
      width: 10px;
      height: 1px;
      background-color: var(--color-black);
    }

    /* pointer-events matters as much as the opacity — an invisible button still
       takes the click that lands on it. */
    @media (hover: hover) {

      .color-palette-remove {
        opacity: 0;
        pointer-events: none;
      }

      .color-palette-swatch:hover .color-palette-remove,
      .color-palette-swatch:focus-within .color-palette-remove {
        opacity: 1;
        pointer-events: auto;
      }

    }

  }

  .color-search-form {
    /* 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. */

    /* Mirrors .clr-picker's width in 22_coloris.css, so the field and the panel
       dropping out of it line up edge to edge. Keep the two in step. */
    --color-search-field-width: 200px;

    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 at connect() time; a flex wrapper keeps the same
       height as the input it now owns. */
    .clr-field {
      flex: 0 0 auto;
      display: flex;

      button {
        display: none;
      }
    }

    /* The block of color itself: the controller writes the chosen hex into this
       element's background-color.

       Top padding is the optical-center nudge a .button .label gets from a
       transform. An input has no inner element to translate, and the browser
       re-centers in what is left of the content box, so 4px buys 2px. */
    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);

      &::selection {
        background-color: transparent;
      }

      &::placeholder {
        color: var(--color-gray-16);
      }

      &:focus {
        outline: none;
        border-color: var(--color-black);
      }
    }

    .button {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: var(--space-2);
      min-height: 40px;
      height: 40px;
      padding: 0 var(--space-5);
      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-3);
      font-weight: 700;
      line-height: 1;
      white-space: nowrap;
      text-decoration: none;
      cursor: pointer;
      transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);

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

      /* MaharamNeue sits high in its em box; see the note in 04_components.css. */
      .label { line-height: 1; transform: translateY(2px); }
    }

    /* Scoped to the submit rather than to .button: the facet summaries carry
       that class too, and a row of orange pills would say nothing about which
       one searches. */
    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);
      }
    }

    .color-breadth-panel {
      /* Sized rather than max-content, which would collapse to the two end labels
         and leave a stub of a track. */

      /* Three things depend on the thumb's diameter: the thumb, the -webkit
         thumb's centering offset, and the scale's inset. */
      --breadth-thumb: 16px;
      --breadth-track: 7px;

      width: 16rem;

      @media (max-width: 32rem) {
        width: 100%;
      }

      /* 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);
      }
    }
  }

  .color-facet {
    /* The containing block for this dropdown's panel. Safe despite the note
       above: Coloris' panel hangs off document.body, not off this. */
    position: relative;

    /* Below the wrap point each row stacks one dropdown per line. The panel is
       sized off this, so it goes full width with the button. */
    @media (max-width: 32rem) {
      flex: 1 1 100%;
    }

    /* <summary> defaults to display: list-item. The flex display each toggle
       takes suppresses the Firefox marker; this drops WebKit's. */
    .color-facet-toggle {
      list-style: none;
      user-select: none;

      &::-webkit-details-marker {
        display: none;
      }
      &.button {
        padding-inline: var(--space-4);
        border-radius: 0;
        font-weight: 400;
      }
    }

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

      .color-facet-icon {
        transform: translateY(2px) rotate(-135deg);
      }
    }

    /* .button lays its children out with a gap, so an 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-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;

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

      /* 17_products.css hides the native box on the products index because a tray
         shows the state as chips. There is no tray here, so the box carries it.
         The .color-facet-* names are what keep that rule out. */
      input[type="checkbox"] {
        flex: 0 0 auto;
        width: 13px;
        height: 13px;
        margin: 0;
        accent-color: var(--color-black);
        cursor: pointer;
      }
    }
  }

  .color-facet-panel {
    /* Above the swatch wall, which lifts a hovered item to 20, and below Coloris'
       panel at 1000.
       max-content so a long option sets the width instead of wrapping; min-width
       so a short list is never narrower than its own button. */
    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;

    &.start {
      left: 0;
    }

    &.end {
      right: 0;
    }

    /* Below the wrap point the row stacks, and an edge-anchored panel under a
       full-width button would hang off the screen. &.end is restated so it does
       not outweigh this on specificity. */
    @media (max-width: 32rem) {
      width: 100%;

      &.end {
        left: 0;
        right: auto;
      }
    }
  }

  .sorting-wrapper {
    /* .sorting-wrapper is space-between so the products index can sit a sort
       dropdown opposite the pagination. This page has no sort control. */
    justify-content: flex-end;
  }

}

/* SWATCH WALL
   The Edelman color library reuses this wall and extends it. */
.color-swatch-grid {
  --swatch-size: 138px;
  --swatch-gap: 6px;
  --swatch-card-width: 300px;

  display: grid;
  /* auto-fill rather than a fixed column count: the swatch is a fixed size, so
     how many fit is a property of the viewport. */
  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 paint in document order, so a later swatch would cover an earlier
       one's card. Raising the item lifts it clear of the ones after it. */
    &.is-previewing,
    &:focus-within {
      z-index: 20;
    }


    /* Styles for devices that have hover, because on touch devices there is no
       hover to leave, so the card would stay open over its neighbours.
       And yet, the selector uses &.is-previewing instead of &:hover because
       browsers may leave a stale :hover behind when a drag ends elsewhere. */
    @media (hover: hover) {

      &.is-previewing .color-swatch-detail,
      &:focus-within .color-swatch-detail {
        opacity: 1;
        visibility: visible;
        transition: opacity 200ms ease;
      }

      &.is-previewing .color-swatch-detail {
        pointer-events: auto;
      }

    }
  }

  .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);
  }

  .color-swatch-detail {
    /* Centred on its swatch, then nudged back inside the viewport by
       swatch_preview_controller.js through the two shift properties.
       `visibility` rather than `display`, so the controller can measure it
       before it shows. pointer-events matters as much: at 300px the hidden
       card covers its neighbours and would swallow hovers meant for them. */
    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;

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