/* Lab · the IRIS device (owner 2026-10-26, "make it look like this"): one gunmetal chassis with bolts and violet edge
   lights holding the monitor (a periwinkle-on-indigo HUD, lab-monitor.js, with the ice-blue star cluster under a radar
   sweep), the pairs keyboard, and the setups' date range in the bottom tray. */
.irisf.dev{position:relative;width:min(100%,600px);box-sizing:border-box;margin:0 auto;padding:16px 14px 14px;gap:14px;border-radius:28px;
  background:
    radial-gradient(circle at 15px 15px,#6b6d7d 0 2.6px,#16171f 3.2px,transparent 4.4px),
    radial-gradient(circle at calc(100% - 15px) 15px,#6b6d7d 0 2.6px,#16171f 3.2px,transparent 4.4px),
    radial-gradient(circle at 15px calc(100% - 15px),#6b6d7d 0 2.6px,#16171f 3.2px,transparent 4.4px),
    radial-gradient(circle at calc(100% - 15px) calc(100% - 15px),#6b6d7d 0 2.6px,#16171f 3.2px,transparent 4.4px),
    linear-gradient(180deg,#22232f 0%,#15161e 30%,#191a23 70%,#121219 100%);
  border:1px solid #33344a;
  box-shadow:inset 0 0 0 2px #0b0b11,inset 0 0 0 3px #2b2c3c,inset 0 1px 0 4px rgba(255,255,255,.03),0 0 0 1px #000,0 24px 46px -22px #000,0 0 34px -16px #7c5cff}
/* side light strips by the keyboard */
.irisf.dev::before,.irisf.dev::after{content:"";position:absolute;top:66%;width:3px;height:16%;border-radius:3px;background:linear-gradient(180deg,#6f8cff,#8b6bff);box-shadow:0 0 10px #6f8cff,0 0 2px #fff;pointer-events:none}
.irisf.dev::before{left:5px}.irisf.dev::after{right:5px}

/* the monitor */
.mon{width:100%;margin:0;display:flex;flex-direction:column;align-items:center}
.mon-bezel{position:relative;width:100%;box-sizing:border-box;padding:10px 10px 0;border-radius:18px;border:2px solid #2d2e40;
  background:linear-gradient(180deg,#191a24,#0e0e15);box-shadow:inset 0 0 0 1px #07070b,0 0 0 1px #0a0a10,0 0 22px -12px #8b6bff}
.mon-bezel::before,.mon-bezel::after{content:"";position:absolute;top:4px;width:26px;height:26px;pointer-events:none;border:2px solid #9b7dff;filter:drop-shadow(0 0 5px #7c5cff)}
.mon-bezel::before{left:4px;border-right:0;border-bottom:0;border-top-left-radius:14px}
.mon-bezel::after{right:4px;border-left:0;border-bottom:0;border-top-right-radius:14px}
.mon .irisf-stage{width:100%;height:auto;aspect-ratio:1000/760;margin:0;border-radius:10px;border:1px solid #05040a;background:#0f0b2b;
  box-shadow:inset 0 0 36px rgba(0,0,0,.7),0 0 0 1px rgba(139,123,255,.35),0 0 16px -6px #7c5cff}
.mon .irisf-stage::after{border-radius:10px;background:repeating-linear-gradient(0deg,rgba(169,194,255,.03) 0 1px,transparent 1px 3px),radial-gradient(120% 90% at 50% 45%,transparent 68%,rgba(0,0,0,.4) 100%)}
.mon .irisf-stage.drag,.mon .irisf-stage.over,.mon .irisf-stage.dropped{box-shadow:inset 0 0 40px rgba(111,140,255,.35),0 0 0 2px #8b7bff,0 0 18px -4px #7c5cff}
.irisf-hud{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0}
.mon .irisf-stage canvas{z-index:1}
.mon .irisf-tokens{z-index:2}
.mon .irisf-stage .irisf-empty{display:none!important}
.mon .irisf-stage .irisf-snd{top:auto;bottom:8px;right:8px;width:26px;height:26px;font-size:12px;z-index:4;background:rgba(15,11,43,.7);border-color:rgba(169,194,255,.55);color:#a9c2ff;box-shadow:0 0 8px -3px #7c5cff}
/* radar sweep over the centre ring (one compositor-only rotation; still when you ask for less motion) */
.mon-sweep{position:absolute;left:50%;top:calc(320 / 760 * 100%);width:26.4%;aspect-ratio:1;transform:translate(-50%,-50%);z-index:1;border-radius:50%;pointer-events:none;
  background:conic-gradient(from 0deg,rgba(139,107,255,0) 0deg,rgba(139,107,255,0) 300deg,rgba(139,107,255,.18) 330deg,rgba(169,140,255,.55) 359deg,rgba(139,107,255,0) 360deg);
  animation:mon-sweep 9s linear infinite}   /* slow (owner 2026-10-28: "don't make it fast") */
@keyframes mon-sweep{to{transform:translate(-50%,-50%) rotate(360deg)}}
/* the IRIS plate under the screen */
.mon-chin{position:relative;width:46%;height:28px;margin:8px auto 0;display:flex;align-items:center;justify-content:center;gap:12px;
  background:linear-gradient(180deg,#1a1b26,#111119);border:1px solid #3a3a58;border-bottom:0;clip-path:polygon(8% 0,92% 0,100% 100%,0 100%);box-shadow:inset 0 1px 0 rgba(255,255,255,.05)}
.mon-brand{font:700 12px/1 var(--f-mono,monospace);letter-spacing:.5em;color:#c3b1ff;text-shadow:0 0 6px #7c5cff}
.mon-led{width:8px;height:8px;border-radius:50%;background:#6fd3ff;box-shadow:0 0 8px #6fd3ff}
.mon-bezel:has(.mon-scanning) .mon-led{animation:mon-led 1s steps(2) infinite}
@keyframes mon-led{50%{opacity:.25}}
.mon-neck,.mon-foot{display:none}
/* the map on the tilted grid */
.mon-map{position:absolute;left:18%;right:18%;bottom:0;height:19%;z-index:0;pointer-events:none;transform:perspective(260px) rotateX(46deg);transform-origin:50% 100%;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 30%);mask-image:linear-gradient(180deg,transparent 0,#000 30%)}
.mon-map svg{width:100%;height:100%;display:block}
/* scan progress across the middle of the screen: real progress, then COMPLETE */
.mon-scan{position:absolute;left:10%;right:10%;top:42%;transform:translateY(-50%);z-index:3;display:grid;grid-template-columns:1fr auto;align-items:center;gap:6px 10px;
  padding:10px 12px;border:1px solid #8b7bff;border-radius:6px;background:rgba(12,9,34,.88);box-shadow:0 0 18px -4px #7c5cff,inset 0 0 14px -6px #6f8cff}
.mon-scan[hidden]{display:none}
.mon-scan>span{grid-column:1/-1;font:700 11px/1 var(--f-mono,monospace);letter-spacing:.2em;color:#a9c2ff;text-shadow:0 0 8px #6f8cff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mon-track{height:10px;border:1px solid #8b7bff;border-radius:2px;overflow:hidden;background:rgba(111,140,255,.08)}
.mon-track i{display:block;height:100%;width:0;background:linear-gradient(90deg,#3b3584,#7f74f0 55%,#a9c2ff);box-shadow:0 0 10px #6f8cff;transition:width .45s ease}
.mon-scan>b{font:800 15px/1 var(--f-mono,monospace);color:#e3ecff;text-shadow:0 0 8px #6f8cff;min-width:3.2em;text-align:right}
.mon-scan.done>span{font-size:18px;letter-spacing:.32em;text-align:center;color:#e3ecff;text-shadow:0 0 10px #a9c2ff,0 0 22px #7c5cff}
.mon-scan.done .mon-track i{background:#a9c2ff}

/* the keyboard deck */
.kbd{position:relative;width:100%;box-sizing:border-box;margin:0;padding:16px 14px 14px;border-radius:20px;transform:none;
  background:linear-gradient(180deg,#14151d,#0d0e14);border:1px solid #2f3044;box-shadow:inset 0 0 0 2px #08080d,inset 0 1px 0 3px rgba(255,255,255,.03),0 0 0 1px #000}
/* amber status LEDs on the deck's sides */
.kbd::before,.kbd::after{content:"";position:absolute;top:30%;width:4px;height:38px;pointer-events:none;
  background:radial-gradient(circle,#ffb43c 0 1.8px,transparent 2.4px) 0 0/4px 10px repeat-y;filter:drop-shadow(0 0 3px #ffb43c)}
.kbd::before{left:4px}.kbd::after{right:4px}
.kbd .irisf-tray{gap:8px}
#irisf-tray .irisf-chip,.kbd #irisf-tray .irisf-chip.live:not(.on),.kbd #irisf-tray .irisf-chip.extra{height:40px;min-width:48px;padding:0 11px;border-radius:9px;border:1.5px solid #4c449f;
  background:linear-gradient(180deg,#1c1d2a,#11121a);color:#d8e3ff;font:700 13px var(--f-mono,monospace);letter-spacing:.04em;text-shadow:0 0 6px rgba(127,168,255,.75);
  box-shadow:0 3px 0 #05050a,0 0 12px -4px #6b5cff,inset 0 0 8px -4px #8b7bff,inset 0 1px 0 rgba(255,255,255,.06);transition:transform .06s,box-shadow .06s}
#irisf-tray .irisf-chip:active{transform:translateY(2px);box-shadow:0 1px 0 #05050a,0 0 14px -3px #6b5cff}
#irisf-tray .irisf-chip.on{border-color:#7fd4ff;color:#eef6ff;background:linear-gradient(180deg,#1d2a45,#121a2e);box-shadow:0 3px 0 #05050a,0 0 16px -2px #6f8cff,inset 0 0 10px -4px #7fd4ff}
#irisf-tray .irisf-chip.all{min-width:100px;border-color:#7fb8ff;box-shadow:0 3px 0 #05050a,0 0 14px -3px #6f8cff,inset 0 0 8px -4px #7fd4ff}
#irisf-tray .irisf-chip.add{order:99;flex:0 1 74%;height:44px;border-color:#8b6bff;color:#d9ccff;text-shadow:0 0 8px #8b6bff;background:linear-gradient(180deg,#1e1830,#120f1e);
  box-shadow:0 3px 0 #05050a,0 0 16px -4px #8b6bff,inset 0 0 10px -4px #a58bff}
#irisf-tray .irisf-add{order:99}
.kbd .irisf-bar{margin-top:12px;justify-content:center;gap:12px}
.kbd .irisf-bar .dbtn{height:44px;padding:0 18px 0 14px;display:inline-flex;align-items:center;gap:10px;border-radius:9px;border:1.5px solid #4c449f;
  background:linear-gradient(180deg,#1a1b28,#101119);color:#c9d6ff;font:800 13px var(--f-mono,monospace);letter-spacing:.08em;text-transform:uppercase;
  box-shadow:0 3px 0 #05050a,0 0 12px -5px #6b5cff,inset 0 1px 0 rgba(255,255,255,.06)}
.kbd .irisf-bar .dbtn::before{content:"";width:20px;height:20px;flex:none;background:currentColor;-webkit-mask:var(--ico) center/contain no-repeat;mask:var(--ico) center/contain no-repeat}
.kbd #irisf-scan{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Ccircle cx='12' cy='12' r='4.5'/%3E%3Ccircle cx='12' cy='12' r='1.2' fill='%23000'/%3E%3Cpath d='M12 1v3M12 20v3M1 12h3M20 12h3'/%3E%3C/svg%3E")}
.kbd #irisf-clear{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M4 6h16M9 6V4h6v2M6 6l1 15h10l1-15M10 10v8M14 10v8'/%3E%3C/svg%3E")}
.kbd .irisf-bar .dbtn:active{transform:translateY(2px);box-shadow:0 1px 0 #05050a}
.kbd .irisf-bar #irisf-scan:not(:disabled){border-color:#6f8cff;color:#cfe0ff;background:linear-gradient(180deg,#18223e,#0f1528);box-shadow:0 3px 0 #05050a,0 0 16px -3px #6f8cff}
.kbd .irisf-bar .dbtn:disabled{opacity:.55}
.kbd .irisf-msg{flex:1 1 100%;text-align:center;color:#a9b4dd}
/* the bottom tray: the setups' date range */
.dev-tray{margin:0;padding:10px 12px;display:flex;gap:8px;flex-wrap:nowrap;border-radius:18px;background:linear-gradient(180deg,#13141c,#0d0e14);border:1px solid #2f3044;box-shadow:inset 0 0 0 2px #08080d}
.dev-tray .chip{flex:0 1 auto;min-width:0;white-space:nowrap;height:38px;padding:0 16px;border-radius:999px;border:1px solid #33355a;background:#151626;color:#c9d6ff;font:600 14px var(--f-body,inherit)}
.dev-tray .chip[aria-pressed="true"]{background:linear-gradient(180deg,#c3b1ff,#a993ff);border-color:#d6c9ff;color:#1a1238;box-shadow:0 0 16px -4px #a58bff}
@media (prefers-reduced-motion:reduce){.mon-track i{transition:none}.mon-bezel:has(.mon-scanning) .mon-led,.mon-sweep{animation:none}}
/* date pills centred in the tray (owner 2026-10-26) */
.irisf.dev .dev-tray{justify-content:center}

/* A loaded pair = a lit key (owner 2026-10-28: no tokens on the screen): bright edge and a slow glow while it's loaded,
   a short flash when you load it, and a livelier glow while the scan runs. */
#irisf-tray .irisf-chip.on{border-color:#bfe9ff;color:#fff;background:linear-gradient(180deg,#2a4f86,#17305a);text-shadow:0 0 8px #bfe9ff,0 0 14px #7fd4ff;
  box-shadow:0 3px 0 #05050a,0 0 18px -1px #7fd4ff,0 0 34px -10px #a9c2ff,inset 0 0 14px -3px #bfe9ff;animation:key-lit 3.6s ease-in-out infinite}
@keyframes key-lit{50%{box-shadow:0 3px 0 #05050a,0 0 26px 1px #9fdcff,0 0 44px -6px #a9c2ff,inset 0 0 18px -2px #d6f1ff}}
#irisf-tray .irisf-chip.flash{animation:key-flash .7s ease-out,key-lit 3.6s ease-in-out .7s infinite}
@keyframes key-flash{0%{filter:brightness(2.2)}100%{filter:none}}
.irisf.dev:has(.irisf-stage.scanning) #irisf-tray .irisf-chip.on{animation-duration:2.2s}
@media (prefers-reduced-motion:reduce){#irisf-tray .irisf-chip.on,#irisf-tray .irisf-chip.flash{animation:none}}

/* The screen comes to life (owner 2026-10-28): while you're on the Lab page the bar graphs glow together, the dials and
   dashed rings turn slowly, the status lights twinkle and the arcs breathe; a scan makes it all a little livelier, never
   fast. Only opacity / transform animate (cheap on a phone); the page hidden = nothing runs. */
#irisf-hud .lm-bar{animation:lm-bar 5.2s ease-in-out infinite}
#irisf-hud .lm-v{transform-box:fill-box;transform-origin:50% 100%;animation-name:lm-bar-v}
@keyframes lm-bar{0%,100%{opacity:.62}50%{opacity:1}}
@keyframes lm-bar-v{0%,100%{opacity:.62;transform:scaleY(.9)}50%{opacity:1;transform:scaleY(1)}}
#irisf-hud .lm-arc{animation:lm-arc 6.5s ease-in-out infinite}
@keyframes lm-arc{0%,100%{opacity:.7}50%{opacity:1}}
#irisf-hud .lm-spin,#irisf-hud .lm-spin-r{transform-box:fill-box;transform-origin:50% 50%;animation:lm-spin 48s linear infinite}
#irisf-hud .lm-spin-r{animation-duration:62s;animation-direction:reverse}
@keyframes lm-spin{to{transform:rotate(360deg)}}
#irisf-hud .lm-led{animation:lm-led 6s ease-in-out infinite}
@keyframes lm-led{0%,100%{opacity:1}45%{opacity:.55}55%{opacity:.9}}
/* during a scan: livelier, still slow */
.irisf-stage.scanning #irisf-hud .lm-bar{animation-duration:3s}
.irisf-stage.scanning #irisf-hud .lm-arc{animation-duration:3.6s}
.irisf-stage.scanning #irisf-hud .lm-spin{animation-duration:24s}
.irisf-stage.scanning #irisf-hud .lm-spin-r{animation-duration:30s}
.irisf-stage.scanning #irisf-hud .lm-led{animation-duration:3.4s}
.irisf-stage.scanning .mon-sweep{animation-duration:6s}
@media (prefers-reduced-motion:reduce){#irisf-hud .lm-bar,#irisf-hud .lm-arc,#irisf-hud .lm-spin,#irisf-hud .lm-spin-r,#irisf-hud .lm-led{animation:none}}

/* the scan progress sits slim and see-through in the gap above the centre ring, so the whole screen stays visible and
   alive while a scan runs (owner 2026-10-28) */
.mon .mon-scan{top:16.5%;left:30%;right:30%;padding:3px 7px;gap:2px 6px;border-radius:4px;background:rgba(12,9,34,.5);backdrop-filter:blur(1px)}
.mon .mon-scan>span{font-size:7.5px;letter-spacing:.12em}
.mon .mon-track{height:4px}
.mon .mon-scan>b{font-size:9px;min-width:2.6em}
.mon .mon-scan.done>span{font-size:9px;letter-spacing:.2em}
