/* SYNC SPEAKER
 *
 * Two themes from one set of tokens. Everything below the token blocks is
 * written in terms of the tokens and never in terms of a colour, so day mode
 * is a different set of values rather than a second stylesheet to keep in
 * step with the first.
 *
 * System fonts throughout so it loads instantly and works on a wifi network
 * with no internet at all, which is a real way people will use this.
 *
 * Every viewport unit is written twice: vh first, then dvh. Safari before
 * 15.4 does not know dvh and drops the whole declaration, and a dropped
 * max-height on a bottom sheet is a sheet that grows off the top of the
 * screen with nothing to scroll it back. That is what made search look
 * broken on older iPhones.
 */

/* ---------------------------- day ---------------------------- */
:root{
  --bg:#F6F7F9; --surface:#FFFFFF; --surface-2:#F1F3F6; --surface-3:#E5E9EE;
  --line:#E3E7EC; --line-2:#CFD6DE;
  --ink:#131820; --ink-2:#525C68; --ink-3:#7C8794;
  --amber:#C97F12; --amber-deep:#A96A0C; --amber-glow:rgba(201,127,18,.10);
  --on-amber:#FFFFFF;
  --green:#1E9E63; --red:#CC4436;
  --mark-bg:#141922;
  --now-a:#FFFFFF; --now-b:#F4F6F9;
  --shadow:0 1px 2px rgba(19,24,32,.06),0 8px 24px -14px rgba(19,24,32,.28);
  --scrim:rgba(24,28,34,.42);
  --sans:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
  --r:14px;
  color-scheme:light;
}
/* ---------------------------- night ---------------------------- */
html[data-theme="dark"]{
  --bg:#0B0E12; --surface:#141922; --surface-2:#1C232D; --surface-3:#242D39;
  --line:#262F3A; --line-2:#36414F;
  --ink:#ECEFF3; --ink-2:#9AA5B2; --ink-3:#6B7480;
  --amber:#F0A93C; --amber-deep:#C4801F; --amber-glow:rgba(240,169,60,.16);
  --on-amber:#191204;
  --green:#4ECB8E; --red:#E86A5E;
  --mark-bg:#141922;
  --now-a:#141922; --now-b:#10151C;
  --shadow:0 10px 30px -18px rgba(0,0,0,.9);
  --scrim:rgba(6,8,11,.72);
  color-scheme:dark;
}
@media (prefers-color-scheme:dark){
  html[data-theme="auto"]{
    --bg:#0B0E12; --surface:#141922; --surface-2:#1C232D; --surface-3:#242D39;
    --line:#262F3A; --line-2:#36414F;
    --ink:#ECEFF3; --ink-2:#9AA5B2; --ink-3:#6B7480;
    --amber:#F0A93C; --amber-deep:#C4801F; --amber-glow:rgba(240,169,60,.16);
    --on-amber:#191204;
    --green:#4ECB8E; --red:#E86A5E;
    --now-a:#141922; --now-b:#10151C;
    --shadow:0 10px 30px -18px rgba(0,0,0,.9);
    --scrim:rgba(6,8,11,.72);
    color-scheme:dark;
  }
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;height:100%}
body{
  background:var(--bg); color:var(--ink); font-family:var(--sans);
  font-size:15px; line-height:1.5; -webkit-font-smoothing:antialiased;
  overflow-x:hidden; overscroll-behavior-y:none;
  transition:background .2s ease,color .2s ease;
}
button,input{font-family:inherit;font-size:inherit;color:inherit}
button{cursor:pointer;border:0;background:none}
:focus-visible{outline:2px solid var(--amber);outline-offset:2px;border-radius:6px}
.hide{display:none!important}

.app{max-width:520px;margin:0 auto;padding:0 18px 130px;min-height:100%}

/* ============================ start screen ============================ */
.start{min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;justify-content:center;
       gap:8px;padding-bottom:40px}
.start .foot{margin-top:auto}
.startbar{display:flex;justify-content:flex-end;padding:14px 0 10px}
.brand{display:flex;align-items:center;gap:13px;margin-bottom:6px}
.brand .mark{width:46px;height:46px;flex:0 0 auto;border-radius:11px}
.brand h1{font-size:27px;font-weight:800;letter-spacing:-.035em;margin:0;line-height:1}
.brand .sub{font-size:12px;color:var(--ink-3);letter-spacing:.14em;text-transform:uppercase;font-weight:600;margin-top:3px}
.pitch{color:var(--ink-2);font-size:16px;margin:14px 0 22px;max-width:34ch}
.pitch b{color:var(--ink);font-weight:600}

/* the segmented day/night control */
.seg{display:inline-flex;background:var(--surface-2);border:1px solid var(--line);border-radius:999px;padding:3px;gap:2px}
/* 26px tall was a thumb's-width too small for a control people hit on a
   phone in a dark room. 34 is comfortable and changes nothing about the look. */
.seg button{font-size:12px;font-weight:700;color:var(--ink-3);padding:9px 14px;min-height:34px;border-radius:999px;
            transition:background .15s,color .15s}
.seg button[aria-pressed="true"]{background:var(--surface);color:var(--ink);box-shadow:var(--shadow)}
.seg.wide{display:flex;width:100%}
.seg.wide button{flex:1 1 0}

/* your name, on the way in */
.namerow{margin:0 0 20px}
.namerow label{display:block;font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
               color:var(--ink-3);margin-bottom:8px}
.nameinput{display:flex;align-items:center;gap:10px;background:var(--surface);border:1px solid var(--line-2);
           border-radius:var(--r);padding:8px 8px 8px 10px}
.nameinput input{flex:1 1 auto;min-width:0;background:none;border:0;padding:8px 2px;font-size:16px;font-weight:600}
.nameinput input:focus{outline:none}
.nameinput button{width:34px;height:34px;border-radius:9px;color:var(--ink-3);display:flex;
                  align-items:center;justify-content:center;flex:0 0 auto}
.nameinput button:active{background:var(--surface-2);color:var(--amber)}
.av{width:32px;height:32px;border-radius:50%;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
    font-size:13px;font-weight:800;background:var(--amber);color:var(--on-amber);letter-spacing:-.02em}

.big-btn{
  width:100%;padding:19px;border-radius:var(--r);font-size:16px;font-weight:700;letter-spacing:.01em;
  background:var(--amber);color:var(--on-amber);display:flex;align-items:center;justify-content:center;gap:10px;
  transition:transform .08s ease,filter .15s ease;box-shadow:var(--shadow);
}
.big-btn:active{transform:scale(.985)}
.big-btn.ghost{background:var(--surface-2);color:var(--ink);border:1px solid var(--line-2);box-shadow:none}
.or{display:flex;align-items:center;gap:14px;color:var(--ink-3);font-size:12px;margin:20px 0;
    letter-spacing:.12em;text-transform:uppercase}
.or::before,.or::after{content:"";height:1px;background:var(--line);flex:1}

.codebox{display:flex;gap:10px}
.codebox input{
  flex:1 1 auto;background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r);
  padding:17px 18px;font-family:var(--mono);font-size:24px;font-weight:600;letter-spacing:.28em;
  text-transform:uppercase;text-align:center;min-width:0;
}
.codebox input::placeholder{color:var(--ink-3);letter-spacing:.28em}
.codebox button{flex:0 0 auto;padding:0 22px;border-radius:var(--r);background:var(--surface-2);
                border:1px solid var(--line-2);font-weight:700}
.err{color:var(--red);font-size:13.5px;margin-top:12px;min-height:20px}

/* ============================ party header ============================ */
.top{display:flex;align-items:center;gap:9px;padding:16px 0 14px;position:sticky;top:0;
     background:var(--bg);z-index:20}
.top::after{content:"";position:absolute;left:0;right:0;bottom:-14px;height:14px;
            background:linear-gradient(var(--bg),transparent);pointer-events:none}
.code-chip{display:flex;align-items:baseline;gap:9px;background:var(--surface);border:1px solid var(--line);
           border-radius:10px;padding:7px 13px;box-shadow:var(--shadow)}
.code-chip .k{font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);font-weight:700}
.code-chip .v{font-family:var(--mono);font-size:19px;font-weight:700;letter-spacing:.16em;color:var(--amber)}
.spacer{flex:1 1 auto}
.pill{white-space:nowrap;display:flex;align-items:center;gap:7px;background:var(--surface);border:1px solid var(--line);
      border-radius:999px;padding:7px 13px;font-size:12.5px;font-weight:600;color:var(--ink-2)}
.pill .dot{width:7px;height:7px;border-radius:50%;background:var(--ink-3);flex:0 0 auto}
.pill.good .dot{background:var(--green);box-shadow:0 0 0 3px rgba(78,203,142,.16)}
.pill.warn .dot{background:var(--amber)}
.pill.bad .dot{background:var(--red)}
.pill.iconpill{padding:8px 10px;color:var(--ink-2)}
.pill.share{color:var(--amber);border-color:var(--amber-deep);gap:6px;font-weight:700}
.pill.share:active{background:var(--surface-2)}
.pill.share.done{color:var(--green);border-color:var(--green)}

/* who you are */
.youbar{display:flex;align-items:center;gap:11px;width:100%;text-align:left;background:var(--surface);
        border:1px solid var(--line);border-radius:14px;padding:10px 13px;margin:2px 0 4px;color:var(--ink-3)}
.youbar .who{flex:1 1 auto;min-width:0}
.youbar .who b{display:block;font-size:14.5px;font-weight:700;color:var(--ink);
               white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.youbar .who span{display:block;font-size:11.5px;color:var(--ink-3);margin-top:1px}
.youbar.admin .av{background:var(--amber)}
.youbar.guest .av{background:var(--surface-3);color:var(--ink-2)}

/* ============================ now playing ============================ */
.now{background:linear-gradient(160deg,var(--now-a) 0%,var(--now-b) 100%);
     border:1px solid var(--line);border-radius:20px;padding:22px 20px 18px;margin-top:8px;
     position:relative;overflow:hidden;box-shadow:var(--shadow)}
.now::after{content:"";position:absolute;inset:0;pointer-events:none;
            background:radial-gradient(120% 70% at 50% -20%,var(--amber-glow),transparent 60%)}
.now .eyebrow{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--amber);font-weight:700}
.now h2{font-size:21px;font-weight:700;letter-spacing:-.015em;margin:9px 0 2px;line-height:1.25;
        word-break:break-word;min-height:1.25em}
.now .by{font-size:13px;color:var(--ink-3);min-height:19px}

/* the meter: 24 bars that move with the music position */
.meter{display:flex;align-items:flex-end;gap:3px;height:34px;margin:16px 0 4px;opacity:.45}
.meter i{flex:1 1 0;background:var(--amber-deep);border-radius:1px;height:12%;
         transition:height .18s ease,background .18s ease}
.meter.live{opacity:1}

.scrub{margin-top:10px;position:relative;padding:11px 0;touch-action:none;cursor:pointer}
.track{height:5px;border-radius:3px;background:var(--surface-3);position:relative;overflow:visible}
.fill{height:100%;border-radius:3px;background:var(--amber);width:0%;position:relative}
.knob{position:absolute;top:50%;right:-8px;width:16px;height:16px;border-radius:50%;background:var(--amber);
      transform:translateY(-50%);box-shadow:0 2px 8px rgba(0,0,0,.35);opacity:0;transition:opacity .15s}
.scrub:hover .knob,.scrub.dragging .knob{opacity:1}
.scrub.locked{cursor:default}
.times{display:flex;justify-content:space-between;font-family:var(--mono);font-size:11.5px;color:var(--ink-3);
       font-variant-numeric:tabular-nums;margin-top:2px}

.transport{display:flex;align-items:center;justify-content:center;gap:26px;margin:16px 0 6px}
.tbtn{width:46px;height:46px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--ink-2)}
.tbtn:active{color:var(--ink)}
.tbtn[disabled]{opacity:.3}
.play{width:70px;height:70px;border-radius:50%;background:var(--amber);color:var(--on-amber);
      display:flex;align-items:center;justify-content:center;position:relative;
      box-shadow:0 6px 22px -8px rgba(201,127,18,.55);transition:transform .08s ease}
html[data-theme="dark"] .play{box-shadow:0 6px 22px -8px rgba(240,169,60,.6)}
.play:active{transform:scale(.96)}
.play[disabled]{opacity:.45;box-shadow:none}
.play .ring{position:absolute;inset:-5px;transform:rotate(-90deg)}
.play .ring circle{fill:none;stroke:var(--amber);stroke-width:3;opacity:.55}

/* ============================ queue ============================ */
.sec{display:flex;align-items:center;gap:10px;margin:26px 0 10px}
.sec h3{font-size:11px;letter-spacing:.15em;text-transform:uppercase;color:var(--ink-3);margin:0;font-weight:700}
.sec .count{font-family:var(--mono);font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.sec .line{flex:1 1 auto;height:1px;background:var(--line)}
.sec button{font-size:12px;font-weight:700;color:var(--amber);padding:5px 10px;border-radius:7px;
            background:var(--surface);border:1px solid var(--line);
            display:inline-flex;align-items:center;justify-content:center;min-height:34px}
.sec button[disabled]{color:var(--ink-3);opacity:.55}
.sec .tog{position:relative;color:var(--ink-3);padding:6px 8px;display:flex;align-items:center;
          background:transparent;border:1px solid transparent}
.sec .tog[aria-pressed="true"],.sec .tog.on{color:var(--amber);background:var(--surface);border-color:var(--line)}
.sec .tog[data-mode="off"]{opacity:.45}
.sec .tog .one{position:absolute;right:3px;bottom:2px;font-size:8.5px;font-weight:800;
               background:var(--amber);color:var(--on-amber);border-radius:3px;padding:0 2px;line-height:1.3;display:none}
.sec .tog[data-mode="one"] .one{display:block}

.queue{display:flex;flex-direction:column;gap:7px}
.item{display:flex;align-items:center;gap:12px;background:var(--surface);border:1px solid var(--line);
      border-radius:12px;padding:12px 13px;position:relative;overflow:hidden}
.item.playing{border-color:var(--amber);background:var(--surface-2)}
.item.failed{border-color:var(--red)}
.item .idx{font-family:var(--mono);font-size:12px;color:var(--ink-3);width:18px;flex:0 0 auto;text-align:right;
           font-variant-numeric:tabular-nums}
.item .t{flex:1 1 auto;min-width:0}
.item .t .n{display:block;font-size:14.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.item .t .m{display:block;font-size:11.5px;color:var(--ink-3);font-family:var(--mono);margin-top:3px;
            white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.item.failed .t .m{color:var(--red)}
.item .grip{width:26px;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
            color:var(--ink-3);cursor:grab;touch-action:none;margin:-12px 0 -12px -4px;padding:12px 0}
.item .grip:active{cursor:grabbing;color:var(--amber)}
.item.dragging{z-index:5;box-shadow:0 12px 28px -10px rgba(0,0,0,.45);border-color:var(--amber);
               opacity:.97}
.queue.reordering .item{transition:transform .16s ease}
.queue.reordering .item.dragging{transition:none}
.item .x{width:30px;height:30px;border-radius:8px;color:var(--ink-3);flex:0 0 auto;
         display:flex;align-items:center;justify-content:center}
.item .x:active{background:var(--surface-3);color:var(--red)}
.item .retry{flex:0 0 auto;font-size:11px;font-weight:700;color:var(--red);border:1px solid var(--red);
             border-radius:7px;padding:5px 9px}
.item .bar{position:absolute;left:0;bottom:0;height:2px;background:var(--amber);width:0;transition:width .3s linear}
.empty{border:1px dashed var(--line-2);border-radius:12px;padding:26px 18px;text-align:center;color:var(--ink-3);font-size:13.5px}

/* ============================ invite / QR ============================ */
.scan-btn{width:100%;margin-top:10px;padding:14px;border-radius:var(--r);background:var(--surface);
          border:1px solid var(--line-2);color:var(--ink-2);font-weight:600;font-size:14.5px;
          display:flex;align-items:center;justify-content:center;gap:9px}
.scan-btn:active{background:var(--surface-2);color:var(--ink)}

.invite{display:flex;gap:15px;align-items:center;background:var(--surface);border:1px solid var(--amber-deep);
        border-radius:16px;padding:15px;margin:4px 0 10px;box-shadow:var(--shadow)}
/* 37 modules across, and a scanner wants three or four pixels each. This is
   the smallest that reads reliably; tapping it opens the full size one. */
.qrwrap{flex:0 0 auto;width:136px;height:136px;background:#fff;border-radius:10px;padding:7px;
        cursor:pointer;border:0}
.qrwrap:active{opacity:.85}
.qrwrap svg{display:block;width:100%;height:100%}
.invite-t{flex:1 1 auto;min-width:0}
.invite-t b{display:block;font-size:14.5px;font-weight:700;margin-bottom:3px}
.invite-t span{display:block;font-size:12.5px;color:var(--ink-3);line-height:1.45}
.invite-actions{display:flex;gap:8px;margin-top:11px;flex-wrap:wrap}
.invite-actions button{font-size:12.5px;font-weight:700;padding:7px 12px;border-radius:9px;
                       background:var(--amber);color:var(--on-amber);
                       display:inline-flex;align-items:center;justify-content:center;min-height:36px}
.invite-actions button:last-child{background:var(--surface-2);color:var(--ink-2);border:1px solid var(--line-2)}

.qrbig{background:#fff;border-radius:14px;padding:16px;max-width:300px;margin:4px auto 16px}
.qrbig svg{display:block;width:100%;height:auto}
.qrcode-line{display:flex;align-items:baseline;justify-content:center;gap:12px}
.qrcode-line .k{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);font-weight:700}
.qrcode-line .v{font-family:var(--mono);font-size:34px;font-weight:700;letter-spacing:.2em;color:var(--amber)}

.camera{position:relative;flex:1 1 auto;min-height:0;background:#000;border-radius:14px;overflow:hidden;
        display:flex;align-items:center;justify-content:center}
.camera video{width:100%;height:100%;object-fit:cover}
.reticle{position:absolute;width:62%;aspect-ratio:1;border-radius:18px;
         box-shadow:0 0 0 100vmax rgba(0,0,0,.45);border:2px solid rgba(255,255,255,.85);pointer-events:none}

/* ============================ devices ============================ */
.devs{display:flex;flex-wrap:wrap;gap:7px}
.dev{display:flex;align-items:center;gap:8px;background:var(--surface);border:1px solid var(--line);
     border-radius:999px;padding:6px 8px 6px 10px;font-size:12.5px}
.dev .d{width:7px;height:7px;border-radius:50%;background:var(--green);flex:0 0 auto}
.dev.loading .d{background:var(--amber)}
/* The face carries the ready light rather than sitting next to it: a green
   ring while the phone has the track, amber while it is still fetching. Same
   information, same width as the dot it replaced. */
.dev .pf{flex:0 0 auto;line-height:0;border-radius:8px;padding:1.5px;
         background:var(--green);display:inline-flex}
.dev.loading .pf{background:var(--amber)}
.dev .pf .av{display:block;border-radius:6px}
.dev .nm{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:11em}
.dev .rt{font-family:var(--mono);font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.dev.me{border-color:var(--amber)}
.dev .crown{font-size:9px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--amber);
            background:var(--amber-glow);border:1px solid var(--amber-deep);border-radius:5px;padding:1px 5px}
.dev .mk{font-size:10.5px;font-weight:700;color:var(--ink-2);background:var(--surface-2);
         border:1px solid var(--line-2);border-radius:999px;padding:4px 10px;
         transition:background .12s,color .12s,opacity .12s}
.dev .mk:active{background:var(--amber);color:var(--on-amber);border-color:var(--amber)}
.dev .mk.busy{opacity:.5;pointer-events:none}
.dev .mk.drop{color:var(--red);border-color:rgba(154,59,49,.4)}
html[data-theme="dark"] .dev .mk.drop{border-color:rgba(224,121,108,.4)}

/* ============================ banners ============================ */
.banner{display:flex;gap:11px;align-items:flex-start;border-radius:12px;padding:13px 15px;font-size:13.5px;
        line-height:1.45;margin:12px 0}
.banner.red{background:rgba(204,68,54,.09);border:1px solid rgba(204,68,54,.4)}
html[data-theme="dark"] .banner.red{background:rgba(232,106,94,.1);border-color:rgba(232,106,94,.45)}
button.banner{width:100%;text-align:left;font-size:13.5px;line-height:1.45;color:var(--ink);
              cursor:pointer;transition:background .15s}
button.banner:active{background:rgba(204,68,54,.18)}
.banner.amber{background:var(--amber-glow);border:1px solid var(--amber-deep)}
.banner b{display:block;margin-bottom:2px}
.banner .s{flex:0 0 auto;margin-top:1px}

/* ============================ toasts ============================ */
.toasts{position:fixed;left:0;right:0;bottom:calc(18px + env(safe-area-inset-bottom));z-index:95;
        display:flex;flex-direction:column;align-items:center;gap:8px;pointer-events:none;padding:0 16px}
.toast{background:var(--ink);color:var(--bg);border-radius:11px;padding:11px 16px;font-size:13.5px;
       font-weight:600;max-width:460px;box-shadow:0 10px 30px -12px rgba(0,0,0,.5);
       animation:tin .22s ease both}
@keyframes tin{from{opacity:0;transform:translateY(8px)}}

/* ============================ sheet ============================ */
.sheet{position:fixed;inset:0;z-index:60;display:none}
.sheet.open{display:block}
.sheet .scrim{position:absolute;inset:0;background:var(--scrim);backdrop-filter:blur(3px)}
.sheet .body{position:absolute;left:0;right:0;bottom:0;
             max-height:86vh; max-height:86dvh;
             overflow-y:auto;-webkit-overflow-scrolling:touch;
             background:var(--surface);border-radius:22px 22px 0 0;border-top:1px solid var(--line-2);
             padding:10px 20px calc(28px + env(safe-area-inset-bottom));max-width:520px;margin:0 auto}
.grab{width:38px;height:4px;border-radius:2px;background:var(--line-2);margin:0 auto 16px}
.sheet h3{font-size:17px;margin:0 0 4px;font-weight:700}
.sheet .note{font-size:13px;color:var(--ink-3);line-height:1.5;margin:0 0 18px}

/* the full height one, for search. One scrolling area, and it is the list. */
.sheet.full .body{
  top:0; height:100vh; height:100dvh; max-height:none;
  border-radius:0; display:flex; flex-direction:column; overflow:hidden;
  padding:calc(10px + env(safe-area-inset-top)) 18px calc(10px + env(safe-area-inset-bottom));
}
.shead{display:flex;align-items:center;gap:10px;padding:6px 0 12px;flex:0 0 auto}
.shead h3{flex:1 1 auto;font-size:19px}
.shead .x{width:36px;height:36px;border-radius:10px;background:var(--surface-2);border:1px solid var(--line);
          color:var(--ink-2);display:flex;align-items:center;justify-content:center;flex:0 0 auto}
.searchrow{display:flex;gap:8px;flex:0 0 auto}
.searchrow button{flex:0 0 auto;width:50px;border-radius:12px;background:var(--amber);color:var(--on-amber);
                  display:flex;align-items:center;justify-content:center}
.sheet.full .note{flex:0 0 auto;margin:10px 0 6px;min-height:18px}
.sheet.full .results{flex:1 1 auto;max-height:none;overflow-y:auto;-webkit-overflow-scrolling:touch;
                     padding-bottom:20px}

.field{margin-bottom:20px}
.field label{display:flex;justify-content:space-between;align-items:baseline;font-size:12.5px;
             color:var(--ink-2);margin-bottom:8px;font-weight:600}
.field label .v{font-family:var(--mono);color:var(--amber);font-size:14px;font-variant-numeric:tabular-nums}
.field input[type=text]{width:100%;background:var(--surface-2);border:1px solid var(--line-2);
                        border-radius:10px;padding:12px 14px}
/* 28px is a thin thing to drag with a thumb on a moving bus. */
input[type=range]{width:100%;accent-color:var(--amber);height:36px}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);border:1px solid var(--line);
       border-radius:12px;overflow:hidden}
.stats div{background:var(--surface-2);padding:11px 12px}
.stats dt{font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-bottom:3px}
.stats dd{margin:0;font-family:var(--mono);font-size:15px;font-weight:600;font-variant-numeric:tabular-nums}
.stats dd small{font-size:10.5px;color:var(--ink-3);font-weight:400}

/* ============================ the sound fix ============================ */
.sound-fix{background:var(--surface-2);border:1px solid var(--line-2);border-radius:14px;
           padding:15px;margin-bottom:20px}
.sound-fix .big-btn{padding:15px;font-size:15px}
.sw{display:flex;gap:12px;align-items:flex-start;margin-top:15px;cursor:pointer}
.sw input{position:absolute;opacity:0;width:0;height:0}
.sw .track{flex:0 0 auto;width:46px;height:27px;border-radius:14px;background:var(--surface-3);
           border:1px solid var(--line-2);position:relative;transition:background .18s,border-color .18s;margin-top:1px}
/* transform:none matters as much as the rest of this rule. The scrubber's
   .knob above is centred on its 5px line with translateY(-50%), and that rule
   is not overridden here just because this one is more specific - specificity
   decides who wins a property, not which properties are set. So the switch
   inherited the lift, and the off state sat 7.5px clear of the top of its
   track, which is what "the toggle is not straight" was. Turning it on hid the
   bug, because the checked rule sets a transform of its own. */
.sw .track .knob{position:absolute;top:2px;left:2px;width:21px;height:21px;border-radius:50%;
                 background:var(--ink-3);transition:transform .18s,background .18s;
                 box-shadow:0 1px 3px rgba(0,0,0,.35);opacity:1;right:auto;transform:none}
.sw input:checked + .track{background:var(--amber-deep);border-color:var(--amber)}
.sw input:checked + .track .knob{transform:translateX(19px);background:#FFF3DF}
.sw input:focus-visible + .track{outline:2px solid var(--amber);outline-offset:2px}
.sw .lab{font-size:12.5px;color:var(--ink-3);line-height:1.45}
.sw .lab b{display:block;color:var(--ink);font-size:14px;font-weight:600;margin-bottom:3px}

/* The same switch as in settings, laid out for the start screen: label first,
   control on the right, so it reads as a setting rather than a third button
   competing with Start a party and Join. */
.homerow{margin-top:11px;padding:13px 15px;border-radius:var(--r);background:var(--surface);
         border:1px solid var(--line-2);align-items:center;justify-content:space-between;gap:14px}
.homerow .lab{flex:1 1 auto;min-width:0;font-size:12px}
.homerow .lab b{font-size:14px;margin-bottom:2px}
.homerow:active{background:var(--surface-2)}

/* ============================ search ============================ */
.searchbox{flex:1 1 auto;min-width:0;width:100%;background:var(--surface-2);border:1px solid var(--line-2);
           border-radius:12px;padding:14px 16px;font-size:16px;-webkit-appearance:none;appearance:none}
.searchbox:focus{outline:2px solid var(--amber);outline-offset:1px}
.results{display:flex;flex-direction:column;gap:6px;
         max-height:46vh; max-height:46dvh;
         overflow-y:auto;-webkit-overflow-scrolling:touch}
.sr{display:flex;align-items:center;gap:12px;width:100%;text-align:left;padding:9px 10px;border-radius:10px;
    background:var(--surface-2);border:1px solid transparent;transition:border-color .12s,background .12s}
.sr:active{background:var(--surface-3)}
.sr.added{border-color:var(--green);opacity:.65}
.sr img,.sr .ph{width:42px;height:42px;border-radius:7px;flex:0 0 auto;object-fit:cover;background:var(--surface-3)}
.sr .ph{display:flex;align-items:center;justify-content:center;color:var(--ink-3);font-size:18px}
.sr .srt{flex:1 1 auto;min-width:0}
.sr .srt .n{display:block;font-size:14px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sr .srt .a{display:block;font-size:12px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:2px}
.sr .srd{font-family:var(--mono);font-size:11.5px;color:var(--ink-3);flex:0 0 auto;font-variant-numeric:tabular-nums}
.sr.added .srd{color:var(--green)}

/* ============================ countdown ============================ */
.cd{position:fixed;inset:0;z-index:80;background:var(--bg);display:none;
    align-items:center;justify-content:center;flex-direction:column}
.cd.on{display:flex}
.cd .n{font-family:var(--mono);font-size:96px;font-weight:700;color:var(--amber);line-height:1;
       font-variant-numeric:tabular-nums}
.cd .t{margin-top:16px;color:var(--ink-2);font-size:14px;letter-spacing:.06em}
.cd .w{margin-top:6px;color:var(--ink-3);font-size:12.5px;font-family:var(--mono)}
.flash{position:fixed;inset:0;background:var(--amber);opacity:0;pointer-events:none;z-index:90}
@media (prefers-reduced-motion:reduce){.flash{display:none}.meter i{transition:none}.toast{animation:none}}

/* Narrow phones. The header carries five things and an iPhone SE is 320
   points wide, so the invite button drops its word and keeps its icon. */
@media (max-width:380px){
  .top{gap:6px}
  .pill.share span{display:none}
  .code-chip{padding:7px 10px}
  .code-chip .v{font-size:17px}
  .sec{gap:7px}
  .sec button{padding:5px 8px;min-height:34px}
}

.foot{margin-top:30px;padding-top:18px;border-top:1px solid var(--line);color:var(--ink-3);font-size:12px;line-height:1.6}

/* Who you are signed in as, on the start screen. Quiet on purpose: it matters
   to the person starting a party and to nobody else. */
.microline{font-size:12.5px;color:var(--ink-3);text-align:center;margin:14px 0 0}
.microline a{color:var(--ink-2);text-decoration:underline}
.err a{color:var(--amber);text-decoration:underline}

/* Any open sheet takes the screen, and the countdown waits its turn. */
body.sheet-open .guestbar{display:none}

/* ============================ the guest clock ============================
   A countdown somebody can see without it shouting, and a full stop when it
   runs out. The number comes from the server on every heartbeat, so closing
   the app and coming back does not buy more time. */
/* Below the sheets, not above them. At z-index 70 this floated over every
   open sheet and swallowed the taps meant for the buttons along the bottom of
   one - the close button on the QR sheet most of all. Sheets are 60, so this
   sits at 50 and is hidden outright while one is open. */
.guestbar{position:fixed;left:50%;transform:translateX(-50%);
          bottom:calc(14px + env(safe-area-inset-bottom));z-index:50;
          display:flex;align-items:center;gap:10px;
          background:var(--surface);border:1px solid var(--line-2);border-radius:999px;
          padding:9px 9px 9px 16px;box-shadow:var(--shadow);
          font-size:13.5px;color:var(--ink-2);
          /* width:max-content, not the shrink-to-fit default. A fixed box with
             auto width resolved narrower than its text here, so the label was
             ellipsised on a 390px phone while 90px of screen sat unused beside
             it. max-content asks for exactly what the words need; the max-width
             is what stops it running off a small screen. */
          width:max-content;max-width:calc(100vw - 24px)}
.guestbar .gdot{width:7px;height:7px;border-radius:50%;background:var(--amber);flex:0 0 auto}
/* The countdown is the point of this bar, so it is the one part that must
   never be the thing that gets cut. It was: the whole line was one ellipsised
   span, and on a 390px phone "Free preview - 9:57 left" became "Free preview -
   ...". So the number is its own inflexible box and the words around it are
   what give way, label first, then the unit. */
.guestbar .gtxt{display:flex;align-items:baseline;gap:6px;min-width:0;white-space:nowrap;flex:1 1 auto}
.guestbar .glabel{overflow:hidden;text-overflow:ellipsis;min-width:0;flex:0 1 auto}
.guestbar .gunit{flex:0 0 auto}
/* No width breakpoints here on purpose. The number cannot shrink and the
   label can, so flex gives up exactly as much of "Free preview" as the screen
   actually demands and not a character more - which on most phones is none. */
/* Big, monospaced and red, because a countdown people are meant to act on
   should not look like a footnote. Tabular figures so it does not jiggle as
   the digits change. */
.guestbar b{color:var(--red);font-variant-numeric:tabular-nums;font-family:var(--mono);
            font-size:19px;font-weight:700;letter-spacing:-.02em;margin:0;flex:0 0 auto}
.guestbar .gcta{flex:0 0 auto;background:var(--amber);color:var(--on-amber);
                border-radius:999px;padding:6px 13px;font-weight:600;font-size:12.5px;text-decoration:none}
.guestbar .gdot{background:var(--red);animation:gpulse 1.6s ease-in-out infinite}
@keyframes gpulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.75)}}
@media(prefers-reduced-motion:reduce){.guestbar .gdot{animation:none}}
/* The last two minutes: the whole bar goes red, not just the number. */
.guestbar.warn{border-color:var(--red);
               background:color-mix(in srgb,var(--red) 12%,var(--surface))}
.guestbar.warn .gtxt{color:var(--ink)}

.gate{position:fixed;inset:0;z-index:95;background:var(--scrim);
      backdrop-filter:blur(6px);display:flex;align-items:center;justify-content:center;padding:22px}
.gatecard{background:var(--surface);border:1px solid var(--line-2);border-radius:20px;
          padding:30px 26px;max-width:390px;width:100%;text-align:center;box-shadow:var(--shadow)}
.gatecard .gicon{font-size:34px;line-height:1;margin-bottom:14px}
.gatecard h2{font-size:1.32rem;margin:0 0 10px;letter-spacing:-.02em}
.gatecard p{color:var(--ink-2);font-size:14.5px;margin:0 0 20px}
.gatecard .btn{display:flex;align-items:center;justify-content:center;padding:14px;
               border-radius:12px;font-weight:600;font-size:15px;text-decoration:none;
               border:1px solid transparent;margin-bottom:10px}
.gatecard .btn.primary{background:var(--amber);color:var(--on-amber)}
.gatecard .btn.ghost{background:var(--surface-2);color:var(--ink);border-color:var(--line-2)}
.gatecard .gatefine{font-size:12.5px;color:var(--ink-3);margin:14px 0 0}

/* ============================ your account ============================ */
.whocard{display:flex;align-items:center;gap:14px;background:var(--surface-2);
         border:1px solid var(--line);border-radius:14px;padding:15px 16px;margin-bottom:14px}
.whocard .wav{flex:0 0 auto;width:46px;height:46px;border-radius:50%;background:var(--amber);
              color:var(--on-amber);display:flex;align-items:center;justify-content:center;
              font-weight:800;font-size:18px}
.whocard .whot{min-width:0}
.whocard .whot b{display:block;font-size:16px;font-weight:700;margin-bottom:2px}
.whocard .whot span{display:block;font-size:13px;color:var(--ink-3);
                    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

.planbox{background:var(--surface);border:1px solid var(--line-2);border-radius:14px;
         padding:16px 17px;margin-bottom:16px}
.planhead{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}
.planname{font-size:16px;font-weight:700}
.planpill{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
          padding:4px 9px;border-radius:999px;white-space:nowrap}
.planpill.ok{background:color-mix(in srgb,var(--green) 16%,transparent);color:var(--green)}
.planpill.trial{background:var(--amber-glow);color:var(--amber)}
.planpill.over{background:color-mix(in srgb,var(--red) 14%,transparent);color:var(--red)}
.plandl{display:grid;grid-template-columns:1fr 1fr;gap:12px 16px;margin:0}
.plandl div{min-width:0}
.plandl dt{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);margin-bottom:3px}
.plandl dd{margin:0;font-size:14px;font-weight:600;color:var(--ink)}
.planbox .note{margin:14px 0 0}

/* An anchor wearing a button's clothes still behaves like an anchor unless it
   is told otherwise: it was arriving underlined and in the browser's own link
   blue rather than the app's. */
a.big-btn{text-decoration:none;display:flex;align-items:center;justify-content:center}
a.big-btn:hover{text-decoration:none}
#profileSheet .note a{color:var(--ink-3);text-decoration:underline;text-underline-offset:2px}
#profileSheet .note a:hover{color:var(--ink-2)}

/* ---- the account row on the start screen ---------------------------- */
.mecard{display:flex;align-items:center;gap:12px;margin:16px 0 0;padding:11px 13px;
        border:1px solid var(--line-2);border-radius:14px;background:var(--surface);
        color:var(--ink);text-decoration:none;transition:border-color .12s,background .12s}
.mecard:hover{border-color:var(--amber);text-decoration:none}
.mecard .mav{flex:0 0 auto;line-height:0}
.mecard .mav .av{width:38px;height:38px;border-radius:11px}
.mecard .mtxt{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 auto}
.mecard .mtxt b{font-size:14.5px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mecard .mtxt span{font-size:12.5px;color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mecard .mgo{flex:0 0 auto;color:var(--ink-3)}
.mecard:hover .mgo{color:var(--amber)}

/* An avatar beside a name in the speaker list. */
.speaker .av,.who .av{width:22px;height:22px;border-radius:7px;flex:0 0 auto}
/* The leave button, once armed by the first tap. */
.pill.iconpill.arm{width:auto;padding:0 12px;background:var(--red);border-color:var(--red);color:#fff}
.pill.iconpill.arm span{font-size:12.5px;font-weight:600;white-space:nowrap}

/* ---- the start screen's own top bar --------------------------------- */
.startbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.startbar .sbspace{flex:1 1 auto}
/* The right-hand controls move as one group, so a narrow phone drops all of
   them to the next line together rather than stranding the avatar on its own. */
.startbar .sbright{display:flex;align-items:center;gap:8px;flex:0 0 auto;margin-left:auto}
.sbtn{display:inline-flex;align-items:center;gap:7px;padding:7px 12px;border-radius:999px;
      border:1px solid var(--line-2);background:var(--surface);color:var(--ink);
      font:inherit;font-size:12.5px;font-weight:600;cursor:pointer;text-decoration:none;
      white-space:nowrap;transition:border-color .12s,background .12s}
.sbtn:hover{border-color:var(--amber);text-decoration:none}
.sbtn.av{padding:3px;line-height:0;border-radius:12px}
.sbtn.av .av{width:30px;height:30px;border-radius:9px}
.sbtn .livedot{width:7px;height:7px;border-radius:50%;background:var(--green);flex:0 0 auto;
               animation:sbpulse 1.8s ease-in-out infinite}
@keyframes sbpulse{0%,100%{opacity:1}50%{opacity:.35}}
@media(prefers-reduced-motion:reduce){.sbtn .livedot{animation:none}}
#btnExitParty{color:var(--red);border-color:color-mix(in srgb,var(--red) 40%,var(--line-2))}
#btnExitParty:hover{background:color-mix(in srgb,var(--red) 10%,transparent);border-color:var(--red)}
#btnExitParty.arm{background:var(--red);border-color:var(--red);color:#fff}

/* ---- party top bar, rebuilt for a phone ----------------------------- */
/* The sync pill is status and the door to settings, so it never shrinks and
   never wraps. What gives way instead are two labels nobody needs to read:
   the word "Party" above the code, and the word "Invite" beside its icon. */
.top{flex-wrap:nowrap}
.top .spacer{flex:1 1 auto;min-width:0}
.pill.sync{flex:0 0 auto}
.code-chip{flex:0 0 auto;min-width:0}
.pill.iconpill{width:38px;height:34px;padding:0;justify-content:center;flex:0 0 auto}
.pill.iconpill#btnShare{width:auto;padding:7px 13px;gap:7px}

@media(max-width:430px){
  .top{gap:6px}
  .code-chip{padding:7px 10px}
  .code-chip .k{display:none}                 /* the code is self-explanatory */
  .pill.iconpill#btnShare{width:38px;padding:0;gap:0}
  .pill.iconpill#btnShare #shareTxt{display:none}
  .pill.sync{padding:7px 10px;font-size:12px}
}
@media(max-width:340px){
  .pill.sync #syncTxt{display:none}           /* the dot still says it */
  /* Height explicitly, not left to the content. Hiding the label left the
     pill the height of its own 7px dot, which is not a thing anybody can
     tap and is not a thing anybody can read either. */
  .pill.sync{width:36px;height:34px;padding:0;justify-content:center}
}

/* Day and night, now inside the settings sheet. */
.setrow{display:flex;align-items:center;justify-content:space-between;gap:12px;
        padding:12px 0;border-bottom:1px solid var(--line)}
.setrow .setlab{font-size:14px;font-weight:600;color:var(--ink)}

/* The plain-words line above the diagnostics grid. */
.verdict{margin:0 0 12px;padding:11px 13px;border-radius:11px;font-size:13.5px;line-height:1.5;
         background:var(--surface-2);border:1px solid var(--line);color:var(--ink-2)}
.verdict.ok{border-color:color-mix(in srgb,var(--green) 45%,var(--line));
            background:color-mix(in srgb,var(--green) 10%,transparent);color:var(--ink)}
.verdict.warn{border-color:color-mix(in srgb,var(--amber) 50%,var(--line));
              background:color-mix(in srgb,var(--amber) 10%,transparent);color:var(--ink)}
.verdict.bad{border-color:color-mix(in srgb,var(--red) 50%,var(--line));
             background:color-mix(in srgb,var(--red) 10%,transparent);color:var(--ink)}
.cap{margin:12px 0 0;font-size:12.5px;line-height:1.55;color:var(--ink-3)}
.cap b{color:var(--ink-2)}
/* The you-bar and speaker chip carry a drawn face now when signed in. */
#youAv,#myAv{line-height:0;display:inline-flex;align-items:center;justify-content:center;overflow:hidden}
#youAv .av{border-radius:9px}
#myAv .av{border-radius:7px}

/* ====================================================================
 * The aesthetic pass
 *
 * The complaint was fair: everything was one weight, one surface, one
 * shadow, and nothing ever moved. What follows adds three things and
 * nothing else - depth, rhythm, and motion that means something.
 *
 * The rule for the motion: it only ever animates in response to a real
 * event. Nothing loops for decoration, so a phone on a table is not
 * burning battery to look busy, and every animation here is switched off
 * under prefers-reduced-motion at the bottom of this block.
 *
 * System fonts stay. The app has to work on a wifi network with no
 * internet at all, and a webfont is a request that cannot be made there.
 * So the hierarchy comes from size, weight and tracking instead.
 * ==================================================================== */

/* ---- depth ----------------------------------------------------------
   One light source, from above. Every raised surface gets the same thin
   highlight along its top edge, which is what makes a flat token colour
   read as a physical card without a heavier shadow. */
/* Named one at a time on purpose. A blanket `position:relative` over a list
   of selectors once caught .sheet, which is fixed, and quietly stopped the
   search panel from opening. Only what needs an anchor gets one. */
.now,.card{position:relative}
.now::before,.card::before{content:"";position:absolute;left:12px;right:12px;top:0;height:1px;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--ink) 12%,transparent),transparent);
  pointer-events:none;border-radius:1px}

/* ---- now playing: the one thing on this screen that should look alive */
.now{padding:26px 22px 20px;border-radius:22px}
.now h2{font-size:25px;letter-spacing:-.025em;margin:10px 0 3px;line-height:1.18}
@media (max-width:390px){ .now h2{font-size:22px} }
.now .eyebrow{display:inline-flex;align-items:center;gap:7px}
/* A dot that beats while the music is running. It is the only thing on
   the screen that says "this is live" without words. */
.now .eyebrow::before{content:"";width:6px;height:6px;border-radius:50%;
  background:var(--ink-3);flex:0 0 auto;transition:background .25s ease}
.now.live .eyebrow::before{background:var(--amber);animation:beat 1.9s ease-in-out infinite}
@keyframes beat{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(.55);opacity:.45}}

/* The glow behind the card breathes only while something is playing. */
.now::after{transition:opacity .5s ease;opacity:.55}
.now.live::after{opacity:1;animation:aurora 9s ease-in-out infinite}
@keyframes aurora{
  0%,100%{background:radial-gradient(120% 70% at 30% -20%,var(--amber-glow),transparent 60%)}
  50%    {background:radial-gradient(130% 80% at 70% -10%,var(--amber-glow),transparent 62%)}
}

/* ---- the meter ------------------------------------------------------
   Mirrored from the middle rather than sitting on a floor, so it reads as
   a waveform instead of a bar chart, and the bars are rounded at both
   ends. `.real` marks the moments it is showing the actual output of this
   phone's speaker rather than the drawn stand-in. */
.meter{align-items:center;height:44px;gap:2.5px;margin:18px 0 6px;opacity:.4;
       transition:opacity .35s ease}
.meter i{border-radius:2px;min-height:3px;
  background:linear-gradient(180deg,var(--amber),var(--amber-deep));
  transition:height .09s linear}
.meter.live{opacity:.9}
.meter.live.real{opacity:1}
.meter.live i{box-shadow:0 0 10px -2px var(--amber-glow)}

/* ---- the progress bar ---------------------------------------------- */
.track{height:6px}
.fill{box-shadow:0 0 12px -2px var(--amber)}
.fill::after{content:"";position:absolute;right:0;top:50%;width:6px;height:6px;border-radius:50%;
  background:var(--amber);transform:translate(50%,-50%);opacity:0;transition:opacity .2s}
.now.live .fill::after{opacity:1}

/* ---- the transport -------------------------------------------------- */
.transport{gap:30px;margin:20px 0 8px}
.play{width:74px;height:74px;transition:transform .12s cubic-bezier(.34,1.56,.64,1),box-shadow .2s ease}
.play:active{transform:scale(.93)}
/* A ripple out of the button on every press, so a tap is acknowledged
   before the network has said anything. */
.play::after{content:"";position:absolute;inset:0;border-radius:50%;
  border:2px solid var(--amber);opacity:0;pointer-events:none}
.play.pressed::after{animation:ripple .5s ease-out}
@keyframes ripple{from{transform:scale(1);opacity:.7}to{transform:scale(1.5);opacity:0}}
.tbtn{transition:transform .12s ease,color .15s ease}
.tbtn:active{transform:scale(.9)}

/* ---- rows that arrive --------------------------------------------- */
/* Only new rows animate: the class is added when a row is drawn for the
   first time and removed once it has played, so a redraw does not make
   the whole list flutter. */
.item.fresh,.dev.fresh{animation:rowin .28s cubic-bezier(.16,1,.3,1) both}
@keyframes rowin{from{opacity:0;transform:translateY(9px) scale(.985)}}
.item{transition:border-color .2s ease,background .2s ease,transform .12s ease}
.item:active{transform:scale(.995)}
.item.playing{box-shadow:0 0 0 1px var(--amber-glow),0 6px 20px -14px var(--amber)}
.dev{transition:border-color .2s ease}

/* ---- the sync pill -------------------------------------------------- */
/* Green when it is right, and it says so quietly rather than sitting
   there as a static label. */
.pill .dot{transition:background .3s ease}
.pill.ok .dot{animation:breathe 3.4s ease-in-out infinite}
@keyframes breathe{0%,100%{opacity:1}50%{opacity:.45}}

/* ---- the start screen ---------------------------------------------- */
.brand h1{font-size:31px;letter-spacing:-.04em}
.brand .mark{width:50px;height:50px;border-radius:13px;
  box-shadow:0 8px 24px -12px rgba(0,0,0,.5)}
.card{transition:border-color .2s ease,box-shadow .25s ease}

/* ---- section headings get air -------------------------------------- */
.sec{margin:32px 0 12px}
.sec h3{letter-spacing:.17em}

/* ---- and none of it, for anybody who asked for none of it ---------- */
@media (prefers-reduced-motion:reduce){
  .now.live::after,.now.live .eyebrow::before,.pill.ok .dot{animation:none}
  .item.fresh,.dev.fresh{animation:none}
  .play.pressed::after{animation:none}
  .meter i{transition:none}
  .play,.tbtn,.item{transition:none}
}
