/* The fabric picker: the fabric of a made-to-order sofa, chosen beside a large swatch that hangs from an oak clamp
   on a brass rail, alone on a white page. The rail, the clamp, the cloth and its shadow on the wall are drawn by
   script.js on a canvas, and so are the five small swatches; their colours come from here. */
:root {
  --page: #ffffff;          /* the page, which is also the wall the rail is screwed to */
  --ink: #221c17;           /* the names, the fabric's name, the stitches round the swatch chosen */
  --muted: #8b8178;         /* the small words */
  --shadow: #3a2a1e;        /* the shadow the swatch casts on the wall */
  --brass: #c49a48;         /* the rail, its brackets, the hook and the clamp's caps */
  --brass-light: #f6dc9c;
  --brass-deep: #6e4f1c;
  --oak: #c08a52;           /* the clamp */
  --oak-light: #e2b882;
  --oak-deep: #7a4f27;
  --linen: #cdbb98;         /* washed linen, oat */
  --linen-deep: #6d5c40;
  --linen-light: #f1e6cf;
  --velvet: #1d5a48;        /* cotton velvet, bottle green */
  --velvet-deep: #06231b;
  --velvet-sheen: #8fd2b4;  /* the glow of the velvet on the flanks of its folds */
  --wool: #a24c2e;          /* herringbone wool, rust */
  --wool-deep: #4e1d0e;
  --wool-light: #e29a6c;
  --denim: #2b3f68;         /* selvedge denim, indigo */
  --denim-deep: #0c1630;
  --denim-light: #8ea3cc;
  --selvedge: #c4392b;      /* the red thread in the denim's finished edge */
  --cord: #c7952b;          /* cotton corduroy, mustard */
  --cord-deep: #5a3b07;
  --cord-light: #f5cf73;
  --label: #f4efe6;         /* the small woven label sewn on each swatch */
}

* {
  box-sizing: border-box;
}

/* a tap is a click at once: no wait for a double tap */
html {
  touch-action: manipulation;
}

html,
body {
  margin: 0;
  overflow-x: clip;
}

body {
  min-height: 100svh;
  background: var(--page);
  color: var(--ink);
  font-family: 'Instrument Sans Variable', 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
}

.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.stage {
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  place-items: center;
  padding: 32px 16px;
}

/* the swatch on its rail on the left, the choice on the right; one over the other on a phone */
.fabric {
  display: grid;
  grid-template-columns: 280px 300px;
  align-items: center;
  gap: 44px;
}

/* ---------------------------------------------------------------- the rail and the swatch */
/* the room the swatch hangs in: 280 by 380 at full size; the drawing scales with its height */
.fabric__hang {
  position: relative;
  width: 280px;
  height: 380px;
  touch-action: pan-y;
}

/* the canvas reaches a little past the room, for the swatch swinging out and its shadow */
.fabric__cloth {
  position: absolute;
  left: -30px;
  top: -30px;
  pointer-events: none;
}

/* ---------------------------------------------------------------- the choice */
.fabric__pick {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.fabric__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  font-size: 13px;
  line-height: 20px;
}

.fabric__title {
  font-weight: 640;
  letter-spacing: 0.01em;
}

.fabric__hint {
  color: var(--muted);
  white-space: nowrap;
}

/* the fabric's name, in a variable serif: every fabric has its own weight, softness and optical size */
.fabric__name {
  --w: 520;
  --s: 100;
  --o: 144;
  height: 58px;
  margin: 18px 0 6px;
  overflow: visible;
  font-family: 'Fraunces Variable', 'Fraunces', Georgia, serif;
  font-size: 52px;
  line-height: 58px;
  letter-spacing: -0.025em;
  font-variation-settings: 'wght' var(--w), 'SOFT' var(--s), 'opsz' var(--o);
  white-space: nowrap;
}

.fabric__name span {
  display: inline-block;
  will-change: transform;
}

.fabric__detail {
  margin: 0;
  font-size: 15px;
  line-height: 22px;
  font-weight: 540;
  white-space: nowrap;
}

.fabric__spec {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin: 2px 0 0;
  padding-bottom: 18px;
  border-bottom: 1px solid rgba(34, 28, 23, 0.1);
  font-size: 13.5px;
  line-height: 20px;
  color: var(--muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.fabric__price {
  color: var(--ink);
  font-weight: 620;
}

.fabric__detail > span,
.fabric__spec > span {
  display: inline-block;
}

/* ---------------------------------------------------------------- the five small swatches */
.fabric__chips {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 10px;
  margin-top: 22px;
}

.chip {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 9px;
  padding-top: 6px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}

/* the radio itself is hidden but stays in the page: it takes the focus, the arrows and the clicks */
.chip__radio {
  position: absolute;
  top: 30px;
  left: 50%;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

/* the swatch lifts and tilts under the pointer on a spring; the script only moves the chip itself */
.chip__lift {
  position: relative;
  display: block;
  width: 100%;
  max-width: 52px;
  aspect-ratio: 1;
  transform-origin: 50% 80%;
  transition: transform 0.5s cubic-bezier(0.34, 1.7, 0.5, 1);
}

.chip__cloth {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 1px 1px rgba(40, 28, 18, 0.22)) drop-shadow(0 5px 6px rgba(40, 28, 18, 0.16));
  transition: filter 0.4s ease;
}

/* the stitches sewn round the swatch chosen: a dashed seam, revealed by its mask as the needle goes round */
.chip__stitch {
  position: absolute;
  inset: -7px;
  width: calc(100% + 14px);
  height: calc(100% + 14px);
  overflow: visible;
  pointer-events: none;
}

.chip__sew {
  fill: none;
  stroke: #fff;
  stroke-width: 6;
  stroke-dasharray: 1 2;
  stroke-dashoffset: 1.5;
}

.chip__seam {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.3;
  stroke-dasharray: 3 2.4;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* the seam of a swatch not chosen fades once it is unpicked, so not even a speck of it stays */
.chip:not(.is-chosen) .chip__seam {
  opacity: 0;
  transition: opacity 0.2s ease 0.3s;
}

.chip__name {
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
  transition: color 0.25s ease, font-weight 0.25s ease;
}

.chip.is-chosen .chip__name {
  color: var(--ink);
  font-weight: 650;
}

.chip.is-chosen .chip__lift {
  transform: translateY(-2px);
}

.chip:active .chip__lift,
.chip.is-tap .chip__lift {
  transform: translateY(0) scale(0.92);
  transition-duration: 0.12s;
}

.chip:has(.chip__radio:focus-visible) .chip__lift {
  outline: 2px solid var(--ink);
  outline-offset: 11px;
  border-radius: 6px;
}

html[data-using='pointer'] .chip:has(.chip__radio:focus-visible) .chip__lift {
  outline: none;
}

@media (hover: hover) and (pointer: fine) {
  .chip:not(.is-chosen):hover .chip__lift {
    transform: translateY(-5px) rotate(-4deg);
  }

  .chip:not(.is-chosen):hover .chip__cloth {
    filter: drop-shadow(0 2px 2px rgba(40, 28, 18, 0.2)) drop-shadow(0 10px 9px rgba(40, 28, 18, 0.2));
  }

  .chip:not(.is-chosen):hover .chip__name {
    color: var(--ink);
  }

  .chip:active .chip__lift {
    transform: translateY(0) scale(0.92);
  }
}

/* ---------------------------------------------------------------- a phone: the swatch over the choice */
@media (max-width: 680px) {
  .fabric {
    grid-template-columns: minmax(0, 358px);
    justify-items: center;
    gap: 10px;
  }

  .fabric__hang {
    width: 200px;
    height: 270px;
  }

  .fabric__pick {
    width: 100%;
  }

  .fabric__name {
    height: 48px;
    margin: 10px 0 4px;
    font-size: 42px;
    line-height: 48px;
  }

  .fabric__spec {
    padding-bottom: 14px;
  }

  .fabric__chips {
    gap: 8px;
    margin-top: 12px;
  }

  .chip__lift {
    max-width: 56px;
  }
}

/* ---------------------------------------------------------------- reduced motion: no lifting, no tilting */
@media (prefers-reduced-motion: reduce) {
  .chip__lift,
  .chip.is-chosen .chip__lift,
  .chip:active .chip__lift,
  .chip.is-tap .chip__lift {
    transform: none;
    transition: none;
  }

  .chip__seam,
  .chip:not(.is-chosen) .chip__seam {
    transition: opacity 0.4s ease;
  }
}

@media (prefers-reduced-motion: reduce) and (hover: hover) and (pointer: fine) {
  .chip:not(.is-chosen):hover .chip__lift {
    transform: none;
  }
}
