/* =========================================================
   DANCEMIX.CA — iPod shuffle (4th generation)
   Body modelled on the real thing: 29 x 31.6 x 8.7 mm,
   one piece of anodised aluminium, circular control pad,
   status light / VoiceOver / three-way switch on the top
   edge. The shuffle never had a screen, so the one line
   readout is a separate object floating above it.
   ========================================================= */

:root {

  /* device geometry, all derived from the width.
     real ratios: h = w x 1.09, depth = w x 0.30,
     corner radius = w x 0.155, pad = w x 0.79 */
  --w:min(300px,74vw);
  --h:calc(var(--w) * 1.09);
  --d:calc(var(--w) * 0.30);
  --r:calc(var(--w) * 0.155);
  --pad:calc(var(--w) * 0.79);
  --tilt:16deg;

  /* (PRODUCT)RED anodising */
  --red-hi:#e2544c;
  --red-1:#cf2e30;
  --red-2:#b81c26;
  --red-3:#95121e;
  --red-4:#720c16;
  --red-edge:#5d0912;

  /* laser etched markings */
  --etch:rgba(255,255,255,.88);
  --etch-dim:rgba(255,255,255,.42);

  /* readout */
  --screen:#fff;
  --blue-1:#8ab7ff;
  --blue-2:#2764c5;
  --blue-3:#17478f;
  --text:#0b0b0b;
  --muted:#6a6a6a;

  --mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono",monospace;
  --ui:-apple-system,BlinkMacSystemFont,"Lucida Grande","Helvetica Neue",Arial,sans-serif;
}

* {
  box-sizing:border-box;
}

html,
body {
  min-height:100%;
}

body {
  margin:0;
  min-height:100svh;
  padding:18px 10px;
  overflow-x:hidden;
  display:grid;
  place-items:center;
  background:#000;
  color:#fff;
  font-family:var(--ui);
}

button {
  font:inherit;
}


/* =========================================================
   BACKGROUND
   ========================================================= */

.site-background {
  position:fixed;
  top:0;
  right:0;
  bottom:0;
  left:0;
  width:100%;
  height:100%;
  object-fit:cover;
  z-index:-3;
  pointer-events:none;
  background:#000;
  filter:brightness(.68) saturate(.9);
}

.site-background-overlay {
  position:fixed;
  top:0;
  right:0;
  bottom:0;
  left:0;
  z-index:-2;
  pointer-events:none;
  background:
    radial-gradient(
      circle at center,
      rgba(0,0,0,.02) 0%,
      rgba(0,0,0,.18) 62%,
      rgba(0,0,0,.45) 100%
    );
}


/* =========================================================
   SHELL
   ========================================================= */

.site-shell {
  width:100%;
  display:grid;
  place-items:center;
}

.rig {
  display:grid;
  justify-items:center;
  gap:clamp(18px,5vw,30px);
}


/* =========================================================
   DETACHED READOUT
   Its own housing. Floats above the shuffle, unattached.
   ========================================================= */

.readout {
  position:relative;
  width:calc(var(--w) * 1.18);
  transform:perspective(900px) rotateX(-5deg);
}

.readout-stem {
  position:absolute;
  left:50%;
  bottom:calc(var(--w) * -0.11);

  width:1px;
  height:calc(var(--w) * 0.09);

  transform:translateX(-50%);

  background:linear-gradient(
    to bottom,
    rgba(255,255,255,.22),
    rgba(255,255,255,0)
  );
}

.display-bezel {
  padding:5px;

  border:1px solid #000;
  border-radius:9px;

  background:
    linear-gradient(
      to bottom,
      #4c4c4e 0%,
      #2b2b2d 40%,
      #171718 100%
    );

  box-shadow:
    0 14px 28px rgba(0,0,0,.6),
    0 2px 5px rgba(0,0,0,.5),
    inset 0 1px 0 rgba(255,255,255,.22),
    inset 0 -1px 0 rgba(0,0,0,.6);
}

.display {
  height:clamp(28px,8vw,34px);

  display:grid;
  grid-template-columns:20px minmax(0,1fr) auto;
  align-items:center;
  gap:7px;

  padding:0 8px;

  position:relative;
  overflow:hidden;

  border-radius:4px;

  background:
    linear-gradient(
      to bottom,
      rgba(255,255,255,.62) 0%,
      rgba(238,240,236,.48) 100%
    );

  color:var(--text);

  box-shadow:
    inset 0 2px 6px rgba(0,0,0,.45),
    inset 0 -1px 0 rgba(255,255,255,.35);
}

.display-video {
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;

  width:100%;
  height:100%;

  object-fit:cover;

  z-index:0;

  opacity:.16;

  pointer-events:none;

  filter:brightness(.9) saturate(.75);
}

/* scanlines */
.display::after {
  content:"";

  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;

  z-index:4;

  pointer-events:none;

  opacity:.14;

  background:
    repeating-linear-gradient(
      to bottom,
      rgba(0,0,0,.16) 0,
      rgba(0,0,0,.16) 1px,
      transparent 1px,
      transparent 3px
    );

  mix-blend-mode:multiply;
}

.display-glyph {
  position:relative;
  z-index:2;

  display:grid;
  place-items:center;

  height:16px;

  border-radius:2px;

  background:
    linear-gradient(
      to bottom,
      var(--blue-1) 0%,
      var(--blue-2) 58%,
      var(--blue-3) 100%
    );

  color:#fff;

  font-size:7px;
  line-height:1;
}

.display-track {
  position:relative;
  z-index:2;

  min-width:0;

  overflow:hidden;

  -webkit-mask-image:linear-gradient(
    to right,
    transparent 0,
    #000 8px,
    #000 calc(100% - 8px),
    transparent 100%
  );

  mask-image:linear-gradient(
    to right,
    transparent 0,
    #000 8px,
    #000 calc(100% - 8px),
    transparent 100%
  );
}

.display-line {
  display:inline-flex;
  align-items:center;

  white-space:nowrap;

  font:10px/1 var(--mono);
  letter-spacing:.6px;
  font-weight:700;

  text-shadow:0 1px 0 rgba(255,255,255,.6);
}

.display-line.is-static {
  display:flex;
  justify-content:center;
}

.display-line.is-scrolling {
  animation:marquee linear infinite;
}

.display-text + .display-text {
  padding-left:38px;
}

@keyframes marquee {
  from { transform:translateX(0); }
  to   { transform:translateX(-50%); }
}

.display-time {
  position:relative;
  z-index:2;

  color:var(--muted);

  font:9px var(--mono);
  font-variant-numeric:tabular-nums;
}

.display.is-dark .display-glyph,
.display.is-dark .display-line,
.display.is-dark .display-time {
  opacity:.18;
}


/* =========================================================
   THE DEVICE
   A real box: front face + top face, tilted back so the
   top edge controls are reachable.
   ========================================================= */

.stage {
  position:relative;

  width:var(--w);
  height:calc(var(--h) + var(--d) * 0.32);

  perspective:1500px;
  perspective-origin:50% 26%;
}

.drop-shadow {
  position:absolute;
  left:50%;
  bottom:calc(var(--w) * -0.06);

  width:86%;
  height:calc(var(--w) * 0.14);

  transform:translateX(-50%);

  border-radius:50%;

  background:radial-gradient(
    ellipse at center,
    rgba(0,0,0,.72) 0%,
    rgba(0,0,0,.35) 45%,
    rgba(0,0,0,0) 72%
  );

  filter:blur(3px);
}

.shuffle {
  position:absolute;
  left:0;
  bottom:0;

  width:var(--w);
  height:var(--h);

  transform-style:preserve-3d;
  transform:rotateX(var(--tilt));

  transition:filter .2s ease;
}

.shuffle.is-off {
  filter:saturate(.86) brightness(.92);
}

.body {
  position:relative;

  width:100%;
  height:100%;

  transform-style:preserve-3d;
}

.face {
  position:absolute;
}


/* ---------- FRONT ---------- */

.front-face {
  top:0;
  right:0;
  bottom:0;
  left:0;

  border-radius:var(--r);

  transform:translateZ(calc(var(--d) / 2));

  background:
    /* specular sweep */
    linear-gradient(
      118deg,
      rgba(255,255,255,.20) 0%,
      rgba(255,255,255,.05) 26%,
      rgba(255,255,255,0) 44%,
      rgba(0,0,0,.10) 76%,
      rgba(0,0,0,.20) 100%
    ),
    /* anodised gradient */
    linear-gradient(
      to bottom,
      var(--red-hi) 0%,
      var(--red-1) 18%,
      var(--red-2) 52%,
      var(--red-3) 82%,
      var(--red-4) 100%
    );

  box-shadow:
    /* rolled edges */
    inset 0 1px 0 rgba(255,255,255,.55),
    inset 0 -1px 0 rgba(0,0,0,.45),
    inset 3px 0 6px -3px rgba(255,255,255,.28),
    inset -3px 0 7px -3px rgba(0,0,0,.45),
    0 0 0 1px rgba(0,0,0,.35);
}

/* fine machined grain */
.front-face::before {
  content:"";

  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;

  border-radius:inherit;

  pointer-events:none;

  opacity:.5;

  background:
    repeating-linear-gradient(
      to right,
      rgba(255,255,255,.035) 0 1px,
      rgba(0,0,0,.035) 1px 2px
    );
}


/* ---------- TOP EDGE ---------- */

.top-face {
  top:0;
  left:0;

  width:100%;
  height:var(--d);

  transform-origin:top center;
  transform:translateZ(calc(var(--d) / -2)) rotateX(90deg);

  border-radius:var(--r) / calc(var(--d) * 0.92);

  background:
    linear-gradient(
      to bottom,
      var(--red-4) 0%,
      var(--red-3) 18%,
      var(--red-1) 58%,
      var(--red-hi) 88%,
      #ef7a6f 100%
    );

  box-shadow:
    inset 0 -1px 0 rgba(255,255,255,.35),
    inset 0 2px 5px rgba(0,0,0,.35);
}

.top-face::before {
  content:"";

  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;

  border-radius:inherit;

  pointer-events:none;

  background:
    repeating-linear-gradient(
      to right,
      rgba(255,255,255,.03) 0 1px,
      rgba(0,0,0,.03) 1px 2px
    );
}


/* status light — a pinhole in the aluminium */

.led {
  position:absolute;
  top:50%;
  left:27%;

  width:calc(var(--w) * 0.032);
  height:calc(var(--w) * 0.032);

  transform:translate(-50%,-50%);

  border-radius:50%;

  background:#3a0a10;

  box-shadow:
    inset 0 1px 1px rgba(0,0,0,.9),
    0 0 0 1px rgba(0,0,0,.25);
}

.led.is-play {
  background:#66ff93;
  box-shadow:
    0 0 6px rgba(93,255,138,.95),
    0 0 12px rgba(93,255,138,.55);
}

.led.is-pause {
  background:#ffc24a;
  box-shadow:
    0 0 5px rgba(255,194,74,.9),
    0 0 11px rgba(255,194,74,.45);
}


/* VoiceOver button */

.voiceover {
  position:absolute;
  top:50%;
  left:45%;

  width:calc(var(--w) * 0.13);
  height:calc(var(--w) * 0.13);

  padding:0;

  transform:translate(-50%,-50%);

  border:0;
  border-radius:50%;

  background:
    radial-gradient(
      circle at 50% 22%,
      var(--red-1) 0%,
      var(--red-2) 55%,
      var(--red-4) 100%
    );

  box-shadow:
    0 0 0 1px rgba(0,0,0,.42),
    inset 0 1px 1px rgba(255,255,255,.35),
    inset 0 -1px 2px rgba(0,0,0,.4);

  cursor:pointer;

  -webkit-tap-highlight-color:transparent;
}

/* bigger invisible target than the button itself */
.voiceover::after {
  content:"";
  position:absolute;
  top:-60%;
  right:-40%;
  bottom:-60%;
  left:-40%;
}

.voiceover.pressed,
.voiceover:active {
  background:
    radial-gradient(
      circle at 50% 22%,
      var(--red-3) 0%,
      var(--red-4) 70%,
      #5d0912 100%
    );
}


/* three-way switch: shuffle | play in order | off
   (off is the far right position, and green shows in the
   slot as soon as you slide away from it) */

.switch {
  position:absolute;
  top:0;
  bottom:0;
  left:66%;

  width:26%;

  display:grid;
  grid-template-columns:repeat(3,1fr);
  align-items:center;
}

.switch-slot {
  position:absolute;
  top:50%;
  left:0;

  width:100%;
  height:calc(var(--w) * 0.088);

  transform:translateY(-50%);

  border-radius:calc(var(--w) * 0.02);

  background:
    linear-gradient(
      90deg,
      #1b0d0f 0 38%,
      #2f8b34 38%,
      #47b14a 100%
    );

  box-shadow:
    inset 0 2px 3px rgba(0,0,0,.8),
    inset 0 -1px 0 rgba(255,255,255,.18);
}

.switch-knob {
  position:absolute;
  top:50%;
  left:3%;

  z-index:2;

  width:40%;
  height:calc(var(--w) * 0.072);

  transform:translateY(-50%);

  border-radius:calc(var(--w) * 0.016);

  background:
    linear-gradient(
      to bottom,
      #fdfdfd 0%,
      #ececec 45%,
      #c9c9c9 100%
    );

  box-shadow:
    0 1px 2px rgba(0,0,0,.55),
    inset 0 1px 0 rgba(255,255,255,.9);

  transition:transform .16s ease-out;
}

/* translateY is re-stated so the transition keeps the centring */
.switch-knob[data-pos="shuffle"] { transform:translate(0,-50%); }
.switch-knob[data-pos="order"]   { transform:translate(67.5%,-50%); }
.switch-knob[data-pos="off"]     { transform:translate(135%,-50%); }

.switch-stop {
  position:relative;
  z-index:3;

  height:100%;

  padding:0;

  border:0;
  border-radius:0;

  background:transparent;

  cursor:pointer;

  -webkit-tap-highlight-color:transparent;
}


/* =========================================================
   CONTROL PAD
   One circle, same aluminium as the body, split by a
   machined hairline. Quadrants are the buttons.
   ========================================================= */

.pad {
  position:absolute;
  top:50%;
  left:50%;

  width:var(--pad);
  height:var(--pad);

  transform:translate(-50%,-50%);

  border-radius:50%;

  background:
    radial-gradient(
      circle at 38% 24%,
      rgba(255,255,255,.14) 0%,
      rgba(255,255,255,.04) 42%,
      rgba(0,0,0,0) 62%,
      rgba(0,0,0,.10) 100%
    );

  box-shadow:
    /* the etched ring */
    0 0 0 1px rgba(0,0,0,.34),
    0 1px 0 1px rgba(255,255,255,.14),
    inset 0 1px 1px rgba(0,0,0,.20),
    inset 0 -1px 1px rgba(255,255,255,.16);

  overflow:hidden;

  touch-action:none;
  user-select:none;
}

.pad-hit {
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;

  padding:0;

  border:0;
  border-radius:50%;

  background:transparent;

  cursor:pointer;

  -webkit-tap-highlight-color:transparent;
}

/* quadrant wedges, the way the real pad is split */
.pad-up    { clip-path:polygon(50% 50%, 0% 0%, 100% 0%); }
.pad-down  { clip-path:polygon(50% 50%, 0% 100%, 100% 100%); }
.pad-left  { clip-path:polygon(50% 50%, 0% 0%, 0% 100%); }
.pad-right { clip-path:polygon(50% 50%, 100% 0%, 100% 100%); }

.pad-hit .mark {
  position:absolute;
}

.pad-up .mark {
  top:6%;
  left:50%;
  transform:translateX(-50%);
}

.pad-down .mark {
  bottom:6%;
  left:50%;
  transform:translateX(-50%);
}

.pad-left .mark {
  left:5.5%;
  top:50%;
  transform:translateY(-50%);
}

.pad-right .mark {
  right:5.5%;
  top:50%;
  transform:translateY(-50%);
}

.pad-hit.pressed,
.pad-hit:active {
  background:
    radial-gradient(
      circle at center,
      rgba(0,0,0,.20) 0%,
      rgba(0,0,0,.10) 62%,
      rgba(0,0,0,.04) 100%
    );
}

.mark {
  fill:var(--etch);
  filter:drop-shadow(0 1px 0 rgba(0,0,0,.35));
}

.mark-plus,
.mark-minus {
  width:calc(var(--w) * 0.055);
  height:calc(var(--w) * 0.055);
}

.mark-skip {
  width:calc(var(--w) * 0.105);
  height:calc(var(--w) * 0.063);
}

.mark-play {
  width:calc(var(--w) * 0.115);
  height:calc(var(--w) * 0.064);
}


/* centre button */

.pad-center {
  position:absolute;
  left:50%;
  top:50%;

  width:42%;
  height:42%;

  transform:translate(-50%,-50%);

  border:0;
  border-radius:50%;

  padding:0;

  background:
    radial-gradient(
      circle at 40% 26%,
      rgba(255,255,255,.16) 0%,
      rgba(255,255,255,.04) 45%,
      rgba(0,0,0,.06) 78%,
      rgba(0,0,0,.14) 100%
    );

  box-shadow:
    0 0 0 1px rgba(0,0,0,.34),
    0 1px 0 1px rgba(255,255,255,.12),
    inset 0 1px 1px rgba(255,255,255,.18),
    inset 0 -1px 2px rgba(0,0,0,.18);

  cursor:pointer;

  -webkit-tap-highlight-color:transparent;
}

.pad-center:active,
.pad-center.pressed {
  background:
    radial-gradient(
      circle at 40% 26%,
      rgba(0,0,0,.16) 0%,
      rgba(0,0,0,.20) 100%
    );
}

.pad-center-mark {
  position:absolute;
  top:50%;
  left:50%;

  transform:translate(-50%,-50%);

  line-height:0;
}


/* =========================================================
   LABELS
   ========================================================= */

.outside-note {
  color:rgba(255,255,255,.35);

  font:8px var(--mono);

  letter-spacing:1.2px;
  text-align:center;
}


/* =========================================================
   FOCUS
   ========================================================= */

:focus-visible {
  outline:2px solid #ffd7d7;
  outline-offset:2px;
}


/* =========================================================
   REDUCED MOTION
   ========================================================= */

@media (prefers-reduced-motion:reduce) {
  *,
  *::before,
  *::after {
    transition:none!important;
  }

  .display-line.is-scrolling {
    animation:none!important;
  }
}


/* =========================================================
   MOBILE
   ========================================================= */

@media (max-width:600px) {

  body {
    padding:
      max(7px,env(safe-area-inset-top))
      5px
      max(12px,env(safe-area-inset-bottom));
  }

  :root {
    --w:min(282px,80vw);
    --tilt:19deg;
  }
}
