/* The Crate: a glass-fronted culture chamber drawn on an 88 x 100 pixel grid (see assets/js/crate.js).
   Layers, back to front: body svg (frame, lid, fill tube, base), colony canvas (52 x 54, sits in the window),
   glass svg (glare), frost, scan line, quarantine tape, plate and label text.
   Window rect in grid units: x 14, y 25, w 52, h 54. Tube glass: x 77, y 27, w 7, h 54. */

:root {
  --disc: polygon(53.125% 3.125%,53.125% 4.688%,62.5% 4.688%,62.5% 6.25%,67.188% 6.25%,67.188% 7.812%,70.312% 7.812%,70.312% 9.375%,73.438% 9.375%,73.438% 10.938%,76.562% 10.938%,76.562% 12.5%,78.125% 12.5%,78.125% 14.062%,79.688% 14.062%,79.688% 15.625%,81.25% 15.625%,81.25% 17.188%,82.812% 17.188%,82.812% 18.75%,84.375% 18.75%,84.375% 20.312%,85.938% 20.312%,85.938% 21.875%,87.5% 21.875%,87.5% 23.438%,89.062% 23.438%,89.062% 26.562%,90.625% 26.562%,90.625% 29.688%,92.188% 29.688%,92.188% 32.812%,93.75% 32.812%,93.75% 37.5%,95.312% 37.5%,95.312% 46.875%,96.875% 46.875%,96.875% 53.125%,95.312% 53.125%,95.312% 62.5%,93.75% 62.5%,93.75% 67.188%,92.188% 67.188%,92.188% 70.312%,90.625% 70.312%,90.625% 73.438%,89.062% 73.438%,89.062% 76.562%,87.5% 76.562%,87.5% 78.125%,85.938% 78.125%,85.938% 79.688%,84.375% 79.688%,84.375% 81.25%,82.812% 81.25%,82.812% 82.812%,81.25% 82.812%,81.25% 84.375%,79.688% 84.375%,79.688% 85.938%,78.125% 85.938%,78.125% 87.5%,76.562% 87.5%,76.562% 89.062%,73.438% 89.062%,73.438% 90.625%,70.312% 90.625%,70.312% 92.188%,67.188% 92.188%,67.188% 93.75%,62.5% 93.75%,62.5% 95.312%,53.125% 95.312%,53.125% 96.875%,46.875% 96.875%,46.875% 95.312%,37.5% 95.312%,37.5% 93.75%,32.812% 93.75%,32.812% 92.188%,29.688% 92.188%,29.688% 90.625%,26.562% 90.625%,26.562% 89.062%,23.438% 89.062%,23.438% 87.5%,21.875% 87.5%,21.875% 85.938%,20.312% 85.938%,20.312% 84.375%,18.75% 84.375%,18.75% 82.812%,17.188% 82.812%,17.188% 81.25%,15.625% 81.25%,15.625% 79.688%,14.062% 79.688%,14.062% 78.125%,12.5% 78.125%,12.5% 76.562%,10.938% 76.562%,10.938% 73.438%,9.375% 73.438%,9.375% 70.312%,7.812% 70.312%,7.812% 67.188%,6.25% 67.188%,6.25% 62.5%,4.688% 62.5%,4.688% 53.125%,3.125% 53.125%,3.125% 46.875%,4.688% 46.875%,4.688% 37.5%,6.25% 37.5%,6.25% 32.812%,7.812% 32.812%,7.812% 29.688%,9.375% 29.688%,9.375% 26.562%,10.938% 26.562%,10.938% 23.438%,12.5% 23.438%,12.5% 21.875%,14.062% 21.875%,14.062% 20.312%,15.625% 20.312%,15.625% 18.75%,17.188% 18.75%,17.188% 17.188%,18.75% 17.188%,18.75% 15.625%,20.312% 15.625%,20.312% 14.062%,21.875% 14.062%,21.875% 12.5%,23.438% 12.5%,23.438% 10.938%,26.562% 10.938%,26.562% 9.375%,29.688% 9.375%,29.688% 7.812%,32.812% 7.812%,32.812% 6.25%,37.5% 6.25%,37.5% 4.688%,46.875% 4.688%,46.875% 3.125%);
}

.crate-slot { position: relative; display: grid; place-items: end center; }
.crate {
  --m1: var(--ink-2); --m2: var(--ink); --m3: var(--ink-3); --led: var(--pink);
  --fill: 0;
  position: relative; width: 100%; aspect-ratio: 88 / 100; container-type: inline-size;
  margin-inline: auto; user-select: none; -webkit-user-select: none;
}
/* snap to half-pixel multiples of the grid so the pixel art stays crisp */
@supports (width: round(down, 100%, 44px)) {
  .crate { width: max(88px, round(down, 100%, 44px)); }
}
.crate > * { position: absolute; }
.crate-body, .crate-glass { inset: 0; width: 100%; height: 100%; display: block; overflow: visible; }
.crate-body rect, .crate-body path { transition: fill .48s steps(4); }
.crate .ink { fill: var(--ink); }
.crate .m1 { fill: var(--m1); } .crate .m2 { fill: var(--m2); } .crate .m3 { fill: var(--m3); }
.crate .pink { fill: var(--pink); } .crate .paper { fill: var(--paper); }
.crate .glass { fill: var(--glass); } .crate .glass-2 { fill: #c9ece4; }
.crate .vent { fill: var(--ink); opacity: .85; }
.crate .led { fill: var(--led); }
.crate .tube { fill: #f4fffb; }
.crate .liq { fill: var(--pink); transform-box: fill-box; transform-origin: 50% 100%; transform: scaleY(var(--fill)); transition: transform .6s steps(9); }
.crate .liq-top { fill: var(--pink-2); transform-box: view-box; transform: translateY(calc((1 - var(--fill)) * 54px)); transition: transform .6s steps(9); }
.crate .tick { fill: var(--ink); opacity: .55; }
.crate .glare { fill: #fff; opacity: .7; }
.crate .shade { fill: var(--ink); opacity: .22; }
.crate .glint { fill: #fff; opacity: 0; }

.crate-colony {
  left: 15.909%; top: 25%; width: 59.091%; height: 54%;
  image-rendering: pixelated; image-rendering: crisp-edges;
}
.crate-glass { pointer-events: none; }

/* frosted glass: a 2 x 2 unit dither over the window */
.crate-frost {
  left: 15.909%; top: 25%; width: 59.091%; height: 54%;
  background-color: rgba(223, 247, 241, .35);
  background-image: repeating-conic-gradient(rgba(255, 253, 244, .92) 0 25%, rgba(201, 236, 228, .5) 0 50%);
  background-size: calc(200% / 52) calc(200% / 54);
  opacity: 0; transition: opacity .6s steps(5);
}
.crate[data-state="sealed"] .crate-frost { opacity: 1; }

/* observation scan line on sealed crates */
.crate-scan {
  left: 15.909%; top: 25%; width: 59.091%; height: 54%; overflow: hidden; opacity: 0; pointer-events: none;
}
.crate-scan::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: calc(100% / 54 * 2);
  background: var(--lime); box-shadow: 0 0 0 1px rgba(143, 209, 79, .35), 0 calc(100cqw / 88 * 2) 0 rgba(143, 209, 79, .25);
  animation: scan 3.2s steps(26) infinite;
}
.crate[data-state="sealed"] .crate-scan { opacity: .9; }
@keyframes scan { from { transform: translateY(0); } to { transform: translateY(calc(100cqw / 88 * 52)); } }

/* quarantine tape */
.crate-tape {
  left: 6%; right: 6%; top: 43%; height: 8.5%;
  display: flex; align-items: center; overflow: hidden; white-space: nowrap;
  background: var(--pink); color: #fff; border-block: calc(100cqw / 88) solid var(--ink);
  transform: rotate(-11deg); transform-origin: 50% 50%;
  font: 400 max(8px, 3.6cqw)/1 var(--num); text-transform: uppercase; letter-spacing: .06em;
  box-shadow: 0 calc(100cqw / 88) 0 rgba(43, 24, 56, .25);
  transition: transform .5s steps(5), opacity .5s steps(5);
}
.crate-tape span { display: inline-block; padding-left: 4%; animation: tape 16s linear infinite; }
.crate-tape--b {
  top: 58%; left: 12%; right: 10%; height: 6.5%; background: var(--gold); color: var(--ink);
  transform: rotate(8deg); font-size: max(7px, 2.8cqw);
}
.crate-tape--b span { animation-duration: 22s; animation-direction: reverse; }
@keyframes tape { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.crate:not([data-state="sealed"]) .crate-tape { opacity: 0; transform: translateY(40%) rotate(-24deg) scale(.9); pointer-events: none; }
.crate:not([data-state="sealed"]) .crate-tape--b { transform: translateY(60%) rotate(20deg) scale(.9); }

/* the "?" in a sealed fill tube */
.crate-tubeq {
  left: 87.5%; top: 27%; width: 7.955%; height: 54%;
  background: repeating-linear-gradient(180deg, var(--ink-3) 0 calc(100cqw / 88 * 2), transparent 0 calc(100cqw / 88 * 4));
  opacity: .45; transition: opacity .4s steps(4);
}
.crate:not([data-state="sealed"]) .crate-tubeq { opacity: 0; }

.crate-plate {
  left: 31.818%; top: 11%; width: 36.364%; height: 6%;
  display: grid; place-items: center; overflow: hidden;
  font: 400 max(7px, 3.7cqw)/1 var(--num); text-transform: uppercase; color: var(--ink); letter-spacing: .04em;
}
.crate-label {
  left: 26.136%; top: 90%; width: 47.727%; height: 4%;
  display: grid; place-items: center; overflow: hidden;
  font: 400 max(6px, 2.4cqw)/1 var(--num); text-transform: uppercase; color: var(--ink-2); white-space: nowrap;
}
@container (max-width: 200px) { .crate-label { display: none; } }

/* steam from the lid vents while unsealing */
.crate-steam { left: 8%; top: 0; width: 84%; height: 14%; pointer-events: none; }
.crate-steam i {
  position: absolute; bottom: 0; width: calc(100cqw / 88 * 3); height: calc(100cqw / 88 * 3); background: var(--paper);
  box-shadow: 0 0 0 calc(100cqw / 88 * .6) var(--ink-3); opacity: 0;
}
.crate.is-unsealing .crate-steam i { animation: steam 1.1s steps(6) both; }
.crate-steam i:nth-child(1) { left: 4%; } .crate-steam i:nth-child(2) { left: 13%; animation-delay: .15s !important; }
.crate-steam i:nth-child(3) { left: 70%; animation-delay: .3s !important; } .crate-steam i:nth-child(4) { left: 80%; animation-delay: .1s !important; }
@keyframes steam { 0% { opacity: 0; transform: translateY(0); } 20% { opacity: .9; } 100% { opacity: 0; transform: translateY(-160%) scale(1.6); } }

/* grade metals */
.crate[data-grade="copper"] { --m1: var(--cu-1); --m2: var(--cu-2); --m3: var(--cu-3); --led: var(--lime); }
.crate[data-grade="bronze"] { --m1: var(--br-1); --m2: var(--br-2); --m3: var(--br-3); --led: var(--lime); }
.crate[data-grade="silver"] { --m1: var(--ag-1); --m2: var(--ag-2); --m3: var(--ag-3); --led: var(--lime); }
.crate[data-grade="gold"] { --m1: var(--au-1); --m2: var(--au-2); --m3: var(--au-3); --led: var(--lime); }
.crate[data-grade="platinum"] { --m1: var(--pt-1); --m2: var(--pt-2); --m3: var(--pt-3); --led: var(--lime); }
.crate[data-grade="empty"], .crate[data-grade="lab"] { --m1: var(--paper-2); --m2: var(--ink-3); --m3: #fff; --led: var(--ink-3); }
.crate[data-grade="gold"] .glint, .crate[data-grade="platinum"] .glint { animation: glint 4.8s steps(16) infinite; }
.crate[data-grade="platinum"] .glint { animation-duration: 3.6s; }
@keyframes glint { 0% { opacity: 0; transform: translateX(0); } 8% { opacity: .55; } 40% { opacity: .55; transform: translateX(120px); } 41%, 100% { opacity: 0; transform: translateX(120px); } }
.crate[data-state="sealed"] .led { animation: blink 1s steps(2) infinite; }

/* ---------------------------------------------------------------- the microscope field: a pixel disc on a 64 grid */
.lens { position: relative; aspect-ratio: 1; width: 100%; }
.lens-field {
  position: absolute; inset: 0; clip-path: var(--disc);
  background:
    radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .7) 0 30%, transparent 62%),
    linear-gradient(rgba(43, 24, 56, .07) 1px, transparent 1px) 0 0 / 6.25% 6.25%,
    linear-gradient(90deg, rgba(43, 24, 56, .07) 1px, transparent 1px) 0 0 / 6.25% 6.25%,
    var(--glass);
  overflow: hidden;
}
.lens-field::before, .lens-field::after { content: ""; position: absolute; background: rgba(43, 24, 56, .16); pointer-events: none; }
.lens-field::before { left: 50%; top: 4%; bottom: 4%; width: 2px; margin-left: -1px; }
.lens-field::after { top: 50%; left: 4%; right: 4%; height: 2px; margin-top: -1px; }
.lens-ring { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; shape-rendering: crispEdges; }
.lens .crate-slot { position: absolute; z-index: 2; left: 50%; top: 50%; width: 66%; transform: translate(-50%, -50%); place-items: center; }
.lens .crate { filter: drop-shadow(6px 6px 0 rgba(43, 24, 56, .16)); }
.lens-tag {
  position: absolute; z-index: 3; padding: 5px 8px; background: var(--ink); color: #fff; border: 2px solid var(--ink);
  font: 400 11px/1 var(--num); text-transform: uppercase; white-space: nowrap;
}
/* the reticle that follows the pointer across the field */
.reticle {
  position: absolute; left: var(--rx, 50%); top: var(--ry, 50%); width: 44px; height: 44px; margin: -22px 0 0 -22px;
  pointer-events: none; opacity: 0; transition: opacity .2s steps(2); z-index: 4;
  background:
    linear-gradient(var(--pink-ink), var(--pink-ink)) 0 0 / 12px 3px no-repeat,
    linear-gradient(var(--pink-ink), var(--pink-ink)) 0 0 / 3px 12px no-repeat,
    linear-gradient(var(--pink-ink), var(--pink-ink)) 100% 0 / 12px 3px no-repeat,
    linear-gradient(var(--pink-ink), var(--pink-ink)) 100% 0 / 3px 12px no-repeat,
    linear-gradient(var(--pink-ink), var(--pink-ink)) 0 100% / 12px 3px no-repeat,
    linear-gradient(var(--pink-ink), var(--pink-ink)) 0 100% / 3px 12px no-repeat,
    linear-gradient(var(--pink-ink), var(--pink-ink)) 100% 100% / 12px 3px no-repeat,
    linear-gradient(var(--pink-ink), var(--pink-ink)) 100% 100% / 3px 12px no-repeat;
}
.lens.is-tracking .reticle { opacity: 1; }
.reticle-read {
  position: absolute; left: 50%; top: calc(100% + 6px); transform: translateX(-50%); white-space: nowrap;
  font: 400 10px/1 var(--num); text-transform: uppercase; background: var(--paper); border: 2px solid var(--ink); padding: 4px 6px; color: var(--ink);
}

/* the magnifying loupe over the grade shelf */
.loupe {
  position: absolute; z-index: 20; width: 240px; height: 240px; pointer-events: none; opacity: 0; transform: scale(.6);
  transition: opacity .16s steps(2), transform .16s steps(2);
}
.loupe.is-on { opacity: 1; transform: none; }
.loupe-field { position: absolute; inset: 0; clip-path: var(--disc); background: var(--glass); overflow: hidden; }
.loupe-inner { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.loupe-inner .crate { width: 100%; }
.loupe .lens-ring { z-index: 2; }
.loupe-tag {
  position: absolute; z-index: 3; left: 50%; bottom: -8px; transform: translateX(-50%); white-space: nowrap;
  font: 400 10px/1 var(--num); text-transform: uppercase; background: var(--ink); color: #fff; padding: 5px 7px;
}
