diff --git a/README.md b/README.md
index 37131d1d..1d12a339 100644
--- a/README.md
+++ b/README.md
@@ -659,11 +659,15 @@ the main tabs in the ui
 * `[🔎]` [search](#searching) by size, date, path/name, mp3-tags ...
 * `[🧯]` [unpost](#unpost): undo/delete accidental uploads
 * `[🚀]` and `[🎈]` are the [uploaders](#uploading)
+* `[📟]` send-msg: either to server-log or into textfiles if `--urlform save`
+* `[⚙️]` client config options
+
+
+## quick actions (+)
+
 * `[📂]` mkdir: create directories
 * `[📝]` new-file: create a new textfile
-* `[📟]` send-msg: either to server-log or into textfiles if `--urlform save`
-* `[🎺]` audio-player config options
-* `[⚙️]` general client config options
+* `[🚀]` upload: quick way to pick files for upload
 
 
 ## hotkeys
@@ -677,7 +681,7 @@ the browser has the following hotkeys  (always qwerty)
 * `G` toggle list / [grid view](#thumbnails) -- same as `田` bottom-right
 * `T` toggle thumbnails / icons
 * `ESC` close various things
-* `ctrl-K` delete selected files/folders
+* `ctrl-K/Del` delete selected files/folders
 * `ctrl-X` cut selected files/folders
 * `ctrl-C` copy selected files/folders to clipboard
 * `ctrl-V` paste (move/copy)
@@ -732,9 +736,9 @@ the browser has the following hotkeys  (always qwerty)
 
 ## navpane
 
-switching between breadcrumbs or navpane
+opening the navpane
 
-click the `🌲` or pressing the `B` hotkey to toggle between breadcrumbs path (default), or a navpane (tree-browser sidebar thing)
+clicking the `≡` or pressing the `B` hotkey toggles the navpane (tree-browser sidebar thing)
 
 * `[+]` and `[-]` (or hotkeys `A`/`D`) adjust the size
 * `[🎯]` jumps to the currently open folder
@@ -747,7 +751,7 @@ click the `🌲` or pressing the `B` hotkey to toggle between breadcrumbs path (
 
 ## thumbnails
 
-press `g` or `田` to toggle grid-view instead of the file listing  and `t` toggles icons / thumbnails
+press `g` or use the view mode buttons in the top left to toggle grid-view instead of the file listing  and `t` toggles icons / thumbnails
 * can be made default globally with `--grid` or per-volume with volflag `grid`
 * enable by adding `?imgs` to a link, or disable with `?imgs=0`
 
@@ -910,9 +914,7 @@ dropping files into the browser also lets you see if they exist on the server
 
 ![copyparty-fsearch-fs8](https://user-images.githubusercontent.com/241032/129635361-c79286f0-b8f1-440e-aaf4-6e929428fac9.png)
 
-when you drag/drop files into the browser, you will see two dropzones: `Upload` and `Search`
-
-> on a phone? toggle the `[🔎]` switch green before tapping the big yellow Search button to select your files
+toggle the `[🔎]` switch in the upload options to search for files instead of uploading
 
 the files will be hashed on the client-side, and each hash is sent to the server, which checks if that file exists somewhere
 
@@ -982,6 +984,8 @@ file selection: click somewhere on the line (not the link itself), then:
 
 you can copy/move files across browser tabs (cut/copy in one tab, paste in another)
 
+you can drag/drop selected files into other folders
+
 
 ## shares
 
@@ -1158,7 +1162,7 @@ some highlights:
 
 click the `play` link next to an audio file, or copy the link target to [share it](https://a.ocv.me/pub/demo/music/Ubiktune%20-%20SOUNDSHOCK%202%20-%20FM%20FUNK%20TERRROR!!/#af-1fbfba61&t=18) (optionally with a timestamp to start playing from, like that example does)
 
-open the `[🎺]` media-player-settings tab to configure it,
+open the `[⚙]` configuration options and go to the `[🎵]` media player section to configure it,
 * "switches":
   * `[🔁]` repeats one single song forever
   * `[🔀]` shuffles the files inside each folder
@@ -1210,7 +1214,7 @@ you can use foobar2000, deadbeef, just about any standalone player should work -
 
 alternatively, you can create the playlist using copyparty itself:
 
-* open the `[🎺]` media-player-settings tab and enable the `[📻]` create-playlist feature -- this adds two new buttons in the bottom-right tray, `[📻add]` and `[📻copy]` which appear when you listen to music, or when you select a few audiofiles
+* open the `[⚙]` configuration options, go to the `[🎵]` media player section and enable the `[📻]` create-playlist feature -- this adds two new buttons in the bottom-right tray, `[📻add]` and `[📻copy]` which appear when you listen to music, or when you select a few audiofiles
 
 * click the `📻add` button while a song is playing (or when you've selected some songs) and they'll be added to "the list" (you can't see it yet)
 
@@ -1299,6 +1303,12 @@ see [./srv/expand/](./srv/expand/) for usage and examples
 
 search by size, date, path/name, mp3-tags, ...
 
+by default, the `[🔍]` search button shows the folder search bar.
+
+search for files within a folder and optionally its subfolders.
+
+for extended search options, use the dropdown arrow to open the full search UI
+
 ![copyparty-search-fs8](https://user-images.githubusercontent.com/241032/129635365-c0ff2a9f-0ee5-4fc3-8bb6-006033cf67b8.png)
 
 when started with `-e2dsa` copyparty will scan/index all your files. This avoids duplicates on upload, and also makes the volumes searchable through the web-ui:
diff --git a/contrib/plugins/minimal-up2k.html b/contrib/plugins/minimal-up2k.html
index bc44cf7f..f437d04c 100644
--- a/contrib/plugins/minimal-up2k.html
+++ b/contrib/plugins/minimal-up2k.html
@@ -18,7 +18,7 @@
 
     #ops, #tree, #path, #wfp,  /* main tabs and navigators (tree/breadcrumbs) */
 
-    #u2conf tr:first-child>td[rowspan]:not(#u2btn_cw),  /* most of the config options */
+    #u2conf tr:first-child>td[rowspan],  /* most of the config options */
 
     #srch_dz, #srch_zd,  /* the filesearch dropzone */
 
@@ -30,16 +30,12 @@
 
     /* add some margins because now it's weird */
     .opview {margin-top: 2.5em}
-    #op_up2k {margin-top: 6em}
 
     /* and embiggen the upload button */
     #u2conf #u2btn, #u2btn {padding:1.5em 0}
 
     /* adjust the button area a bit */
-    #u2conf.w, #u2conf.ww {width: 35em !important; margin: 5em auto}
-
-    /* a */
-    #op_up2k {min-height: 0}
+    #u2conf.w {width: 35em !important; margin: 5em auto}
 
 </style>
 
diff --git a/contrib/plugins/minimal-up2k.js b/contrib/plugins/minimal-up2k.js
index b3514aea..92689a25 100644
--- a/contrib/plugins/minimal-up2k.js
+++ b/contrib/plugins/minimal-up2k.js
@@ -39,20 +39,6 @@ var u2min = `
   display: none !important;
 }
 #u2conf {margin:5em auto 0 auto !important}
-#u2conf.ww {width:70em}
-#u2conf.w {width:50em}
-#u2conf.w .c,
-#u2conf.w #u2btn_cw {text-align:left}
-#u2conf.w #u2btn_cw {width:70%}
-#u2etaw {margin:3em auto}
-#u2etaw.w {
-  text-align: center;
-  margin: -3.5em auto 5em auto;
-}
-#u2etaw.w #u2etas {margin-right:-37em}
-#u2etaw.w #u2etas.o {margin-top:-2.2em}
-#u2etaw.ww {margin:-1em auto}
-#u2etaw.ww #u2etas {padding-left:4em}
 #u2etas {
   background: none !important;
   border: none !important;
diff --git a/contrib/plugins/rave.js b/contrib/plugins/rave.js
index c6fed874..8e4ea94c 100644
--- a/contrib/plugins/rave.js
+++ b/contrib/plugins/rave.js
@@ -119,7 +119,7 @@ body.untz {
         if (--uofs >= 0) {
             document.body.style.marginLeft = hrand() * uofs + 'px';
             ebi('tree').style.marginLeft = hrand() * uofs + 'px';
-            for (var a of QSA('#ops>a, #path>a, #pctl>a'))
+            for (var a of QSA('#ops>a, #path>a, .pctl>a'))
                 a.style.transform = 'translate(' + hrand() * uofs * 1 + 'px, ' + hrand() * uofs * 0.7 + 'px) rotate(' + Math.random() * uofs * 0.7 + 'deg)'
         }
 
diff --git a/copyparty/__main__.py b/copyparty/__main__.py
index 2f568b5c..ae82d8ce 100644
--- a/copyparty/__main__.py
+++ b/copyparty/__main__.py
@@ -1903,9 +1903,9 @@ def add_ui(ap, retry: int):
     THEMES = 10
     ap2 = ap.add_argument_group("ui options")
     ap2.add_argument("--grid", action="store_true", help="show grid/thumbnails by default (volflag=grid)")
-    ap2.add_argument("--gsel", action="store_true", help="select files in grid by ctrl-click (volflag=gsel)")
+    ap2.add_argument("--no-gsel", action="store_true", help="ctrl-click in gridview will open-in-new-tab instead of select-file (volflag=-gsel)")
     ap2.add_argument("--localtime", action="store_true", help="default to local timezone instead of UTC")
-    ap2.add_argument("--ui-filesz", metavar="FMT", type=u, default="1", help="default filesize format; one of these: 0, 1, 2, 2c, 3, 3c, 4, 4c, 5, 5c, 6, 6c, 7, 7c, fuzzy (see UI)")
+    ap2.add_argument("--ui-filesz", metavar="FMT", type=u, default="6", help="default filesize format; one of these: 0, 1, 2, 2c, 3, 3c, 4, 4c, 5, 5c, 6, 6c, 7, 7c, fuzzy (see UI)")
     ap2.add_argument("--gauto", metavar="PERCENT", type=int, default=0, help="switch to gridview if more than \033[33mPERCENT\033[0m of files are pics/vids; 0=disabled")
     ap2.add_argument("--rcm", metavar="TXT", default="yy", help="rightclick-menu; two yes/no options: 1st y/n is enable-custom-menu, 2nd y/n is enable-double")
     ap2.add_argument("--lang", metavar="LANG", type=u, default="eng", help="language, for example \033[32meng\033[0m / \033[32mnor\033[0m / ...")
@@ -1966,6 +1966,7 @@ def add_ui(ap, retry: int):
     ap2.add_argument("--ui-noctxb", action="store_true", help="hide context-buttons in the UI (volflag=ui_noctxb)")
     ap2.add_argument("--ui-norepl", action="store_true", help="hide repl-button in the UI (volflag=ui_norepl)")
     ap2.add_argument("--have-unlistc", action="store_true", help=argparse.SUPPRESS)
+    ap2.add_argument("--gsel", action="store_true", default=True, help=argparse.SUPPRESS)
 
 
 def add_debug(ap):
diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py
index d8df0715..05e7265a 100644
--- a/copyparty/httpcli.py
+++ b/copyparty/httpcli.py
@@ -5282,7 +5282,7 @@ class HttpCli(object):
         # chrome cannot handle more than ~2000 unique SVGs
         # so url-param "raster" returns a png/webp instead
         # (useragent-sniffing kinshi due to caching proxies)
-        mime, ico = self.conn.hsrv.ico.get(txt, not small, "raster" in self.uparam)
+        mime, ico = self.conn.hsrv.ico.get(txt, not small, "raster" in self.uparam, self.uparam.get('a'))
 
         lm = formatdate(self.E.t0)
         self.reply(ico, mime=mime, headers={"Last-Modified": lm})
@@ -6642,7 +6642,7 @@ class HttpCli(object):
             {
                 "lead": "",
                 "href": "%s/" % (x,),
-                "ext": "---",
+                "ext": "",
                 "sz": 0,
                 "ts": 0,
                 "tags": e_d,
@@ -6851,7 +6851,7 @@ class HttpCli(object):
                                 pass
 
                     if is_dir:
-                        return self.tx_svg("folder")
+                        return self.reply(b"(no thumbnail)")
 
                 thp = None
                 if self.thumbcli and not nothumb:
@@ -6871,7 +6871,7 @@ class HttpCli(object):
                 elif th_fmt in ACODE2_FMT:
                     raise Pebkac(415)
 
-                return self.tx_ico(rem)
+                return self.reply(b"(no thumbnail)")
 
         elif self.can_write and th_fmt is not None:
             return self.tx_svg("upload\nonly")
@@ -6966,15 +6966,20 @@ class HttpCli(object):
             elif not self.can_write:
                 return self.tx_404(True)
 
+        srv_name = ""
         srv_info = []
 
         try:
             if not self.args.nih:
+                srv_name = self.args.name_html
                 srv_info.append(self.args.name_html)
         except:
             self.log("#wow #whoa")
 
         zi = vn.flags["du_iwho"]
+        h1 = ""
+        h2 = ""
+        space_used_percent = 0
         if zi and (
             zi == 9
             or (zi == 7 and self.uname != "*")
@@ -7002,6 +7007,8 @@ class HttpCli(object):
                 h1 = humansize(free or 0)
                 h2 = humansize(total)
                 srv_info.append("{} free of {}".format(h1, h2))
+                if(total > 0):
+                    space_used_percent = (total - (free or 0)) / total * 100
             elif zs:
                 self.log("diskfree(%r): %s" % (abspath, zs), 3)
 
@@ -7052,6 +7059,9 @@ class HttpCli(object):
             "files": [],
             "taglist": [],
             "srvinf": srv_infot,
+            "space_used_percent": space_used_percent,
+            "space_free": h1,
+            "space_total": h2,
             "acct": self.uname,
             "perms": perms,
             "cfg": vn.js_ls,
@@ -7075,6 +7085,10 @@ class HttpCli(object):
             "url_suf": url_suf,
             "title": html_escape("%s %s" % (self.args.bname, self.vpath), crlf=True),
             "srv_info": srv_infot,
+            "srv_name": srv_name,
+            "space_used_percent": space_used_percent,
+            "space_free": h1,
+            "space_total": h2,
             "dtheme": self.args.theme,
         }
 
@@ -7219,12 +7233,12 @@ class HttpCli(object):
                     margin = "DIR"
                 elif add_dk:
                     zs = absreal(fspath)
-                    margin = '<a href="%s?k=%s&zip=crc" rel="nofollow">zip</a>' % (
+                    margin = '<a href="%s?k=%s&zip=crc" rel="nofollow" class="dir">zip</a>' % (
                         quotep(href),
                         self.gen_fk(2, self.args.dk_salt, zs, 0, 0)[:add_dk],
                     )
                 else:
-                    margin = '<a href="%s?zip=crc" rel="nofollow">zip</a>' % (
+                    margin = '<a href="%s?zip=crc" rel="nofollow" class="dir">zip</a>' % (
                         quotep(href),
                     )
             elif fn in hist:
@@ -7248,7 +7262,7 @@ class HttpCli(object):
             )
 
             if is_dir:
-                ext = "---"
+                ext = ""
             elif "." in fn:
                 ext = ptn_hr.sub("@", fn.rsplit(".", 1)[1])
                 if len(ext) > 16:
diff --git a/copyparty/ico.py b/copyparty/ico.py
index 820c53af..5b27027a 100644
--- a/copyparty/ico.py
+++ b/copyparty/ico.py
@@ -11,31 +11,32 @@ from .th_srv import HAVE_PIL, HAVE_PILF
 from .util import BytesIO, html_escape  # type: ignore
 
 
+RE_CSS_COLOR = re.compile(r"[^a-zA-Z0-9#()%.,/-]")
+
+
 class Ico(object):
     def __init__(self, args: argparse.Namespace) -> None:
         self.args = args
 
-    def get(self, ext: str, as_thumb: bool, chrome: bool) -> tuple[str, bytes]:
+    def get(self, ext: str, as_thumb: bool, png: bool, accent: str) -> tuple[str, bytes]:
         """placeholder to make thumbnails not break"""
 
         bext = ext.encode("ascii", "replace")
         ext = bext.decode("utf-8")
-        zb = hashlib.sha1(bext).digest()[2:4]
-        if PY2:
-            zb = [ord(x) for x in zb]  # type: ignore
-
-        c1 = colorsys.hsv_to_rgb(zb[0] / 256.0, 1, 0.3)
-        c2 = colorsys.hsv_to_rgb(zb[0] / 256.0, 0.8 if HAVE_PILF else 1, 1)
-        ci = [int(x * 255) for x in list(c1) + list(c2)]
-        c = "".join(["%02x" % (x,) for x in ci])
-
+        
         w = 100
         h = 30
         if as_thumb:
             sw, sh = self.args.th_size.split("x")
             h = int(100.0 / (float(sw) / float(sh)))
 
-        if chrome:
+        if accent:
+            accent = RE_CSS_COLOR.sub("", accent)
+
+        # obsolete. 2000+ svgs slows chrome down massively, but no crash.
+        # further, unique svgs are only used for non-standard thumbnails,
+        # so it's unrealistic to see that many in use
+        if png & 0:
             # cannot handle more than ~2000 unique SVGs
             if HAVE_PILF:
                 # pillow 10.1 made this the default font;
@@ -48,11 +49,11 @@ class Ico(object):
 
                     h = int(128.0 * h / w)
                     w = 128
-                    img = Image.new("RGB", (w, h), "#" + c[:6])
+                    img = Image.new("RGBA", (w, h), "#00000000")
                     pb = ImageDraw.Draw(img)
                     _, _, tw, th = pb.textbbox((0, 0), ext2, font_size=16)
                     xy = (int((w - tw) / 2), int((h - th) / 2))
-                    pb.text(xy, ext2, fill="#" + c[6:], font_size=16)
+                    pb.text(xy, ext2, fill=accent, font_size=16)
 
                     img = img.resize((w * 2, h * 2), Image.NEAREST)
 
@@ -69,7 +70,7 @@ class Ico(object):
 
                 h = int(64.0 * h / w)
                 w = 64
-                img = Image.new("RGB", (w, h), "#" + c[:6])
+                img = Image.new("RGBA", (w, h), "#00000000")
                 pb = ImageDraw.Draw(img)
                 try:
                     _, _, tw, th = pb.textbbox((0, 0), ext)
@@ -79,7 +80,7 @@ class Ico(object):
                 tw += len(ext)
                 cw = tw // len(ext)
                 x = ((w - tw) // 2) - (cw * 2) // 3
-                fill = "#" + c[6:]
+                fill = accent
                 for ch in ext:
                     pb.text((x, (h - th) // 2), " %s " % (ch,), fill=fill)
                     x += cw
@@ -93,9 +94,9 @@ class Ico(object):
         svg = """\
 <?xml version="1.0" encoding="UTF-8"?>
 <svg version="1.1" viewBox="0 0 100 {}" xmlns="http://www.w3.org/2000/svg"><g>
-<rect width="100%" height="100%" fill="#{}" />
+<rect width="100%" height="100%" fill="#0000" />
 <text x="50%" y="{}" dominant-baseline="middle" text-anchor="middle" xml:space="preserve"
-  fill="#{}" font-family="monospace" font-size="14px" style="letter-spacing:.5px">{}</text>
+  fill="{}" font-family="monospace" font-size="14px" style="letter-spacing:.5px">{}</text>
 </g></svg>
 """
 
@@ -109,6 +110,6 @@ class Ico(object):
         else:
             y = "50%"
 
-        svg = svg.format(h, c[:6], y, c[6:], txt)
+        svg = svg.format(h, y, accent or '#000', txt)
 
         return "image/svg+xml", svg.encode("utf-8")
diff --git a/copyparty/util.py b/copyparty/util.py
index 1f7b9cec..a2330291 100644
--- a/copyparty/util.py
+++ b/copyparty/util.py
@@ -450,7 +450,10 @@ if ANYWIN:
     IMPLICATIONS.extend([["z", "zm4"]])
 
 
-UNPLICATIONS = [["no_dav", "daw"]]
+UNPLICATIONS = [
+    ["no_dav", "daw"],
+    ["no_gsel", "gsel"],
+]
 
 
 DAV_ALLPROP_L = [
diff --git a/copyparty/web/baguettebox.js b/copyparty/web/baguettebox.js
index 3bd2a53e..b1f12792 100644
--- a/copyparty/web/baguettebox.js
+++ b/copyparty/web/baguettebox.js
@@ -28,7 +28,7 @@ window.baguetteBox = (function () {
             onChange: null,
             readDirRtl: false,
         },
-        overlay, slider, btnPrev, btnNext, btnHelp, btnAnim, btnRotL, btnRotR, btnSel, btnFull, btnZoom, btnVmode, btnReadDir, btnClose,
+        overlay, slider, btnPrev, btnNext, btnHelp, btnAnim, btnRotL, btnRotR, btnSel, btnFull, btnZoom, btnPixelated, btnVmode, btnReadDir, btnClose,
         currentGallery = [],
         currentIndex = 0,
         isOverlayVisible = false,
@@ -305,19 +305,20 @@ window.baguetteBox = (function () {
             ctr.innerHTML = (
                 '<div id="bbox-overlay" role="dialog">' +
                 '<div id="bbox-slider"></div>' +
-                '<button id="bbox-prev" class="bbox-btn" type="button" aria-label="Previous">&lt;</button>' +
-                '<button id="bbox-next" class="bbox-btn" type="button" aria-label="Next">&gt;</button>' +
+                '<div id="bbox-prev"><a class="btn" aria-label="Previous">◀</a></div>' +
+                '<div id="bbox-next"><a class="btn" aria-label="Next">▶</a></div>' +
                 '<div id="bbox-btns">' +
-                '<button id="bbox-help" type="button">?</button>' +
-                '<button id="bbox-anim" type="button" tt="a">-</button>' +
-                '<button id="bbox-readdir" type="button" tt="a">ltr</button>' +
-                '<button id="bbox-rotl" type="button">↶</button>' +
-                '<button id="bbox-rotr" type="button">↷</button>' +
-                '<button id="bbox-tsel" type="button">sel</button>' +
-                '<button id="bbox-full" type="button" tt="full-screen">⛶</button>' +
-                '<button id="bbzoom" type="button" tt="zoom/stretch">z</button>' +
-                '<button id="bbox-vmode" type="button" tt="a"></button>' +
-                '<button id="bbox-close" type="button" aria-label="Close">X</button>' +
+                    '<a id="bbox-close" class="btn" aria-label="Close">✕</a>' +
+                    '<a id="bbox-vmode" class="btn" tt="a"></a>' +
+                    '<a id="bbox-full" class="btn" tt="full-screen">⛶</a>' +
+                    '<a id="bbzoom" class="tgl btn" tt="zoom/stretch smaller images to fill screen">↕</a>' +
+                    '<a id="bbpixelated" class="tgl btn" tt="pixelated rendering (good for pixel art)">👾</a>' +
+                    '<a id="bbox-tsel" class="tgl btn">☑️sel</a>' +
+                    '<a id="bbox-rotr" class="btn">↷</a>' +
+                    '<a id="bbox-rotl" class="btn">↶</a>' +
+                    '<a id="bbox-readdir" class="btn" tt="a">ltr</a>' +
+                    '<a id="bbox-anim" class="btn" tt="a">-</a>' +
+                    '<a id="bbox-help" class="btn">?</a>' +
                 '</div></div>'
             );
             overlay = ctr.firstChild;
@@ -335,11 +336,14 @@ window.baguetteBox = (function () {
         btnSel = ebi('bbox-tsel');
         btnFull = ebi('bbox-full');
         btnZoom = ebi('bbzoom');
+        btnPixelated = ebi('bbpixelated');
         btnVmode = ebi('bbox-vmode');
         btnClose = ebi('bbox-close');
 
         bcfg_bind(options, 'bbzoom', 'bbzoom', false, setzoom);
         setzoom();
+        bcfg_bind(options, 'bbpixelated', 'bbpixelated', false, setpixelated);
+        setpixelated();
     }
 
     function halp() {
@@ -356,6 +360,7 @@ window.baguetteBox = (function () {
             ['R', 'rotate (shift=ccw)'],
             ['F', 'toggle fullscreen'],
             ['Z', 'toggle zoom/stretch'],
+            ['X', 'toggle pixelated rendering'],
             ['S', 'toggle file selection'],
             ['space, P, K', 'video: play / pause'],
             ['U', 'video: seek 10sec back'],
@@ -440,6 +445,8 @@ window.baguetteBox = (function () {
             tglfull();
         else if (kl == "z")
             btnZoom.click();
+        else if (kl == "x")
+            btnPixelated.click();
         else if (kl == "s")
             tglsel();
         else if (kl == "r")
@@ -553,6 +560,12 @@ window.baguetteBox = (function () {
         btnState(btnZoom, sel);
     }
 
+    function setpixelated() {
+        var sel = clgot(btnPixelated, 'on')
+        clmod(ebi('bbox-overlay'), 'pixelated', sel);
+        btnState(btnPixelated, sel);
+    }
+
     function tglsel() {
         var o = findfile()[3];
         clmod(o.closest('tr'), 'sel', 't');
@@ -576,18 +589,14 @@ window.baguetteBox = (function () {
             if (vsplit(files[a].vp)[1] == name)
                 sel = true;
 
-        ebi('bbox-overlay').style.background = sel ?
-            'rgba(153,34,85,0.7)' : '';
+        clmod(ebi('bbox-overlay'), 'sel', sel);
 
         img.style.borderRadius = sel ? '1em' : '';
         btnState(btnSel, sel);
     }
 
     function btnState(btn, sel) {
-        btn.style.color = sel ? '#fff' : '';
-        btn.style.background = sel ? '#d48' : '';
-        btn.style.textShadow = sel ? '1px 1px 0 #b38' : '';
-        btn.style.boxShadow = sel ? '.15em .15em 0 #502' : '';
+        clmod(btn, 'on', sel);
     }
 
     function keyUpHandler(e) {
@@ -729,7 +738,7 @@ window.baguetteBox = (function () {
         if (options.buttons === 'auto' && ('ontouchstart' in window || currentGallery.length === 1))
             options.buttons = false;
 
-        btnPrev.style.display = btnNext.style.display = (options.buttons ? '' : 'none');
+        QS('#bbox-next .btn').style.display = QS('#bbox-prev .btn').style.display = (options.buttons ? '' : 'none');
     }
 
     function showOverlay(chosenImageIndex) {
@@ -1233,9 +1242,7 @@ window.baguetteBox = (function () {
     }
 
     function show_buttons(v) {
-        clmod(ebi('bbox-btns'), 'off', v);
-        clmod(btnPrev, 'off', v);
-        clmod(btnNext, 'off', v);
+        clmod(ebi('bbox-overlay'), 'immersive', v);
     }
 
     function bounceAnimation(direction) {
@@ -1297,11 +1304,11 @@ window.baguetteBox = (function () {
                 x = e.clientX - rc.left,
                 fx = x / (rc.right - rc.left);
 
-            if (fx < 0.3)
-                return showLeftImage();
+            // if (fx < 0.3)
+            //     return showLeftImage();
 
-            if (fx > 0.7)
-                return showRightImage();
+            // if (fx > 0.7)
+            //     return showRightImage();
 
             show_buttons('t');
 
@@ -1367,4 +1374,18 @@ window.baguetteBox = (function () {
     };
 })();
 
+
+function init(){
+    if(thegrid != undefined && thegrid.dirty == false && thegrid.bbox != true){
+        console.log('bbox load')
+        thegrid.bagit();
+    }
+    else{
+        setTimeout(init, 100)
+    }
+}
+
+console.log('wait for grid init');
+init();
+
 J_BBX = 2;
diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css
index fb3db76a..03f2b16f 100644
--- a/copyparty/web/browser.css
+++ b/copyparty/web/browser.css
@@ -1,5 +1,6 @@
 :root {
 	color-scheme: dark;
+  	--transparent: transparent;
 
 	--grid-sz: 10em;
 	--grid-ln: 3;
@@ -7,71 +8,50 @@
 	--sbw: 0.5em;
 	--sbh: 0.5em;
 
-	--fg: #ccc;
-	--fg-max: #fff;
-	--fg2-max: #fff;
-	--fg-weak: #bbb;
-
-	--bg-u6: #4c4c4c;
-	--bg-u5: #444;
-	--bg-u4: #383838;
-	--bg-u3: #333;
-	--bg-u2: #2b2b2b;
-	--bg-u1: #282828;
-	--bg: #222;
-	--bgg: var(--bg);
-	--bg-d1: #1c1c1c;
-	--bg-d2: #181818;
-	--bg-d3: #111;
-	--bg-max: #000;
-
-	--tab-alt: #f5a;
-	--row-alt: #282828;
-
-	--scroll: #eb0;
+	--tab-alt: var(--a);
+	--row-alt: var(--bg-u1);
+
 	--sel-fg: var(--bg-d1);
 	--sel-bg: var(--fg);
 
-	--a: #fc5;
-	--a-b: #c90;
-	--a-hil: #fd9;
-	--a-dark: #e70;
-	--a-gray: #666;
-
 	--btn-fg: var(--a);
+	--btn-bg-a: rgba(128,128,128,0.15);
+	--btn-bg-a: color-mix(in oklab, var(--bg-max) 85%, var(--fg-max) 20%);
 	--btn-bg: rgba(128,128,128,0.15);
+	--btn-bg: linear-gradient(-5deg, color-mix(in oklab, var(--btn-bg-a) 40%, transparent), color-mix(in oklab, var(--btn-bg-a)70%, var(--a-gray)));
 	--btn-h-fg: var(--a-hil);
-	--btn-h-bg: #805;
-	--btn-1-fg: #400;
+	--btn-h-bg: color-mix(in oklab, var(--a-gray) 45%, var(--bg-max));
+	--btn-1-fg: var(--bg);
 	--btn-1-bg: var(--a);
 	--btn-h-bs: var(--btn-bs);
 	--btn-h-bb: var(--btn-bb);
 	--btn-1-bs: var(--btn-bs);
 	--btn-1-bb: var(--btn-bb);
 	--btn-1h-fg: var(--btn-1-fg);
-	--btn-1h-bg: #fe8;
+	--btn-1h-bg: var(--a-hil);
 	--btn-1h-bs: var(--btn-1-bs);
+	--btn-bb: 1px solid var(--bg-u3);
 	--btn-1h-bb: var(--btn-1-bb);
 	--chk-fg: var(--tab-alt);
 	--txt-sh: var(--bg-d2);
-	--txt-bg: var(--btn-bg);
+	--txt-bg: var(--btn-bg-a);
 
 	--op-aa-fg: var(--a);
 	--op-aa-bg: var(--bg-d2);
-	--op-a-sh: rgba(0,0,0,0.5);
+	--op-a-sh: color-mix(in oklab, var(--bg-max) 50%, transparent 50%);
 
 	--u2-btn-b1: #999;
 	--u2-sbtn-b1: #999;
 	--u2-txt-bg: var(--bg-u5);
 	--u2-tab-bg: linear-gradient(to bottom, var(--bg), var(--bg-u1));
 	--u2-tab-b1: rgba(128,128,128,0.8);
-	--u2-tab-1-fg: #fd7;
-	--u2-tab-1-bg: linear-gradient(to bottom, #353, var(--bg) 80%);
-	--u2-tab-1-b1: #7c5;
-	--u2-tab-1-b2: #583;
-	--u2-tab-1-sh: #280;
+	--u2-tab-1-fg: var(--a-hil);
+	--u2-tab-1-bg: var(--bg);
+	--u2-tab-1-b1: #999;
+	--u2-tab-1-b2: #999;
+	--u2-tab-1-sh: transparent;
 	--u2-b-fg: #fff;
-	--u2-b1-bg: #c38;
+	--u2-b1-bg: #c83;
 	--u2-b2-bg: #d80;
 	--u2-inf-bg: #07a;
 	--u2-inf-b1: #0be;
@@ -81,8 +61,8 @@
 	--u2-err-b1: #d06;
 	--ud-b1: #888;
 
-	--sort-1: #fb0;
-	--sort-2: #d09;
+	--sort-1: var(--a);
+	--sort-2: var(--a-gray);
 
 	--sz-b: #aaa;
 	--sz-k: #4ff;
@@ -93,153 +73,75 @@
 
 	--srv-1: #aaa;
 	--srv-2: #a73;
-	--srv-3: #f4c;
-	--srv-3b: rgba(255,68,204,0.6);
+	--srv-3: #fc4;
+	--srv-3b: rgba(255,204,68,0.6);
 
-	--tree-bg: #2b2b2b;
+	--tree-bg: var(--bg-u1);
 
 	--g-play-bg: #750;
-	--g-play-b1: #c90;
-	--g-play-b2: #da4;
-	--g-play-sh: #b83;
-
-	--g-sel-fg: #fff;
-	--g-sel-bg: #925;
-	--g-sel-b1: #e39;
-	--g-sel-sh: #b36;
-	--g-fsel-bg: #d39;
-	--g-fsel-b1: #f4a;
-	--g-fsel-ts: #804;
-	--g-dfg: var(--srv-3);
-	--g-fg: var(--a-hil);
+	--g-play-b1: var(--a-dark);
+	--g-play-b2: var(--a);
+
+	--g-sel-fg: var(--fg-max);
+	--g-sel-bg: color-mix(in xyz, var(--g-sel-b1) 30%, var(--bg) 70%);
+	--g-sel-b1: var(--a-dark);
+	--g-sel-sh: hsl(from var(--a) h calc(s * 1.05) calc(l * .3));
+	--g-fsel-bg: color-mix(in xyz, var(--g-sel-b1) 70%, var(--bg-max) 30%);
+	--g-fsel-b1: var(--a);
+	--g-fsel-ts: hsl(from var(--a) h calc(s * 1.05) calc(l * .3));
+	--g-dfg: #bbb;
+	--g-fg: var(--fg);
 	--g-bg: var(--bg-u2);
-	--g-b1: var(--bg-u4);
+	--g-b1: var(--bg-u3);
 	--g-b2: var(--bg-u5);
 	--g-g1: var(--bg-u2);
 	--g-g2: var(--bg-u5);
-	--g-f-bg: var(--bg-u4);
+	--g-f-bg: var(--bg-u3);
 	--g-f-b1: var(--bg-u5);
-	--g-f-fg: var(--a-hil);
-	--g-sh: rgba(0,0,0,0.3);
+	--g-f-fg: var(--fg-max);
+	--g-sh: color-mix(in oklab, var(--bg-max) 30%, transparent 70%);
 
 	--f-sh1: 0.33;
 	--f-sh2: 0.02;
 	--f-sh3: 0.2;
 	--f-h-b1: rgba(128,128,128,0.7);
 
-	--f-play-bg: #fc5;
-	--f-play-fg: #000;
-	--f-sel-sh: #fc0;
+	--f-play-bg: var(--a-dark);
+	--f-play-fg: var(--fg-max);
+	--f-sel-sh: var(--a);
 	--f-gray: #999;
 
-	--fm-off: #f6c;
-	--mp-sh: var(--bg-d3);
-	--mp-b-bg: rgba(0,0,0,0.2);
+	--fm-off: var(--a-hil);
+	--mp-sh: #1116;
+	--mp-b-bg: color-mix(in oklab, var(--bg-max) 20%, transparent 80%);
+
+	--scrl-hint: var(--bg-u2);
 
 	--err-fg: #fff;
 	--err-bg: #a20;
 	--err-b1: #f00;
 	--err-ts: #500;
 }
-html.y {
-	color-scheme: light;
-
-	--fg: #222;
-	--fg-max: #000;
-	--fg-weak: #555;
-
-	--bg-d3: #fff;
-	--bg-d2: #fff;
-	--bg-d1: #fff;
-	--bg: #eaeaea;
-	--bg-u1: #fff;
-	--bg-u2: #f7f7f7;
-	--bg-u3: #eaeaea;
-	--bg-u4: #fff;
-	--bg-u5: #ccc;
-	--bg-u6: #ddd;
-	--bg-max: #fff;
-
-	--tab-alt: #c07;
-	--row-alt: #f2f2f2;
-
-	--scroll: #490;
-
-	--a: #06a;
-	--a-b: #08b;
-	--a-hil: #058;
-	--a-gray: #bbb;
-	--a-dark: #c0f;
-
-	--btn-fg: #555;
-	--btn-h-fg: #222;
-	--btn-h-bg: #caf;
-	--btn-1-fg: #fff;
-	--btn-1-bg: #4a0;
-	--btn-1h-bg: #5c0;
-	--chk-fg: var(--fg);
-	--txt-sh: #aaa;
-	--txt-bg: rgba(255,255,255,0.6);
-
-	--op-a-sh: #fff;
-
-	--u2-txt-bg: var(--bg-max);
-	--u2-tab-1-sh: #0ad;
-	--u2-tab-1-b1: #09c;
-	--u2-tab-1-b2: #05a;
-	--u2-tab-1-fg: var(--fg-max);
-	--u2-tab-1-bg: inherit;
-	--ud-b1: #bbb;
-
-	--sort-1: #059;
-	--sort-2: #f5d;
-
-	--sz-b: #777;
-	--sz-k: #380;
-
-	--srv-1: #555;
-	--srv-2: #c83;
-	--srv-3: #c0a;
-
-	--tree-bg: #fff;
-
-	--g-fg: var(--a);
-	--g-bg: var(--bg-u2);
-	--g-b1: var(--bg-u6);
-	--g-b2: var(--bg-u6);
-	--g-g1: var(--bg-u2);
-	--g-g2: var(--bg-u5);
-	--g-f-bg: var(--bg-u4);
-	--g-f-b1: var(--bg-u5);
-	--g-sh: rgba(0,0,0,0.07);
-
-	--f-sh1: 0.3;
-	--f-sh2: 0.5;
-	--f-sh3: 0.02;
-
-	--f-sel-sh: #e80;
-
-	--fm-off: #c4a;
-	--mp-sh: #bbb;
-	--mp-b-bg: transparent;
 
-	text-shadow: none;
+html.y {
+	--scrl-hint: var(--bg);
 }
-html.a {
+html.b {
 	--op-aa-sh: 0 0 .2em var(--bg-d3) inset;
 
-	--btn-bs: 0 0 .2em var(--bg-d3);
+	--btn-bs: .1em .2em .1em var(--mp-sh);
 }
-html.az {
-	--btn-1-bs: 0 0 .1em var(--fg) inset;
+html.bz {
+	--btn-1-bs: .05em .1em .2em var(--a-dark) inset;
 }
-html.ay {
-	--op-aa-sh: 0 .1em .2em #ccc;
-	--op-aa-bg: var(--bg-max);
+html.by {
+	--btn-bg: linear-gradient(-5deg, color-mix(in oklab, var(--btn-bg-a)80%, var(--a)), color-mix(in oklab, var(--btn-bg-a) 50%, transparent));
 }
-html.b {
+
+html.a {
 	--btn-bs: 0 .05em 0 var(--bg-d3) inset;
 	--btn-1-bs: 0 .05em 0 var(--btn-1h-bg) inset;
+	--btn-bg: color-mix(in oklab, var(--bg-u5), transparent);
 
 	--tree-bg: var(--bg);
 
@@ -251,7 +153,6 @@ html.b {
 
 	--op-aa-bg: rgba(255,255,255,0.06);
 
-	--u2-sbtn-b1: #fc0;
 	--u2-txt-bg: transparent;
 	--u2-tab-1-sh: var(--bg);
 	--u2-b1-bg: rgba(128,128,128,0.15);
@@ -261,60 +162,11 @@ html.b {
 	--mp-b-bg: transparent;
 }
 html.bz {
-	--fg: #cce;
-	--fg-weak: #bbd;
-
-	--bg-u5: #3b3f58;
-	--bg-u4: #1e2130;
-	--bg-u3: #1e2130;
-	--bg-u1: #1e2130;
-	--bg: #11121d;
-	--bg-d1: #232536;
-	--bg-d2: #34384e;
-	--bg-d3: #34384e;
-
-	--row-alt: #181a27;
-
-	--a-b: #fb4;
-
-	--btn-bg: #202231;
-	--btn-h-bg: #2d2f45;
-	--btn-1-bg: #eb6;
-	--btn-1-fg: #000;
-	--btn-1h-fg: #000;
-	--btn-1h-bg: #ff9;
-	--txt-sh: a;
-
-	--u2-tab-b1: var(--bg-u5);
-	--u2-tab-1-fg: var(--fg-max);
-	--u2-tab-1-bg: var(--bg);
-
-	--srv-1: #79b;
-
-	--g-sel-bg: #ba2959;
-	--g-fsel-bg: #e6336e;
-
-	--f-h-b1: #34384e;
-	--mp-sh: #11121d;
-	/*--mp-b-bg: #2c3044;*/
-	--f-play-bg: var(--btn-1-bg);
+	--a: #fc5;
 }
-html.by {
-	--bg: #f2f2f2;
-
-	--row-alt: #f9f9f9;
-
-	--scroll: var(--a);
-
-	--btn-1-bg: #07a;
-	--btn-1h-bg: var(--a-hil);
-
-	--op-aa-bg: #fff;
-
-	--u2-sbtn-b1: #c70;
-	--u2-tab-1-b1: #999;
-	--u2-tab-1-b2: #aaa;
-	--u2-b-fg: #444;
+html.ay {
+	--a: #07c;
+	--bg: var(--bg-u2);
 }
 html.c {
 	font-weight: bold;
@@ -323,7 +175,7 @@ html.c {
 	--fg-weak: #cef;
 	--bg-u5: #409;
 	--bg-u2: linear-gradient(-35deg, #fd7233, #cd27a0, #5d47a5 49.5%, #16e9fb 50%, #3b6cc8 50.4%, #0e51ac);
-	--bg: #37235d;
+	--bg: #376ac5;
 	--bg-u3: #407;
 
 	--a: #f9dc22;
@@ -331,10 +183,9 @@ html.c {
 
 	--tab-alt: #6ef;
 	--row-alt: #47237d;
-	--scroll: #ff0;
 
 	--btn-fg: #fff;
-	--btn-bg: #9019bf;
+	--btn-bg-a: #9019bf;
 	--btn-h-bg: #a039ff;
 	--chk-fg: #d90;
 
@@ -380,7 +231,6 @@ html.cy {
 
 	--tab-alt: #f00;
 	--row-alt: #fff;
-	--scroll: #fff;
 
 	--btn-bg: #000;
 	--btn-fg: #ff0;
@@ -406,9 +256,7 @@ html.dz {
 	--fg: #4d4;
 	--fg-weak: #2a2;
 
-	--bg-u6: #020;
 	--bg-u5: #050;
-	--bg-u4: #020;
 	--bg-u3: #020;
 	--bg-u2: #020;
 	--bg-u1: #020;
@@ -420,10 +268,7 @@ html.dz {
 	--tab-alt: #6f6;
 	--row-alt: #030;
 
-	--scroll: #0f0;
-
 	--a: #9f9;
-	--a-b: #cfc;
 	--a-hil: #cfc;
 	--a-dark: #afa;
 	--a-gray: #2a2;
@@ -454,10 +299,6 @@ html.dz {
 
 	--tree-bg: #010;
 
-	--g-sel-b1: #c37;
-	--g-sel-sh: #b36;
-	--g-fsel-b1: #d48;
-
 	--f-h-b1: #3b3;
 
 	text-shadow: none;
@@ -475,23 +316,19 @@ html.dy {
 	--bg: #fff;
 	--bg-u1: #fff;
 	--bg-u2: #fff;
-	--bg-u3: #fff;
-	--bg-u4: #fff;
+	--bg-u3: #000;
 	--bg-u5: #fff;
-	--bg-u6: #fff;
 	--bg-max: #fff;
 
 	--tab-alt: #000;
 	--row-alt: #eee;
 
-	--scroll: #000;
-
 	--a: #000;
-	--a-b: #000;
 	--a-hil: #000;
 	--a-gray: #bbb;
 	--a-dark: #000;
 
+	--btn-bg: #fff;
 	--btn-fg: #000;
 	--btn-h-fg: #000;
 	--btn-h-bg: #fff;
@@ -526,6 +363,7 @@ html.dy {
 	--tree-bg: #fff;
 
 	--g-sel-bg: #000;
+	--g-sel-fg: #fff;
 	--g-fsel-bg: #444;
 	--g-fsel-ts: #000;
 	--g-fg: a;
@@ -548,6 +386,32 @@ html.dy {
 	--mp-sh: a;
 	--mp-b-bg: #fff;
 }
+html.dy #files tr.sel a, 
+html.dy #files tr.sel a.play {
+	color: #fff;
+}
+html.dy tr.play td:nth-child(1) a {
+  background: #fff;
+  border: #000 solid 1px;
+}
+html.dy #spaceUsed_bar {
+	background: #000;
+}
+html.dy #barpos {
+	border: var(--btn-bb);
+}
+html.dy #pathBar {
+	background: var(--bg);
+}
+html.dy #spaceTotal_bar,
+html.dy select,
+html.dy input {
+	border: #000 solid 1px !important;
+}
+html.dy h3 {
+	border-top: #000 solid 1px;
+	border-radius: 0 !important;
+}
 * {
 	line-height: 1.2em;
 }
@@ -557,13 +421,24 @@ html.dy {
 	text-shadow: none;
 }
 html,body,tr,th,td,#files,a,#blogout {
-	color: inherit;
+	/* color: inherit; */
 	background: none;
 	font-weight: inherit;
 	font-size: inherit;
 	padding: 0;
 	border: none;
 }
+body {
+	background: #e4edf8;
+}
+@supports (background: var(--bg)) {
+	body {
+		background: none;
+	}
+}
+#files {
+	margin-top: .2em;
+}
 html {
 	color: var(--fg);
 	background: var(--bgg);
@@ -575,6 +450,9 @@ html, body {
 	margin: 0;
 	padding: 0;
 }
+.noscroll {
+	overflow: hidden;
+}
 pre, code, tt, #doc, #doc>code {
 	font-family: 'scp', monospace, monospace;
 	font-family: var(--font-mono), 'scp', monospace, monospace;
@@ -587,7 +465,7 @@ pre, code, tt, #doc, #doc>code {
 	left: -10em;
 	color: var(--bg);
 }
-html .ayjump:focus {
+html .ayjump:focus-visible {
 	z-index: 80386;
 	color: #fff;
 	color: var(--a-hil);
@@ -606,56 +484,119 @@ html .ayjump:focus {
 #path * {
 	font-size: 1em;
 }
+#pathBar {
+	display: flex;
+	margin: 0;
+	align-content: center;
+	position: sticky;
+	z-index: 4;
+	background: linear-gradient(to bottom, var(--bg), transparent);
+	padding: .6em .5em;
+	top: 0;
+	margin: 0 -.5em;
+}
+#wfp.shifted {
+	margin-left: 2em;
+}
 #path {
 	color: var(--fg);
 	text-shadow: 1px 1px 0 var(--bg-max);
 	font-weight: normal;
+	display: block;
+	margin: 0 .5em 0 0;
+	width: calc(100% - .5em);
+	padding: 0 .2em;
+	font-size: 1.2em;
+	white-space: nowrap;
+	overflow-x: auto;
+	overflow-y: hidden;
+	background: var(--bg-u2);
+	border-radius: 5px;
+	border-radius: var(--radius);
+}
+#pathBar #folder_search {
+	margin: 0;
+	height: calc(100% - .5em);
+	width: calc(100% - .6em);
+	right: 0;
+}
+#qs_btns {
+	position: absolute;
+	right: .2em;
+	top: .1em;
+	font-size: 1.3em;
+	cursor: pointer;
+}
+#qs_btns a {
+	background: color-mix(in oklab, var(--txt-bg), transparent);
+	width: 1em;
 	display: inline-block;
-	padding: .35em .5em .2em .5em;
-	margin: 1.3em 0 -.2em 0;
-	font-size: 1.4em;
+	text-align: center;
+	border-radius: 5px;
+	border-radius: var(--radius);
+}
+#qs_btns a:hover {
+	background: var(--bg);
 }
 html.y #path {
 	text-shadow: none;
 }
+#path a.dtarget {
+	text-shadow: var(--f-sel-sh) 0 0 5px;
+	background: color-mix(in oklab, var(--a), transparent);
+}
 #path #entree {
 	margin-left: -.7em;
 }
 #files {
+	overflow-x: auto;
+	display: block;
 	z-index: 1;
 	top: -.3em;
 	border-spacing: 0;
 	position: relative;
+	margin: .2em -.5em;
+  	padding: 0 .5em;
 }
 #files tbody a {
 	display: block;
-	padding: .5em 0;
-	margin: -.3em 0;
+	padding: .5em;
 	scroll-margin-top: 45vh;
 }
 #files tr {
 	scroll-margin-top: 25vh;
 	scroll-margin-bottom: 20vh;
 }
+.td_w {
+	width: 30em;
+	max-width: 30em;
+}
+.td_s {
+	width: 14em;
+	max-width: 14em;
+}
 #files tbody div a {
 	color: var(--tab-alt);
 }
 a, #blogout, #files tbody div a:last-child {
-	color: var(--a);
+	color: var(--fg);
 	padding: .2em;
 	text-decoration: none;
 }
+#goh,
 #blogout {
 	margin: -.2em;
+	text-shadow: 1px 1px 0px var(--bg-max);
 }
-#blogout:hover,
+#ops input[type=submit]:hover,
+#goh:hover,
 a:hover {
 	color: var(--a-hil);
 	background: var(--a-h-bg);
 }
 #files a:hover {
 	color: var(--fg-max);
-	background: var(--bg-d3);
+	background: color-mix(in oklab, var(--a) 20%, transparent);
 	text-decoration: underline;
 }
 #files thead th {
@@ -668,13 +609,13 @@ a:hover {
 }
 .s0:after,
 .s1:after {
-	content: '⌄';
-	margin-left: -.15em;
+	content: '▾';
+	/* margin-left: -.15em; */
 }
 .s0r:after,
 .s1r:after {
-	content: '⌃';
-	margin-left: -.15em;
+	content: '▴';
+	/* margin-left: -.15em; */
 }
 .s0:after,
 .s0r:after {
@@ -689,8 +630,14 @@ a:hover {
 }
 #files tbody tr:hover td,
 #files tbody tr:hover td+td {
-	background: var(--bg-d1);
-	box-shadow: 0 1px 0 var(--bg-u5) inset, 0 -1px 0 var(--bg-u5) inset;
+	background: color-mix(in oklab, var(--a) 15%, transparent);
+}
+a.dir {
+	color: var(--a);
+}
+tr.dir td:nth-child(2) a::before {
+	content: "📁";
+	margin: 0 .1em 0 -.2em;
 }
 #files thead th {
 	padding: .3em;
@@ -702,9 +649,10 @@ html.y #files thead th {
 	box-shadow: 0 1px 0 rgba(0,0,0,0.12);
 }
 html #files.hhpick thead th {
-	color: #f7d;
-	background: #000;
-	box-shadow: .1em .2em 0 #f6c inset, -.1em -.1em 0 #f6c inset;
+	color: rgb(0, 0, 0);
+	background: #df5555;
+	text-shadow: none;
+	border: red solid 2px;
 }
 #files td {
 	margin: 0;
@@ -714,6 +662,9 @@ html #files.hhpick thead th {
 	word-wrap: break-word;
 	overflow: hidden;
 }
+#files td:has(a) {
+	padding: 0;
+}
 #files tr.fade a {
 	color: #999;
 	color: rgba(255, 255, 255, 0.4);
@@ -733,11 +684,11 @@ html.y #files tr.fade a {
 	box-shadow: 1px 0 0 0 rgba(128,128,128,var(--f-sh1)) inset, 0 1px 0 rgba(0,0,0,var(--f-sh3)) inset, 0 -1px 0 rgba(0,0,0,var(--f-sh3)) inset;
 }
 #files td:first-child {
-	border-radius: .25em 0 0 .25em;
+	border-radius: var(--radius) 0 0 var(--radius);
 	white-space: nowrap;
 }
 #files td:last-child {
-	border-radius: 0 .25em .25em 0;
+	border-radius: 0 var(--radius) var(--radius) 0;
 }
 #files tbody td:nth-child(3) {
 	font-family: 'scp', monospace, monospace;
@@ -768,36 +719,44 @@ html.y #files span.fsz_P { font-weight: bold }
 #files .srch_hdr a {
 	display: inline;
 }
+#files tr.dtarget {
+	box-shadow: 0 0 5px 0 var(--f-sel-sh) inset;
+	background: color-mix(in oklab, var(--a), transparent);
+}
+#files tr.dtarget td {
+	background: none;
+}
 #path a {
-	padding: 0 .35em;
+	padding: .4em .35em;
 	position: relative;
+	display: inline-block;
+	height: 100%;
 	z-index: 1;
 	/* ie: */
 	border-bottom: .1em solid #777\9;
 	margin-right: 1em\9;
 }
-#path a:first-child {
-	padding-left: .8em;
-}
 #path i {
-	width: 1.05em;
-	height: 1.05em;
-	margin: -.5em .15em -.15em -.7em;
+	width: 2em;
+	height: 2.5em;
+	margin: -1em .3em -1em -1.7em;
 	display: inline-block;
-	border: 1px solid rgba(255,224,192,0.3);
-	border-width: .05em .05em 0 0;
-	transform: rotate(45deg);
-	background: linear-gradient(45deg, rgba(0,0,0,0) 40%, rgba(0,0,0,0.25) 75%, rgba(0,0,0,0.35));
+	transform: skew(-25deg);
+	border-right: #222 solid 2px;
+	border-right: var(--bg) solid 2px;
+	background: linear-gradient(70deg, transparent 40%, color-mix(in oklab, var(--bg-max) 25%, transparent) 75%, color-mix(in oklab, var(--bg-max) 35%, transparent));
 }
-html.y #path i {
-	background: none;
-	border-color: rgba(0,0,0,0.2);
-	border-width: .1em .1em 0 0;
+html.b #path i {
+	border-right: var(--bg) solid 1px;
 }
 #path a:hover {
 	color: var(--fg-max);
 	background: linear-gradient(90deg, rgba(0,0,0,0), rgba(0,0,0,0.2), rgba(0,0,0,0));
 }
+html.a #ggrid>a.dir:before,
+html.a #path i {
+	background: none;
+}
 html.y #path a:hover {
 	background: none;
 }
@@ -811,23 +770,28 @@ html.y #path a:hover {
 	display: none;
 }
 .logue.raw {
+	background: #ccc;
+	background: var(--transparent);
 	white-space: pre;
 	font-family: 'scp', 'consolas', monospace;
 	font-family: var(--font-mono), 'scp', 'consolas', monospace;
 }
+.iframe {
+  background: none;
+}
 #doc>iframe,
 .logue>iframe {
 	background: var(--bgg);
 	border: 1px solid var(--bgg);
 	border-width: 0 .3em 0 .3em;
-	border-radius: .5em;
+	border-radius: var(--radius);
 	visibility: hidden;
-	margin: 0 -.3em;
-	width: 100%;
+	margin: 0 .3em;
+	width: calc(100% - 1em);
 	height: 0;
 }
-#doc>iframe.focus,
-.logue>iframe.focus {
+#doc>iframe.focus-visible,
+.logue>iframe.-visible {
 	box-shadow: 0 0 .1em .1em var(--a);
 }
 #pro.logue>iframe {
@@ -852,14 +816,7 @@ html.y #path a:hover {
 .mdo>h1:first-child,
 .mdo>h2:first-child,
 .mdo>h3:first-child {
-	margin-top: 1.5rem;
-}
-.mdo {
-	max-width: 52em;
-}
-.mdo.sb,
-.logue.mdo>iframe {
-	max-width: 54em;
+	margin-top: 0.5rem;
 }
 .mdo,
 .mdo * {
@@ -874,14 +831,15 @@ html.y #path a:hover {
 }
 #srv_info,
 #acc_info {
-	position: absolute;
+	position: relative;
 	font-size: .8em;
-	top: .5em;
+	bottom: 18.5em;
 }
 #srv_info {
 	left: 2em;
 	padding-right: .5em;
 }
+#accessType,
 #acc_info,
 #srv_info span,
 #srv_info2 span {
@@ -891,18 +849,18 @@ html.y #path a:hover {
 	padding: 0;
 }
 #srv_info2 {
-	display: none;
+	display: block;
 }
 #acc_info {
-	right: 2em;
+	left: 2em;
 }
 #acc_info > span:not([id]) {
 	color: var(--srv-1);
-	margin-right: .6em;
+	margin-left: .6em;
 }
 #acc_info span.warn {
 	color: var(--srv-3);
-	border-bottom: 1px solid var(--srv-3b);
+	border-top: 1px solid var(--srv-3b);
 }
 #flogout {
 	display: inline;
@@ -917,23 +875,37 @@ html.dz #flogout {
 	border-left: .2em solid var(--bg-u5);
 }
 #repl {
+	opacity: .3;
 	padding: .33em;
 }
+#repl:hover{
+	opacity: 1;
+}
 #files a.doc {
 	color: var(--a-gray);
 }
 #files a.doc.bri {
 	color: var(--tab-alt);
 }
-#files a.play {
+tr td:nth-child(1) a {
+	border-radius: var(--radius);
+}
+/* #files a.play {
 	color: var(--a-dark);
 	padding: .3em;
 	margin: -.3em;
+} */
+tr.play td:nth-child(2) a::before {
+  content: "▶";
+}
+tr.play td:nth-child(1) a {
+  background: var(--btn-1-bg);
+  color:var(--btn-1-fg);
+  text-shadow: none;
 }
-#files tbody tr.play td,
+/* #files tbody tr.play td,
 #files tbody tr.play td+td,
 #files tbody tr.play div a {
-	background: #fc0;
 	background: var(--f-play-bg);
 	color: var(--f-play-fg);
 	text-shadow: none;
@@ -946,7 +918,7 @@ html.dz #flogout {
 	background: var(--btn-1h-bg);
 	box-shadow: var(--btn-1h-bs);
 	border-bottom: var(--btn-1h-bb);
-}
+} */
 #ggrid {
 	margin: -.2em -.5em;
 }
@@ -965,7 +937,8 @@ html.dz #flogout {
 	width: var(--grid-sz);
 	vertical-align: top;
 	overflow-wrap: break-word;
-	border-radius: .3em;
+	border-radius: 5px;
+	border-radius: var(--radius);
 	padding: .3em;
 	margin: .5em;
 	color: var(--g-fg);
@@ -974,47 +947,153 @@ html.dz #flogout {
 	border-top: 1px solid var(--g-b2);
 	box-shadow: 0 .1em .3em var(--g-sh);
 }
-#ggrid>a:focus,
+#ggrid>a:focus-visible,
 #ggrid>a:hover {
 	color: var(--g-f-fg);
 	background: var(--g-f-bg);
 	border-color: var(--g-f-b1);
 	box-shadow: 0 .1em .3em var(--g-sh);
+	.gselchk {
+		display: block;
+	}
+}
+#ggrid>a.play .thumb,
+#ggrid>a.play img {
+	background: var(--bg-u2);
 }
+#ggrid>a .thumb,
 #ggrid>a img {
-	border-radius: .2em;
+	z-index: 1;
+	border-radius: 5px;
+	border-radius: var(--radius);
 	max-width: 10em;
-	max-width: var(--grid-sz);
-	max-height: 8em;
-	max-height: calc(var(--grid-sz)/1.25);
+	max-width: calc(var(--grid-sz) - 4px);
 	margin: 0 auto;
 	display: block;
+	width: 100%;
+	height: calc(var(--grid-sz) - 2.5em);
+	object-fit: cover;
+}
+#ggrid>a img {
+	position: absolute;
+	opacity: 0;
+}
+#ggrid>a.dir .thumb,
+#ggrid>a.dir img {
+	max-width: calc(var(--grid-sz) - 20px);
+	margin: 10px auto 0 auto;
+}
+#ggrid.noupscale>a img {
+	width: auto;
+	height: auto;
+}
+#ggrid.noupscale.gallery.nocrop>a img {
+	object-fit: scale-down;
 }
 #ggrid.nocrop>a img {
 	max-height: 20em;
 	max-height: calc(var(--grid-sz)*2);
+	object-fit: contain;
+	height: 100%;
+}
+
+.imgcontainer {
+	display: flex;
+	overflow: hidden;
+	position: relative;
+	border-radius: 5px;
+	border-radius: var(--radius);
+	box-sizing: border-box;
+	margin: -3px -2px;
+	padding: 4px 3px;
+	justify-content: center;
+}
+.th_ext {
+	z-index: 1;
+	position: absolute;
+	text-align: center;
+	width: 100%;
+	width: calc(100% - 8px);;
+	top: 50%;
+	top: calc(55% - .5em);
+	color: var(--a);
+	text-shadow: none;
+	font-family: monospace;
+}
+.thumbed,
+#ggrid>a.thumbed {
+	.thumb,
+	.th_ext {
+		display: none;
+	}
+	img {
+		position: static;
+		opacity: 1;
+	}
+}
+.sel .gselchk {
+	display: block;
+}
+.srch_hdr .gselchk {
+	display: none !important;
+}
+.gselchk {
+	position: absolute;
+	display: none;
+	top: .3em;
+	right: .3em;
+	z-index: 2;
+	font-size: 1.15em;
+	width: 1em;
+  	height: 1em;
+	opacity: .69;
+}
+
+@keyframes rotate {
+	100% {
+		transform: rotate(1turn);
+	}
+}
+
+.play .imgcontainer {
+	&::before {
+		content: '';
+		box-sizing: border-box;
+		position: absolute;
+		left: -50%;
+		top: -50%;
+		width: 200%;
+		height: 200%;
+		background-repeat: no-repeat;
+		background-size: 50% 50%, 50% 50%;
+		background-position: 0 0, 100% 0, 100% 100%, 0 100%;
+		background-image: linear-gradient(var(--a-hil), var(--a-hil)), linear-gradient(transparent, transparent), linear-gradient(var(--a-hil), var(--a-hil)), linear-gradient(transparent, transparent);
+		animation: rotate 10s linear infinite;
+	}
 }
-#ggrid>a.dir:before {
+html:not(.e) #ggrid>a.thumbed.dir:before {
 	content: '📂';
 }
 #ggrid>a.dir>span {
-	color: var(--g-dfg);
+	color: var(--g-fg);
 }
 #ggrid>a.au:before {
 	content: '▶';
 }
 #ggrid>a:before {
+	z-index: 2;
 	display: block;
 	position: absolute;
 	padding: .3em 0;
 	margin: -.4em;
 	text-shadow: 0 0 .1em var(--bg-max);
 	background: linear-gradient(135deg,rgba(255,255,255,0) 50%,rgba(255,255,255,0.2));
-	border-radius: .3em;
+	border-radius: 5px;
+	border-radius: var(--radius);
 	font-size: 2em;
 	transition: font-size .15s, margin .15s;
 }
-#ggrid>a:focus:before,
+#ggrid>a:focus-visible:before,
 #ggrid>a:hover:before {
 	font-size: 2.5em;
 	margin: -.2em;
@@ -1022,25 +1101,22 @@ html.dz #flogout {
 #ggrid>a[tt] {
 	background: linear-gradient(135deg, var(--g-g1) 95%, var(--g-g2) 95%);
 }
-#ggrid>a[tt]:focus,
+#ggrid>a[tt]:focus-visible,
 #ggrid>a[tt]:hover {
 	background: var(--g-f-bg);
 }
 #ggrid>a.play,
 #ggrid>a[tt].play {
 	color: var(--g-sel-fg);
-	background: #fc0;
-	background: var(--g-play-bg);
 	border-color: var(--g-play-b1);
 	border-top: 1px solid var(--g-play-b2);
-	box-shadow: 0 .1em 1.2em var(--g-play-sh);
 }
 #files tbody tr.sel td,
 #files tbody tr.sel span,
 #ggrid>a.sel,
 #ggrid>a[tt].sel {
 	color: var(--g-sel-fg);
-	background: #f3c;
+	background: #8af;
 	background: var(--g-sel-bg);
 	border-color: var(--g-sel-b1);
 }
@@ -1054,49 +1130,45 @@ html.dz #flogout {
 	transition: all 0.2s cubic-bezier(.2, 2.2, .5, 1); /* https://cubic-bezier.com/#.4,2,.7,1 */
 }
 #files tbody tr.sel:hover td,
-#files tbody tr.sel:focus td,
+#files tbody tr.sel:focus-visible td,
 #ggrid>a.sel:hover,
-#ggrid>a.sel:focus {
+#ggrid>a.sel:focus-visible {
 	color: var(--g-sel-fg);
 	background: var(--g-fsel-bg);
 	border-color: var(--g-fsel-b1);
 	text-shadow: 1px 1px 0 var(--g-fsel-ts);
 }
-#ggrid>a.sel img,
-#ggrid>a.play img {
-	opacity: .7;
-	filter: contrast(130%) brightness(107%);
-}
 #ggrid>a.sel img {
 	box-shadow: 0 0 1em var(--g-sel-sh);
 }
-#ggrid>a.play img {
-	box-shadow: 0 0 1em var(--g-play-sh);
-}
 #ggrid a {
 	scroll-margin-top: 25vh;
 	scroll-margin-bottom: 20vh;
 }
+#ggrid a.dtarget {
+	box-shadow: 0 0 5px 0 var(--f-sel-sh);
+	background: color-mix(in oklab, var(--a), transparent);
+}
 #files tr.sel a,
 #files tr.sel a.play {
-	color: var(--fg2-max);
+	color: var(--fg-max);
 }
 #files tr.sel a:hover {
 	color: var(--fg-max);
 	text-shadow: none;
 }
 #files tr.sel a.play.act {
-	text-shadow: 0 0 1px var(--fg2-max);
+	text-shadow: 0 0 1px var(--fg-max);
 }
-#files tr:focus {
+#files tr:focus-visible {
 	outline: none;
 	position: relative;
 }
-#files tr:focus td+td {
+#files tr:focus-visible td+td {
 	background: var(--bg-d3);
 	box-shadow: 0 .2em 0 var(--f-sel-sh), 0 -.2em 0 var(--f-sel-sh);
 }
-#files tr:focus:not(.play):not(.sel) td:first-child {
+#files tr:focus-visible:not(.play):not(.sel) td:first-child {
 	background: var(--bg-d3);
 	box-shadow: -.2em .2em 0 var(--f-sel-sh), -.2em -.2em 0 var(--f-sel-sh);
 }
@@ -1108,43 +1180,63 @@ html.dz #flogout {
 	font-size: 1.4em;
 	left: 0;
 	right: 0;
-	bottom: -6em;
-	height: 6em;
-	width: 100%;
+	bottom: 0;
 	z-index: 3;
 	touch-action: none;
+	box-shadow: 0 0 .5em var(--mp-sh);
 }
 #widget.anim {
-	transition: bottom 0.15s;
+	transition: margin-left 0; /* can't set this above 0 due to onwidgetresize */
 }
-#widget.open {
-	box-shadow: 0 0 1em rgba(0,48,64,0.2);
-	bottom: 0;
+#widget.anim #widgeti {
+	transition: height 0.15s;
 }
-html.y #widget.open {
-	border-top: .2em solid var(--bg-u2);
+#widget.open #widgeti{
+	/* box-shadow: 0 0 1em rgba(0,48,64,0.2); */
+	display: block;
 }
-#widgeti {
-	position: relative;
-	z-index: 10;
-	width: 100%;
-	height: 100%;
+
+#pbarthinpos {
+	display: none;
+	align-content: center;
+	padding: .2em .5em;
+	padding-bottom: 0;
+	height: 2em;
 }
-#fshr,
-#wtgrid,
-#wtico {
+#widget.thin #pctl{
+	display: flex;
+}
+#widget.thin #pbarthinpos{
+	display: block;
+}
+#widget.thin #trackname {
+	margin-right: auto;
+}
+
+#np_inf {
+	height: 0;
+}
+#fshr {
 	position: relative;
 	font-size: .9em;
 	top: -.04em;
+	margin-right: .3em;
 }
 #wtgrid {
-	font-size: .75em;
+	padding: 0;
+}
+.btn.svgIcon {
+	width: 1.5em;
+  	height: 1.5em;
 	padding: .1em;
-	top: -.12em;
 }
-#wtico {
-	cursor: pointer;
+.btn.svgIcon.gb_grd,
+.btn.svgIcon.gb_glr {
+	width: 1.7em;
+  	height: 1.7em;
+	padding: 0;
 }
+
 @keyframes spin {
 	100% {transform: rotate(360deg)}
 }
@@ -1152,43 +1244,157 @@ html.y #widget.open {
 	0% {opacity: 0}
 	100% {opacity: 1}
 }
-#wtoggle {
-	position: absolute;
-	white-space: nowrap;
-	top: -1em;
-	right: 0;
-	height: 1em;
-	font-size: 2em;
-	line-height: 1em;
+#wtico,
+.open #up_quick_more,
+#wtoggle,
+#widgeti {
+	background: #cde;
+	background: var(--bg-u2);
+	border: 1px solid #222;
+	border: 1px solid var(--bg-u3);
+}
+#widgeti {
+	position: relative;
+	display: none;
+	border-width: 1px 0 0 0;
+}
+#wtico {
+	display: inline-block;
+	cursor: pointer;
+	line-height: 1.2em;
+  	vertical-align: bottom;
+	padding: .05em .5em .1em .3em;
+	border-radius: var(--radius) 0 0 0;
+	pointer-events: all;
+	border-width: 1px 0 0 1px;
+}
+#wstack {
+	display: block;
+	position: absolute;
+	text-wrap-mode: nowrap;
+	width: 100%;
+	bottom: 100%;
+	right: 0;
+	font-size: 2em;
+
+	text-align: right;
+	color: var(--fg-max);
+	pointer-events: none;
+}
+#wstack div {
+	pointer-events: all;
+	vertical-align: bottom;
+}
+#wtoggle {
+	display: inline-block;
+	text-wrap-mode: nowrap;
 	text-align: center;
-	text-shadow: none;
+	max-width: calc(100% - 3.5em);
+	overflow-x: auto;
+	overflow-y: hidden;
+	margin: 0 .1em .1em .2em;
 	box-shadow: 0 0 .5em var(--mp-sh);
-	border-radius: .3em 0 0 0;
-	padding: 0 0 0 .1em;
-	color: var(--fg-max);
+	border-radius: var(--radius);
 }
-#wtoggle,
-#widgeti {
-	background: #fff;
-	background: var(--bg-u3);
+#up_quick {
+	display: inline-block;
+	position: relative;
+	margin: 0 .2em .2em .1em;
+	font-size: .7em;
+	border-radius: 10px;
+	border-radius: var(--radius);
+	background: #cde;
+    background: var(--bg-u2);
+}
+#up_quick_more {
+	position: absolute;
+	bottom: 100%;
+	right: -2px;
+	font-weight: bold;
+	box-shadow: 0 0 .5em color-mix(in oklab, var(--a) 20%, transparent);
+	border-radius: 10px;
+	border-radius: var(--radius);
+	text-align: right;
+}
+.open #up_quick_more {
+	box-shadow: 0 0 .5em color-mix(in oklab, var(--mp-sh) 20%, transparent);
+}
+#up_quick_more {
+	display: none;
+	min-width: 4em;
+	font-weight: normal;
+	margin-bottom: .2em;
+	text-wrap-mode: wrap;
+}
+#up_quick_more.vis {
+	display: block;
+}
+#up_quick_more a:hover {
+	background: var(--btn-h-bg);
+}
+#up_quick_more a {
+	position: static;
+	font-size: large;
+	display: block;
+	text-wrap-mode: nowrap;
+	padding: .5em;
+	cursor: pointer;
+	border-radius: 10px;
+	border-radius: var(--radius);
+}
+#up_quick .overlay_plus {
+	right: .3em;
+	margin-top: -1.5em;
+}
+#up_quick .btn{
+	transition: all .25s;
+	margin: -1px;
+	border: none;
+	cursor: pointer;
+	width: max-content;
+	border: 1px solid var(--bg-u3);
+}
+html:not(.e):not(.d) #up_quick .btn {
+	transform: rotate(0deg);
+}
+html:not(.e):not(.d) #up_quick .btn.on {
+	/* transform: rotate(-90deg); */
+	box-shadow: -.05em .02em .3em color-mix(in oklab, var(--a) 20%, transparent);
+}
+#up_quick .btn .rotatable {
+	transition: all .20s;
+	transform: rotate(-45deg);
+
+	background: none;
+
+	font-size: 1.2em;
+	line-height: .9em;
+}
+#up_quick .btn.on .rotatable {
+	transform: none;
 }
 #wfs, #wfm, #wzip, #wnp, #wm3u {
 	display: none;
 }
 #wfs, #wzip, #wnp, #wm3u {
-	margin-right: .2em;
+	margin-left: .2em;
 	padding-right: .2em;
-	border: 1px solid var(--bg-u5);
-	border-width: 0 .1em 0 0;
+	border: 0 solid var(--bg-u5);
 }
 #wzip1 {
-	margin-right: .2em;
+	margin-right: 0em;
+}
+#wzip {
+    margin-left: 0 !important;
+    padding-left: 0 !important;
+    margin-right: 0 !important;
+    padding-right: 0 !important;
 }
 #wfm.act+#wzip1+#wzip,
 #wfm.act+#wzip1+#wzip+#wnp {
 	margin-left: .2em;
 	padding-left: .2em;
-	border-left-width: .1em;
+	border-left-width: 2px;
 }
 #wfs.act,
 #wfm.act {
@@ -1197,6 +1403,7 @@ html.y #widget.open {
 #wtoggle,
 #wtoggle * {
 	line-height: 1em;
+	vertical-align: middle;
 }
 #wtoggle.sel #wzip,
 #wtoggle.m3u #wm3u,
@@ -1207,19 +1414,17 @@ html.y #widget.open {
 #wtoggle.sel.np #wnp {
 	display: none;
 }
-#wfm a,
-#wnp a,
-#wm3u a,
-#zip1,
-#wzip a {
+#wtoggle a {
 	font-size: .5em;
-	padding: 0 .3em;
+	padding: .7em .5em;
 	margin: -.3em .1em;
-	position: relative;
 	display: inline-block;
 }
-#zip1 {
-	font-size: .38em;
+#wtoggle #zip1 {
+	padding: .5em;
+	margin: -.1em .1em;
+  	vertical-align: top;
+	white-space: nowrap;
 }
 #wm3u a {
 	margin: -.2em .1em;
@@ -1230,17 +1435,35 @@ html.y #widget.open {
 	text-align: right;
 	line-height: 1.3em;
 	padding: 0 .3em 0 0;
-	border-width: 0 .25em 0 0;
+	border-width: 0 2px 0 0;
 }
 #wfm span,
 #wm3u span,
 #zip1 span,
 #wnp span {
-	font-size: .6em;
+	font-size: .7em;
 	display: block;
 }
-#zip1 span {
-	font-size: .9em;
+.unfun {
+	#wfm span,
+	#wm3u span,
+	#zip1 span,
+	#wnp span {
+		font-size: 1em;
+	}
+
+	#wtoggle a {
+		font-size: .45em;
+	}
+
+	#up_quick_more a:after {
+		content: "+"
+	}
+
+	#up_quick_more a span,
+	#favico_onpage {
+		display: none;
+	}
 }
 #wnp span {
 	font-size: .7em;
@@ -1275,79 +1498,123 @@ html.y #widget.open {
 	font-size: .4em;
 	margin: -.3em .1em;
 }
-#wtoggle.sel .l1 {
-	top: -.6em;
-	padding: .4em .3em;
+#trackname {
+	font-size: small;
+	font-weight: bold;
+	white-space: nowrap;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	margin-left: .3em;
+	padding: 1.2em 0;
+}
+#progbar {
+	display: none;
+	margin: 0 .3em;
+	font-size: 20px;
+}
+#progbar.vis {
+	display: block;
+}
+#altprogbar {
+	display: none;
+	grid-template-columns: max-content auto max-content;
+	text-align: center;
+}
+#altprogbar.vis {
+	display: grid;
+}
+#altprogbar span {
+	font-size: medium;
+	font-family: monospace;
+	color: var(--fg-weak);
+	margin: .3em;
+	align-self: center;
+}
+#sliderpos {
+	width: 100%;
 }
 #barpos,
 #barbuf {
+	border-radius: var(--radius);
 	position: absolute;
-	bottom: 1em;
-	left: 1em;
-	height: 2em;
-	border-radius: 9em;
-	width: calc(100% - 2em);
+	top: 0;
+	height: 100%;
+	width: 100%;
 }
 #barbuf {
 	background: var(--mp-b-bg);
-	z-index: 21;
 }
 #barpos {
 	box-shadow: -.03em -.03em .7em rgba(0,0,0,0.5) inset;
-	z-index: 22;
+	border: var(--a-dark) solid 1px;
 }
 #pctl {
-	position: absolute;
-	top: .5em;
-	left: 1em;
+	display: flex;
+	display: grid;
+  	grid-template-columns: max-content max-content max-content 20% auto max-content max-content max-content;
+	align-items: center;
+	margin-right: .4em;
+	margin-left: .1em;
+	padding: .1em;
 }
-#pctl a {
-	display: inline-block;
-	font-size: 1.25em;
-	width: 1.3em;
-	height: 1.2em;
-	text-align: center;
-	border-radius: .3em;
+.pctl .icon {
+	width: 1.5em;
+	height: 1.5em;
+}
+.pctl .icon.btn {
+	padding: .2em;
+	margin: .1em;
+}
+#favico_onpage svg {
+	margin: -1px 7px 0 0;
+    vertical-align: top;
+	height: 1.5em;
+}
+.pctl svg {
+	width: 1.5em;
+	height: 1.5em;
+}
+.pctl .btn {
+	font-size: 1em;
+	padding: 0;
+	opacity: .4;
+	cursor: pointer;
+}
+.pctl .btn.on {
+	opacity: 1;
 }
 #pvol {
-	position: absolute;
-	top: .7em;
-	right: 1em;
-	height: 1.6em;
 	border-radius: 9em;
-	max-width: 12em;
-	width: calc(100% - 10.5em);
+	max-width: 9em;
+	height: .5em;
+	aspect-ratio: 8;
 	background: rgba(0,0,0,0.2);
+	border: 1px solid var(--bg-u1);
+	margin-left: .3em;
+	transition: opacity .15s;
 }
-#widget.cmp {
-	height: 1.6em;
-	bottom: -1.6em;
+#pvolbg {
+	height: 1.3em;
+	padding: .3em;
+	cursor: pointer;
+	align-items: center;
+	display: flex;
 }
-#widget.cmp.open {
-	bottom: 0;
+#pvolbg svg {
+	height: 1.3em;
 }
-#widget.cmp #wtoggle {
-	font-size: 1.2em;
+#widget.cmp #wstack {
+	font-size: 1.4em;
 }
-#widget.cmp #fshr,
-#widget.cmp #wtgrid {
+#widget.cmp #fshr {
 	display: none;
 }
-#widget.cmp #pctl {
-	top: 0;
-	left: 0;
-	font-size: .75em;
-}
-#widget.cmp #pctl a {
-	margin: 0;
+#widget.cmp #widgeti {
+	font-size: .7em;
 }
 #widget.cmp #barpos,
 #widget.cmp #barbuf {
-	height: 1.6em;
-	width: calc(100% - 11em);
 	border-radius: 0;
-	left: 5em;
-	top: 0;
 }
 #widget.cmp #pvol {
 	top: 0;
@@ -1355,27 +1622,129 @@ html.y #widget.open {
 	max-width: 5.8em;
 	border-radius: 0;
 }
+
+#music {
+	margin: 0;
+	border-radius: 0;
+	border: none;
+	background: #ccc;
+	background: var(--bg-u2);
+}
+#music a {
+	cursor: pointer;
+}
+html.b #mu_inner {
+	background: color-mix(in oklab, var(--bg-u2) 70%, transparent);
+	backdrop-filter: blur(32px);
+}
+#h_music {
+	position: absolute;
+	top: 0;
+	left: 0;
+}
+#mu_inner {
+	align-content: center;
+	text-align: center;
+	position: relative;
+	width: 100%;
+}
+#mu_th {
+	cursor: default !important;
+	display: flex;
+	position: relative;
+	height: 35vh;
+}
+#mu_th svg {
+	margin: 0 auto;
+}
+#mu_th span {
+	font-size: 8vh;
+}
+#mu_th img {
+	opacity: 0;
+	margin: 0 auto;
+	position: absolute;
+	max-width: 100%;
+	object-fit: scale-down;
+}
+#mu_tn {
+	display: block;
+	margin-top: .5em;
+	min-height: 2em;
+	font-size: 1.3em;
+}
+#mu_pbc {
+	font-size: 1.6em;
+}
+#mu_pbb {
+	height: 3em;
+	margin: .5em auto;
+	width: 80vw;
+	display: block;
+	position: relative;
+	align-content: center;
+	text-align: left;
+}
+#mu_vol {
+	position: absolute;
+	right: 1em;
+	bottom: 1em;
+	font-size: 1.2em;
+}
+
+
 .opview {
 	display: none;
+	margin-bottom: 1em;
+}
+.opview.splitsub {
+	margin-bottom: 0;
 }
 .opview.act {
 	display: block;
 }
+#op_search.opview.act {
+	display: none;
+}
+#op_search.opview.act.vis {
+	display: block;
+}
+#ops input[type=submit],
 #ops a {
+	/* fallback if emojis don't render */
+	border: #777 solid 1px;
+	border-radius: 5px;
+
+	border: var(--transparent) solid 1px;
+	color: #07c;
 	color: var(--a);
-	text-shadow: 1px 1px 1px var(--op-a-sh);
 	font-size: 1.5em;
-	padding: .25em .4em;
+	padding: .15em .4em;
 	margin: 0;
 }
+.unfun #ops a {
+	font-size: 1.2em;
+}
+.unfun #srchfolder_div {
+	left: 5.2em;
+}
+#opa_mkd {
+	display: none;
+}
+#ops a.vis {
+	display: block;
+}
 #ops a.act {
 	color: #fff;
 	color: var(--op-aa-fg);
-	background: #000;
+	background: rgb(85, 144, 255);
 	background: var(--op-aa-bg);
-	border-radius: 0 0 .2em .2em;
-	border-bottom: .3em solid var(--a-b);
+	border-radius: 0 0 5px 5px;
+	border-radius: 0 0 var(--radius) var(--radius);
+	border-bottom: .3em solid var(--a);
 	box-shadow: var(--op-aa-sh);
+	margin: -1px 0 -.35em 0;
+	padding-top: .2em;
 }
 #ops a svg {
 	width: 1.75em;
@@ -1385,43 +1754,101 @@ html.y #widget.open {
 html.y #ops svg circle {
 	stroke: black;
 }
+#srv_name{
+	padding-top: .5em;
+	padding-bottom: .3em;
+	margin-left: 2.2em;
+	font-size: x-large;
+	text-wrap-mode: nowrap;
+	display: block;
+	line-height: 1.5em;
+}
+#treeToggleBtn{
+	z-index: 6;
+	position: fixed;
+	top: 0;
+	left: 0;
+	margin: .5em;
+	padding: 0;
+	width: 2em;
+	height: 2em;
+	vertical-align: bottom;
+}
 #ops {
-	padding: .3em .6em;
+	padding: 0 .5em;
 	white-space: nowrap;
+	display: flex;
+	height: 2.5em;
+	border-radius: 5px;
+	border-radius: var(--radius);
+	background: var(--bg-u2);
 }
 #noie {
 	color: #b60;
 	margin: 0 0 0 .5em;
 }
+.pfp {
+	/* aspect-ratio: 1 / 1; */
+	min-width: 1.25em;
+
+	background: #ccc;
+	color: #000;
+
+	background: var(--btn-1-bg);
+	box-shadow: var(--btn-1-bs);
+	color: var(--bg);
+
+	border: var(--btn-bg-a) solid 1px;
+	border-radius: var(--radius);  
+	justify-content: center;
+  	display: flex;
+	text-shadow: none;
+}
+.pfp.placeholder {
+	text-shadow: 1px 1px 0 var(--bg-half), 1px -1px 0 var(--bg-half), -1px -1px 0 var(--bg-half), -1px 1px 0 var(--bg-half);
+}
 .opbox {
 	padding: .5em;
-	border-radius: 0 .3em .3em 0;
-	border-width: 1px 1px 1px 0;
+	border-radius: 5px;
+	border-radius: var(--radius);
+	border-width: 1px;
 	max-width: 41em;
-	max-width: min(41em, calc(100% - 2.6em));
 }
 .opbox input {
 	position: relative;
-	margin: .5em;
+	margin: .2em;
 }
-#op_cfg input[type=text] {
-	top: -.3em;
+#op_bup {
+	margin: 0;
+	border-radius: 0 0 var(--radius) var(--radius);
+}
+#op_cfg {
+	display: none;
 }
+#pathBar input[type=text],
 .opview select,
-.opview input[type=text] {
+.opview input[type=text],
+.opview input[type=color],
+.opview input[type=date] {
 	color: var(--fg);
 	background: var(--txt-bg);
 	border: none;
 	box-shadow: 0 0 2px var(--txt-sh);
 	border-bottom: 1px solid #999;
 	border-color: var(--a);
-	border-radius: .2em;
+	border-radius: 5px;
+	border-radius: var(--radius);
 	padding: .2em .3em;
+	font-size: medium;
+	min-width: 3em;
+	margin: .3em;
+}
+input[type=color] {
+	vertical-align: bottom;
 }
 .opview select {
 	padding: .3em;
-	margin: .2em .4em;
-	background: var(--bg-u3);
+	margin: .2em 0	;
 }
 .opview input.err {
 	color: var(--err-fg);
@@ -1436,7 +1863,7 @@ input[type="checkbox"]+label {
 }
 input[type="radio"]:checked+label,
 input[type="checkbox"]:checked+label {
-	color: #0e0;
+	color: rgb(9, 185, 9);
 	color: var(--btn-1-bg);
 }
 input[type="checkbox"]:checked+label {
@@ -1453,10 +1880,20 @@ html.dz input {
 	cursor: pointer;
 }
 .opview input.i {
-	width: calc(100% - 16.2em);
+	width: calc(100% - 12em);
+}
+input.eq_gain[type=range]{
+	writing-mode: vertical-lr;
+    direction: rtl;
+	color: var(--a);
+}
+input.eq_gain[type=text]{
+    width: 2em;
+	min-width: 0;
+	margin: 0 .15em .5em .15em;
+	text-align: center;
 }
 input.drc_v,
-input.eq_gain,
 input.ssconf_v {
 	width: 3em;
 	text-align: center;
@@ -1477,13 +1914,6 @@ input.ssconf_v {
 	padding: 0;
 }
 #au_ss,
-#au_drc,
-#au_eq {
-	display: block;
-	margin-top: .5em;
-	padding: 1.3em .3em;
-}
-#au_ss,
 #au_drc {
 	padding: .4em .3em;
 }
@@ -1492,9 +1922,6 @@ input.ssconf_v {
 	height: 1em;
 	overflow: hidden;
 }
-#ico1 {
-	cursor: pointer;
-}
 
 
 
@@ -1521,9 +1948,9 @@ input.ssconf_v {
 }
 #srch_q {
 	white-space: pre;
-	color: var(--a-b);
+	color: var(--a);
 	min-height: 1em;
-	margin: .2em 0 -1em 1.6em;
+	margin-top: .2em;
 }
 #srch_q.err {
 	color: var(--srv-3);
@@ -1541,6 +1968,18 @@ input.ssconf_v {
 	width: 100%;
 	display: block;
 }
+
+#wfp{
+	margin: 0 .3em 0 0;
+	white-space: nowrap;
+	display: flex;
+}
+#wfp a {
+	display: inline-block;
+	width: 1.3em;
+	height: 1.3em;
+}
+
 #files td div span {
 	color: var(--fg-max);
 	padding: 0 .4em;
@@ -1562,40 +2001,52 @@ input.ssconf_v {
 	border-collapse: collapse;
 	width: 100%;
 }
+
 #wrap {
-	margin: 1.8em 1.5em 0 1.5em;
+	padding:  0 .6em 10em .6em;
 	min-height: 70vh;
-	padding-bottom: 7em;
 }
 #tree {
 	display: none;
-	position: absolute;
+	position: fixed;
+	top: 0;
 	left: 0;
 	bottom: 0;
-	top: 7em;
 	overflow-x: hidden;
 	overflow-y: auto;
 	-ms-scroll-chaining: none;
 	overscroll-behavior-y: none;
-	box-shadow: 0 0 1em var(--bg-d2), 0 -1px 0 rgba(128,128,128,0.3);
+	box-shadow: 0 0 1em var(--mp-sh), 0 -1px 0 rgba(128,128,128,0.3);
+	border: 1px solid var(--bg-u3);
+	transition: width .05s;
+	z-index: 5;
+	padding-bottom: 3em;
 }
+#files,
+#wtoggle,
+#ghead,
 #tree,
 html {
-	scrollbar-color: var(--scroll) var(--bg-u3);
+	scrollbar-color: var(--a) var(--bg-u3);
 }
-#treeh {
+#treesuperh {
 	position: sticky;
-	z-index: 1;
 	top: 0;
-	height: 2.2em;
-	line-height: 2.2em;
+	z-index: 1;
 	background: var(--tree-bg);
+}
+#treeh {
+	line-height: 2.2em;
 	border-bottom: 1px solid var(--bg-d3);
-	overflow: hidden;
+  	display: block;
+	padding: .3em .5em;
+	text-wrap-mode: nowrap;
+	overflow-x: auto;
+	overflow-y: hidden;
 }
 #treepar {
-	z-index: 1;
 	position: fixed;
+	z-index: 1;
 	background: #fff;
 	background: var(--tree-bg);
 	left: -.96em;
@@ -1607,8 +2058,8 @@ html {
 #treepar.off {
 	display: none;
 }
-.np_open #thx_ff {
-	padding: 4.5em 0;
+#thx_ff {
+	padding: 1em 0;
 	/* widget */
 }
 #tree::-webkit-scrollbar-track,
@@ -1616,10 +2067,7 @@ html {
 	background: var(--bg-u3);
 }
 #tree::-webkit-scrollbar-thumb {
-	background: var(--scroll);
-}
-#tree:hover {
-	z-index: 2;
+	background: var(--a);
 }
 #treeul {
 	position: relative;
@@ -1631,22 +2079,28 @@ html {
 	background: #eee;
 	background: var(--btn-bg);
 	box-shadow: var(--btn-bs);
+	border: 1px solid var(--bg-u3);
 	border-bottom: var(--btn-bb);
-	border-radius: .3em;
+	border-radius: 5px;
+	border-radius: var(--radius);
 	padding: .2em .4em;
 	font-size: 1.2em;
 	margin: .2em;
 	display: inline-block;
-	white-space: pre;
+	text-wrap-mode: wrap;
+	white-space-collapse: preserve;
 	position: relative;
-	top: -.12em;
-}
-html.c .btn,
-html.a .btn {
-	border-radius: .2em;
+	vertical-align: top;
+	cursor: pointer;
 }
-html.dz .btn {
+#wfp .btn {
 	font-size: 1em;
+	padding: .15em;
+	margin: 0 .1em 0 0;
+}
+html.c .btn,
+html.b .btn {
+	border-radius: var(--radius);
 }
 .btn:hover {
 	color: var(--btn-h-fg);
@@ -1655,9 +2109,9 @@ html.dz .btn {
 	border-bottom: var(--btn-h-bb);
 }
 .tgl.btn.on {
-	background: #000;
+	background: rgb(85, 144, 255);
 	background: var(--btn-1-bg);
-	color: #fff;
+	color: #222;
 	color: var(--btn-1-fg);
 	text-shadow: none;
 	box-shadow: var(--btn-1-bs);
@@ -1694,6 +2148,10 @@ html.dz .btn {
 	margin-left: -.25em;
 	z-index: 3;
 }
+#tree li a.dtarget {
+	box-shadow: 0 0 5px 0 var(--f-sel-sh) inset;
+	background: color-mix(in oklab, var(--a) 30%, transparent);
+}
 #tree ul a.sel {
 	background: #000;
 	background: var(--bg-d3);
@@ -1701,11 +2159,15 @@ html.dz .btn {
 	color: #fff;
 	color: var(--fg-max);
 }
+#tree .ntree a + a.hl:hover {
+	background: var(--btn-1h-bg);
+}
 #tree ul a.hl {
 	color: #fff;
 	color: var(--btn-1-fg);
-	background: #000;
+	background: rgb(85, 144, 255);
 	background: var(--btn-1-bg);
+	box-shadow: var(--btn-1-bs);
 	text-shadow: none;
 }
 #tree ul a.ld::before {
@@ -1724,8 +2186,12 @@ html.dz .btn {
 	color: var(--fg-max);
 }
 #tree ul a {
-	border-radius: .3em;
+	border-radius: var(--radius);
 	display: inline-block;
+	vertical-align: center;
+}
+.ntree a {
+	padding: .3em .2em;
 }
 .ntree a+a {
 	width: calc(100% - 2.2em);
@@ -1735,25 +2201,19 @@ html.dz .btn {
 	min-height: 1.4em;
 	white-space: nowrap;
 }
-#tree.nowrap .ntree a+a:hover {
-	background: rgba(16, 16, 16, 0.67);
-	min-width: calc(var(--nav-sz) - 2em);
-	width: auto;
-}
-html.y #tree.nowrap .ntree a+a:hover {
-	background: rgba(255, 255, 255, 0.67);
-	color: var(--fg-max);
-}
 #docul a:hover,
-#tree .ntree a+a:hover {
-	background: var(--bg-d2);
-	color: var(--fg-max);
+#tree .ntree a + a:hover {
+	background: var(--btn-h-bg);
+	color: var(--btn-h-fg);
+}
+#tree .ntree a + a.hl:hover {
+	color: var(--btn-1-fg);
 }
 .ntree a:first-child {
 	font-family: 'scp', monospace, monospace;
 	font-family: var(--font-mono), 'scp', monospace, monospace;
 	font-size: 1.2em;
-	line-height: 0;
+	line-height: .7em;
 }
 .dumb_loader_thing {
 	display: block;
@@ -1782,7 +2242,7 @@ html.y #tree.nowrap .ntree a+a:hover {
 #files th:hover .cfg {
 	display: block;
 	width: 1em;
-	border-radius: .2em;
+	border-radius: var(--radius);
 	margin: -1.2em auto 0 auto;
 	background: var(--bg-u5);
 }
@@ -1817,7 +2277,6 @@ html.y #tree.nowrap .ntree a+a:hover {
 #op_unpost,
 #srch_form {
 	max-width: none;
-	margin-right: 1.5em;
 }
 .opwide>div {
 	display: inline-block;
@@ -1831,14 +2290,11 @@ html.y #tree.nowrap .ntree a+a:hover {
 	margin: 0 .4em;
 	padding: 0;
 }
-#op_cfg>div>div>span {
-	display: inline-block;
-	padding: .2em .4em;
-}
 .opbox h3 {
 	margin: .8em 0 0 .6em;
 	padding: 0;
 }
+.disabled,
 #thumbs,
 #au_prescan,
 #au_fullpre,
@@ -1847,39 +2303,71 @@ html.y #tree.nowrap .ntree a+a:hover {
 #u2tdate {
 	opacity: .3;
 }
-#griden.on+#thumbs,
-#au_preload.on+#au_prescan,
-#au_preload.on+#au_prescan+#au_fullpre,
-#au_os_ctl.on+#au_os_seek,
-#au_os_ctl.on+#au_os_seek+#au_osd_cv,
-#u2turbo.on+#u2tdate {
+#up_quick.disabled {
+	display: none;
+}
+.setting:has(#griden.on)+.setting #thumbs,
+.setting:has(#au_preload.on)+.setting #au_prescan,
+.setting:has(#au_preload.on)+.setting #au_prescan,
+.setting:has(#au_preload.on)~.setting #au_fullpre,
+.setting:has(#au_os_ctl.on)+.setting #au_os_seek,
+.setting:has(#au_os_ctl.on)+.setting #au_os_seek,
+.setting:has(#au_os_ctl.on)~.setting #au_osd_cv,
+.setting:has(#u2turbo.on)+.setting #u2tdate {
 	opacity: 1;
 }
 #wraptree.on+#hovertree {
 	display: none;
 }
 .ghead {
+	position: sticky;
 	background: #fff;
 	background: var(--bg-u2);
-	border-radius: .3em;
-	padding: .2em .5em;
+	border-radius: 5px;
+	border-radius: var(--radius);
+	padding: 0 .2em;
 	line-height: 2.3em;
 	margin-bottom: 1.5em;
-}
-#hdoc,
-#ghead {
-	position: sticky;
-	top: -.3em;
-	z-index: 2;
+	z-index: 3;
+	margin-top: 0;
+	top: 3.7em;
+	transition: opacity .15s;
 }
 .ghead .btn {
 	position: relative;
 	top: 0;
 }
+#twig,
+#gridchop a:first-child,
+#gridzoom a:first-child {
+  line-height: 1.1em;
+  padding-bottom: .3em;
+}
 .ghead>span {
 	white-space: pre;
 	padding-left: .3em;
 }
+.ghead details {
+	display: inline-block;
+	background: transparent;
+	box-shadow: var(--btn-bs);
+}
+.ghead summary {
+	background: var(--btn-bg);
+}
+.ghead details .setting {
+	position: absolute;
+	background: var(--bg-u2);
+	border: 1px solid var(--bg-u3);
+  	border-bottom: var(--btn-bb);
+	border-radius: var(--radius);
+	max-width: 11em;
+	max-height: 30vh;
+	overflow-y: auto;
+}
+#hcol_content:has(#hcolsh.on) {
+  margin-top: 3.5em;
+}
 #tailbtns {
 	display: none;
 }
@@ -1949,6 +2437,9 @@ html.y #tree.nowrap .ntree a+a:hover {
 #rui td input[type="text"] {
 	width: 100%;
 }
+input[type="text"].invalid {
+	border-color: var(--err-b1);
+}
 #rui #rn_n_d,
 #rui #rn_n_s,
 #shui td.exs input[type="text"] {
@@ -1988,14 +2479,16 @@ html.y #tree.nowrap .ntree a+a:hover {
 	background: var(--bg);
 	margin: -1em 0 .5em 0;
 	padding: 1em 0 1em 0;
-	border-radius: .3em;
+	border-radius: var(--radius);
+	overflow: auto;
+	box-shadow: 0 0 .3em var(--bg-d2);
+	background: var(--bg-u2);
 }
 #doc.wrap {
 	white-space: pre-wrap;
 }
-html.y #doc {
-	box-shadow: 0 0 .3em var(--bg-u5);
-	background: #f7f7f7;
+#bdoc {
+	margin-top: .3em;
 }
 #docul {
 	position: relative;
@@ -2025,7 +2518,7 @@ html.y #doc {
 	line-height: 1.5em;
 }
 #doc .line-highlight {
-	border-radius: .3em;
+	border-radius: var(--radius);
 	box-shadow: 0 0 .5em rgba(128,128,128,0.2);
 	background: linear-gradient(90deg, var(--bg-d3), var(--bg));
 }
@@ -2039,21 +2532,19 @@ html.y #doc .line-highlight {
 	display: block;
 }
 #seldoc.sel {
-	color: var(--fg2-max);
+	color: var(--fg-max);
 	background: #f0f;
 	background: var(--g-sel-b1);
 }
 #pvol,
 #barbuf,
 #barpos,
-a.btn,
+.btn,
 #u2btn,
-#u2conf label,
 #rui label,
 #modal-ok,
 #modal-ng,
-#ops,
-#ico1 {
+#ops {
 	-webkit-user-select: none;
 	-moz-user-select: none;
 	-ms-user-select: none;
@@ -2149,6 +2640,9 @@ html.noscroll .sbar::-webkit-scrollbar {
 #bbox-overlay.visible {
 	opacity: 1;
 }
+#bbox-overlay.sel {
+	background: color-mix(in oklab, var(--a-dark) 70%, transparent);
+}
 .full-image {
 	display: inline-block;
 	position: relative;
@@ -2175,6 +2669,11 @@ html.noscroll .sbar::-webkit-scrollbar {
 	vertical-align: middle;
 	transition: transform .23s, left .23s, top .23s, width .23s, height .23s;
 }
+.immersive .full-image img,
+.immersive .full-image video {
+	max-height: 100%;
+	margin-bottom: 0;
+}
 .full-image img.asap,
 .full-image video.asap {
 	transition: none;
@@ -2185,6 +2684,17 @@ html.noscroll .sbar::-webkit-scrollbar {
     height: 100%;
     object-fit: contain;
 }
+#bbox-overlay:has(video) { 	
+	#bbox-next,
+	#bbox-prev {
+		height: 0;
+	}
+}
+#bbox-overlay.pixelated .full-image img,
+#bbox-overlay.pixelated .full-image video {
+	-ms-interpolation-mode: nearest-neighbor;
+	image-rendering: pixelated;
+}
 html.bb_fsc .full-image img,
 html.bb_fsc .full-image video {
 	max-height: 100%;
@@ -2203,6 +2713,10 @@ html.bb_fsc figcaption {
 .full-image video {
 	background: #222;
 }
+#bbox-overlay.immersive figcaption {
+	opacity: 0;
+	pointer-events: none;
+}
 .full-image figcaption {
 	display: block;
 	position: fixed;
@@ -2212,10 +2726,11 @@ html.bb_fsc figcaption {
 	white-space: normal;
 	color: var(--fg);
 	z-index: 1;
+	transition: opacity .15s;
 }
 #bbox-overlay figcaption a {
 	background: rgba(0, 0, 0, 0.6);
-	border-radius: .4em;
+	border-radius: var(--radius);
 	padding: .3em .6em;
 }
 html.y #bbox-overlay figcaption a {
@@ -2259,61 +2774,76 @@ html.y #bbox-overlay figcaption a {
 @keyframes eog {
 	0% {filter: brightness(1.5)}
 }
-#bbox-next,
-#bbox-prev {
-	top: 50%;
-	top: calc(50% - 30px);
-	width: 44px;
-	height: 60px;
-	transition: background-color .3s ease, color .3s ease, left .3s ease, right .3s ease;
+#bbox-overlay #bbox-next,
+#bbox-overlay #bbox-prev {
+	position: fixed;
+	top: 0;
+	bottom: 0;
+	width: 70px;
+	left: 0;
+	cursor: pointer;
 }
-#bbox-btns button {
-	transition: background-color .3s ease, color .3s ease;
+#bbox-overlay #bbox-next {
+	right: 0;
+	left: auto;
 }
-#bbox-btns {
-	transition: top .3s ease;
+#bbox-overlay #bbox-next:hover a,
+#bbox-overlay #bbox-prev:hover a {
+	background: #fff2;
+	background: var(--btn-h-bg);
 }
-.bbox-btn {
+#bbox-overlay #bbox-next a,
+#bbox-overlay #bbox-prev a {
 	position: fixed;
+	top: 50%;
+	top: calc(50% - 30px);
+	width: 30px;
+	height: 60px;
+	transition: opacity .3s ease;
+	text-align: center;
+	line-height: 60px;
 }
-#bbox-next.off {
-	right: -2.6em;
+#bbox-btns .btn {
+	cursor: pointer;
+	direction: ltr;
 }
-#bbox-prev.off {
-	left: -2.6em;
+#bbox-overlay.immersive #bbox-next a,
+#bbox-overlay.immersive #bbox-prev a {
+	opacity: 0;
 }
-#bbox-btns.off {
-	top: -2.2em;
+#bbox-overlay.immersive #bbox-btns {
+	opacity: 0;
+	top: -3.5em;
+	pointer-events: none;
 }
-#bbox-overlay button {
+#bbox-overlay .btn {
 	cursor: pointer;
-	outline: none;
-	padding: 0 .3em;
-	margin: 0 .4em;
-	border: 0;
-	border-radius: 15%;
-	background: rgba(50, 50, 50, 0.5);
-	color: rgba(255,255,255,0.7);
+	padding: 0 .4em;
+	margin: 0 .1em .3em .1em;
 	font-size: 1.4em;
-	line-height: 1.4em;
+	line-height: 2em;
 	vertical-align: top;
 	font-variant: small-caps;
+	color: var(--fg);
+}
+#bbox-overlay .btn.on {
+	color: var(--bg);
 }
-#bbox-overlay button:focus,
-#bbox-overlay button:hover {
-	color: rgba(255,255,255,0.9);
-	background: rgba(50, 50, 50, 0.9);
+#bbox-overlay .btn:hover {
+	opacity: 1 !important;
 }
-#bbox-next {
+#bbox-next a {
 	right: 1%;
 }
-#bbox-prev {
+#bbox-prev a {
 	left: 1%;
 }
 #bbox-btns {
 	top: .5em;
-	right: 2%;
+	right: .2em;
 	position: fixed;
+	direction: rtl;
+	transition: top .3s ease, opacity .3s ease;
 }
 #bbox-halp {
 	color: var(--fg-max);
@@ -2328,79 +2858,240 @@ html.y #bbox-overlay figcaption a {
 #bbox-halp td {
 	padding: .2em .5em;
 }
-#bbox-halp td:first-child:not([colspan]) {
-	text-align: right;
+#bbox-halp td:first-child:not([colspan]) {
+	text-align: right;
+}
+.bbox-spinner {
+	width: 40px;
+	height: 40px;
+	display: inline-block;
+	position: absolute;
+	top: 50%;
+	left: 50%;
+	margin-top: -20px;
+	margin-left: -20px;
+}
+.bbox-double-bounce1,
+.bbox-double-bounce2 {
+	width: 100%;
+	height: 100%;
+	border-radius: 50%;
+	background-color: #fff;
+	opacity: .6;
+	position: absolute;
+	top: 0;
+	left: 0;
+	animation: bounce 2s infinite ease-in-out;
+}
+.bbox-double-bounce2 {
+	animation-delay: -1s;
+}
+@keyframes bounce {
+	0%, 100% {transform: scale(0)}
+	50% {transform: scale(1)}
+}
+.no-transition {
+	transition: none !important;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* modals */
+.modalcontent{
+	display: grid;
+  	grid-template-rows: max-content auto;
+	margin: 5vh 5vw;
+	border-radius: 10px;
+	border-radius: var(--radius);
+	border: var(--a) solid 1px;
+	background: #fff;
+	background: var(--bg);
+	max-width: 66.6em;
+	position: relative;
+	overflow: auto;
+	box-shadow: .1em .2em 1em var(--mp-sh);
+}
+html.c .modalcontent {
+	background: var(--bg-u2);
+}
+.modalheader {
+	display: flex;
+	align-items: center;
+	margin: 0;
+	padding: .7em 3em .7em .7em;
+	background: var(--ttlbar);
+	font-size: large;
+	font-weight: bold;
+	color: var(--fg);
+}
+.modalheader:hover {
+	color: var(--fg);
+}
+#cfg_mu,
+.close{
+	position: absolute;
+	cursor: default;
+	top: 0;
+	right: 0;
+	margin: .3em;
+	color: var(--fg);
+	box-shadow: 0 0 .3em var(--mp-sh);
+	border: 1px solid var(--bg-u3);
+	height: 1.8em;
+	aspect-ratio: 1 / 1;
+	text-align: center;
+	display: block;
+	padding: 0;
+	align-content: center;
+}
+#cfg_mu {
+	right: 2.3em;
+}
+.closepane {
+	position: absolute;
+	cursor: default;
+	top: 0;
+	left: 0;
+	bottom: 0;
+	right: 0;
+	background: none !important;
+}
+
+/* settings */
+.modalsplit {
+	display: grid;
+  	grid-template-columns: auto auto auto;
+	min-height: 0;
+}
+.splitsub {
+	display: block;
+	overflow-y: auto;
+	padding: 0 .5em 5em .5em;
+}
+.divider{
+	background: var(--a);
+	width: 1px;
+	margin: 1em 0;
+}
+.divider_h {
+	background: var(--bg);
+	height: 1px;
+	margin: .3em 0;
+}
+#s_nav .btn::after{
+	position: absolute;
+	content: ">";
+	right: .5em;
+}
+#s_nav .btn{
+	display: block;
+	padding-right: 2em;
+	border: 1px solid var(--bg-u3);
+	color: var(--fg);
+}
+#s_nav .btn:hover{
+	color: var(--a-hil);
+}
+#s_nav .sub {
+	margin-left: 1em;
+}
+#s_nav .sub:before {
+	content: "";
+	width: 2px;
+	background: var(--bg-u3);
+	position: absolute;
+	left: -.5em;
+	top: -.2em;
+	bottom: -.1em;
+}
+.s_section {
+	border-radius: var(--radius);
+	margin-bottom: 1.5em;
+}
+.s_section .setting:last-child {
+	border-radius: 0 0 5px 5px;
+	border-radius: 0 0 var(--radius) var(--radius);
 }
-.bbox-spinner {
-	width: 40px;
-	height: 40px;
-	display: inline-block;
-	position: absolute;
-	top: 50%;
-	left: 50%;
-	margin-top: -20px;
-	margin-left: -20px;
+.setting{
+	padding: .5em;
+	border: var(--bg-u5) solid 1px;
+	border-top: 0;
+	overflow-x: auto;
+	position: relative;
 }
-.bbox-double-bounce1,
-.bbox-double-bounce2 {
-	width: 100%;
-	height: 100%;
-	border-radius: 50%;
-	background-color: #fff;
-	opacity: .6;
-	position: absolute;
-	top: 0;
-	left: 0;
-	animation: bounce 2s infinite ease-in-out;
+.modal .setting:hover{
+	background: var(--bg-u1);
 }
-.bbox-double-bounce2 {
-	animation-delay: -1s;
+.s_desc{
+	margin: 0 0 0 0;
+	font-size: medium;
+	color: var(--fg-weak);
 }
-@keyframes bounce {
-	0%, 100% {transform: scale(0)}
-	50% {transform: scale(1)}
+#s_list h3{
+	background-color: var(--bg-u5);
+	border-radius: 5px 5px 0 0;
+	border-radius: var(--radius) var(--radius) 0 0;
+	padding: .5em;
+	margin: 0;
 }
-.no-transition {
-	transition: none !important;
+#s_list .sub_section h3 {
+	background: none;
+	border-top: var(--bg-u5) solid 1px;
+    border-radius: 0;
+    margin: 0 -.4em;
+    text-align: center;
+}
+.modal.vis.unmodal {
+	position: initial;
+	.modalcontent{
+		width: 100%;
+		max-width: none;
+		margin: 0;
+	}
+	.closepane,
+	.close {
+		display: none;
+	}
+	.splitsub {
+		margin-bottom: .5em;
+	}
 }
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 /* upload.css */
 
-#op_up2k {
-	padding: 0 1em 1em 1em;
-}
-#drops {
+.modal {
 	display: none;
-	z-index: 3;
+	z-index: 10;
 	background: rgba(48, 48, 48, 0.7);
 }
-#drops.vis,
+.modal.vis,
 .dropzone {
+	/* fallback */
 	display: block;
+	overflow-y: auto;
+
+	display: flex;
+  	justify-content: center;
 	position: fixed;
 	top: 0;
 	left: 0;
@@ -2412,26 +3103,27 @@ html.y #bbox-overlay figcaption a {
 	display: table;
 	left: 10%;
 	width: 78%;
-	height: 26%;
+	height: 78%;
 	margin: 0;
 	font-size: 3em;
 	font-weight: bold;
 	text-shadow: .05em .05em .1em #333;
 	background: rgba(224, 224, 224, 0.2);
 	box-shadow: 0 0 0 #999;
-	border: .5em solid var(--ud-b1);
-	border-radius: .5em;
-	border-width: 1vw;
+	border: .1em solid var(--ud-b1);
+	border-radius: 10px;
+	border-radius: var(--radius);
+	border-width: 2px;
 	color: #fff;
 	transition: all 0.12s;
 }
 .dropdesc.hl.ok {
 	border-color: #fff;
-	box-shadow: 0 0 1em .4em #cf5, 0 0 1em #000 inset;
+	box-shadow: 0 0 1em .4em var(--a), 0 0 1em #000 inset;
 	background: rgba(24, 24, 24, 0.7);
 	left: 8%;
 	width: 82%;
-	height: 32%;
+	height: 82%;
 	margin: -3vh 0;
 }
 .dropdesc.hl.err {
@@ -2473,26 +3165,32 @@ html.y #bbox-overlay figcaption a {
 }
 .dropzone {
 	z-index: 80386;
-	height: 50%;
+	height: 100%;
 }
 #up_dz {
-	bottom: 50%;
+	position: absolute;
+	bottom: 0;
 }
 #srch_dz {
-	top: 50%;
+	position: absolute;
+	top: 0;
 }
 #up_zd {
+	position: absolute;
 	top: 12%;
+	bottom: 12%;
 }
 #srch_zd {
+	position: absolute;
+	top: 12%;
 	bottom: 12%;
 }
 .dropdesc span {
 	color: #fff;
-	background: #490;
-	border-bottom: .3em solid #6d2;
+	background: var(--a-dark);
+	border-bottom: .3em solid var(--a);
 	text-shadow: 1px 1px 1px #000;
-	border-radius: .3em;
+	border-radius: var(--radius);
 	padding: .4em .8em;
 	font-size: .4em;
 }
@@ -2512,6 +3210,11 @@ html.y #bbox-overlay figcaption a {
 	background: var(--bg-u5);
 	border: 0px solid var(--bg-u5);
 }
+#up_status_h {
+	margin: -1.8em .5em 0 .5em;
+	position: absolute;
+	z-index: 1;
+}
 #u2err.err {
 	color: var(--a-dark);
 	padding: .5em;
@@ -2524,35 +3227,38 @@ html.y #bbox-overlay figcaption a {
 #u2btn {
 	line-height: 1.3em;
 	border: .15em dashed var(--u2-btn-b1);
-	border-radius: .4em;
+	border-radius: var(--radius);
 	text-align: center;
-	font-size: 1.5em;
-	margin: .5em auto;
-	padding: .8em 0;
-	width: 16em;
+	font-size: 1.3em;
+	padding: 1em 2em;
 	cursor: pointer;
+	box-shadow: .4em .4em 0 var(--bg-d1);
 }
-#op_up2k.srch #u2btn {
-	border-color: var(--u2-sbtn-b1);
+#u2btn sup {
+	font-size: 1.1em;
 }
-#u2conf.ww #u2btn {
-	line-height: 1em;
-	padding: .5em 0;
-	margin: -2em 1em -3em 0;
+#u2btn:hover {
+	background: linear-gradient(var(--a) 0%, var(--a) 20%, color-mix(in oklab, transparent 85%, var(--a) 15%));
+	border-color: var(--bg);
+	border-style: solid;
+	color: var(--fg-max);
 }
-#u2conf #u2btn {
-	padding: .4em 0;
-	margin: -2em 0;
-	font-size: 1.25em;
-	width: 100%;
-	max-width: 12em;
-	display: inline-block;
+#u2c3t {
+	margin: 1em 0;
 }
-#u2conf #u2btn_cw {
-	text-align: right;
+#op_up2k {
+	display: block;
+	padding-top: .5em;
+}
+#op_up2k.srch #u2btn {
+	border-color: var(--u2-sbtn-b1);
+}
+#up2k_qs {
+	margin-top: .5em;
 }
 #u2bm {
-	display: block;
+	display: flex;
+	justify-content: center;
 }
 #u2bm sup {
 	font-weight: bold;
@@ -2573,7 +3279,6 @@ html.y #bbox-overlay figcaption a {
 #u2tabw {
 	min-height: 0;
 	transition: min-height .2s;
-	margin: 2em 0;
 }
 #u2tabw.na>table {
 	display: none;
@@ -2601,23 +3306,11 @@ html.y #bbox-overlay figcaption a {
 #u2tab td:nth-child(3) {
 	width: 40%;
 }
-#u2tab.up.ok td:nth-child(3),
-#u2tab.up.bz td:nth-child(3),
-#u2tab.up.q  td:nth-child(3) {
-	width: 18em;
-}
 @media (max-width: 65em) {
 	#u2tab {
 		font-size: .9em;
 	}
 }
-@media (max-width: 50em) {
-	#u2tab.up.ok td:nth-child(3),
-	#u2tab.up.bz td:nth-child(3),
-	#u2tab.up.q  td:nth-child(3) {
-		width: 16em;
-	}
-}
 #op_up2k.srch td.prog {
 	font-family: sans-serif;
 	font-family: var(--font-main), sans-serif;
@@ -2632,7 +3325,6 @@ html.y #bbox-overlay figcaption a {
 	width: 17em;
 	cursor: pointer;
 	text-align: center;
-	white-space: nowrap;
 	display: inline-block;
 	font-family: 'scp', monospace, monospace;
 	font-family: var(--font-mono), 'scp', monospace, monospace;
@@ -2648,53 +3340,35 @@ html.y #bbox-overlay figcaption a {
 	display: unset;
 }
 #u2etaw {
-	width: 18em;
-	font-size: .94em;
-	margin: 1.8em auto .5em auto;
+	display: flex;
+	justify-content: center;
 }
 #u2etas.o #u2etaw {
 	width: 21em;
 }
 #u2cards {
-	padding: 1em 1em .42em 1em;
-	margin: 0 auto;
-	white-space: nowrap;
 	text-align: center;
-	overflow: hidden;
-	min-width: 24em;
-}
-#u2cards.w {
-	width: 48em;
-	text-align: left;
-}
-#u2cards.ww {
-	display: inline-block;
-}
-#u2etaw.w {
-	width: 55em;
-	text-align: right;
-	margin: 2em auto -2.7em auto;
-}
-#u2etaw.ww {
-	margin: -1em 2em 1em 1em;
+	overflow-y: hidden;
+	overflow-x: auto;
 }
 #u2cards a {
+	display: inline-block;
 	padding: .2em 1em;
+	padding-bottom: .3em;
 	background: var(--u2-tab-bg);
 	border: 1px solid #999;
 	border-color: var(--u2-tab-b1);
 	border-width: 0 0 1px 0;
 }
 #u2cards a:first-child {
-	border-radius: .4em 0 0 0;
+	border-radius: var(--radius) 0 0 0;
 }
 #u2cards a:last-child {
-	border-radius: 0 .4em 0 0;
+	border-radius: 0 var(--radius) 0 0;
 }
 #u2cards a.act {
-	padding-bottom: .5em;
 	border-width: 1px 1px .1em 1px;
-	border-radius: .3em .3em 0 0;
+	border-radius: var(--radius) var(--radius) 0 0;
 	margin-left: -1px;
 	background: var(--u2-tab-1-bg);
 	box-shadow: 0 -.17em .67em var(--u2-tab-1-sh);
@@ -2712,104 +3386,23 @@ html.y #bbox-overlay figcaption a {
 	text-align: center;
 	min-width: 1.3em;
 }
-#u2conf {
-	margin: 1em auto;
-	width: 30em;
-}
-#u2conf.w {
-	width: 51em;
-}
-#u2conf.ww {
-	width: 82em;
-}
-#u2conf.ww #u2c3w {
-	width: 29em;
-}
-#u2conf.ww #u2c3w.s {
-	width: 39em;
-}
-#u2conf .c,
-#u2conf .c * {
-	text-align: center;
-	line-height: 1em;
-	margin: 0;
-	padding: 0;
-	border: none;
-}
-#u2conf .txtbox {
-	width: 3em;
-	color: var(--fg-max);
-	background: var(--u2-txt-bg);
-	border: 1px solid #777;
-	font-size: 1.2em;
-	padding: .15em 0;
-	height: 1.05em;
-}
-#u2conf .txtbox.err {
-	color: var(--err-fg);
-	background: var(--err-bg);
-}
-#u2conf a.b {
-	color: var(--u2-b-fg);
-	background: var(--u2-b1-bg);
-	text-decoration: none;
-	border-radius: .1em;
-	font-size: 1.5em;
-	padding: .1em 0;
-	margin: 0 -1px;
-	width: 1.5em;
-	height: 1em;
-	display: inline-block;
-	position: relative;
-	bottom: -0.08em;
-}
-#u2conf input+a.b {
-	background: var(--u2-b2-bg);
-}
-html.b #u2conf a.b:hover {
-	background: var(--btn-h-bg);
-}
-#u2conf .c label {
-	font-size: 1.6em;
-	width: 2em;
-	height: 1em;
-	padding: .4em 0;
-	display: block;
-	border-radius: .25em;
-}
-#u2conf input[type="checkbox"] {
-	position: relative;
-	opacity: .02;
-	top: 2em;
-}
-#u2conf input[type="checkbox"]+label,
-#u2conf input[type="checkbox"]:checked+label {
-	position: relative;
-	cursor: pointer;
-	background: var(--btn-bg);
-	box-shadow: var(--btn-bs);
-	border-bottom: var(--btn-bb);
-	text-shadow: 1px 1px 1px #000, 1px -1px 1px #000, -1px -1px 1px #000, -1px 1px 1px #000;
+#u2conft {
+	width: max-content;
 }
-#u2conf input[type="checkbox"]:checked+label {
-	background: var(--btn-1-bg);
-	box-shadow: var(--btn-1-bs);
-	border-bottom: var(--btn-1-bb);
+#u2conf details[open] {
+	border-bottom: none;
+	border-radius: var(--radius) var(--radius) 0 0;
 }
-#u2conf input[type="checkbox"]+label:hover {
-	background: var(--btn-h-bg);
-	box-shadow: var(--btn-h-bs);
-	border-bottom: var(--btn-h-bb);
+details .setting {
+	border-left: none;
+	border-right: none;
 }
-#u2conf input[type="checkbox"]:checked+label:hover {
-	background: var(--btn-1h-bg);
-	box-shadow: var(--btn-1h-bs);
-	border-bottom: var(--btn-1h-bb);
+.c input[type=checkbox] {
+	position: absolute;
+  	opacity: 0;
 }
-#op_up2k.srch #u2conf td:nth-child(2)>*,
-#op_up2k.srch #u2conf td:nth-child(3)>* {
-	background: #777;
-	border-color: var(--fg);
+#u2conf.srch #multitask,
+#u2conf.srch #potato {
 	box-shadow: none;
 	opacity: .2;
 }
@@ -2880,7 +3473,7 @@ html.b #u2conf a.b:hover {
 #u2tab span.err {
 	color: #fff;
 	padding: .22em;
-	border-radius: .2em;
+	border-radius: var(--radius);
 	border: 2px solid #f0f;
 }
 #u2tab span.inf {
@@ -2905,10 +3498,45 @@ html.b #u2conf a.b:hover {
 }
 .fsearch_explain {
 	color: var(--a-dark);
-	padding-left: .7em;
+	padding: .7em;
 	font-size: 1.1em;
 	line-height: 0;
 }
+details {
+	border: var(--bg-u3) solid 1px;
+	border-radius: var(--radius);
+	margin: .3em 0;
+}
+details:not(.open) .setting {
+	display: none;
+}
+summary {
+	cursor: pointer;
+	background: #ccc;
+	background: var(--bg-u1);
+	color: var(--a);
+	padding: .3em;
+	border-radius: var(--radius);
+	font-size: large;
+}
+.modal summary:hover {
+	background: var(--bg-u3);
+}
+#actionsArea {
+	position: relative;
+	height: max-content;
+	margin-left: auto;
+}
+#srchfolder_div {
+	display: none;
+	position: absolute;
+	left: 3.8em;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	padding: .2em;
+	margin-left: .3em;
+}
 
 
 
@@ -2920,57 +3548,29 @@ html.b #u2conf a.b:hover {
 
 
 
-
-html.c #path,
-html.a #path {
-	border-radius: 0 .3em .3em 0;
-}
-html.c #pctl a,
-html.a #pctl a {
-	background: rgba(0,0,0,0.1);
-	margin-right: .5em;
-	box-shadow: -.02em -.02em .3em rgba(0,0,0,0.2) inset;
-}
-html.d #pctl,
-html.b #pctl {
-	left: .5em;
-}
-html.d #ops,
-html.c #ops,
-html.a #ops {
-	margin: 1.7em 1.5em 0 1.5em;
-	border-radius: .3em;
-	border-width: 1px 0;
-}
-html.c .opbox,
-html.a .opbox {
-	margin: 1.5em 0 0 0;
-}
 html.dz .opview input.i {
 	width: calc(100% - 18em);
 }
-html.c #tree,
-html.c #treeh,
-html.a #tree,
-html.a #treeh {
-	border-radius: 0 .3em 0 0;
+#tree,
+#treesuperh {
+	background: #fff;
 	background: var(--bg-u2);
 }
 html.c #treepar,
-html.a #treepar {
+html.b #treepar {
 	background: var(--bg-u2);
 }
 html.c #tree li,
-html.a #tree li {
+html.b #tree li {
 	border-top: 1px solid var(--bg-u5);
 	border-bottom: 1px solid var(--bg-d3);
 }
 html.c #tree li:last-child,
-html.a #tree li:last-child {
+html.b #tree li:last-child {
 	border-bottom: none;
 }
 html.c .opbox h3,
-html.a .opbox h3 {
+html.b .opbox h3 {
 	border-bottom: 1px solid var(--bg-u5);
 }
 html.c #ops,
@@ -2979,212 +3579,154 @@ html.c #path,
 html.c #srch_form,
 html.c .ghead,
 
-html.a #ops,
-html.a .opbox,
-html.a #path,
-html.a #srch_form,
-html.a .ghead {
-	background: var(--bg-u2);
+html.b #ops,
+html.b .opbox,
+html.b #path,
+html.b #srch_form,
+html.b .ghead {
+	background: #c1d1ed;
+	background: var(--btn-bg);
 	border: 1px solid var(--bg-u3);
-	box-shadow: 0 0 .3em var(--bg-d3);
+	border-bottom: var(--btn-bb);
+	box-shadow: var(--btn-bs);
 }
-html.c #u2btn,
-html.a #u2btn {
-	color: #eee;
-	background: var(--bg-u5);
-	background: -moz-linear-gradient(top, #367 0%, #489 50%, #38788a 51%, #367 100%);
-	background: -webkit-linear-gradient(top, #367 0%, #489 50%, #38788a 51%, #367 100%);
-	background: linear-gradient(to bottom, #367 0%, #489 50%, #38788a 51%, #367 100%);
-	box-shadow: .4em .4em 0 var(--bg-d3);
-	border: 1px solid #222;
+html.b,
+html.cz {
+	.ghead,
+	#wfp .btn:not(:hover),
+	#treeToggleBtn:not(:hover):not(.on),
+	#ops,
+	#path,
+	#wtoggle,
+	#up_quick_more,
+	#up_quick_btn:not(:hover):not(.on) {
+		backdrop-filter: blur(10px);
+		background: var(--btn-bg);
+	}
 }
-html.ay #u2btn {
+html.c .modal .setting:hover {
+	background: color-mix(in oklab, var(--bg-u5) 30%, transparent);
+}
+html.by #u2btn {
 	box-shadow: .4em .4em 0 #ccc;
 }
 html.dz #u2btn {
 	letter-spacing: -.033em;
 }
-html.c #u2conf.ww #u2btn,
-html.a #u2conf.ww #u2btn {
-	margin: -2em .5em -3em 0;
-	padding: .9em 0;
-}
-html.c #op_up2k.srch #u2btn,
-html.a #op_up2k.srch #u2btn {
-	background: linear-gradient(to bottom, #ca3 0%, #fd8 50%, #fc6 51%, #b92 100%);
-	text-shadow: 1px 1px 1px #fc6;
-	color: #333;
-}
-html.c #u2conf #u2btn,
-html.a #u2conf #u2btn {
-	padding: .6em 0;
-	margin-top: -2.6em;
-}
 html.c #u2etas,
-html.a #u2etas {
+html.b #u2etas {
 	background: var(--bg-d1);
 	border: 1px solid var(--bg-u1);
-	border-width: .1em 0;
-	border-radius: .5em;
-	border-width: .25em 0;
-}
-html.c #u2cards,
-html.a #u2cards {
-	margin: 0 auto -1em auto;
+	border-width: 2px;
+	border-radius: var(--radius);
 }
 html.c #u2foot:empty,
-html.a #u2foot:empty {
+html.b #u2foot:empty {
 	margin-bottom: -1em;
 }
-html.ay #ops,
-html.ay .opbox,
-html.ay #path,
-html.ay #doc,
-html.ay #srch_form,
-html.ay .ghead,
-html.ay #u2etas {
+html.by #ops,
+html.by .opbox,
+html.by #path,
+html.by #doc,
+html.by #srch_form,
+html.by .ghead,
+html.by #u2etas {
 	border-color: var(--bg-u2);
 	box-shadow: 0 0 .3em var(--bg-u5);
 }
-html.ay #tree li,
-html.ay #treepar {
-	border-color: #f7f7f7 var(--bg-max) #ddd var(--bg-max);
+html.by #tree li,
+html.by #treepar {
+	border-color: var(--bg) var(--bg-max) #ddd var(--bg-max);
 }
-html.ay #path {
-	background: #f7f7f7;
-	box-shadow: 0 0 .3em #bbb;
-}
-html.ay #treeh,
-html.ay #treepar {
-	background: #f7f7f7;
+html.by #treesuperh,
+html.by #treepar {
+	background: var(--bg);
 	border-color: #ddd;
 }
-html.ay #tree {
+html.by #tree {
 	border-color: #ddd;
 	box-shadow: 0 0 1em #ddd;
-	background: #f7f7f7;
+	background: var(--bg);
 }
 
 
 
 
 
-html.b #path {
-	margin: .3em 0;
-	line-height: 1.7em;
-}
-html.b.op_open #path {
-	margin-top: .2em;
-}
-html.b #srv_info {
-	display: none;
-}
-html.b #srv_info2 {
-	display: inline-block;
-}
-html.b #srv_info2:after {
-	content: '//';
-	margin: 0 .4em;
-}
-html.b #acc_info {
-	right: .5em;
-}
-html.b #wtoggle {
-	border-radius: .1em 0 0 0;
-}
-html.d #barpos,
-html.d #barbuf,
-html.d #pvol,
 html.b #barpos,
 html.b #barbuf,
 html.b #pvol {
-	border-radius: .2em;
+	border-radius: calc(var(--radius) * 3);
 }
-html.b #barpos {
+html.a #barpos {
 	box-shadow: 0 0 0 1px rgba(0,0,0,0.4);
 }
-html.by #barpos {
+html.ay #barpos {
 	box-shadow: 0 0 0 1px rgba(0,0,0,0.2) inset;
 }
-html.b #ops {
-	max-width: 1em;
-	margin-bottom: 1.7em;
-	position: relative;
-	z-index: 2;
-}
-html.b #ops a {
+html.a #pathBar {
 	background: var(--bg);
 }
-html.b .opview {
-	margin: 1em 0;
-}
-html.b #srch_q {
+html.a #srch_q {
 	margin: .2em 0 0 1.6em;
 }
-html.b #srch_q:empty {
+html.a #srch_q:empty {
 	margin-bottom: -1em;
 }
-html.b #op_up2k {
-	margin-top: 3em;
-}
-html.b #tree {
+html.a #tree {
 	box-shadow: 0 -1px 0 rgba(128,128,128,0.4);
 }
-html.bz #tree {
+html.az #tree {
 	box-shadow: 0 -1px 0 var(--bg-d3);
 }
-html.b #treeh,
-html.b #tree li {
+html.a #treeh,
+html.a #tree li {
 	border: none;
 }
-html.b #tree li {
+html.a #tree li {
 	margin-left: .8em;
 }
-html.b #docul a,
-html.b .ntree a {
+html.a #docul a,
+html.a .ntree a {
 	padding: .6em .2em;
 }
-html.b #treepar {
+html.dy *,
+html.cy *,
+html.a * {
+	box-shadow: none !important;
+}
+html.a #path,
+html.a #ops {
+	background: color-mix(in oklab, var(--bg-u5), transparent);
+}
+html.a #treepar {
 	margin-left: .63em;
 	width: calc(.1em + var(--nav-sz) - var(--sbw));
 	border-bottom: .2em solid var(--f-h-b1);
 }
-html.b #wrap {
-	margin-top: 2em;
+html.d #path i,
+html.a #path i {
+	border-right: var(--a) solid 2px;
+	height: 1.5em;
+  	margin: -.4em .3em -.4em -1.7em;
 }
-html.by .ghead,
-html.bz .ghead {
+html.dy .ghead,
+html.a .ghead {
 	background: var(--bg);
 	padding: .2em 0;
+	border-bottom: var(--btn-bb);
+	border-radius: 0;
+	margin: 0 -.5em;
+	padding-left: .5em;
+	padding-right: .5em;
 }
-html.b #files td {
-	padding: .5em .7em;
-}
-html.b .btn {
-	top: -.1em;
-}
-html.b #op_up2k.srch sup {
-	color: #fc0;
-}
-html.by #u2btn sup {
-	color: #06b;
-}
-html.by #op_up2k.srch sup {
-	color: #b70;
+html.a #files tbody a {
+	padding: .7em;
 }
-html.bz #u2cards a.act {
+html.az #u2cards a.act {
 	box-shadow: 0 -.1em .2em var(--bg-d2);
 }
-html.b #u2conf {
-	margin: 2em auto 0 auto;
-}
-html.b #u2conf .txtbox {
-	border: none;
-}
-html.b #u2conf a.b {
-	border-radius: .2em;
-}
-html.by #u2cards a.act {
+html.ay #u2cards a.act {
 	border-width: 2px;
 }
 
@@ -3197,7 +3739,6 @@ html.cy .mdo a {
 }
 html.cy #wrap,
 html.cy #acc_info a,
-html.cy #op_up2k,
 html.cy #files,
 html.cy #files a,
 html.cy #files tbody div a:last-child {
@@ -3216,6 +3757,19 @@ html.cy #barbuf {
 html.cy #pvol {
 	filter: hue-rotate(4deg) contrast(2.2);
 }
+html.cy #path i {
+	background: transparent;
+}
+html.cy #up_quick_btn.on:not(:hover) {
+	background: #f00;
+}
+html.cy .ghead span {
+	color: #f00;
+}
+html.cy #s_list h3 {
+	background: #ff0;
+	color: #000;
+}
 
 
 
@@ -3230,82 +3784,310 @@ html.d #treepar {
 
 
 
+/* basically a mobile / phone layout */
+#pathBar.thin {
+	display: block;
 
-@media (max-width: 32em) {
-	#u2conf {
-		font-size: .9em;
+	#path {
+		position: relative;
+		height: 2.2em;
+		margin: .5em 0 0 0;
+		z-index: -1;
+	}
+	#path a {
+		padding-top: .45em;
+	}
+	#wfp.shifted {
+		margin-left: 2.5em;
 	}
+	#actionsArea {
+		position: absolute;
+		top: .6em;
+		right: .6em;
+	}
+}
+html.e #pathBar.thin #path {
+	margin: 0;
+}
+html:not(.e) #wrap.thin {
+	.ghead {
+		top: 7em;
+		padding: .3em;
+	}
+	#ghead {
+		text-wrap-mode: nowrap;
+		overflow-x: auto;
+		overflow-y: hidden;
+	}
+}
+html.cz #wrap.thin .ghead{
+	top: 7.4em;
+}
+html.dy #wrap.thin .ghead,
+html.a #wrap.thin .ghead {
+	top: 6.9em;
+	margin-left: -.5em;
+	margin-right: -.5em;
+}
+#wrap.thin {
+	.td_w {
+		width: calc(100vw - 8.5em);
+	}
+	.td_s {
+		width: calc(50vw - 5em);
+	}
+}
+html:not(.e) #treeh:not(.noa):after,
+html:not(.e) #wrap.thin #ghead:not(.noa)::after {
+	content: "";
+	position: sticky;
+	right: -.5em;
+	background: linear-gradient(to left, var(--scrl-hint), transparent);
+	width: 3em;
+	height: 3.5em;
+	display: inline-block;
+	margin: -1.4em -0.5em -1.6em -1.4em;;
+	pointer-events: none;
 }
-@media (max-width: 28em) {
-	#u2conf {
-		font-size: .8em;
+html.e #wrap.thin {
+	.ghead {
+		top: 5.1em;
 	}
 }
-@media (min-width: 70em) {
-	#barpos,
-	#barbuf {
-		width: calc(100% - 21em);
-		left: 9.8em;
-		top: .7em;
-		height: 1.6em;
-		bottom: auto;
+@media (max-width: 50em){
+	#path {
+		position: relative;
+		height: 2.2em;
+		margin: .5em 0 0 0;
+		z-index: -1;
+	}
+	html.dy .ghead,
+	html.a .ghead,
+	html.dy #wrap.thin .ghead,
+	html.a #wrap.thin .ghead {
+		top: 7.2em;
+		padding-left: 1em;
+	}
+	.ntree a + a {
+		padding: .6em .2em;
+	}
+	#files tbody a {
+		padding: .8em;
 	}
-	html.d #barpos,
-	html.b #barpos,
-	html.d #barbuf,
-	html.b #barbuf {
-		width: calc(100% - 19em);
-		left: 8em;
+	html:not(.e) body {
+		font-size: 1.1em;
+	}
+	html:not(.e) #treeToggleBtn {
+		margin: .8em;
+	}
+	html:not(.e) #srv_name {
+		padding-top: .9em;
+		padding-bottom: .6em;
+		margin-left: 2.9em;
+	}
+	#widget, #wrap {
+		margin-left: 0 !important;
 	}
 	#widget {
-		bottom: -3.2em;
-		height: 3.2em;
+		font-size: 1.4em;
 	}
-	#pvol {
-		max-width: 9em;
+	#pathBar {
+		display: block;
+		padding: .5em 1em;
+		padding-top: 1em;
+		margin-left: -1em;
+		margin-right: -1em;
 	}
-	html.d #ops,
-	html.b #ops {
-		padding-left: 1.7em;
+	#actionsArea,
+	#pathBar.thin #actionsArea {
+		position: absolute;
+		top: 1em;
+		right: 1em;
 	}
-	html.d .opview,
-	html.b .opview {
-		margin: 1em;
+	#folder_search {
+		margin: .5em 1em 0 .2em;
 	}
-	html.d #path,
-	html.b #path {
-		padding-left: 1.3em;
+	html:not(.e) #wrap {
+		padding-left: 1em;
+		padding-right: 1em;
 	}
-}
-@media (max-width: 35em) {
-	#ops>a[data-dest="new_md"],
-	#ops>a[data-dest="msg"] {
+	#wfp {
+		margin-left: .1em;
+	}
+	#gfiles {
+		margin: 0em -0.5em;
+	}
+	#ghead {
+		margin: 0 .5em 1em .5em;
+	}
+	.modalsplit {
+		display: block;
+		overflow-y: auto;
+		padding-bottom: 5em;
+	}
+	.splitsub {
+		padding-bottom: .5em;
+	}
+	.divider {
 		display: none;
 	}
-	#op_mkdir.act+div,
-	#op_mkdir.act+div+div {
+	#up_status_h {
+		margin: .5em .5em 0 .5em;
+		position: inherit;
+	}
+	#u2btn {
+		padding: 1em .3em;
+	}
+	#pctl {
+		padding: .2em .5em .5em .5em;
+	}
+	#pvol {
+		border: .7em solid var(--bg-u3);
+		transform: rotate(-90deg);
+		position: fixed;
+		bottom: 4em;
+		right: -.7em;
+		opacity: 0;
+		pointer-events: none;
+		box-shadow: 0 0 .5em var(--mp-sh);
+	}
+	#music #pvol {
+		position: absolute;
+		bottom: 3.5em;
+		right: -1.7em;
+	}
+	#pvolbg:hover #pvol {
 		display: block;
-		margin-top: 1em;
+		opacity: 1;
+		pointer-events: all;
+	}
+	#up_quick_more a {
+		padding: .6em;
+	}
+	#s_nav .btn {
+		padding: .5em;
+		padding-right: 2em;
+	}
+	#wfp,
+	#wfp.shifted,
+	#pathBar.thin #wfp,
+	#pathBar.thin #wfp.shifted {
+		margin-left: 2em;
+	}
+	#wrap.thin .ghead {
+		top: 7em;
+	}
+	html.cy .ghead,
+	html.b .ghead,
+	html.cy #wrap.thin .ghead,
+	html.b #wrap.thin .ghead {
+		top: 7.3em;
+	}
+	html.cz .ghead,
+	html.cz #wrap.thin .ghead {
+		top: 7.7em;
+	}
+	.gselchk {
+		font-size: 1.4em;
+		top: 5px;
+		right: 5px;
+	}
+	#music {
+		padding: 1em;
+	}
+	#mu_pbb {
+		width: 100%;
+	}
+	#mu_inner {
+		margin: -.5em;
+	}
+}
+
+@media (max-width: 40em) {
+	#ops a {
+		padding-left: .15em;
+		padding-right: .15em;
+	}
+	#srchfolder_div {
+		left: 2.8em;
+	}
+}
+@media (max-width: 33em) {
+	#wfp #gon,
+	#wfp #gop {
+		display: none;
 	}
 }
 @media (max-width: 54em) {
-	html.b #ops {
-		margin-top: 1.7em;
+	#opa_msg {
+		display: none;
 	}
 }
 @supports (display: grid) and (gap: 1em) {
 	#ggrid {
 		display: grid;
-		margin: 0em 0.25em;
+		margin: .5em;
 		padding: unset;
 		grid-template-columns: repeat(auto-fit,var(--grid-sz));
 		justify-content: center;
 		gap: 1em;
 	}
-
-	html.b #ggrid {
-		padding: 0 0 2em 0;
-		gap: 1em 1.5em;
+	#ggrid.gallery {
+		gap: 2px 3px;
+		margin: .2em -.5em;
+		a::before {
+			padding: .1em 0;
+			margin: .3em;
+		}
+		a.img.thumbed {
+			max-height: none;
+			span:not(.th_ext) {
+				display: none;
+			}
+			.thumb,
+			img {
+				max-height: none;
+				height: calc(var(--grid-sz) - 8px);
+			}
+		}
+	}
+	#ggrid.gallery.nocrop {
+		text-align: center;
+		display: block;
+		margin: .2em -.5em;
+		a::before {
+			padding: .1em 0;
+			margin: .3em;
+		}
+		a {
+			margin-bottom: .2em;
+			.thumb,
+			img {
+				height: calc(var(--grid-sz) - 1.5em);
+			}
+		}
+		a.img.thumbed {
+			min-width: calc(var(--grid-sz) / 2);
+			width: auto;
+			.thumb {
+				height: var(--grid-sz);
+			}
+			img {
+				max-width: 100%;
+				height: var(--grid-sz);
+			}
+			span:not(.th_ext) {
+				display: none;
+			}
+		}
+		a.dir {
+			.thumb,
+			img {
+				height: calc(var(--grid-sz) - 1.5em - 10px);
+				margin-left: 10px;
+				margin-right: 10px;
+			}
+		}
 	}
 
 	#ggrid > a {
@@ -3316,6 +4098,7 @@ html.d #treepar {
   	#ggrid>a>span {
 		text-align: center;
 		padding: .2em .2em .15em .2em;
+		user-select: text;
 	}
 }
 
@@ -3332,14 +4115,16 @@ html.d #treepar {
 
 	#ggrid>a:before,
 	#widget.anim,
+	#tree,
 	#u2tabw,
+	#up_quick,
 	.dropdesc,
 	.dropdesc b,
 	.dropdesc>div>div {
 		transition: none;
 	}
-	#bbox-next,
-	#bbox-prev,
+	#bbox-next a,
+	#bbox-prev a,
 	#bbox-btns {
 		transition: background-color .3s ease, color .3s ease;
 	}
@@ -3356,7 +4141,7 @@ html.ey {
   --fg-max: #0000ff;
   --fg-weak: #0000ff;
   --bg: #c6c3c6;
-  --bg-d3: #ff0;
+  --bg-d3: #7eb8f591;
   --bg-d2: var(--w3);
   --bg-d1: var(--bg);
   --bg-u2: var(--bg);
@@ -3367,10 +4152,8 @@ html.ey {
   --g-sel-bg: #00f;
   --g-fsel-b1: #fff;
   --row-alt: var(--w);
-  --scroll: var(--silver);
   --f-sel-sh: transparent;
   --a: #000;
-  --a-b: #fff;
   --a-hil: #fff;
   --a-h-bg: var(--bg);
   --a-dark: var(--a);
@@ -3405,7 +4188,6 @@ html.ey {
   --white: #fff;
   --grey: grey;
   --silver: silver;
-  --transparent: transparent;
   --shadow-color-1: #0a0a0a;
   --shadow-color-2: #808080;
   --border-dashed-black: 1px dashed var(--black);
@@ -3468,10 +4250,8 @@ html.ez {
   --g-sel-bg: #00f;
   --g-fsel-b1: #fff;
   --row-alt: #555555;
-  --scroll: #555555;
   --f-sel-sh: transparent;
   --a: var(--fg);
-  --a-b: var(--fg);
   --a-hil: var(--fg);
   --btn-1h-bg: var(--bg-d3);
   --a-h-bg: var(--bg);
@@ -3546,38 +4326,64 @@ html.ez {
 
 html.e {
   text-shadow: none;
+  --bg-u1: #0002;
+  --g-sel-fg: #fff;
+}
+html.e * {
+  --radius: 0;
+  border-radius: 0 !important;
 }
+html.e #ggrid > a.sel {
+	box-shadow: none;
+}
+html.e #files tr.sel a, #files tr.sel a.play {
+	color: #fff;
+}
+html.e tr.play td:nth-child(1) a {
+  	background: var(--g-fsel-bg);
+	color: #fff;
+}
+html.e .pfp {
+	background: transparent;
+	color: var(--fg);
+}
+html.e .modalcontent {
+	border-color: var(--fg);
+}
+html.e .divider {
+	background: var(--fg);
+}
+html.e details[open] summary:hover,
 html.e #files,
-html.e #u2conf input[type="checkbox"]:hover + label,
 html.e .tgl.btn.on:hover,
 html.e body {
   background: var(--bg);
 }
-html.e #pctl a,
+html.e summary,
+html.e .pctl a,
 html.e #repl,
-html.e #u2conf a,
-html.e #u2conf input[type="checkbox"] + label,
 html.e #wfp a,
 html.e .btn,
 html.e .eq_step,
 html.e input[type="submit"] {
   box-shadow: var(--shadow-outset);
-  border-radius: var(--radius);
   background: var(--bg);
   border: 0;
 }
+html.e #ops {
+	background: transparent;
+}
+html.e details[open] summary,
 a.s0r,
 html.e #ghead a.s0,
-html.e #u2conf input[type="checkbox"]:checked + label,
 html.e .tgl.btn.on,
 html.e input[type="submit"]:active {
   box-shadow: var(--shadow-inset) !important;
 }
+html.e summary:hover,
 html.e #ops a:hover,
-html.e #pctl a:hover,
+html.e .pctl a:hover,
 html.e #repl:hover,
-html.e #u2conf a:hover,
-html.e #u2conf input[type="checkbox"]:hover + label,
 html.e #wfp a:hover,
 html.e .btn:hover,
 html.e .eq_step:hover,
@@ -3596,9 +4402,9 @@ input[type="text"]:focus {
 html.e tr:focus {
   box-shadow: none;
 }
-html.e #pctl a:focus,
+html.e summary:focus,
+html.e .pctl a:focus,
 html.e #repl:hover,
-html.e #u2conf input[type="checkbox"]:focus + label,
 html.e #wfp a:focus,
 html.e .btn:focus,
 html.e .eq_step:focus {
@@ -3626,9 +4432,6 @@ html.e #files thead th {
 #files td {
   background: var(--w2);
 }
-html.e #files tr {
-  background-color: var(--black);
-}
 html.e #srv_info span,
 html.e label {
   color: var(--btn-fg) !important;
@@ -3637,15 +4440,29 @@ html.e #acc_info {
   background: var(--transparent);
   color: var(--white);
   height: 2em;
-  left: 1em;
+  right: 1em;
   width: fit-content;
 }
 html.e #acc_info,
 html.e #ops,
 html.e #srv_info {
-  display: flex;
   align-items: center;
 }
+html.e .overlay_plus {
+	margin-top: -.3em;
+	text-shadow: none;
+}
+html.e #spaceUsed_bar {
+	background: var(--ttlbar);
+}
+html.e #h_up2k,
+html.e #up_status_h,
+html.e #h_cfg {
+	color: #fff;
+}
+html.e .modalheader:hover {
+	background: var(--ttlbar);
+}
 html.e #acc_info span.warn,
 html.e #acc_info a {
   color: var(--white);
@@ -3676,12 +4493,6 @@ html.e #u2cards a.act {
 }
 html.e #u2btn {
   border: var(--border-dashed-black);
-  border-radius: var(--border-radius);
-  transform: translateY(30%);
-}
-html.e #ops,
-html.e #ops a {
-  border-radius: var(--radius);
 }
 @media only screen and (max-width: 600px) {
   html.e #acc_info {
@@ -3689,9 +4500,9 @@ html.e #ops a {
     color: var(--white);
     height: fit-content;
     align-items: center;
-    top: 3.2em;
-    right: 1em;
-    left: auto;
+    bottom: 9.2em;
+    left: 1em;
+    right: auto;
     display: flex;
     gap: 0.2em;
   }
@@ -3700,14 +4511,23 @@ html.e #ops a {
   }
 }
 html.e #ops {
-  background: var(--ttlbar);
-  /*HC*/
-  box-shadow: inset 0-1px grey, inset 0-2px var(--shadow-color-1);
-  height: 2em;
-  gap: 0.6em;
-  padding: 0.2em;
-  flex-direction: row-reverse;
-  margin-bottom: 1.2em;
+	/*HC*/
+	gap: 0.6em;
+	font-size: larger;
+	padding: 0;
+	height: 2em;
+}
+html.e #srchfolder_div {
+	left: 2em;
+	top: -.1em;
+	bottom: -.6em;
+}
+html.e #qs_btns {
+	right: 0.7em;
+  	top: .3em;
+}
+html.e .under {
+	border: var(--fg) solid 1px;
 }
 html.e #srch_form,
 html.e .opbox {
@@ -3715,10 +4535,13 @@ html.e .opbox {
   padding-top: 1em;
   max-width: 100vw;
 }
+html.e #srv_name {
+	padding-top: .2em;
+	margin-left: 1.4em;
+}
 html.e #ghead,
 html.e #ops a {
   align-items: center;
-  display: flex;
 }
 html.e #ops a {
   text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5);
@@ -3726,13 +4549,11 @@ html.e #ops a {
   padding: 0;
   box-shadow: var(--shadow-outset);
   background: var(--bg);
-  aspect-ratio: 1/1;
   justify-content: center;
   font-size: 1.25em;
-  z-index: 4;
 }
-html.e #blogout:focus,
-html.e #ops a:focus {
+html.e #blogout:focus-visible,
+html.e #ops a:focus-visible {
   outline: 1px dashed var(--w) !important;
 }
 
@@ -3740,21 +4561,15 @@ html.e #blogout:hover {
   text-decoration: underline;
 }
 
-html.e #ops > a:not(:first-child).act {
-  height: 1.4em;
-  width: 1.4em;
-  padding-bottom: 0.3em;
-  margin-top: 0.3em;
+html.e #ops a.act {
+  border-bottom: 0;
+  margin-top: -.6em;
   border-top-left-radius: 3px;
   border-top-right-radius: 3px;
   box-shadow: var(--shadow-inset-left), var(--shadow-inset-top),
     var(--shadow-inset-right);
   z-index: 6;
 }
-html.e #ops a.act {
-  box-shadow: var(--shadow-inset);
-  border-bottom: 0;
-}
 html.e a:active {
   border: 0;
 }
@@ -3762,23 +4577,10 @@ html.e :focus,
 html.e :focus + label {
   border: 0 !important;
   outline-offset: 1px;
-  border-radius: var(--radius) !important;
   box-shadow: inherit;
 }
-html.e #opa_x {
-  text-shadow: 0 0 0 var(--transparent) !important;
-  color: var(--bg) !important;
-  display: flex;
-}
-html.e #opa_x:before {
-  content: "⨯";
-  color: var(--fg) !important;
-  margin-top: -0.1em;
-  font-size: 1.75em;
-  position: absolute;
-}
 html.e .opbox {
-  margin: -1.2em 0 0;
+  margin: -.3em 0 0;
   box-shadow: var(--shadow-inset-bottom), var(--shadow-inset-left),
     var(--shadow-inset-right);
   border-radius: var(--radius);
@@ -3787,7 +4589,6 @@ html.e .opbox {
 }
 html.e #srch_form {
   margin: 0;
-  border-radius: var(--radius);
 }
 html.e #op_unpost {
   max-width: 100vw;
@@ -3837,7 +4638,6 @@ html.e select {
   box-shadow: var(--shadow-input) !important;
   box-sizing: border-box;
   padding: 3px 4px;
-  border-radius: var(--radius);
   border: 0;
 }
 html.e #gfiles {
@@ -3853,20 +4653,20 @@ html.e #ggrid {
   box-shadow: var(--shadow-input);
   padding: 1.5em;
   margin: 0;
-  overflow-x: scroll;
+  overflow-x: auto;
 }
 html.e #ghead {
   margin: 0;
   justify-content: flex-end;
   gap: 0.4em;
-  padding: 0;
-  overflow: auto;
-  top: 0px;
-  border-radius: 0px;
+  padding-top: .2em;
+  top: 2.3em;
 }
 html.e #ghead a {
   margin: 0;
-  border-radius: var(--radius);
+}
+html.e #treeToggleBtn {
+	margin: 0;
 }
 html.e ::-webkit-scrollbar,
 html.e::-webkit-scrollbar {
@@ -3880,7 +4680,7 @@ html.e::-webkit-scrollbar-button,
 html.e::-webkit-scrollbar-thumb {
   width: 16px !important;
   height: 16px !important;
-  background: var(--scroll) !important;
+  background: var(--a) !important;
   /*HC*/
   box-shadow: var(--shadow-outset);
   border: 1px solid !important;
@@ -3930,8 +4730,9 @@ html.e #tree {
 }
 html.e #tree {
   background: var(--bg);
-  padding-left: 0.4em;
+  /* padding-left: 0.4em; */
   padding-top: 0;
+  padding-bottom: 0;
   margin-left: var(--negative-space);
 }
 html.e.noscroll #tree {
@@ -3942,10 +4743,8 @@ html.e.noscroll #tree {
 html.e #treeh {
   background: var(--bg);
   box-shadow: var(--shadow-outset-top), var(--shadow-outset-bottom);
-  width: calc(1.5em + var(--nav-sz) - var(--sbw));
   height: 2.4em;
   border: none;
-  top: -2px;
   display: flex;
   align-items: center;
   gap: 0.6em;
@@ -3966,7 +4765,6 @@ html.e .ntree a:first-child {
   aspect-ratio: 1/1;
   text-align: center;
   align-content: center;
-  border-radius: var(--radius) !important;
   padding: 0.057em;
   border: 1px solid var(--black);
 }
@@ -3982,8 +4780,9 @@ html.e #treeul {
   border: 0 !important;
   position: static;
   margin: 0 !important;
-  min-height: 100%;
+  min-height: calc(100% - 3em);
   height: max-content;
+  width: calc(100% - 1.1em);
 }
 html.e .ntree a:last-of-type:before {
   content: "📁";
@@ -4002,7 +4801,6 @@ html.e #tree li {
 html.e .ntree a:hover {
   outline-offset: -2px;
   color: var(--fg);
-  border-radius: var(--radius) !important;
 }
 html.e #treepar {
   width: calc(-1em + var(--nav-sz) - var(--sbw));
@@ -4013,6 +4811,8 @@ html.e #treepar {
   border-bottom: var(--border-dashed-black);
   margin-left: calc(2.1em - (1em - var(--negative-space))) !important;
 }
+html.e #ghead,
+html.e #op_acc,
 html.e #path,
 html.e #widgeti,
 html.e #wtoggle,
@@ -4030,34 +4830,51 @@ html.e #docul {
   border-left: 0 !important;
   margin-left: 0 !important;
 }
+html.e #spaceFree {
+	background: var(--inset-bg);
+}
+html.e #tree_footer {
+	background: transparent;
+}
 html.e #wrap {
-  transform: translateX(calc((var(--negative-space) * 2) - 1.2em));
   padding-right: var(--negative-space);
   position: relative;
-  margin-right: calc((var(--negative-space) * 2) - 1.2em);
-  margin-top: var(--negative-space);
-  margin-left: 1.2em;
+  margin-right: 0;
+  margin-left: -10px;
+  margin-top: 0;
   /*overflow-x: auto; fix for OOB table when screen space is limited (mobile), but removes sticky header*/
 }
+html.e #pathBar {
+	padding: 0;
+	top: 0;
+	background: var(--ttlbar);
+}
+html.e   #pathBar.thin #actionsArea {
+	top: 0 !important;
+}
 html.e input[type="radio"] {
   accent-color: #232323;
 }
 html.e #path {
-  width: calc(100% - 0.4em);
-  display: flex;
-  align-items: center;
-  margin: 0;
-  padding: 0.2em;
-  overflow-x: auto;
+	background: var(--bg-u2);
+	margin-right: 0;
+	width: auto;
 }
 html.e #path i {
   border: 1px solid var(--w);
   border-color: var(--w);
-  margin: 0;
-  border-width: 0.1em 0.1em 0 0;
-  height: 0.5em;
-  width: 0.5em;
-}/*
+  border-width: 0 0.1em 0 0;
+  transform: none;
+  width: 1.8em;
+  box-shadow: inset -1px 0 var(--shadow-color-1), inset -2px 0 var(--grey);
+}
+html.e #path *:last-child:is(i) {
+    display: none;
+}
+html.e .dir span::before {
+  content: "📁";
+}
+/*
 html.e #hovertree:after {
   color: red;
   content: "BUGGY";
@@ -4066,16 +4883,12 @@ html.ez #hovertree:after {
   content: "BUGGY";
 }
 }*/
-html.e #widget {
-  box-shadow: 0 0;
-  border: 0 !important;
-}
 html.e #wtico,
 html.e #zip1 {
   box-shadow: 0 0 !important;
 }
-html.e #wtgrid {
-  top: -0.09em;
+html.e #wtc {
+  top: 0.2em;
 }
 html.e #wfs,
 html.e #wm3u,
@@ -4088,21 +4901,11 @@ html.e #wfm.act + #wzip1 + #wzip + #wnp {
   border-left-width: 1px;
 }
 html.e #barpos {
-  /* border-radius: var(--radius); */
   box-shadow: var(--shadow-inset);
 }
 html.e #goh + span {
   border-left: 0.1em solid var(--bg-u5);
 }
-html.e #wfp {
-  margin: var(--negative-space);
-  font-size: 0;
-  display: inline-block;
-}
-html.e #wfp a {
-  font-size: large;
-  display: inline-block;
-}
 html.e #repl {
   font-size: large;
   padding: 0.33em;
@@ -4128,23 +4931,30 @@ html.e #doc {
   box-shadow: var(--shadow-inset);
   background: var(--inset-bg);
   margin: 0.2em;
-  border-radius: var(--radius);
 }
 
 html.e #detree {
   padding: 0px;
 }
 
+html.e #wtc {
+	margin: -.2em 0 -.5em .1em;
+}
+
 #rcm {
-	position: absolute;
+	position: fixed;
+	overflow-y: auto;
 	display: none;
 	background: #fff;
-	background: var(--bg);
-	border: 1px solid var(--bg-u3);
+	background: var(--bg-u2);
+	border: 1px solid var(--bg-u5);
 	outline: none;
-	border-radius: .3rem;
+	border-radius: var(--radius);
 	box-shadow: 0 0 .3rem var(--bg-d3);
-	z-index: 3;
+	z-index: 5;
+}
+#rcm.large a {
+	padding: 1em;
 }
 
 #rcm > * {
@@ -4152,7 +4962,7 @@ html.e #detree {
 }
 
 #rcm > a {
-	padding: .2rem .3rem;
+	padding: .3rem;
 }
 
 #rcm > .hide {
@@ -4165,7 +4975,12 @@ html.e #detree {
 
 #rcm > .sep {
 	margin: 0 .2rem;
-	border-bottom: 1px solid var(--a-gray);
+	border-bottom: 1px solid var(--bg-u5);
+}
+
+#rcm_tmp {
+	min-height: 5em;
+	max-width: var(--grid-sz);
 }
 
 #tempname {
@@ -4175,7 +4990,7 @@ html.e #detree {
 	box-shadow: 0 0 2px var(--txt-sh);
 	border-bottom: 1px solid #999;
 	border-color: var(--a);
-	border-radius: .2em;
+	border-radius: var(--radius);
 	padding: .2em .3em;
 }
 
@@ -4188,3 +5003,123 @@ html.e #detree {
     pointer-events: none;
 	z-index: 99;
 }
+
+#spaceFree, #rtt_latency {
+	color: var(--fg);
+	text-align: left;
+	padding: 2px;
+	font-size: small;
+	cursor: default;
+	pointer-events: all;
+	max-width: max-content;
+	background: #fff;
+	background: var(--transparent);
+}
+#rtt_latency {
+	opacity: .5;
+}
+#spaceUsed_bar, #spaceTotal_bar{
+	height: .3em;
+	border-radius: 5px;
+	border-radius: var(--radius);
+}
+#spaceUsed_bar{
+	background: rgb(85, 144, 255);
+	background: linear-gradient(to right, transparent, var(--a-dark), var(--a));
+}
+#spaceTotal_bar {
+	position: relative;
+	margin-bottom: .5em;
+	background: #ccc;
+	background: var(--bg-u1);
+}
+#spaceMax {
+	position: absolute;
+	background: var(--a);
+	right: 0;
+	top: 0;
+	width: .3em;
+	height: .3em;
+	border-radius: var(--radius);
+}
+#tree_footer {
+	width: 0;
+	display: none;
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	padding: 1em;
+	pointer-events: none;
+	transition: width .05s;
+	background: linear-gradient(to top, var(--bg-u2), transparent);
+}
+.popup_button {
+	border-radius: var(--radius);
+	margin: 0;
+	color: var(--btn-1-fg);
+	text-align: left;
+	text-shadow: none;
+}
+#acc_button p{
+	margin: 0;
+}
+#acc_button {
+	margin: 0;
+	cursor: pointer;
+	display: flex;
+}
+#op_acc {
+	font-size: medium;
+	margin-top: .3em;
+	text-align: right;
+}
+#ops input[type=submit],
+#ops #goh {
+	font-size: medium;
+	padding-bottom: .2em;
+}
+
+.popup {
+	display: none;
+	width: fit-content;
+	background: #222;
+	background: var(--bg-u2);
+	border: 1px solid var(--bg-u3);
+	box-shadow: 0 .5em 1em var(--txt-sh);
+	text-align: center;
+	border-radius: 5px;
+	border-radius: var(--radius);
+	padding: .5em;
+	position: absolute;
+	z-index: 6;
+	bottom: 2.5em;
+}
+.under {
+	top: calc(100% + .2em);
+	left: 0;
+	bottom: auto;
+	right: 0;
+  	text-align: left;
+	width: auto;
+}
+#op_acc {
+	left: auto;
+}
+#accessType {
+	font-size: small;
+}
+
+#srchfolder_div:focus-within .popup {
+	display: block;
+}
+/* has to be separate because IE will ignore the whole rule if it can't do focus within */
+.popup.act {
+	display: block;
+}
+
+.overlay_plus{
+	position: absolute;
+	margin: -.5em 0 0 .8em;
+	color: var(--fg);
+	text-shadow: -1px 1px 1px var(--bg-max);
+}
diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html
index a5b412b0..cc46e984 100644
--- a/copyparty/web/browser.html
+++ b/copyparty/web/browser.html
@@ -16,121 +16,267 @@
 </head>
 
 <body>
-	<div id="ops"></div>
+	<a href="#" id="treeToggleBtn" class="tgl btn"></a>
 
-	<div id="op_search" class="opview">
-		{%- if have_tags_idx %}
-		<div id="srch_form" class="tags opbox"></div>
-		{%- else %}
-		<div id="srch_form" class="opbox"></div>
-		{%- endif %}
-		<div id="srch_q"></div>
-	</div>
+	<div id="tree" class="sbar">
+		<div id="treesuperh">
+			<a href="/" id="srv_name"><span id="favico_onpage"></span>{{ srv_name }}</a>
+			<div id="treeh"></div>
+		</div>
+		<ul class="ntree" id="treepar"></ul>
+		<ul id="docul"></ul>
+		<ul class="ntree" id="treeul"></ul>
+		<div id="thx_ff">&nbsp;</div>
 
-	<div id="op_player" class="opview opbox opwide"></div>
+		<div id="tree_footer">
+			<div id="rtt_latency"></div>
 
-	<div id="op_bup" class="opview opbox {% if not ls0 %}act{% endif %}">
-		<div id="u2err"></div>
-		<form method="post" enctype="multipart/form-data" accept-charset="utf-8" action="{{ url_suf }}">
-			<input type="hidden" name="act" value="bput" />
-			<input type="file" name="f" multiple /><br />
-			<input type="submit" value="start upload">
-		</form>
-		<a id="bbsw" href="?b=u" rel="nofollow"><br />switch to basic browser</a>
-	</div>
+			<div id="spaceFree">{{ space_free }} free of {{ space_total }}</div>
 
-	<div id="op_mkdir" class="opview opbox {% if not ls0 %}act{% endif %}">
-		<form method="post" enctype="multipart/form-data" accept-charset="utf-8" action="{{ url_suf }}">
-			<input type="hidden" name="act" value="mkdir" />
-			📂<input type="text" name="name" class="i" placeholder="awesome mix vol.1">
-			<input type="submit" value="make directory">
-		</form>
-	</div>
+			<div id="spaceTotal_bar">
+				<div id="spaceUsed_bar" style="width: {{ space_used_percent }}%;"></div>
+				<div id="spaceMax"></div>
+			</div>
 
-	<div id="op_new_md" class="opview opbox">
-		<form method="post" enctype="multipart/form-data" accept-charset="utf-8" action="{{ url_suf }}">
-			<input type="hidden" name="act" value="new_md" />
-			📝<input type="text" name="name" class="i" placeholder="weekend-plans">
-			<input type="submit" value="new file">
-		</form>
-		<span id="new_mdi"></span>
+			<span id="op_acc" class="opview popup under">
+				<div id="acc_button" class="tgl btn on">
+					<p id="acc_name"></p>
+				</div>
+				<div id="accessType" style="display: block;"></div>
+				<a href="{{ r }}/?h" id="goh" style="display: block;">control-panel</a>
+				<form id="flogout" style="display: block;" method="post" enctype="multipart/form-data">
+					<input type="hidden" name="act" value="logout" />
+					<input id="blogout" type="submit" />
+				</form>
+			</span>
+		</div>
 	</div>
 
-	<div id="op_msg" class="opview opbox {% if not ls0 %}act{% endif %}">
-		<form method="post" enctype="application/x-www-form-urlencoded" accept-charset="utf-8" action="{{ url_suf }}">
-			📟<input type="text" name="msg" class="i" placeholder="lorem ipsum dolor sit amet">
-			<input type="submit" value="send msg to srv log">
-		</form>
-	</div>
+	<div id="wrap">
 
-	<div id="op_unpost" class="opview opbox"></div>
+		<div id="pathBar">
+			<h2 id="wfp" class="shifted">
+				<a href="#" id="gop" class="btn"></a>
+				<a href="#" id="gon" class="btn"></a>
+				<a href="#" id="gou" class="btn"></a>
+			</h2>
+			<h1 id="path">
+				{%- for n in vpnodes %}
+				<a href="{{ r }}/{{ n[0] }}">{{ n[1] }}</a>
+				{%- endfor %}
+			</h1>
 
-	<div id="op_up2k" class="opview"></div>
+			<div id="actionsArea">
+				<div id="ops">
+					<a href="#" id="opa_srch" data-perm="read" data-dep="idx" data-dest="search">🔎</a>
+					<a href="#" id="opa_del" data-perm="write" data-dest="unpost">🧯</a>
+					<a href="#" id="opa_up" data-dest="up2k">🚀</a>
+					<a href="#" id="opa_bup" data-perm="write" data-dest="bup">🎈</a>
+					<a href="#" id="opa_mkd" data-perm="write" data-dest="mkdir"><p class="overlay_plus">+</p>📂</a>
+					<a href="#" id="opa_msg" data-dest="msg">📟</a>
+					<a href="#" id="opa_cfg" data-dest="cfg">⚙️</a>
+					<a href="#" id="opa_acc" data-dest="acc"><span id="acc_pfp" class="pfp">👤</span></a>
+					<div id="opdesc"></div>
+				</div>
 
-	<div id="op_cfg" class="opview opbox opwide"></div>
+				<div id="srchfolder_div">
+					<input id="folder_search" type="text" />
+					<span id="srch_quickopts" class="popup under">
+						<input type="checkbox" id="srch_recursivec" checked="true">
+						<label for="srch_recursivec" id="srch_recursivelbl" tabindex="0"></label>
+					</span>
+					<div id="qs_btns">
+						<a id="moresearch">▾</a>
+						<a id="closesearch">✕</a>
+					</div>
+				</div>
+			</div>
+		</div>
 
-	<h1 id="path">
-		<a href="#" id="entree">🌲</a>
-		{%- for n in vpnodes %}
-		<a href="{{ r }}/{{ n[0] }}">{{ n[1] }}</a>
-		{%- endfor %}
-	</h1>
 
-	<div id="tree"></div>
+		<div id="op_search" class="opview">
+			{%- if have_tags_idx %}
+			<div id="srch_form" class="tags opbox"></div>
+			{%- else %}
+			<div id="srch_form" class="opbox"></div>
+			{%- endif %}
+			<div id="srch_q"></div>
+		</div>
 
-<div id="wrap">
+		<div id="op_player" class="opview opbox opwide"></div>
 
-	{%- if doc %}
-	<div id="bdoc"><pre>{{ doc|e }}</pre></div>
-	{%- else %}
-	<div id="bdoc"></div>
-	{%- endif %}
+		<div id="op_bup" class="opview opbox {% if not ls0 %}act{% endif %}">
+			<form method="post" enctype="multipart/form-data" accept-charset="utf-8" action="{{ url_suf }}">
+				<input type="hidden" name="act" value="bput" />
+				<input id="bup_btn" type="file" name="f" multiple /><br />
+				<input type="submit" value="start upload">
+			</form>
+			<a id="bbsw" href="?b=u" rel="nofollow"><br />switch to basic browser</a>
+		</div>
+
+		<div id="op_mkdir" class="opview opbox {% if not ls0 %}act{% endif %}">
+			<form method="post" enctype="multipart/form-data" accept-charset="utf-8" action="{{ url_suf }}">
+				<input type="hidden" name="act" value="mkdir" />
+				📂<input type="text" name="name" class="i" placeholder="awesome mix vol.1">
+				<input type="submit" value="make directory">
+			</form>
+		</div>
+
+		<div id="op_new_md" class="opview opbox">
+			<form method="post" enctype="multipart/form-data" accept-charset="utf-8" action="{{ url_suf }}">
+				<input type="hidden" name="act" value="new_md" />
+				📝<input type="text" name="name" class="i" placeholder="weekend-plans">
+				<input type="submit" value="new file">
+			</form>
+			<span id="new_mdi"></span>
+		</div>
+
+		<div id="op_msg" class="opview opbox {% if not ls0 %}act{% endif %}">
+			<form method="post" enctype="application/x-www-form-urlencoded" accept-charset="utf-8" action="{{ url_suf }}">
+				📟<input type="text" name="msg" class="i" placeholder="lorem ipsum dolor sit amet">
+				<input type="submit" value="send msg to srv log">
+			</form>
+		</div>
+
+		<div id="op_unpost" class="opview opbox"></div>
+
+		<div id="op_cfg" class="opview opbox opwide"></div>
+
+
+		{%- if doc %}
+		<div id="bdoc"><pre>{{ doc|e }}</pre></div>
+		{%- else %}
+		<div id="bdoc"></div>
+		{%- endif %}
+
+		<div id="pro" class="logue">{{ "" if sb_lg else logues[0] }}</div>
+
+		<div id="cfg" class="modal">
+			<a id="s_outside" class="closepane"></a>
+			<div id="s_content" class="modalcontent">
+				<a id="h_cfg" class="modalheader" href="#h_cfg"></a>
+				<div id="s_hor" class="modalsplit">
+					<div id="s_nav" class="splitsub"></div>
+					<div class="divider"></div>
+					<div id="s_list" class="opview splitsub"></div>
+				</div>
+				<a id="cl_cfg" class="close btn">✕</a>
+			</div>
+		</div>
 
-	<div id="pro" class="logue">{{ "" if sb_lg else logues[0] }}</div>
+		<div id="up2k" class="modal">
+			<a id="up_outside" class="closepane"></a>
+			<div id="up_content" class="modalcontent">
+				<a id="h_up2k" class="modalheader" href="#h_up2k">🚀 Upload</a>
+				<div id="up_hor" class="modalsplit">
+					<div id="op_up2k" class="opview splitsub"></div>
+					<div class="divider"></div>
+					<div id="up_info" class="splitsub"></div>
+				</div>
+				<a id="cl_up" class="close btn">✕</a>
+			</div>
+		</div>
 
-	<table id="files">
-		<thead>
-			<tr>
-				<th name="lead"><span>c</span></th>
-				<th name="href"><span>File Name</span></th>
-				<th name="sz" sort="int"><span>Size</span></th>
-				{%- for k in taglist %}
+		<div id="music" class="modal">
+			<div id="mu_inner">
+				<a id="h_music" class="modalheader" href="#">💿 Music Player</a>
+				
+				<a id="mu_th">
+					<svg class="thumb" width="100%" height="100%" version="1.1">
+						<use href="#file-icon"/>
+					</svg>
+					<span class="th_ext"></span>
+					<img onload="th_onload(this)"/>
+				</a>
+				<span id="mu_tn"></span>				
+				<span id="mu_deets"></span>				
+				<div id="mu_pbb"></div>			
+				<div id="mu_pbc" class="pctl"></div>			
+				<div id="mu_toggles"></div>				
+				<div id="mu_vol"></div>	
+
+				<a id="cfg_mu" class="btn" href="#h_mp">⚙️</a>
+				<a id="cl_mu" class="close btn">✕</a>	
+			</div>
+		</div>
+
+		<!-- define symbol in hidden svg document -->
+		<svg style="display: none" version="1.1">
+			<defs>
+				<symbol id="folder-icon" viewBox="0 0 24 24">
+					<path fill-rule="evenodd" clip-rule="evenodd" d="M3 7C3 5.89543 3.89543 5 5 5L8.67157 5C9.20201 5 9.71071 5.21071 10.0858 5.58579L10.9142 6.41421C11.2893 6.78929 11.798 7 12.3284 7H19C20.1046 7 21 7.89543 21 9V17C21 18.1046 20.1046 19 19 19H5C3.89543 19 3 18.1046 3 17V7Z"
+						  style="fill:#07c; fill:var(--a);" />
+				</symbol>
+				<symbol id="file-icon" viewBox="0 0 48 48">
+					<path fill="currentColor"
+						  opacity=".7"
+						  d="m 28.22643,4.6905246 0.0063,9.1096644 a 1.6331061,1.6331061 43.698111 0 0 1.649296,1.632007 l 9.339558,-0.09259 z" />
+					<path class="a"
+						  d="M39.5,15.5h-9a2,2,0,0,1-2-2v-9h-18a2,2,0,0,0-2,2v35a2,2,0,0,0,2,2h27a2,2,0,0,0,2-2Z"
+						  id="path1"
+						  style="stroke:#07c; stroke:var(--a);"
+						  stroke-width="1" fill="none" stroke-linecap="round" stroke-linejoin="round" />
+					<line class="a"
+						  x1="28.5"
+						  y1="4.5"
+						  x2="39.5"
+						  y2="15.5"
+						  style="stroke:#07c; stroke:var(--a);"
+						  stroke-width="1" fill="none" stroke-linecap="round" stroke-linejoin="round" />
+				</symbol>
+			</defs>
+		</svg>
+
+		<div id="wtc" class="ghead"></div>
+		<table id="files">
+			<thead>
+				<tr>
+					<th name="lead"><span>!</span></th>
+					<th name="href"><span>File Name</span></th>
+					<th name="sz" sort="int"><span>Size</span></th>
+					{%- for k in taglist %}
 					{%- if k.startswith('.') %}
-				<th name="tags/{{ k }}" sort="int"><span>{{ k[1:] }}</span></th>
+					<th name="tags/{{ k }}" sort="int"><span>{{ k[1:] }}</span></th>
 					{%- else %}
-				<th name="tags/{{ k }}"><span>{{ k[0]|upper }}{{ k[1:] }}</span></th>
+					<th name="tags/{{ k }}"><span>{{ k[0]|upper }}{{ k[1:] }}</span></th>
 					{%- endif %}
-				{%- endfor %}
-				<th name="ext"><span>T</span></th>
-				<th name="ts"><span>Date</span></th>
-			</tr>
-		</thead>
-<tbody>
+					{%- endfor %}
+					<th name="ext"><span>Ext</span></th>
+					<th name="ts"><span>Date</span></th>
+				</tr>
+			</thead>
+			<tbody>
 
-{%- for f in files %}
-<tr><td>{{ f.lead }}</td><td><a href="{{ f.href }}">{{ f.name|e }}</a></td><td>{{ f.sz }}</td>
-{%- if f.tags is defined %}
-	{%- for k in taglist %}<td>{{ f.tags[k]|e }}</td>{%- endfor %}
-{%- endif %}<td>{{ f.ext }}</td><td>{{ f.dt }}</td></tr>
-{%- endfor %}
-
-		</tbody>
-	</table>
+				{%- for f in files %}
+				<tr>
+					<td>{{ f.lead }}</td>
+					<td><a href="{{ f.href }}">{{ f.name|e }}</a></td>
+					<td>{{ f.sz }}</td>
+					{%- if f.tags is defined %}
+					{%- for k in taglist %}
+					<td>{{ f.tags[k]|e }}</td>{%- endfor %}
+					{%- endif %}
+					<td>{{ f.ext }}</td>
+					<td>{{ f.dt }}</td>
+				</tr>
+				{%- endfor %}
 
-	<div id="epi" class="logue">{{ "" if sb_lg else logues[1] }}</div>
+			</tbody>
+		</table>
 
-	<h2 id="wfp"><a href="{{ r }}/?h" id="goh">control-panel</a></h2>
+		<div id="epi" class="logue">{{ "" if sb_lg else logues[1] }}</div>
 
-	<a href="#" id="repl">π</a>
+		<a href="#" id="repl">π</a>
 
-</div>
+	</div>
 
-	<div id="srv_info"><span>{{ srv_info }}</span></div>
+	<div id="srv_info" style="display: none;"><span>{{ srv_info }}</span></div>
 
 	<div id="widget"></div>
 
 	<div id="rcm" tabindex="0"></div>
 
+
 	<script>
 		var SR = "{{ r }}",
 			CGV1 = {{ cgv1 }},
@@ -150,18 +296,18 @@
 	{%- if lang != "eng" %}
 	<script src="{{ r }}/.cpr/w/tl/{{ lang }}.js?_={{ ts }}"></script>
 	{%- endif %}
-	<script src="{{ r }}/.cpr/w/baguettebox.js?_={{ ts }}"></script>
 	<script src="{{ r }}/.cpr/w/browser.js?_={{ ts }}"></script>
+	<script src="{{ r }}/.cpr/w/baguettebox.js?_={{ ts }}"></script>
 	<script src="{{ r }}/.cpr/w/up2k.js?_={{ ts }}"></script>
 	{%- if js %}
 	<script src="{{ js }}_={{ ts }}"></script>
 	{%- endif %}
 	<script>
-		Date.now();function jsldp(a,b){2!=window[a]&&alert("FATAL ERROR: cannot load "+b+".js due to unreliable network or broken reverse-proxy; try CTRL-SHIFT-R")}
-		jsldp("J_UTL","util");
-		jsldp("J_BBX","baguettebox");
-		jsldp("J_BRW","browser");
-		jsldp("J_U2K","up2k");
+		Date.now(); function jsldp(a, b) { 2 != window[a] && alert("FATAL ERROR: cannot load " + b + ".js due to unreliable network or broken reverse-proxy; try CTRL-SHIFT-R") }
+		jsldp("J_UTL", "util");
+		jsldp("J_BRW", "browser");
+		jsldp("J_BBX", "baguettebox");
+		jsldp("J_U2K", "up2k");
 	</script>
 </body>
 </html>
diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js
index 57685423..c548fc89 100644
--- a/copyparty/web/browser.js
+++ b/copyparty/web/browser.js
@@ -2,6 +2,16 @@
 
 var J_BRW = 1;
 
+// disables emojis
+var fun_tgl = sread('fun_tgl');
+if( fun_tgl == null)
+	swrite('fun_tgl', 1);
+fun_tgl = fun_tgl != 0;
+console.log('fun_tgl: ' + fun_tgl);
+if(!fun_tgl){
+	clmod(document.documentElement, 'unfun', true);
+}
+
 if (window.dgauto === undefined)
 	alert('FATAL ERROR: receiving stale data from the server; this may be due to a broken reverse-proxy (stuck cache). Try restarting copyparty and press CTRL-SHIFT-R in the browser');
 
@@ -12,7 +22,7 @@ if (1)
 		"tt": "English",
 
 		"cols": {
-			"c": "action buttons",
+			"!": "action buttons",
 			"dur": "duration",
 			"q": "quality / bitrate",
 			"Ac": "audio codec",
@@ -21,7 +31,7 @@ if (1)
 			"Ahash": "audio checksum",
 			"Vhash": "video checksum",
 			"Res": "resolution",
-			"T": "filetype",
+			"Ext": "filetype",
 			"aq": "audio quality / bitrate",
 			"vq": "video quality / bitrate",
 			"pixfmt": "subsampling / pixel structure",
@@ -40,7 +50,7 @@ if (1)
 				["G", "toggle list / grid view"],
 				["T", "toggle thumbnails / icons"],
 				["⇧ A/D", "thumbnail size"],
-				["ctrl-K", "delete selected"],
+				["ctrl-K/Del", "delete selected"],
 				["ctrl-X", "cut selection to clipboard"],
 				["ctrl-C", "copy selection to clipboard"],
 				["ctrl-V", "paste (move/copy) here"],
@@ -114,12 +124,16 @@ if (1)
 		"ht_and": " and ",
 
 		"goh": "control-panel",
-		"gop": 'previous sibling">prev',
-		"gou": 'parent folder">up',
-		"gon": 'next folder">next',
+		"gop": 'previous sibling',
+		"gou": 'parent folder',
+		"gon": 'next folder',
 		"logout": "Logout ",
 		"login": "Login",
 		"access": " access",
+		"options": "options",
+		"more_options": "more options",
+		"bup": "basic uploader",
+		"up2k": "up2k",
 		"ot_close": "close submenu",
 		"ot_search": "`search for files by attributes, path / name, music tags, or any combination of those$N$N`foo bar` = must contain both «foo» and «bar»,$N`foo -bar` = must contain «foo» but not «bar»,$N`^yana .opus$` = start with «yana» and be an «opus» file$N`&quot;try unite&quot;` = contain exactly «try unite»$N$Nthe date format is iso-8601, like$N`2009-12-31` or `2020-09-12 23:30:00`",
 		"ot_unpost": "unpost: delete your recent uploads, or abort unfinished ones",
@@ -155,6 +169,7 @@ if (1)
 		"wt_m3ua": "add to m3u playlist (click <code>📻copy</code> later)",
 		"wt_m3uc": "copy m3u playlist to clipboard",
 		"wt_grid": "toggle grid / list view$NHotkey: G",
+		"wt_gallery": "toggle gallery view with larger image previews",
 		"wt_prev": "previous track$NHotkey: J",
 		"wt_play": "play / pause$NHotkey: P",
 		"wt_next": "next track$NHotkey: L",
@@ -164,7 +179,7 @@ if (1)
 		"ut_u2ts": "copy the last-modified timestamp$Nfrom your filesystem to the server\">📅",
 		"ut_ow": "overwrite existing files on the server?$N🛡️: never (will generate a new filename instead)$N🕒: overwrite if server-file is older than yours$N♻️: always overwrite if the files are different$N⏭️: unconditionally skip all existing files",
 		"ut_mt": "continue hashing other files while uploading$N$Nmaybe disable if your CPU or HDD is a bottleneck",
-		"ut_ask": 'ask for confirmation before upload starts">💭',
+		"ut_ask": 'ask for confirmation before upload starts',
 		"ut_pot": "improve upload speed on slow devices$Nby making the UI less complex",
 		"ut_srch": "don't actually upload, instead check if the files already $N exist on the server (will scan all folders you can read)",
 		"ut_par": "pause uploads by setting it to 0$N$Nincrease if your connection is slow / high latency$N$Nkeep it 1 on LAN or if the server HDD is a bottleneck",
@@ -212,12 +227,15 @@ if (1)
 		"u_nav_m": '<h6>aight, what do you have?</h6><code>Enter</code> = Files (one or more)\n<code>ESC</code> = One folder (including subfolders)',
 		"u_nav_b": '<a href="#" id="modal-ok">Files</a><a href="#" id="modal-ng">One folder</a>',
 
-		"cl_opts": "switches",
+		"cl_opts": "general",
 		"cl_hfsz": "filesize",
 		"cl_themes": "theme",
+		"cl_accent": "accent color (keep empty for default)$Nsupports any css color, like rgba(255, 210, 0, 1)",
+		"cl_radius": "corner radius in pixels (keep empty for default)",
+		"cl_fun": "enables or disables the FUN 🎉🚀👽🐹🥳❗ (reload the page after changing this setting)",
 		"cl_langs": "language",
 		"cl_ziptype": "folder download",
-		"cl_uopts": "up2k switches",
+		"cl_uopts": "upload",
 		"cl_favico": "favicon",
 		"cl_bigdir": "big dirs",
 		"cl_hsort": "#sort",
@@ -235,6 +253,7 @@ if (1)
 		"ct_thumb": 'in grid-view, toggle icons or thumbnails$NHotkey: T">🖼️ thumbs',
 		"ct_csel": 'use CTRL and SHIFT for file selection in grid-view">sel',
 		"ct_dsel": 'use drag-selection in grid-view">dsel',
+		"ct_den": 'use dragging to move files into other folders">mvd',
 		"ct_dl": 'force download (don\'t display inline) when a file is clicked">dl',
 		"ct_ihop": 'when the image viewer is closed, scroll down to the last viewed file">g⮯',
 		"ct_dots": 'show hidden files (if server permits)">dotfiles',
@@ -295,10 +314,11 @@ if (1)
 		"ml_drc": "dynamic range compressor",
 		"ml_ss": "skip silence",
 
-		"mt_loop": "loop/repeat one song\">🔁",
+		"mt_loop": "loop/repeat one song",
 		"mt_one": "stop after one song\">1️⃣",
-		"mt_shuf": "shuffle the songs in each folder\">🔀",
+		"mt_shuf": "shuffle the songs in each folder",
 		"mt_aplay": "autoplay if there is a song-ID in the link you clicked to access the server$N$Ndisabling this will also stop the page URL from being updated with song-IDs when playing music, to prevent autoplay if these settings are lost but the URL remains\">a▶",
+		"mt_afade": "fade in / out when pausing / unpausing audio\">fade",
 		"mt_preload": "start loading the next song near the end for gapless playback\">preload",
 		"mt_prescan": "go to the next folder before the last song$Nends, keeping the webbrowser happy$Nso it doesn't stop the playback\">nav",
 		"mt_fullpre": "try to preload the entire song;$N✅ enable on <b>unreliable</b> connections,$N❌ <b>disable</b> on slow connections probably\">full",
@@ -312,7 +332,7 @@ if (1)
 		"mt_follow": "keep the playing track scrolled into view\">🎯",
 		"mt_compact": "compact controls\">⟎",
 		"mt_uncache": "clear cache &nbsp;(try this if your browser cached$Na broken copy of a song so it refuses to play)\">uncache",
-		"mt_mloop": "loop the open folder\">🔁 loop",
+		"mt_mloop": "loop the open folder",
 		"mt_mnext": "load the next folder and continue\">📂 next",
 		"mt_mstop": "stop playback\">⏸ stop",
 		"mt_cflac": "convert flac / wav to {0}\">flac",
@@ -490,6 +510,7 @@ if (1)
 		"gt_vau": "don't show videos, just play the audio\">🎧",
 		"gt_msel": "enable file selection; ctrl-click a file to override$N$N&lt;em&gt;when active: doubleclick a file / folder to open it&lt;/em&gt;$N$NHotkey: S\">multiselect",
 		"gt_crop": "center-crop thumbnails\">crop",
+		"gt_upscale": "scale up small image previews to fit",
 		"gt_3x": "hi-res thumbnails\">3x",
 		"gt_zoom": "zoom",
 		"gt_chop": "chop",
@@ -502,7 +523,7 @@ if (1)
 		"gt_c2": "truncate filenames less (show more)",
 
 		"sm_w8": "searching...",
-		"sm_prev": "search results below are from a previous query:\n  ",
+		"sm_prev": "search results below are from a previous query:  ",
 		"sl_close": "close search results",
 		"sl_hits": "showing {0} hits",
 		"sl_moar": "load more",
@@ -524,6 +545,8 @@ if (1)
 		"s_f1": "name contains &nbsp; (negate with -nope)",
 		"s_t1": "tags contains &nbsp; (^=start, end=$)",
 		"s_a1": "specific metadata properties",
+		"s_dir": "search this folder",
+		"s_rec": "include subfolders",
 
 		"md_eshow": "cannot render ",
 		"md_off": "[📜<em>readme</em>] disabled in [⚙️] -- document hidden",
@@ -798,57 +821,168 @@ if (!Ls[lang])
 modal.load();
 
 
-// toolbar
-ebi('ops').innerHTML = (
-	'<a href="#" id="opa_x" data-dest="" tt="' + L.ot_close + '">--</a>' +
-	'<a href="#" id="opa_srch" data-perm="read" data-dep="idx" data-dest="search" tt="' + L.ot_search + '">🔎</a>' +
-	(have_del ? '<a href="#" id="opa_del" data-perm="write" data-dest="unpost" tt="' + L.ot_unpost + '">🧯</a>' : '') +
-	'<a href="#" id="opa_up" data-dest="up2k">🚀</a>' +
-	'<a href="#" id="opa_bup" data-perm="write" data-dest="bup" tt="' + L.ot_bup + '">🎈</a>' +
-	'<a href="#" id="opa_mkd" data-perm="write" data-dest="mkdir" tt="' + L.ot_mkdir + '">📂</a>' +
-	'<a href="#" id="opa_md" data-perm="read write" data-dest="new_md" tt="' + L.ot_md + '">📝</a>' +
-	'<a href="#" id="opa_msg" data-dest="msg" tt="' + L.ot_msg + '">📟</a>' +
-	'<a href="#" id="opa_auc" data-dest="player" tt="' + L.ot_mp + '">🎺</a>' +
-	'<a href="#" id="opa_cfg" data-dest="cfg" tt="' + L.ot_cfg + '">⚙️</a>' +
-	(IE ? '<span id="noie">' + L.ot_noie + '</span>' : '') +
-	'<div id="opdesc"></div>'
-);
+var opa = QSA('#ops>a, #wfp>a')
+for(var i = 0; i <opa.length; i++)
+	get_tt(opa[i])
+
+function get_tt(el) {
+	var tlid = 'tt_' + el.id
+	if(!L[tlid] && el.getAttribute('data-dest'))
+		tlid = 'ot_' + el.getAttribute('data-dest')
+	if(!L[tlid])
+		tlid = el.id
+	if(L[tlid])
+		el.setAttribute('tt', L[tlid])
+}
+if(!have_del)
+	ebi('opa_del').style.display = 'none'
+
+if(!fun_tgl){
+	ebi('opa_srch').innerHTML = 'search'
+	ebi('opa_del').innerHTML = 'undo'
+	ebi('opa_up').innerHTML = 'upload'
+	ebi('opa_bup').innerHTML = 'bup'
+	ebi('opa_msg').innerHTML = 'message'
+	ebi('opa_cfg').innerHTML = 'settings'
+	ebi('acc_pfp').innerHTML = 'account'
+	clmod(ebi('acc_pfp'), 'pfp', false)
+}
+
+// mkdir + md
+function mktemp(is_dir) {
+	if(!has(perms, 'read')){
+		if(is_dir)
+			goto('mkdir');
+		else
+			goto('new_md');
+	}
+	qsr('#rcm_tmp');
+	if (!thegrid.en) {
+		var row = mknod('tr', 'rcm_tmp',
+			'<td>-new-</td><td colspan="' + (QSA("#files thead th").length - 1) + '"><input id="tempname" class="i" type="text" placeholder="' + (is_dir ? 'Folder' : 'File') + ' Name"></td>');
+		QS("#files tbody").appendChild(row);
+	}
+	else {
+		var row = mknod('a', 'rcm_tmp',
+			'<span class="dir" style="align-self:end"><input id="tempname" class="dir" type="text" placeholder="' + (is_dir ? 'Folder' : 'File') + ' Name"></span>');
+		if (is_dir)
+			row.className = 'dir';
+		row.style.display = 'flex';
+		QS("#ggrid").appendChild(row);
+	}
+
+	function sendit(name) {
+		name = ('' + name).trim();
+		if (!name)
+			return;
+		var data = new FormData();
+		data.set("act", is_dir ? "mkdir" : "new_md");
+		data.set("name", name);
+
+		var req = new XHR();
+		req.open("POST", get_evpath());
+		req.onload = req.onerror = function() {
+			if (req.status == 405 || req.status == 500)
+				return toast.err(3, "a " + (is_dir ? "folder" : "file") + " with that name already exists.");
+			if (req.status < 200 || req.status > 399)
+				return toast.err(3, "couldn't create " + (is_dir ? "folder" : "file") + ": <br><code>" + esc(req.responseText) + '</code>');
+			treectl.goto();
+		};
+		req.send(data);
+	}
 
+	var input = ebi("tempname");
+	input.onblur = function() {
+		sendit(input.value);
+		// Chrome blurs elements when calling remove for some reason
+		input.onblur = null;
+		row.remove();
+	};
+	input.onkeydown = function(e) {
+		if (e.key == "Enter")
+			sendit(input.value);
+		if (e.key == "Enter" || e.key == "Escape") {
+			input.onblur = null;
+			row.remove();
+			ev(e);
+		}
+	};
+	input.focus();
+}
 
 // media player
+
+// svg from https://www.svgrepo.com/collection/iconcino-interface-icons/8
+var svg_box = '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">';
+var svg_options = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"';
+var svg_prev = svg_box + '<path d="M8 6V18M11.4761 12.7809L16.3753 16.7002C17.0301 17.2241 18 16.7579 18 15.9194V8.08062C18 7.24212 17.0301 6.77595 16.3753 7.29976L11.4761 11.2191C10.9757 11.6195 10.9757 12.3805 11.4761 12.7809Z" ' + svg_options + '/></svg>';
+var svg_next = svg_box + '<path d="M17 6V18M13.5239 12.7809L8.6247 16.7002C7.96993 17.2241 7 16.7579 7 15.9194V8.08062C7 7.24212 7.96993 6.77595 8.6247 7.29976L13.5239 11.2191C14.0243 11.6195 14.0243 12.3805 13.5239 12.7809Z" ' + svg_options + '/></svg>';
+var svg_play = svg_box + '<path fill-rule="evenodd" clip-rule="evenodd" d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z" ' + svg_options + '/><path fill-rule="evenodd" clip-rule="evenodd" d="M10.4706 8.78431C9.80448 8.42906 9 8.91175 9 9.66667V14.3333C9 15.0883 9.80448 15.5709 10.4706 15.2157L15.6728 12.4412C16.0257 12.2529 16.0257 11.7471 15.6728 11.5588L10.4706 8.78431Z" ' + svg_options + '/></svg>'
+var svg_pause = svg_box + '<path d="M10 9V15M14 9V15M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z" ' + svg_options + '/></svg>'
+var svg_vol = svg_box + '<path d="M16.0004 9.00009C16.6281 9.83575 17 10.8745 17 12.0001C17 13.1257 16.6281 14.1644 16.0004 15.0001M18 5.29177C19.8412 6.93973 21 9.33459 21 12.0001C21 14.6656 19.8412 17.0604 18 18.7084M4.6 9.00009H5.5012C6.05213 9.00009 6.32759 9.00009 6.58285 8.93141C6.80903 8.87056 7.02275 8.77046 7.21429 8.63566C7.43047 8.48353 7.60681 8.27191 7.95951 7.84868L10.5854 4.69758C11.0211 4.17476 11.2389 3.91335 11.4292 3.88614C11.594 3.86258 11.7597 3.92258 11.8712 4.04617C12 4.18889 12 4.52917 12 5.20973V18.7904C12 19.471 12 19.8113 11.8712 19.954C11.7597 20.0776 11.594 20.1376 11.4292 20.114C11.239 20.0868 11.0211 19.8254 10.5854 19.3026L7.95951 16.1515C7.60681 15.7283 7.43047 15.5166 7.21429 15.3645C7.02275 15.2297 6.80903 15.1296 6.58285 15.0688C6.32759 15.0001 6.05213 15.0001 5.5012 15.0001H4.6C4.03995 15.0001 3.75992 15.0001 3.54601 14.8911C3.35785 14.7952 3.20487 14.6422 3.10899 14.4541C3 14.2402 3 13.9601 3 13.4001V10.6001C3 10.04 3 9.76001 3.10899 9.54609C3.20487 9.35793 3.35785 9.20495 3.54601 9.10908C3.75992 9.00009 4.03995 9.00009 4.6 9.00009Z" ' + svg_options + '/></svg>'
+
 ebi('widget').innerHTML = (
-	'<div id="wtoggle">' +
-	'<span id="wfs"></span>' +
-	'<span id="wfm"><a' +
-	' href="#" id="fshr" tt="' + L.wt_shr + '">📨<span>share</span></a><a' +
-	' href="#" id="fren" tt="' + L.wt_ren + '">✎<span>name</span></a><a' +
-	' href="#" id="fdel" tt="' + L.wt_del + '">⌫<span>del.</span></a><a' +
-	' href="#" id="fcut" tt="' + L.wt_cut + '">✂<span>cut</span></a><a' +
-	' href="#" id="fcpy" tt="' + L.wt_cpy + '">⧉<span>copy</span></a><a' +
-	' href="#" id="fpst" tt="' + L.wt_pst + '">📋<span>paste</span></a>' +
-	'</span><span id="wzip1"><a' +
-	' href="#" id="zip1" tt="' + L.wt_zip1 + '">📦<span>zip</span></a>' +
-	'</span><span id="wzip"><a' +
-	' href="#" id="selall" tt="' + L.wt_selall + '">sel.<br />all</a><a' +
-	' href="#" id="selinv" tt="' + L.wt_selinv + '">sel.<br />inv.</a><a' +
-	' href="#" id="selzip" class="l1" tt="' + L.wt_selzip + '">zip</a><a' +
-	' href="#" id="seldl" class="l1" tt="' + L.wt_seldl + '">dl</a>' +
-	'</span><span id="wnp"><a' +
-	' href="#" id="npirc" tt="' + L.wt_npirc + '">📋<span>irc</span></a><a' +
-	' href="#" id="nptxt" tt="' + L.wt_nptxt + '">📋<span>txt</span></a>' +
-	'</span><span id="wm3u"><a' +
-	' href="#" id="m3ua" tt="' + L.wt_m3ua + '">📻<span>add</span></a><a' +
-	' href="#" id="m3uc" tt="' + L.wt_m3uc + '">📻<span>copy</span></a>' +
-	'</span><a' +
-	'	href="#" id="wtgrid" tt="' + L.wt_grid + '">田</a><a' +
-	'	href="#" id="wtico">♫</a>' +
+	'<div id="wstack">' +
+
+		'<div id="wtoggle">' +
+		'<span id="wfs"></span>' +
+			'<span id="wfm"><a' +
+				' href="#" id="fshr" tt="' + L.wt_shr + '">📨<span>share</span></a><a' +
+				' href="#" id="fren" tt="' + L.wt_ren + '">✎<span>name</span></a><a' +
+				' href="#" id="fdel" tt="' + L.wt_del + '">🗑️<span>del.</span></a><a' +
+				' href="#" id="fcut" tt="' + L.wt_cut + '">✂<span>cut</span></a><a' +
+				' href="#" id="fcpy" tt="' + L.wt_cpy + '">⧉<span>copy</span></a><a' +
+				' href="#" id="fpst" tt="' + L.wt_pst + '">📋<span>paste</span></a>' +
+			'</span><span id="wzip1"><a' +
+				' href="#" id="zip1" tt="' + L.wt_zip1 + '">' + (fun_tgl ? '⬇️📦' : 'download') + '<span>zip</span></a>' +
+			'</span><span id="wzip"><a' +
+				' href="#" id="selall" tt="' + L.wt_selall + '">sel.<br />all</a><a' +
+				' href="#" id="selinv" tt="' + L.wt_selinv + '">sel.<br />inv.</a><a' +
+				' href="#" id="selzip" class="l1" tt="' + L.wt_selzip + '">⬇️zip</a><a' +
+				' href="#" id="seldl" class="l1" tt="' + L.wt_seldl + '">⬇️files</a>' +
+			'</span><span id="wnp"><a' +
+				' href="#" id="npirc" tt="' + L.wt_npirc + '">📋<span>irc</span></a><a' +
+				' href="#" id="nptxt" tt="' + L.wt_nptxt + '">📋<span>txt</span></a>' +
+			'</span><span id="wm3u"><a' +
+				' href="#" id="m3ua" tt="' + L.wt_m3ua + '">📻<span>add</span></a><a' +
+				' href="#" id="m3uc" tt="' + L.wt_m3uc + '">📻<span>copy</span></a>' +
+			'</span>' +
+		'</div>' +
+
+		'<div id="up_quick">' +
+		'	<div id="up_quick_more">' +
+		'		<a id="uq_nd">' + L.rc_nfo + ' <span><p class="overlay_plus">+</p>📂</span></a>\n' +
+		'		<a id="uq_nf">' + L.rc_nfi + ' <span><p class="overlay_plus">+</p>📝</span></a>\n' +
+		'		<a id="uq_up">' + L.cl_uopts + ' <span>🚀<span></a>\n' +
+		'	</div>' +
+		'	<a id="up_quick_btn" class="tgl btn on"><div class="rotatable">+</div></a>' +
+		'</div>' +
+
+		'<a href="#" id="wtico">♫</a>' +
+
 	'</div>' +
+
 	'<div id="widgeti">' +
-	'	<div id="pctl"><a href="#" id="bprev" tt="' + L.wt_prev + '">⏮</a><a href="#" id="bplay" tt="' + L.wt_play + '">▶</a><a href="#" id="bnext" tt="' + L.wt_next + '">⏭</a></div>' +
-	'	<canvas id="pvol" width="288" height="38"></canvas>' +
-	'	<canvas id="barpos"></canvas>' +
-	'	<canvas id="barbuf"></canvas>' +
-	'</div>' +
+	'	<div id="pbarthinpos"></div>' +
+	'	<div id="pctl" class="pctl">' +
+	'		<a href="#" id="bprev" class="icon btn on" tt="' + L.wt_prev + '">' + svg_prev + '</a>' +
+	'		<a href="#" id="bplay" class="icon btn on" tt="' + L.wt_play + '">' + svg_play + '</a>' +
+	'		<a href="#" id="bnext" class="icon btn on" tt="' + L.wt_next + '">' + svg_next + '</a>' +
+	'		<a id="trackname" href="#h_music"></a>' +
+	'		<div id="progbar" style="position: relative; height: 80%;">' +
+	'			<canvas id="barbuf"></canvas>' +
+	'			<canvas id="barpos"></canvas>' +
+	'		</div>' +
+	'		<div id="altprogbar" class="vis">' +
+	'			<span id="txtpos">0:00</span>' +
+	'			<input type="range" min="0" max="1" step="0.001" value="0" id="sliderpos"></input>' +
+	'			<span id="txtsongend"/>0:00</span>' +
+	'		</div>' +
+	'		<a class="tgl btn" tabindex="0" id="cyclebtn_loopmode" tt="' + L.mt_loop + '$N' + L.mt_mloop + '">🔁</a>' +
+	'		<a class="tgl btn" tabindex="0" id="au_shuf" tt="' + L.mt_shuf + '">🔀</a>' +
+	'		<div id="pvolbg" tabindex="0">' + svg_vol + '<canvas id="pvol"></canvas></div>' +
+	'	</div>' +
+	'</div>'+
 	'<div id="np_inf">' +
 	'	<img id="np_img" />' +
 	'	<span id="np_url"></span>' +
@@ -862,45 +996,39 @@ ebi('widget').innerHTML = (
 	'</div>'
 );
 
+ebi('mu_pbc').innerHTML = (
+	'<a href="#" id="bprev2" class="icon btn on" tt="' + L.wt_prev + '">' + svg_prev + '</a>' +
+	'<a href="#" id="bplay2" class="icon btn on" tt="' + L.wt_play + '">' + svg_play + '</a>' +
+	'<a href="#" id="bnext2" class="icon btn on" tt="' + L.wt_next + '">' + svg_next + '</a>'
+);
+
+ebi('wtoggle').addEventListener('wheel', function (e) {
+	scroll_v_to_h(e, this);
+});
+
+ebi('up_quick').onclick = function(){
+	if(!has(perms, 'write'))
+		return;
+	var btn = ebi('up_quick_btn');
+	clmod(btn, 'on', 't');
+	var isOff = clgot(btn, 'on'); // button has inverted display logic
+	clmod(ebi('up_quick_more'), 'vis', !isOff)
+	clmod(ebi('up_quick'), 'open', !isOff)
+}
+ebi('uq_nd').onclick = function(){
+	mktemp(true);
+};
+ebi('uq_nf').onclick = function(){
+	mktemp();
+};
+
 
 // up2k ui
+ebi('h_up2k').innerHTML = (fun_tgl ? '🚀 ' : '') + L.cl_uopts;
 ebi('op_up2k').innerHTML = (
 	'<form id="u2form" method="post" enctype="multipart/form-data" onsubmit="return false;"></form>\n' +
 
-	'<table id="u2conf">\n' +
-	'	<tr>\n' +
-	'		<td class="c" data-perm="read"><br />' + L.ul_par + '</td>\n' +
-	'		<td class="c" rowspan="2">\n' +
-	'			<input type="checkbox" id="multitask" />\n' +
-	'			<label for="multitask" tt="' + L.ut_mt + '">🏃</label>\n' +
-	'		</td>\n' +
-	'		<td class="c" rowspan="2">\n' +
-	'			<input type="checkbox" id="potato" />\n' +
-	'			<label for="potato" tt="' + L.ut_pot + '">🥔</label>\n' +
-	'		</td>\n' +
-	'		<td class="c" rowspan="2">\n' +
-	'			<input type="checkbox" id="u2rand" />\n' +
-	'			<label for="u2rand" tt="' + L.ut_rand + '">🎲</label>\n' +
-	'		</td>\n' +
-	'		<td class="c" rowspan="2">\n' +
-	'			<input type="checkbox" id="u2ow" />\n' +
-	'			<label for="u2ow" tt="' + L.ut_ow + '">?</a>\n' +
-	'		</td>\n' +
-	'		<td class="c" data-perm="read" data-dep="idx" rowspan="2">\n' +
-	'			<input type="checkbox" id="fsearch" />\n' +
-	'			<label for="fsearch" tt="' + L.ut_srch + '">🔎</label>\n' +
-	'		</td>\n' +
-	'		<td data-perm="read" rowspan="2" id="u2btn_cw"></td>\n' +
-	'		<td data-perm="read" rowspan="2" id="u2c3w"></td>\n' +
-	'	</tr>\n' +
-	'	<tr>\n' +
-	'		<td class="c" data-perm="read">\n' +
-	'			<a href="#" class="b" id="nthread_sub">&ndash;</a><input\n' +
-	'				class="txtbox" id="nthread" value="" tt="' + L.ut_par + '"/><a\n' +
-	'				href="#" class="b" id="nthread_add">+</a><br />&nbsp;\n' +
-	'		</td>\n' +
-	'	</tr>\n' +
-	'</table>\n' +
+	'	<div data-perm="read" rowspan="2" id="u2c3w"></div>\n' +
 
 	'<div id="u2notbtn"></div>\n' +
 
@@ -910,24 +1038,41 @@ ebi('op_up2k').innerHTML = (
 	'	</div>\n' +
 	'</div>\n' +
 
+	'	<div id="up2k_qs">' +
+	'		<label tabindex="0" for="fsearch" id="fsearch_copy" class="tgl btn" tt="' + L.ut_srch +'">🔎</label>\n' +
+	'		<label tabindex="0" for="u2ow" id="u2ow_copy" class="tgl btn on" tt="' + L.ut_ow +'"></label>\n' +
+	'		<label tabindex="0" for="u2rand" id="u2rand_copy" class="tgl btn" tt="' + L.ut_rand +'">🎲</label>\n' +
+	'		<label tabindex="0" for="multitask" id="multitask_copy" class="tgl btn" tt="' + L.ut_mt +'">🏃</label>\n' +
+	'		<a id="up_moreopts" class="btn" href="#h_up2kcfg">↗️ ' + L.more_options + '</a>\n' +
+	'	</div>\n' +
+
 	'<div id="u2c3t">\n' +
 
-	'<div id="u2etaw"><div id="u2etas"><div class="o">\n' +
+	'	<div id="u2etaw">' +
+	'		<div id="u2etas">' +
+	'			<div class="o">\n' +
 	L.ul_hash + ': <span id="u2etah" tt="' + L.ut_etah + '">(' + L.ul_idle1 + ')</span><br />\n' +
 	L.ul_send + ': <span id="u2etau" tt="' + L.ut_etau + '">(' + L.ul_idle1 + ')</span><br />\n' +
-	'	</div><span class="o">' +
+	'			</div><span class="o">' +
 	L.ul_done + ': </span><span id="u2etat" tt="' + L.ut_etat + '">(' + L.ul_idle1 + ')</span>\n' +
-	'</div></div>\n' +
+	'		</div>' +
+	'	</div>' +
+	'</div>' +
 
-	'<div id="u2cards">\n' +
+	'<details id="bup_tgl" href="#v=bup" data-dest="bup" data-perm="write" tt="' + L.ot_bup + '"><summary id="h_bup">' + (IE ? '>> ' : '') + L.bup + (IE ? ' <<' : '') + '</summary></details>'
+);
+
+ebi('up_info').innerHTML = (
+	'<h3 id="up_status_h">' + L.utl_stat + '</h3>' +
+
+	'</div>\n<div id="u2cards">\n' +
 	'	<a href="#" act="ok" tt="' + L.uct_ok + '">ok <span>0</span></a><a\n' +
 	'	href="#" act="ng" tt="' + L.uct_ng + '">ng <span>0</span></a><a\n' +
 	'	href="#" act="done" tt="' + L.uct_done + '">done <span>0</span></a><a\n' +
 	'	href="#" act="bz" tt="' + L.uct_bz + '" class="act">busy <span>0</span></a><a\n' +
 	'	href="#" act="q" tt="' + L.uct_q + '">que <span>0</span></a>\n' +
-	'</div>\n' +
-
-	'</div>\n' +
+	//'	href="#" style="pointer-events: none; width: 90%; display: inline-block; font-size: 1.1em;"><span style="opacity: 0">_</span></a>\n' +
+	'</div>\n</div>\n' +
 
 	'<div id="u2tabw" class="na"><table id="u2tab">\n' +
 	'	<thead>\n' +
@@ -945,6 +1090,20 @@ ebi('op_up2k').innerHTML = (
 	'<div id="u2foot"></div>'
 );
 
+ebi('h_up2k').onclick = function(){
+	ebi('up_info').scrollTop =
+	ebi('op_up2k').scrollTop =
+	ebi('up_hor').scrollTop =
+	ebi('up_content').scrollTop =
+		0;
+}
+
+ebi('cl_up').onclick =
+ebi('up_outside').onclick =
+	function () {
+		hist_push('#')
+		modaltoggle('up2k', false);
+	}
 
 ebi('wrap').insertBefore(mknod('div', 'lazy'), ebi('epi'));
 
@@ -952,13 +1111,27 @@ var x = ebi('bbsw');
 x.parentNode.insertBefore(mknod('div', null,
 	'<input type="checkbox" id="uput" name="uput"><label for="uput">' + L.u_uput + '</label>'), x);
 
+var bup = ebi('op_bup');
+ebi('bup_tgl').appendChild(bup);
+ebi('h_bup').onclick = function() {
+	var open = !clgot(bup, 'act');
+	if(open){
+		location.hash = '#h_bup';
+		modaltoggle('bup', true);
+	}
+	else{
+		location.hash = '#h_up2k';
+		modaltoggle('up2k', true);
+	}
+	ebi('bup_tgl').open = !open;
+};
 
 (function () {
 	var o = mknod('div');
 	o.innerHTML = (
-		'<div id="drops">\n' +
-		'	<div class="dropdesc" id="up_zd"><div>🚀 ' + L.udt_up + '<br /><span></span><div>🚀<b>' + L.udt_up + '</b></div><div><b>' + L.udt_up + '</b>🚀</div></div></div>\n' +
-		'	<div class="dropdesc" id="srch_zd"><div>🔎 ' + L.udt_srch + '<br /><span></span><div>🔎<b>' + L.udt_srch + '</b></div><div><b>' + L.udt_srch + '</b>🔎</div></div></div>\n' +
+		'<div id="drops" class="modal">\n' +
+		'	<div class="dropdesc" id="up_zd"><div>🚀 ' + L.udt_up + '<br /><span></span></div></div>\n' +
+		'	<div class="dropdesc" id="srch_zd"><div>🔎 ' + L.udt_srch + '<br /><span></span></div></div>\n' +
 		'	<div class="dropzone" id="up_dz" v="up_zd"></div>\n' +
 		'	<div class="dropzone" id="srch_dz" v="srch_zd"></div>\n' +
 		'</div>'
@@ -966,38 +1139,97 @@ x.parentNode.insertBefore(mknod('div', null,
 	document.body.appendChild(o);
 })();
 
-
 // config panel
+
+var musicSettings = (
+	'<div class="sub_section"><h3 id="h_mp">🎵 ' + L.ot_mp + '</h3></div>' +
+
+	'<div class="sub"><h3 id="h_mpopts">✅ ' + L.cl_opts + '</h3><div>' +
+	'<a href="#" class="tgl btn" id="au_loop" tt="' + L.mt_loop + '">🔂</a>' +
+	'<a href="#" class="tgl btn" id="au_one" tt="' + L.mt_one + '</a>' +
+	'<a href="#" class="tgl btn" id="au_aplay" tt="' + L.mt_aplay + '</a>' +
+	'<a href="#" class="tgl btn" id="au_afade" tt="' + L.mt_afade + '</a>' +
+	'<a href="#" class="tgl btn" id="au_preload" tt="' + L.mt_preload + '</a>' +
+	'<a href="#" class="tgl btn" id="au_prescan" tt="' + L.mt_prescan + '</a>' +
+	'<a href="#" class="tgl btn" id="au_fullpre" tt="' + L.mt_fullpre + '</a>' +
+	'<a href="#" class="tgl btn" id="au_fau" tt="' + L.mt_fau + '</a>' +
+	'<a href="#" class="tgl btn" id="au_waves" tt="' + L.mt_waves + '</a>' +
+	'<a href="#" class="tgl btn" id="au_npclip" tt="' + L.mt_npclip + '</a>' +
+	'<a href="#" class="tgl btn" id="au_m3u_c" tt="' + L.mt_m3u_c + '</a>' +
+	'<a href="#" class="tgl btn" id="au_os_ctl" tt="' + L.mt_octl + '</a>' +
+	'<a href="#" class="tgl btn" id="au_os_seek" tt="' + L.mt_oseek + '</a>' +
+	'<a href="#" class="tgl btn" id="au_osd_cv" tt="' + L.mt_oscv + '</a>' +
+	'<a href="#" class="tgl btn" id="au_follow" tt="' + L.mt_follow + '</a>' +
+	'<a href="#" class="tgl btn" id="au_compact" tt="' + L.mt_compact + '</a>' +
+	'</div></div>' +
+
+	'<div class="sub"><h3 id="h_cmds">▶️ ' + L.ml_btns + '</h3><div>' +
+	'<a href="#" class="btn" id="au_uncache" tt="' + L.mt_uncache + '</a>' +
+	'</div></div>' +
+
+	'<div class="sub"><h3 id="h_pbmode">📁 ' + L.ml_pmode + '</h3><div id="pb_mode">' +
+	'<a href="#" class="tgl btn" m="loop" tt="' + L.mt_mloop + '">🔁</a>' +
+	'<a href="#" class="tgl btn" m="next" tt="' + L.mt_mnext + '</a>' +
+	'<a href="#" class="tgl btn" m="stop" tt="' + L.mt_mstop + '</a>' +
+	'</div></div>' +
+
+	(have_acode ? (
+		'<div class="sub"><h3 id="h_transfrom">🏹 ' + L.ml_tcode + '</h3><div>' +
+		'<a href="#" id="ac_flac" class="tgl btn" tt="' + L.mt_cflac + '</a>' +
+		'<a href="#" id="ac_aac" class="tgl btn" tt="' + L.mt_caac + '</a>' +
+		'<a href="#" id="ac_oth" class="tgl btn" tt="' + L.mt_coth + '</a>' +
+		'</div></div>' +
+		'<div class="sub"><h3 id="h_transto">🎯 ' + L.ml_tcode2 + '</h3><div>' +
+		'<a href="#" id="ac2opus" class="tgl btn" tt="' + L.mt_c2opus + '</a>' +
+		'<a href="#" id="ac2owa" class="tgl btn" tt="' + L.mt_c2owa + '</a>' +
+		'<a href="#" id="ac2caf" class="tgl btn" tt="' + L.mt_c2caf + '</a>' +
+		'<a href="#" id="ac2mp3" class="tgl btn" tt="' + L.mt_c2mp3 + '</a>' +
+		'<a href="#" id="ac2flac" class="tgl btn" tt="' + L.mt_c2flac + '</a>' +
+		'<a href="#" id="ac2wav" class="tgl btn" tt="' + L.mt_c2wav + '</a>' +
+		'</div></div>'
+	) : '') +
+
+	'<div class="sub"><h3 id="h_tint">🕶️ ' + L.ml_tint + '</h3><div>' +
+	'<input type="text" id="pb_tint" value="0" ' + NOAC + ' style="width:2.4em" tt="' + L.mt_tint + '" />' +
+	'</div></div>' +
+
+	'<div class="sub"><h3 id="h_drc">🐘 ' + L.ml_drc + '</h3><div><div id="audio_drc"></div></div></div>' +
+	'<div class="sub"><h3 id="h_eq">📊 ' + L.ml_eq + '</h3><div><div id="audio_eq"></div></div></div>' +
+	'<div class="sub"><h3 id="h_silence">🔇 ' + L.ml_ss + '</h3><div><div id="audio_ss"></div></div></div>' +
+	'');
+
 ebi('op_cfg').innerHTML = (
 	'<div>\n' +
-	'	<h3>' + L.cl_opts + '</h3>\n' +
+	'	<h3 id="h_general">✅ ' + L.cl_opts + '</h3>\n' +
 	'	<div>\n' +
-	'		<a id="tooltips" class="tgl btn" href="#" tt="' + L.ct_ttips + '</a>\n' +
-	'		<a id="griden" class="tgl btn" href="#" tt="' + L.wt_grid + '">' + L.ct_grid + '</a>\n' +
-	'		<a id="thumbs" class="tgl btn" href="#" tt="' + L.ct_thumb + '</a>\n' +
-	'		<a id="csel" class="tgl btn" href="#" tt="' + L.ct_csel + '</a>\n' +
-	'		<a id="dsel" class="tgl btn" href="#" tt="' + L.ct_dsel + '</a>\n' +
-	'		<a id="dlni" class="tgl btn" href="#" tt="' + L.ct_dl + '</a>\n' +
-	'		<a id="ihop" class="tgl btn" href="#" tt="' + L.ct_ihop + '</a>\n' +
-	'		<a id="dotfiles" class="tgl btn" href="#" tt="' + L.ct_dots + '</a>\n' +
-	'		<a id="qdel" class="tgl btn" href="#" tt="' + L.ct_qdel + '</a>\n' +
-	'		<a id="dir1st" class="tgl btn" href="#" tt="' + L.ct_dir1st + '</a>\n' +
-	'		<a id="nsort" class="tgl btn" href="#" tt="' + L.ct_nsort + '</a>\n' +
-	'		<a id="utctid" class="tgl btn" href="#" tt="' + L.ct_utc + '</a>\n' +
-	'		<a id="ireadme" class="tgl btn" href="#" tt="' + L.ct_readme + '</a>\n' +
-	'		<a id="idxh" class="tgl btn" href="#" tt="' + L.ct_idxh + '</a>\n' +
-	'		<a id="sbars" class="tgl btn" href="#" tt="' + L.ct_sbars + '</a>\n' +
+	'		<a id="tooltips" class="tgl btn" tt="' + L.ct_ttips + '</a>\n' +
+	'		<a id="griden" class="tgl btn" tt="' + L.wt_grid + '">' + L.ct_grid + '</a>\n' +
+	'		<a id="thumbs" class="tgl btn" tt="' + L.ct_thumb + '</a>\n' +
+	'		<a id="csel" class="tgl btn" tt="' + L.ct_csel + '</a>\n' +
+	'		<a id="dsel" class="tgl btn" tt="' + L.ct_dsel + '</a>\n' +
+	'		<a id="den" class="tgl btn" tt="' + L.ct_den + '</a>\n' +
+	'		<a id="dlni" class="tgl btn" tt="' + L.ct_dl + '</a>\n' +
+	'		<a id="ihop" class="tgl btn" tt="' + L.ct_ihop + '</a>\n' +
+	'		<a id="dotfiles" class="tgl btn" tt="' + L.ct_dots + '</a>\n' +
+	'		<a id="qdel" class="tgl btn" tt="' + L.ct_qdel + '</a>\n' +
+	'		<a id="dir1st" class="tgl btn" tt="' + L.ct_dir1st + '</a>\n' +
+	'		<a id="nsort" class="tgl btn" tt="' + L.ct_nsort + '</a>\n' +
+	'		<a id="utctid" class="tgl btn" tt="' + L.ct_utc + '</a>\n' +
+	'		<a id="ireadme" class="tgl btn" tt="' + L.ct_readme + '</a>\n' +
+	'		<a id="idxh" class="tgl btn" tt="' + L.ct_idxh + '</a>\n' +
+	'		<a id="sbars" class="tgl btn" tt="' + L.ct_sbars + '</a>\n' +
 	'	</div>\n' +
 	'</div>\n' +
+	'<div><h3 id="h_mouse">🖱️ ' + L.cl_rcm + '</h3><div><a id="rcm_en" class="tgl btn" tt="' + L.cdt_ren + '</a><a id="rcm_db" class="tgl btn" tt="' + L.cdt_rdb + '</a></div></div>' +
 	'<div>\n' +
-	'	<h3>' + L.cl_gauto + '</h3>\n' +
+	'	<h3 id="h_gauto">🅰️ ' + L.cl_gauto + '</h3>\n' +
 	'	<div>\n' +
 	'		<a id="gauto" class="tgl btn" href="#" tt="' + L.tt_gauto + '">' + L.enable + '</a>\n' +
 	'		<input type="text" id="ga_thresh" value="" ' + NOAC + ' style="width:1.5em" tt="' + L.tt_gathr + '" />' +
 	'	</div>\n' +
 	'</div>\n' +
 	'<div>\n' +
-	'	<h3>' + L.cl_hfsz + '</h3>\n' +
+	'	<h3 id="h_filesize">🔢 ' + L.cl_hfsz + '</h3>\n' +
 	'	<div><select id="fszfmt">\n' +
 	'		<option value="0">0 ┃ 2345678</option>\n' +
 	'		<option value="1">1 ┃ 2 345 678</option>\n' +
@@ -1017,86 +1249,245 @@ ebi('op_cfg').innerHTML = (
 	'	</select></div>\n' +
 	'</div>\n' +
 	'<div>\n' +
-	'	<h3>' + L.cl_themes + '</h3>\n' +
-	'	<div><select id="themes"></select></div>\n' +
+	'	<h3 id="h_theme">🎨 ' + L.cl_themes + '</h3>\n' +
+	'	<div>' +
+	'		<select id="themes"></select>' +
+	'		<div id="colordiv" tt="' + L.cl_accent +'">' +
+	'			<input type="text" id="accent" placeholder="#color"></input>' +
+	'			<input type="color" id="accent_picker"></input>' +
+	'		</div>' +
+'			<input tt="' + L.cl_radius +'" type="text" id="radius" placeholder="[0-inf]"></input>' +
+	'		<a id="fun_tgl" class="tgl btn" tt="' + L.cl_fun + '">🥳</a>\n' +
+	'	</div>\n' +
+	'</div>\n' +
+	'<div>\n' +
+	'	<h3 id="h_favico">🎉 ' + L.cl_favico + '</h3>\n' +
+	'	<div>\n' +
+	'		<input type="text" id="icot" value="" ' + NOAC + ' style="width:1.3em" tt="' + L.cft_text + '" />' +
+	'		<input type="text" id="icof" value="" ' + NOAC + ' style="width:2em" tt="' + L.cft_fg + '" />' +
+	'		<input type="text" id="icob" value="" ' + NOAC + ' style="width:2em" tt="' + L.cft_bg + '" />' +
+	'		<a id="ico1" class="btn">🔄️</a>\n' +
 	'	</div>\n' +
 	'</div>\n' +
 	'<div>\n' +
-	'	<h3>' + L.cl_langs + '</h3>\n' +
+	'	<h3 id="h_language">🌐 ' + L.cl_langs + '</h3>\n' +
 	'	<div><select id="langs"></select></div>\n' +
 	'</div>\n' +
 	(have_zip ? (
-		'<div><h3>' + L.cl_ziptype + '</h3><div id="arc_fmt"></div></div>\n'
+		'<div><h3 id="h_zip">⬇️ ' + L.cl_ziptype + '</h3><div><div id="arc_fmt"></div></div></div>\n'
 	) : '') +
-	'<div>\n' +
-	'	<h3>' + L.cl_uopts + '</h3>\n' +
-	'	<div>\n' +
-	'		<a id="ask_up" class="tgl btn" href="#" tt="' + L.ut_ask + '</a>\n' +
-	'		<a id="u2ts" class="tgl btn" href="#" tt="' + L.ut_u2ts + '</a>\n' +
-	'		<a id="umod" class="tgl btn" href="#" tt="' + L.cut_umod + '</a>\n' +
-	'		<a id="hashw" class="tgl btn" href="#" tt="' + L.cut_mt + '</a>\n' +
-	'		<a id="nosubtle" class="tgl btn" href="#" tt="' + L.cut_wasm + '</a>\n' +
-	'		<a id="u2turbo" class="tgl btn ttb" href="#" tt="' + L.cut_turbo + '</a>\n' +
-	'		<a id="u2tdate" class="tgl btn ttb" href="#" tt="' + L.cut_datechk + '</a>\n' +
-	'		<input type="text" id="u2szg" value="" ' + NOAC + ' style="width:3em" tt="' + L.cut_u2sz + '" />' +
-	'		<a id="flag_en" class="tgl btn" href="#" tt="' + L.cut_flag + '">💤</a>\n' +
-	'		<a id="u2sort" class="tgl btn" href="#" tt="' + L.cut_az + '">az</a>\n' +
-	'		<a id="upnag" class="tgl btn" href="#" tt="' + L.cut_nag + '">🔔</a>\n' +
-	'		<a id="upsfx" class="tgl btn" href="#" tt="' + L.cut_sfx + '">🔊</a>\n' +
-	'		</td>\n' +
+
+	'<div class="sub_section"><h3 id="h_up">☁️ ' + L.cl_uopts + '</h3></div>' +
+
+	'<div class="sub">\n' +
+	'	<h3 id="h_up2kcfg">🚀 ' + L.up2k + '</h3>\n' +
+	'	<div id="u2conf">\n' +
+	'		<div class="c" data-perm="read" data-dep="idx" tt="' + L.ut_srch +'">\n' +
+	'			<input type="checkbox" id="fsearch" />\n' +
+	'			<label class="tgl btn" for="fsearch">🔎</label>\n' +
+	'		</div>\n' +
+
+	'		<div class="c" tt="' + L.ut_ow +'">\n' +
+	'			<input type="checkbox" id="u2ow" />\n' +
+	'			<label class="tgl btn on" for="u2ow">?</a>\n' +
+	'		</div>\n' +
+
+	'		<div id="u2conft" tt="' + L.ut_par +'">\n' +
+	'			<tr>\n' +
+	'				<span class="c" data-perm="read" style="display: block; margin-bottom: .5em;">' + L.ul_par + '</span>\n' +
+	'			</tr>\n' +
+	'			<tr>\n' +
+	'				<div class="c" data-perm="read">\n' +
+	'					<a href="#" class="b btn" id="nthread_sub">&ndash;</a><input\n' +
+	'						class="txtbox" type="text" id="nthread" style="width: 3em;" value=""/><a\n' +
+	'						href="#" class="b btn" id="nthread_add">+</a>&nbsp;\n' +
+	'				</div>\n' +
+	'			</tr>\n' +
+	'		</div>\n' +
+
+	'		<div class="c" tt="' + L.ut_mt +'">\n' +
+	'			<input type="checkbox" id="multitask" />\n' +
+	'			<label class="tgl btn" for="multitask">🏃</label>\n' +
+	'		</div>\n' +
+
+	'		<div class="c" tt="' + L.ut_pot +'">\n' +
+	'			<input type="checkbox" id="potato" />\n' +
+	'			<label class="tgl btn" for="potato">🥔</label>\n' +
+	'		</div>\n' +
+
+	'		<div class="c" tt="' + L.ut_rand +'">\n' +
+	'			<input type="checkbox" id="u2rand" />\n' +
+	'			<label class="tgl btn" for="u2rand">🎲</label>\n' +
+	'		</div>\n' +
 	'	</div>\n' +
 	'</div>\n' +
-	'<div>\n' +
-	'	<h3>' + L.cl_favico + ' <span id="ico1">🎉</span></h3>\n' +
+
+	'<div class="sub">\n' +
+	'	<h3 id="h_upload">🎈 ' + L.cl_opts + '</h3>\n' +
 	'	<div>\n' +
-	'		<input type="text" id="icot" value="" ' + NOAC + ' style="width:1.3em" tt="' + L.cft_text + '" />' +
-	'		<input type="text" id="icof" value="" ' + NOAC + ' style="width:2em" tt="' + L.cft_fg + '" />' +
-	'		<input type="text" id="icob" value="" ' + NOAC + ' style="width:2em" tt="' + L.cft_bg + '" />' +
-	'		</td>\n' +
+	'		<a id="ask_up" class="tgl btn" tt="' + L.ut_ask + '">💭</a>\n' +
+	'		<a id="u2ts" class="tgl btn" tt="' + L.ut_u2ts + '</a>\n' +
+	'		<a id="umod" class="tgl btn" tt="' + L.cut_umod + '</a>\n' +
+	'		<a id="hashw" class="tgl btn" tt="' + L.cut_mt + '</a>\n' +
+	'		<a id="nosubtle" class="tgl btn" tt="' + L.cut_wasm + '</a>\n' +
+	'		<a id="u2turbo" class="tgl btn ttb" tt="' + L.cut_turbo + '</a>\n' +
+	'		<a id="u2tdate" class="tgl btn ttb" tt="' + L.cut_datechk + '</a>\n' +
+	'		<input type="text" id="u2szg" value="" ' + NOAC + ' style="width:3em" tt="' + L.cut_u2sz + '" />' +
+	'		<a id="flag_en" class="tgl btn" tt="' + L.cut_flag + '">💤</a>\n' +
+	'		<a id="u2sort" class="tgl btn" tt="' + L.cut_az + '">az</a>\n' +
+	'		<a id="upnag" class="tgl btn" tt="' + L.cut_nag + '">🔔</a>\n' +
+	'		<a id="upsfx" class="tgl btn" tt="' + L.cut_sfx + '">🔊</a>\n' +
 	'	</div>\n' +
 	'</div>\n' +
+
 	'<div>\n' +
-	'	<h3>' + L.cl_bigdir + '</h3>\n' +
+	'	<h3 id="h_bigdir">📁 ' + L.cl_bigdir + '</h3>\n' +
 	'	<div>\n' +
 	'		<input type="text" id="bd_lim" value="250" ' + NOAC + ' style="width:4em" tt="' + L.cdt_lim + '" />' +
-	'		<a id="bd_ask" class="tgl btn" href="#" tt="' + L.cdt_ask + '">ask</a>\n' +
+	'		<a id="bd_ask" class="tgl btn" tt="' + L.cdt_ask + '">ask</a>\n' +
 	'		</td>\n' +
 	'	</div>\n' +
 	'</div>\n' +
 	'<div>\n' +
-	'	<h3>' + L.cl_hsort + '</h3>\n' +
+	'	<h3 id="h_sort">🔃 ' + L.cl_hsort + '</h3>\n' +
 	'	<div>\n' +
 	'		<input type="text" id="hsortn" value="" ' + NOAC + ' style="width:3em" tt="' + L.cdt_hsort + '" />' +
 	'		</td>\n' +
 	'	</div>\n' +
 	'</div>\n' +
-	'<div><h3>' + L.cl_keytype + '</h3><div><select id="key_notation"></select></div></div>\n' +
-	(!MOBILE ? '<div><h3>' + L.cl_rcm + '</h3><div><a id="rcm_en" class="tgl btn" href="#" tt="' + L.cdt_ren + '</a><a id="rcm_db" class="tgl btn" href="#" tt="' + L.cdt_rdb + '</a></div></div>' : '') +
-	'<div><h3>' + L.cl_hiddenc + ' &nbsp;' + (MOBILE ? '<a href="#" id="hcolsh">' + L.cl_hidec + '</a> / ' : '') + '<a href="#" id="hcolsr">' + L.cl_reset + '</a></h3><div id="hcols"></div></div>'
+	musicSettings +
+	'<div><h3 id="h_keytype">🎼 ' + L.cl_keytype + '</h3><div><select id="key_notation"></select></div></div>\n'
 );
 
+// modalize settings
+(function () {
+	ebi('h_cfg').innerHTML = (fun_tgl ? '⚙️ ' : '') + L.ot_cfg;
+	var sections = ebi('op_cfg').children;
+	for (var i = 0; i < sections.length; i++){
+		var h = sections[i].children[0];
+		var sName = h.innerHTML;
+		if(!fun_tgl){
+			if(sName && sName.match(' ') && sName[0] != '<')
+				sName = sName.split(' ').slice(1).join(' ');
+		}
+		var sId = h.id;
+		h.id = ''
+		var subSettings = sections[i].children[1];
+		var section = '<div id="' + sId + '" class="s_section ' + sections[i].classList +'"><h3>' + sName + '</h3>';
+		if(subSettings != null){
+			for (var ii = 0; ii < subSettings.children.length; ii++){
+				var s = subSettings.children[ii];
+				var info = tt.parse(s.getAttribute('tt'));
+				s.removeAttribute('tt');
+				section += '<div class="setting">' +
+					s.outerHTML +
+					((info != null && info.length > 0) ? '<p class="s_desc">' + info + '</p>' : '') +
+					'</div>';
+			}
+			subSettings.innerHTML = '';
+		}
+		section += '</div>'
+		ebi('s_list').innerHTML += section;
+		ebi('s_nav').innerHTML += '<a href="#' + sId + '" class="btn ' + sections[i].classList +'">' + sName + '</a>\n';
+	}
+
+	ebi('h_cfg').onclick = function(){
+		ebi('s_list').scrollTop =
+		ebi('s_hor').scrollTop =
+		ebi('s_nav').scrollTop =
+		ebi('s_content').scrollTop =
+			0;
+	}
+
+	ebi('cl_cfg').onclick =
+	ebi('s_outside').onclick =
+	function () {
+			hist_push('#')
+			modaltoggle('cfg');
+		}
+})();
+
+// accent color
+function parseColor (strColor) {
+	var s = new Option().style;
+	s.color = strColor;
+	return s.color !== '' ? s.color : '';
+}
+function setColor (color) {
+	accent = color;
+	swrite('accent', accent);
+	var a = accent || '';
+	console.log('accent color set to: ' + a);
+	document.documentElement.style.setProperty('--a', a);
+	pbar.drawbuf();
+	pbar.drawpos();
+	vbar.draw();
+}
+ebi('accent').oninput = ebi('accent_picker').oninput = function () {
+	var validcolor = parseColor(this.value);
+	console.log(this.value);
+
+	if(this == ebi('accent')){
+		ebi('accent_picker').value = this.value;
+	}
+	else if(this == ebi('accent_picker')){
+		if(this.value == '#000000')
+			return; // firefox submits the color picker value on browser startup
+		ebi('accent').value = this.value;
+	}
+
+	clmod(ebi('accent'), 'invalid', this.value.length != 0 && validcolor.length == 0);
+	if(validcolor == accent)
+		return;
+
+	setTimeout(function(){
+		setColor(validcolor);
+	}, 100);
+}
+var accent = sread('accent');
+if(accent && accent.length > 3){
+	console.log('read accent color from settings: ' + accent);
+	document.documentElement.style.setProperty('--a', parseColor(accent));
+	ebi('accent').value = ebi('accent_picker').value = accent;
+}
+
+// corner radius
+ebi('radius').oninput = function () {
+	var r = parseFloat(this.value);
+
+	clmod(ebi('radius'), 'invalid', this.value.length != 0 && r.length == 0);
+	if(r === radius)
+		return;
+
+	if(isNaN(r))
+		r = ''
+	swrite('radius', r);
+	var setV = this.value == '' ? '' : (r + 'px');
+	document.documentElement.style.setProperty('--radius', setV);
+	console.log(setV);
+}
+var radius = sread('radius');
+if(radius){
+	console.log('read radius from settings: ' + radius);
+	document.documentElement.style.setProperty('--radius', parseFloat(radius) + 'px');
+	ebi('radius').value = radius;
+}
+
+
+// no fun allowed
+bcfg_bind(this, 'fun_tgl', 'fun_tgl');
 
 // navpane
-ebi('tree').innerHTML = (
-	'<div id="treeh">\n' +
-	'	<a href="#" id="detree" tt="' + L.tt_detree + '">🍞...</a>\n' +
-	'	<a href="#" class="btn" step="2" id="twobytwo" tt="Hotkey: D">+</a>\n' +
-	'	<a href="#" class="btn" step="-2" id="twig" tt="Hotkey: A">&ndash;</a>\n' +
-	'	<a href="#" class="btn" id="visdir" tt="' + L.tt_visdir + '">🎯</a>\n' +
-	'	<a href="#" class="tgl btn" id="filetree" tt="' + L.tt_ftree + '">📃</a>\n' +
-	'	<a href="#" class="tgl btn" id="parpane" tt="' + L.tt_pdock + '">📌</a>\n' +
-	'	<a href="#" class="tgl btn" id="dyntree" tt="' + L.tt_dynt + '">a</a>\n' +
-	'	<a href="#" class="tgl btn" id="wraptree" tt="' + L.tt_wrap + '">↵</a>\n' +
-	'	<a href="#" class="tgl btn" id="hovertree" tt="' + L.tt_hover + '">👀</a>\n' +
-	'</div>\n' +
-	'<ul id="docul"></ul>\n' +
-	'<ul class="ntree" id="treepar"></ul>\n' +
-	'<ul class="ntree" id="treeul"></ul>\n' +
-	'<div id="thx_ff">&nbsp;</div>'
+ebi('treeh').innerHTML += (
+	'<a href="#" class="btn" step="-2" id="twig" tt="Hotkey: A">&ndash;</a>\n' +
+	'<a href="#" class="btn" step="2" id="twobytwo" tt="Hotkey: D">+</a>\n' +
+	'<a href="#" class="btn" id="visdir" tt="' + L.tt_visdir + '">🎯</a>\n' +
+	'<a href="#" class="tgl btn" id="filetree" tt="' + L.tt_ftree + '">📃</a>\n' +
+	'<a href="#" class="tgl btn" id="parpane" tt="' + L.tt_pdock + '">📌</a>\n' +
+	'<a href="#" class="tgl btn" id="dyntree" tt="' + L.tt_dynt + '">a</a>\n' +
+	'<a href="#" class="tgl btn" id="wraptree" tt="' + L.tt_wrap + '">↵</a>\n' +
+	'<a href="#" class="tgl btn" id="hovertree" tt="' + L.tt_hover + '">👀</a>\n'
 );
-clmod(ebi('tree'), 'sbar', 1);
-ebi('entree').setAttribute('tt', L.tt_entree);
-ebi('goh').textContent = L.goh;
 QS('#op_mkdir input[type="submit"]').value = L.ab_mkdir;
 QS('#op_new_md input[type="submit"]').value = L.ab_mkdoc;
 QS('#op_msg input[type="submit"]').value = L.ab_msg;
@@ -1139,15 +1530,53 @@ ebi('rcm').innerHTML = (
 		if (v)
 			ops[a].href = '#v=' + v;
 	}
+
+	ebi('opa_acc').appendChild(ebi('op_acc'));
+	ebi('op_acc').onclick = function (e){
+		e.stopPropagation();
+	};
 })();
 
+// fallback in case href change method somehow doesn't work
+var closebtns = QSA('.close');
+for(var a = 0; a < closebtns.length; a++){
+	closebtns[a].onclick = function(){
+		var modal = QS('.modal.vis');
+		if(modal)
+			modaltoggle(modal.id, false);
+	}
+}
+
+function modaltoggle(dest, show){
+	if(show == null)
+		show = 't';
+	if (show == false || show == 't' && QS('#' + dest + '.vis'))
+		dest = '';
+
+	var layoutchange = dest == 'music' || QS('#music.vis');
+
+	swrite('opmode', dest || null);
+
+	goto(dest);
+
+	var input = QS('.opview.act input:not([type="hidden"])')
+	if (input && !TOUCH) {
+		tt.skip = true;
+		input.focus();
+	}
 
+	if(layoutchange) {
+		onwidgetresize();
+		mpl.set_mu_cv();
+	}
+}
 function opclick(e) {
 	var dest = this.getAttribute('data-dest');
 	if (QS('#op_' + dest + '.act'))
 		dest = '';
 
-	swrite('opmode', dest || null);
+	if(dest != 'acc')
+		swrite('opmode', dest || null);
 	if (ctrl(e))
 		return;
 
@@ -1155,6 +1584,8 @@ function opclick(e) {
 	goto(dest);
 
 	var input = QS('.opview.act input:not([type="hidden"])')
+	if(dest == 'search')
+		input = ebi('folder_search');
 	if (input && !TOUCH) {
 		tt.skip = true;
 		input.focus();
@@ -1171,9 +1602,13 @@ function goto(dest) {
 	for (var a = obj.length - 1; a >= 0; a--)
 		clmod(obj[a], 'act');
 
+	obj = QSA('.modal');
+	for (var a = obj.length - 1; a >= 0; a--)
+		clmod(obj[a], 'vis');
+
 	if (dest) {
 		var lnk = QS('#ops>a[data-dest=' + dest + ']'),
-			nps = lnk.getAttribute('data-perm');
+			nps = lnk && lnk.getAttribute('data-perm');
 
 		nps = nps && nps.length ? nps.split(' ') : [];
 
@@ -1185,21 +1620,79 @@ function goto(dest) {
 		if (!has(perms, 'read') && !has(perms, 'write') && (dest == 'up2k'))
 			return;
 
-		clmod(ebi('op_' + dest), 'act', 1);
+		var modal = ebi(dest);
+		if(modal != null){
+			clmod(modal, 'vis', true);
+			if(location.hash.length <= 1)
+				location.hash = '#h_' + dest;
+		}
+
+		var opd = ebi('op_' + dest);
+		var page = opd != null ? opd : QS('#' + dest + ' .opview')
+		if(page != null)
+			clmod(page, 'act', 1);
 		clmod(lnk, 'act', 1);
 
+		if(dest == 'bup'){
+			clmod(ebi('up2k'), 'vis', true);
+			location.hash = '#h_bup';
+		}
+		if(dest == 'bup' || dest == 'up2k')
+			ebi('bup_tgl').open = dest == 'bup';
+
 		var fn = window['goto_' + dest];
 		if (fn)
 			fn();
 	}
+	else{
+		if(location.hash.startsWith('#h_'))
+			location.hash = '#';
+	}
+
+	ebi('srchfolder_div').style.display = dest == 'search' ? 'block' : 'none';
 
 	clmod(document.documentElement, 'op_open', dest);
+	// enables the use of keyboard page nav on modals
+	var a_modal = QS('.modal.vis');
+	clmod(document.documentElement, 'noscroll', a_modal && window.getComputedStyle(a_modal).position == 'fixed');
 
 	if (treectl)
 		treectl.onscroll();
 }
 
 
+window.onhashchange = function() {
+	console.log('hash change: ' + location.hash)
+	var a_modal = QS('.modal.vis');
+	if(location.hash.length <= 1 && a_modal){
+		modaltoggle(a_modal.id);
+		console.log('closing modal due to hash');
+	}
+	if(a_modal && location.hash == '#h_' + a_modal.id){
+		if(a_modal.style.position != 'fixed')
+			return;
+		var m_header = QS('.modal.vis .modalheader');
+		if(m_header){
+			m_header.click();
+			console.log('going to top of modal');
+		}
+	}
+  	else if (location.hash.startsWith("#h_")){
+		var header = ebi(location.hash.slice(1));
+		if(!header)
+			return;
+		var p_modal = header.closest('.modal');
+		if(!p_modal)
+			return;
+		if(!clgot(p_modal, 'vis')){
+			console.log('forcing modal open due to subheader hash');
+			modaltoggle(p_modal.id, true);
+		}
+		ebi(location.hash.slice(1)).scrollIntoView();
+	}
+}
+
+
 var m = SPINNER.split(','),
 	SPINNER_CSS = SPINNER.slice(1 + m[0].length);
 SPINNER = m[0];
@@ -1240,8 +1733,8 @@ check_image_support('jxl', "data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgA=");
 
 
 var img_re = APPLE ?
-	/\.(a?png|avif|bmp|gif|hei[cf]s?|jpe?g|jfif|svg|webp|webm|mkv|mp4|m4v|mov)(\?|$)/i :
-	/\.(a?png|avif|bmp|gif|jpe?g|jfif|svg|webp|webm|mkv|mp4|m4v|mov)(\?|$)/i;
+	/\.(a?png|avif|bmp|gif|hei[cf]s?|jpe?g|jxl|jfif|svg|ico|webp|webm|mkv|mp4|m4v|mov)(\?|$)/i :
+	/\.(a?png|avif|bmp|gif|jpe?g|jxl|jfif|svg|ico|webp|webm|mkv|mp4|m4v|mov)(\?|$)/i;
 
 
 function set_files_html(html) {
@@ -1340,61 +1833,6 @@ ebi('hsortn').oninput = function (e) {
 var mpl = (function () {
 	var have_mctl = 'mediaSession' in navigator && window.MediaMetadata;
 
-	ebi('op_player').innerHTML = (
-		'<div><h3>' + L.cl_opts + '</h3><div>' +
-		'<a href="#" class="tgl btn" id="au_loop" tt="' + L.mt_loop + '</a>' +
-		'<a href="#" class="tgl btn" id="au_one" tt="' + L.mt_one + '</a>' +
-		'<a href="#" class="tgl btn" id="au_shuf" tt="' + L.mt_shuf + '</a>' +
-		'<a href="#" class="tgl btn" id="au_aplay" tt="' + L.mt_aplay + '</a>' +
-		'<a href="#" class="tgl btn" id="au_preload" tt="' + L.mt_preload + '</a>' +
-		'<a href="#" class="tgl btn" id="au_prescan" tt="' + L.mt_prescan + '</a>' +
-		'<a href="#" class="tgl btn" id="au_fullpre" tt="' + L.mt_fullpre + '</a>' +
-		'<a href="#" class="tgl btn" id="au_fau" tt="' + L.mt_fau + '</a>' +
-		'<a href="#" class="tgl btn" id="au_waves" tt="' + L.mt_waves + '</a>' +
-		'<a href="#" class="tgl btn" id="au_npclip" tt="' + L.mt_npclip + '</a>' +
-		'<a href="#" class="tgl btn" id="au_m3u_c" tt="' + L.mt_m3u_c + '</a>' +
-		'<a href="#" class="tgl btn" id="au_os_ctl" tt="' + L.mt_octl + '</a>' +
-		'<a href="#" class="tgl btn" id="au_os_seek" tt="' + L.mt_oseek + '</a>' +
-		'<a href="#" class="tgl btn" id="au_osd_cv" tt="' + L.mt_oscv + '</a>' +
-		'<a href="#" class="tgl btn" id="au_follow" tt="' + L.mt_follow + '</a>' +
-		'<a href="#" class="tgl btn" id="au_compact" tt="' + L.mt_compact + '</a>' +
-		'</div></div>' +
-
-		'<div><h3>' + L.ml_btns + '</h3><div>' +
-		'<a href="#" class="btn" id="au_uncache" tt="' + L.mt_uncache + '</a>' +
-		'</div></div>' +
-
-		'<div><h3>' + L.ml_pmode + '</h3><div id="pb_mode">' +
-		'<a href="#" class="tgl btn" m="loop" tt="' + L.mt_mloop + '</a>' +
-		'<a href="#" class="tgl btn" m="next" tt="' + L.mt_mnext + '</a>' +
-		'<a href="#" class="tgl btn" m="stop" tt="' + L.mt_mstop + '</a>' +
-		'</div></div>' +
-
-		(have_acode ? (
-			'<div><h3>' + L.ml_tcode + '</h3><div>' +
-			'<a href="#" id="ac_flac" class="tgl btn" tt="' + L.mt_cflac + '</a>' +
-			'<a href="#" id="ac_aac" class="tgl btn" tt="' + L.mt_caac + '</a>' +
-			'<a href="#" id="ac_oth" class="tgl btn" tt="' + L.mt_coth + '</a>' +
-			'</div></div>' +
-			'<div><h3>' + L.ml_tcode2 + '</h3><div>' +
-			'<a href="#" id="ac2opus" class="tgl btn" tt="' + L.mt_c2opus + '</a>' +
-			'<a href="#" id="ac2owa" class="tgl btn" tt="' + L.mt_c2owa + '</a>' +
-			'<a href="#" id="ac2caf" class="tgl btn" tt="' + L.mt_c2caf + '</a>' +
-			'<a href="#" id="ac2mp3" class="tgl btn" tt="' + L.mt_c2mp3 + '</a>' +
-			'<a href="#" id="ac2flac" class="tgl btn" tt="' + L.mt_c2flac + '</a>' +
-			'<a href="#" id="ac2wav" class="tgl btn" tt="' + L.mt_c2wav + '</a>' +
-			'</div></div>'
-		) : '') +
-
-		'<div><h3>' + L.ml_tint + '</h3><div>' +
-		'<input type="text" id="pb_tint" value="0" ' + NOAC + ' style="width:2.4em" tt="' + L.mt_tint + '" />' +
-		'</div></div>' +
-
-		'<div><h3 id="h_drc">' + L.ml_drc + '</h3><div id="audio_drc"></div></div>' +
-		'<div><h3>' + L.ml_eq + '</h3><div id="audio_eq"></div></div>' +
-		'<div><h3>' + L.ml_ss + '</h3><div id="audio_ss"></div></div>' +
-		'');
-
 	var r = {
 		"pb_mode": (sread('pb_mode', ['loop', 'next', 'stop']) || 'next').split('-')[0],
 		"os_ctl": bcfg_get('au_os_ctl', have_mctl) && have_mctl,
@@ -1414,6 +1852,7 @@ var mpl = (function () {
 		mp.read_order();  // don't bind
 	});
 	bcfg_bind(r, 'aplay', 'au_aplay', true);
+	bcfg_bind(r, 'afade', 'au_afade', true);
 	bcfg_bind(r, 'preload', 'au_preload', true);
 	bcfg_bind(r, 'prescan', 'au_prescan', true);
 	bcfg_bind(r, 'fullpre', 'au_fullpre', false);
@@ -1428,7 +1867,26 @@ var mpl = (function () {
 	});
 	bcfg_bind(r, 'waves', 'au_waves', true, function (v) {
 		if (!v) pbar.unwave();
+		r.selectprogbar();
 	});
+	r.selectprogbar = function(){
+		if (r.waves){
+			clmod(ebi('progbar'), 'vis', true)
+			clmod(ebi('altprogbar'), 'vis', false)
+			if(pbar){
+				pbar.unwave();
+				if (mpl.waves && mp && mp.au)
+					pbar.loadwaves(mp.au.src.replace(/\bth=(opus|mp3)&/, '') + '&th=p');
+				pbar.onresize();
+			}
+		}
+		else{
+			clmod(ebi('progbar'), 'vis', false)
+			clmod(ebi('altprogbar'), 'vis', true)
+		}
+	}
+	r.selectprogbar();
+
 	bcfg_bind(r, 'os_seek', 'au_os_seek', !IPHONE, announce);
 	bcfg_bind(r, 'osd_cv', 'au_osd_cv', true, announce);
 	bcfg_bind(r, 'clip', 'au_npclip', false, function (v) {
@@ -1481,12 +1939,48 @@ var mpl = (function () {
 		draw_pb_mode();
 	}
 
+	ebi('cyclebtn_loopmode').onclick = function(){
+		if(r.pb_mode == 'loop'){
+			// #3: folder loop was set, switch to none / next folder
+			r.pb_mode = 'next';
+		}
+		else if(clgot(ebi('au_loop'), 'on')) {
+			// #2: single loop was set, switch to folder loop
+			ebi('au_loop').click();
+			r.pb_mode = 'loop';
+		}
+		else {
+			// #1: no loop set, click single loop btn
+			ebi('au_loop').click();
+		}
+		swrite('pb_mode', r.pb_mode);
+		draw_pb_mode();
+		drawLoopStatus();
+	}
+
+	function drawLoopStatus(){
+		var btn = ebi('cyclebtn_loopmode');
+		if(r.pb_mode == 'loop'){
+			btn.innerHTML = '🔁';
+			clmod(btn, 'on', true);
+		}
+		else if(clgot(ebi('au_loop'), 'on')) {
+			btn.innerHTML = '🔂';
+			clmod(btn, 'on', true);
+		}
+		else {
+			btn.innerHTML = '🔁';
+			clmod(btn, 'on', false);
+		}
+	}
+	drawLoopStatus();
+
 	function set_tint() {
 		var tint = icfg_get('pb_tint', 0);
 		if (!tint)
 			ebi('barbuf').style.removeProperty('background');
 		else
-			ebi('barbuf').style.background = 'rgba(126,163,75,' + (tint / 100.0) + ')';
+			ebi('barbuf').style.background = 'rgba(126,126,126,' + (tint / 100.0) + ')';
 	}
 	ebi('pb_tint').oninput = function (e) {
 		swrite('pb_tint', this.value);
@@ -1553,9 +2047,9 @@ var mpl = (function () {
 			btns.push(btn);
 		}
 		if (!IPHONE)
-			btns[1].style.display = btns[2].style.display = 'none';
-		btns[4].style.display = have_c2flac ? '' : 'none';
-		btns[5].style.display = have_c2wav ? '' : 'none';
+			btns[1].parentElement.style.display = btns[2].parentElement.style.display = 'none';
+		btns[4].parentElement.style.display = have_c2flac ? '' : 'none';
+		btns[5].parentElement.style.display = have_c2wav ? '' : 'none';
 
 		if (v)
 			swrite('acode2', v);
@@ -1567,9 +2061,9 @@ var mpl = (function () {
 			clmod(btns[a], 'on', fmts[a] == v)
 
 		r.ac2 = v;
-		ebi('ac_flac').setAttribute('tt', L.mt_cflac.split('"')[0].format(v));
-		ebi('ac_aac').setAttribute('tt', L.mt_caac.split('"')[0].format(v));
-		ebi('ac_oth').setAttribute('tt', L.mt_coth.split('"')[0].format(v));
+		ebi('ac_flac').nextSibling.innerHTML = L.mt_cflac.split('"')[0].format(v);
+		ebi('ac_aac').nextSibling.innerHTML = L.mt_caac.split('"')[0].format(v);
+		ebi('ac_oth').nextSibling.innerHTML = L.mt_coth.split('"')[0].format(v);
 	};
 
 	r.pp = function () {
@@ -1593,6 +2087,20 @@ var mpl = (function () {
 	}
 	setaufollow();
 
+	r.set_mu_cv = function() {
+		var o = QS('#music.vis #mu_th>img');
+		if (o) {
+			var url = r.cover.slice(0, -1) + 'wf3';
+
+			set_loaded(o, false);
+			o.setAttribute('src', url);
+
+			o = QS('html.b #music');
+			if (o)
+				o.style.background = "url('" + url + "') no-repeat center / cover";
+		}
+	}
+
 	function announce() {
 		if (!r.os_ctl || !mp.au)
 			return;
@@ -1624,13 +2132,14 @@ var mpl = (function () {
 			cover = addq(cover || mp.au.osrc, 'th=j');
 			tags.artwork = [{ "src": cover, type: "image/jpeg" }];
 		}
+		r.cover = cover;
 
 		ebi('np_circle').textContent = np.circle || '';
 		ebi('np_album').textContent = np.album || '';
 		ebi('np_tn').textContent = np['.tn'] || '';
 		ebi('np_artist').textContent = np.artist || (fns.length > 1 ? fns[0] : '');
 		ebi('np_title').textContent = np.title || '';
-		ebi('np_dur').textContent = np['.dur'] || '';
+		ebi('txtsongend').innerHTML = ebi('np_dur').textContent = np['.dur'] || '';
 		ebi('np_url').textContent = uricom_dec(get_evpath()) + np.file.split('?')[0];
 		if (!MOBILE && cover)
 			ebi('np_img').setAttribute('src', cover);
@@ -1645,6 +2154,7 @@ var mpl = (function () {
 		navigator.mediaSession.setActionHandler('previoustrack', prev_song);
 		navigator.mediaSession.setActionHandler('nexttrack', next_song);
 		r.pp();
+		r.set_mu_cv();
 	}
 	r.announce = announce;
 
@@ -1783,7 +2293,7 @@ function MPlayer() {
 				continue;
 
 			tid = tid.slice(1);
-			if (r.tracks[tid]) 
+			if (r.tracks[tid])
 				order.push(tid);
 		}
 		r.order = order;
@@ -1803,7 +2313,14 @@ function MPlayer() {
 			r.ftid = r.au.tid;
 			r.au.play();
 			mpl.pp();
-			fader();
+			if(mpl.afade != false)
+				fader();
+			else{
+				// insta start
+				r.fvol = r.vol;
+				mpss.go();
+				r.au.volume = r.expvol(r.fvol);
+			}
 		}
 	};
 	r.fade_out = function () {
@@ -1811,7 +2328,13 @@ function MPlayer() {
 		r.fvol = r.vol;
 		r.fdir = -0.05 * r.vol * (CHROME ? 2 : 1);
 		r.ftid = r.au.tid;
-		fader();
+		if(mpl.afade != false)
+			fader();
+		else {
+			// insta stop
+			r.au.pause();
+			mpl.pp();
+		}
 	};
 	r.stopfade = function (hard) {
 		clearTimeout(r.ftimer);
@@ -1971,7 +2494,6 @@ var widget = (function () {
 		if (r.is_open == is_open)
 			return false;
 
-		clmod(document.documentElement, 'np_open', is_open);
 		clmod(widget, 'open', is_open);
 		bcfg_set('au_open', r.is_open = is_open);
 		if (vbar) {
@@ -1988,11 +2510,17 @@ var widget = (function () {
 	r.paused = function (paused) {
 		if (was_paused != paused) {
 			was_paused = paused;
-			ebi('bplay').innerHTML = paused ? '▶' : '⏸';
+			ebi('bplay').innerHTML = ebi('bplay2').innerHTML = 
+				paused ? svg_play : svg_pause;
 		}
 	};
 	r.setvis = function () {
-		widget.style.display = !has(perms, "read") || showfile.abrt ? 'none' : '';
+		var display = !has(perms, "read") || showfile.abrt ? 'none' : '';
+		ebi('wtico').style.display =
+		ebi('wtoggle').style.display =
+		ebi('widgeti').style.display =
+		ebi('np_inf').style.display =
+			display;
 	};
 	wtico.onclick = function (e) {
 		if (!touchmode)
@@ -2085,13 +2613,25 @@ function canvas_cfg(can) {
 	return r;
 }
 
-
-function glossy_grad(can, h, s, l) {
+function auto_grad(can, color, color2) {
+	if(color2 == null)
+		color2 = '#000';
 	var g = can.ctx.createLinearGradient(0, 0, 0, can.h),
-		p = [0, 0.49, 0.50, 1];
-
-	for (var a = 0; a < p.length; a++)
-		g.addColorStop(p[a], 'hsl(' + h + ',' + s[a] + '%,' + l[a] + '%)');
+		p = [0, 0.49, 0.50, 1],
+		mix = [70, 100, 90, 70];
+
+	for (var a = 0; a < p.length; a++){
+		var c = 'color-mix(in oklab, ' + color + ' ' + mix[a] + '%, ' + color2 + ' ' + (100 - mix[a]) + '%)';
+		var pc = parseColor(c);
+        if (pc) {
+            try {
+				g.addColorStop(p[a], pc);
+            } catch (e) {
+				console.log(e);
+				g.addColorStop(p[a], color2);
+			}
+		}
+	}
 
 	return g;
 }
@@ -2116,7 +2656,7 @@ var pbar = (function () {
 		r.pos = canvas_cfg(ebi('barpos'));
 		r.buf.ctx.font = '.5em sans-serif';
 		r.pos.ctx.font = '.9em sans-serif';
-		r.pos.ctx.strokeStyle = 'rgba(24,56,0,0.5)';
+		r.pos.ctx.strokeStyle = 'rgba(40, 40, 40, 0.5)';
 		r.drawbuf();
 		r.drawpos();
 		if (!r.pos.can.onmouseleave)
@@ -2173,7 +2713,7 @@ var pbar = (function () {
 			bctx = bc.ctx,
 			apos, adur;
 
-		if (!widget.is_open)
+		if (!widget.is_open || mpl.waves == false)
 			return;
 
 		bctx.clearRect(0, 0, bc.w, bc.h);
@@ -2183,17 +2723,19 @@ var pbar = (function () {
 
 		bau = mp.au;
 
+		var accent = getComputedStyle(document.body).getPropertyValue('--a');
+
 		var sm = bc.w * 1.0 / mp.au.duration,
-			gk = bc.h + '/' + themen,
+			gk = bc.h + '/' + themen + '/' + accent,
 			dz = themen == 'dz',
 			dy = themen == 'dy';
 
 		if (gradh != gk) {
 			gradh = gk;
-			grad = glossy_grad(bc, dz ? 120 : 85,
-				dy ? [0, 0, 0, 0] : [35, 40, 37, 35],
-				dy ? [20, 24, 22, 20] : light ? [45, 56, 50, 45] : [42, 51, 47, 42]);
+			grad = auto_grad(bc, accent);
 		}
+		if(IE)
+			grad = 'rgb(85, 144, 255)';
 		bctx.fillStyle = grad;
 		for (var a = 0; a < mp.au.buffered.length; a++) {
 			var x1 = sm * mp.au.buffered.start(a),
@@ -2210,20 +2752,21 @@ var pbar = (function () {
 		}
 
 		var step = sm > 1 ? 1 : sm > 0.4 ? 3 : sm > 0.05 ? 30 : 720;
-		bctx.fillStyle = light && !dy ? 'rgba(0,64,0,0.15)' : 'rgba(204,255,128,0.15)';
-		for (var p = step, mins = adur / 10; p <= mins; p += step)
-			bctx.fillRect(Math.floor(sm * p * 10), 0, 2, pc.h);
 
-		step = sm > 0.15 ? 1 : sm > 0.05 ? 10 : 360;
-		bctx.fillStyle = light && !dy ? 'rgba(0,64,0,0.5)' : 'rgba(192,255,96,0.5)';
-		for (var p = step, mins = adur / 60; p <= mins; p += step)
-			bctx.fillRect(Math.floor(sm * p * 60), 0, 2, pc.h);
+		//bctx.fillStyle = light && !dy ? 'rgba(0,0,0,0.15)' : 'rgba(255, 255, 255, 0.15)';
+		//for (var p = step, mins = adur / 10; p <= mins; p += step)
+		//	bctx.fillRect(Math.floor(sm * p * 10), 0, 2, pc.h);
 
-		step = sm > 0.33 ? 1 : sm > 0.15 ? 5 : sm > 0.05 ? 10 : sm > 0.01 ? 60 : 720;
-		bctx.fillStyle = dz ? '#0f0' : dy ? '#999' : light ? 'rgba(0,64,0,0.9)' : 'rgba(192,255,96,1)';
-		for (var p = step, mins = adur / 60; p <= mins; p += step) {
-			bctx.fillText(p, Math.floor(sm * p * 60 + 3), pc.h / 3);
-		}
+		//step = sm > 0.15 ? 1 : sm > 0.05 ? 10 : 360;
+		//bctx.fillStyle = light && !dy ? 'rgba(0, 0, 0, 0.5)' : 'rgba(255, 255, 255, 0.5)';
+		//for (var p = step, mins = adur / 60; p <= mins; p += step)
+		//	bctx.fillRect(Math.floor(sm * p * 60), 0, 2, pc.h);
+
+		//step = sm > 0.33 ? 1 : sm > 0.15 ? 5 : sm > 0.05 ? 10 : sm > 0.01 ? 60 : 720;
+		//bctx.fillStyle = dz ? '#0f0' : dy ? '#999' : light ? 'rgba(0, 0, 0, 0.9)' : 'rgb(255, 255, 255)';
+		//for (var p = step, mins = adur / 60; p <= mins; p += step) {
+		//	bctx.fillText(p, Math.floor(sm * p * 60 + 3), pc.h / 3);
+		//}
 
 		step = sm > 0.2 ? 10 : sm > 0.1 ? 30 : sm > 0.01 ? 60 : sm > 0.005 ? 720 : 1440;
 		bctx.fillStyle = light ? 'rgba(0,0,0,1)' : 'rgba(255,255,255,1)';
@@ -2231,11 +2774,11 @@ var pbar = (function () {
 			bctx.fillRect(Math.floor(sm * p * 60), 0, 2, pc.h);
 	};
 
-	r.drawpos = function () {
+	r.drawpos = function (force) {
 		var bc = r.buf,
 			pc = r.pos,
 			pctx = pc.ctx,
-			w = 8,
+			w = 2,
 			apos, adur;
 
 		if (t_redraw) {
@@ -2273,8 +2816,12 @@ var pbar = (function () {
 			t2 = s2ms(apos),
 			x = sm * apos;
 
+		if(adur > 0)
+			ebi('sliderpos').value = apos / adur;
+
 		if (w && html_txt != t2) {
-			ebi('np_pos').textContent = html_txt = t2;
+			ebi('txtpos').innerHTML = ebi('np_pos').textContent = html_txt = t2;
+			ebi('txtsongend').innerHTML = t1;
 			if (mpl.os_ctl)
 				navigator.mediaSession.setPositionState({
 					'duration': adur,
@@ -2283,11 +2830,11 @@ var pbar = (function () {
 				});
 		}
 
-		if (!widget.is_open)
+		if (!widget.is_open || mpl.waves == false && !force)
 			return;
 
-		pctx.fillStyle = '#573'; pctx.fillRect((x - w / 2) - 1, 0, w + 2, pc.h);
-		pctx.fillStyle = '#dfc'; pctx.fillRect((x - w / 2), 0, w, pc.h);
+		pctx.fillStyle = '#bbb'; pctx.fillRect((x - w / 2) - 1, 0, w + 2, pc.h);
+		pctx.fillStyle = '#fff'; pctx.fillRect((x - w / 2), 0, w, pc.h);
 
 		pctx.lineWidth = 2.5;
 		pctx.fillStyle = '#fff';
@@ -2295,7 +2842,7 @@ var pbar = (function () {
 		var m1 = pctx.measureText(t1),
 			m1b = pctx.measureText(t1 + ":88"),
 			m2 = pctx.measureText(t2),
-			yt = pc.h * 0.94,
+			yt = pc.h * 0.65,
 			xt1 = pc.w - (m1.width + 12),
 			xt2 = x < m1.width * 1.4 ? (x + 12) : (Math.min(pc.w - m1b.width, x - 12) - m2.width);
 
@@ -2321,10 +2868,10 @@ var vbar = (function () {
 		gradh = -1,
 		lastv = -1,
 		untext = -1,
-		can, ctx, w, h, grad1, grad2;
+		can, ctx, w, h, style1, style2;
 
 	r.onresize = function () {
-		if (!widget.is_open && r.can)
+		if (!widget.is_open && r.can )
 			return;
 
 		r.can = canvas_cfg(ebi('pvol'));
@@ -2334,41 +2881,44 @@ var vbar = (function () {
 		ctx.fontVariantCaps = 'small-caps';
 		w = r.can.w;
 		h = r.can.h;
-		r.draw();
+		setTimeout(r.draw, 1);
 	}
 
 	r.draw = function () {
 		if (!mp)
 			return;
 
-		var gh = h + '' + light,
+		var accent = getComputedStyle(document.body).getPropertyValue('--a');
+		var bg = getComputedStyle(document.body).getPropertyValue('--bg-u2');
+
+		var gh = h + '' + light  + '/' + accent,
 			dz = themen == 'dz',
 			dy = themen == 'dy';
 
 		if (gradh != gh) {
 			gradh = gh;
-			grad1 = glossy_grad(r.can, dz ? 120 : 50,
-				dy ? [0, 0, 0, 0] : light ? [50, 55, 52, 48] : [45, 52, 47, 43],
-				dy ? [20, 24, 22, 20] : light ? [54, 60, 52, 47] : [42, 51, 47, 42]);
-			grad2 = glossy_grad(r.can, dz ? 120 : 205,
-				dz ? [100, 100, 100, 100] : dy ? [0, 0, 0, 0] : [10, 15, 13, 10],
-				dz ? [10, 14, 12, 10] : dy ? [90, 90, 90, 90] : [16, 20, 18, 16]);
+			style1 = auto_grad(r.can, accent, accent);
+			style2 = light ? 'color-mix(in oklab, ' + bg + ' 85%, #000 15%' : 'color-mix(in oklab, ' + bg + ' 85%, #fff 15%';
 		}
-		ctx.fillStyle = grad2; ctx.fillRect(0, 0, w, h);
-		ctx.fillStyle = grad1; ctx.fillRect(0, 0, w * mp.vol, h);
+		if(IE){
+			style1 = 'rgb(85, 144, 255)';
+			style2 = 'rgb(174, 193, 214)'
+		}
+		ctx.fillStyle = style2; ctx.fillRect(0, 0, w, h);
+		ctx.fillStyle = style1; ctx.fillRect(0, 0, w * mp.vol, h);
 
-		var vt = 'volume ' + Math.floor(mp.vol * 100),
-			tw = ctx.measureText(vt).width,
-			x = w * mp.vol - tw - 8,
-			li = dy;
+		// var vt = Math.floor(mp.vol * 100) + '%',
+		// 	tw = ctx.measureText(vt).width,
+		// 	x = w * mp.vol - tw - 8,
+		// 	li = dy;
 
-		if (mp.vol < 0.5) {
-			x += tw + 16;
-			li = !li;
-		}
+		// if (mp.vol < 0.5) {
+		// 	x += tw + 16;
+		// 	li = !li;
+		// }
 
-		ctx.fillStyle = li ? '#fff' : '#210';
-		ctx.fillText(vt, x, h / 3 * 2);
+		// ctx.fillStyle = li ? '#fff' : '#210';
+		// ctx.fillText(vt, x, h / 3 * 2);
 
 		clearTimeout(untext);
 		untext = setTimeout(r.draw, 1000);
@@ -2376,8 +2926,15 @@ var vbar = (function () {
 	onresize100.add(r.onresize, true);
 
 	var rect;
+	var cs;
+	var left, top, width, height;
 	function mousedown(e) {
 		rect = can.getBoundingClientRect();
+		cs = getComputedStyle(ebi('pvol'));
+		top = rect.top + parseFloat(cs.borderTopWidth);
+		left = rect.left + parseFloat(cs.borderLeftWidth);
+		height = rect.height - 2 * parseFloat(cs.borderTopWidth);
+		width = rect.width - 2 * parseFloat(cs.borderLeftWidth);
 		mousemove(e);
 	}
 	function mousemove(e) {
@@ -2389,8 +2946,14 @@ var vbar = (function () {
 			return;
 		}
 
-		var x = e.clientX - rect.left,
-			mul = x * 1.0 / rect.width;
+		var x = e.clientX - left,
+			mul = x * 1.0 / width;
+
+		if(height > width) {
+			// vertical
+			var y = e.clientY - top;
+			mul = 1 - y * 1.0 / height;
+		}
 
 		if (mul > 0.98)
 			mul = 1;
@@ -2404,20 +2967,32 @@ var vbar = (function () {
 				toast.inf(6, 'volume doesnt work because <a href="https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW11" target="_blank">apple says no</a>');
 		}, 1);
 	}
-	can.onmousedown = function (e) {
+	ebi('pvolbg').onmousedown = can.onmousedown = function (e) {
 		if (e.button !== 0)
 			return;
 
-		can.onmousemove = mousemove;
+		ebi('pvolbg').onmousemove = can.onmousemove = mousemove;
 		mousedown(e);
 	};
-	can.onmouseup = function (e) {
+	ebi('pvolbg').onmouseup = can.onmouseup = function (e) {
 		if (e.button === 0)
-			can.onmousemove = null;
+			ebi('pvolbg').onmousemove = can.onmousemove = null;
 	};
 	if (TOUCH) {
-		can.ontouchstart = mousedown;
-		can.ontouchmove = mousemove;
+		ebi('pvolbg').ontouchstart = can.ontouchstart = mousedown;
+		ebi('pvolbg').ontouchmove = can.ontouchmove = mousemove;
+	}
+	var mute = ebi('pvolbg').children[0];
+	mute.onclick = function (e) {
+		ev(e);
+		if(mp.vol > 0)
+			mp.setvol(0);
+		else
+			mp.setvol(1);
+		r.draw();
+	}
+	mute.onmousedown = function (e) {
+		ev(e);
 	}
 	return r;
 })();
@@ -2573,9 +3148,9 @@ function mpause(e) {
 
 // hook up the widget buttons
 (function () {
-	ebi('bplay').onclick = playpause;
-	ebi('bprev').onclick = prev_song;
-	ebi('bnext').onclick = next_song;
+	ebi('bplay').onclick = ebi('bplay2').onclick = playpause;
+	ebi('bprev').onclick = ebi('bprev2').onclick = prev_song;
+	ebi('bnext').onclick = ebi('bnext2').onclick = next_song;
 
 	var bar = ebi('barpos');
 
@@ -2590,6 +3165,13 @@ function mpause(e) {
 
 		seek_au_mul(x * 1.0 / rect.width);
 	};
+	ebi('sliderpos').oninput = function(){
+		if (!mp.au) {
+			play(0, true);
+			return mp.fade_in();
+		}
+		seek_au_mul(this.value);
+	}
 
 	if (!TOUCH) {
 		bar.onwheel = function (e) {
@@ -2603,16 +3185,16 @@ function mpause(e) {
 			seek_au_rel(dist);
 			ev(e);
 		};
-		ebi('pvol').onwheel = function (e) {
+		ebi('pvolbg').onwheel = function (e) {
 			var dist = Math.sign(e.deltaY) * 10;
 			if (Math.abs(e.deltaY) < 30 && !e.deltaMode)
 				dist = e.deltaY;
 
-			if (!dist || !mp.au)
+			if (!dist)
 				return true;
 
 			dist *= -1;
-			mp.setvol(Math.round((mp.vol + dist / 500) * 100) / 100 );
+			mp.setvol(Math.round((mp.vol + dist / 250) * 100) / 100 );
 			vbar.draw();
 			ev(e);
 		};
@@ -2871,12 +3453,14 @@ var afilt = (function () {
 		swrite('au_eq_amp', r.amp);
 		swrite('au_eq_chw', r.chw);
 
-		var txt = QSA('input.eq_gain');
+		var gains = QSA('input.eq_gain');
 		for (var a = 0; a < r.bands.length; a++)
-			txt[a].value = r.gains[a];
+			gains[a + gains.length / 2].value = gains[a].value = r.gains[a].toFixed(1);
 
-		QS('input.eq_gain[band="amp"]').value = r.amp;
-		QS('input.eq_gain[band="chw"]').value = r.chw;
+		var amps = QSA('input.eq_gain[band="amp"]');
+		amps[0].value = amps[1].value = r.amp;
+		var chws = QSA('input.eq_gain[band="chw"]');
+		chws[0].value = chws[1].value = r.chw;
 	};
 
 	r.stop = function () {
@@ -3064,7 +3648,7 @@ var afilt = (function () {
 				vs = that.value,
 				v = parseFloat(vs);
 
-			if (!isNum(v) || v + '' != vs)
+			if (!isNum(v) || (v + '' != vs && v.toFixed(1) != vs))
 				throw new Error('inval band');
 
 			if (sb == 'amp')
@@ -3148,9 +3732,11 @@ var afilt = (function () {
 		ebi('h_drc').textContent = f2f(r.drcn.reduction, 1);
 	}
 
-	var html = ['<table><tr><td rowspan="4">',
-		'<a id="au_eq" class="tgl btn" href="#" tt="' + L.mt_eq + '">' + L.enable + '</a></td>'],
-		h2 = [], h3 = [], h4 = [];
+	ebi('audio_eq').innerHTML = '<a id="au_eq" class="tgl btn" href="#">' + L.enable +
+		'</a><p class="s_desc">' + tt.parse(L.mt_eq) + '</p><br/>';
+
+	var html = ['<table><tr>'],
+		h2 = [], h3 = [], h4 = [], h5 = [];
 
 	var vs = [];
 	for (var a = 0; a < r.bands.length; a++) {
@@ -3166,20 +3752,23 @@ var afilt = (function () {
 
 	for (var a = 0; a < vs.length; a++) {
 		var b = vs[a][0];
-		html.push('<td><a href="#" class="eq_step" step="0.5" band="' + b + '">+</a></td>');
-		h2.push('<td>' + vs[a][1] + '</td>');
+		html.push('<td>' + vs[a][1] + '</td>');
+		h2.push('<td><a href="#" class="eq_step" step="0.5" band="' + b + '">+</a></td>');
+		h3.push('<td><input class="eq_gain" type="range" min="-6" max="6" step="0.5" orient="vertical" band="' + b + '" value="' + vs[a][2] + '" /></td>');
 		h4.push('<td><a href="#" class="eq_step" step="-0.5" band="' + b + '">&ndash;</a></td>');
-		h3.push('<td><input type="text" class="eq_gain" ' + NOAC + ' band="' + b + '" value="' + vs[a][2] + '" /></td>');
+		h5.push('<td><input class="eq_gain" type="text" ' + NOAC + ' band="' + b + '" value="' + vs[a][2] + '" /></td>');
 	}
 	html = html.join('\n') + '</tr><tr>';
 	html += h2.join('\n') + '</tr><tr>';
 	html += h3.join('\n') + '</tr><tr>';
-	html += h4.join('\n') + '</tr><table>';
-	ebi('audio_eq').innerHTML = html;
+	html += h4.join('\n') + '</tr><tr>';
+	html += h5.join('\n') + '</tr><table>';
+	ebi('audio_eq').innerHTML += html;
 
+	ebi('audio_drc').innerHTML = '<a id="au_drc" class="tgl btn" href="#">' + L.enable +
+		'</a><p class="s_desc">' + tt.parse(L.mt_drc) + '</p><br/>';
 	h2 = [];
-	html = ['<table><tr><td rowspan="2">',
-		'<a id="au_drc" class="tgl btn" href="#" tt="' + L.mt_drc + '">' + L.enable + '</a></td>'];
+	html = ['<table><tr>'];
 
 	for (var a = 0; a < r.drch.length; a++) {
 		html.push('<td>' + r.drch[a] + '</td>');
@@ -3187,11 +3776,12 @@ var afilt = (function () {
 	}
 	html = html.join('\n') + '</tr><tr>';
 	html += h2.join('\n') + '</tr><table>';
-	ebi('audio_drc').innerHTML = html;
+	ebi('audio_drc').innerHTML += html;
 
+	ebi('audio_ss').innerHTML = '<a id="au_ss" class="tgl btn" href="#">' + L.enable +
+		'</a><p class="s_desc">' + tt.parse(L.mt_ss) + '</p><br/>';
 	h2 = [];
-	html = ['<table><tr><td rowspan="2">',
-		'<a id="au_ss" class="tgl btn" href="#" tt="' + L.mt_ss + '">' + L.enable + '</a></td>'];
+	html = ['<table><tr>'];
 
 	for (var a = 0; a < r.sscl.length; a++) {
 		html.push('<td tt="' + r.sscl[a] + '</td>');
@@ -3200,7 +3790,7 @@ var afilt = (function () {
 
 	html = html.join('\n') + '</tr><tr>';
 	html += h2.join('\n') + '</tr><table>';
-	ebi('audio_ss').innerHTML = html;
+	ebi('audio_ss').innerHTML += html;
 
 	var stp = QSA('a.eq_step');
 	for (var a = 0, aa = stp.length; a < aa; a++)
@@ -3309,9 +3899,19 @@ function play(tid, is_ev, seek) {
 		mp.au.src = mp.au.rsrc = url;
 	}
 
-	mp.au.osrc = mp.tracks[tid];
+	mp.au.osrc = decodeURI(mp.tracks[tid].split('/').pop());
+	var tname = esc(uricom_dec(mp.au.osrc));
+	ebi('trackname').innerHTML = tname;
+	ebi('trackname').setAttribute('tt', tname);
 	afilt.apply();
 
+	// popup player
+	ebi('mu_tn').innerHTML = tname.replace(/\.[0-9a-z]+$/i, '');
+	var m_ext = tname.match(/[^\.]*$/);
+	if(m_ext){
+		QS('#mu_th>svg').style.color = intToHSL(hashCode(m_ext[0]))
+		QS('#mu_th>span').innerHTML = m_ext[0];
+	}
 	setTimeout(function () {
 		mpl.unbuffer(url);
 	}, 500);
@@ -3333,6 +3933,7 @@ function play(tid, is_ev, seek) {
 	clmod(t_tr, 'play', 1);
 	clmod(ebi('wtoggle'), 'np', mpl.clip);
 	clmod(ebi('wtoggle'), 'm3u', mpl.m3uen);
+
 	if (thegrid)
 		thegrid.loadsel();
 
@@ -3359,13 +3960,9 @@ function play(tid, is_ev, seek) {
 		}
 		mpl.np = ft2dict(t_tr, { 'up_ip': 1 });
 
-		pbar.unwave();
-		if (mpl.waves)
-			pbar.loadwaves(url.replace(/\bth=(opus|mp3)&/, '') + '&th=p');
-
 		mpss.go();
 		mpui.progress_updater();
-		pbar.onresize();
+		mpl.selectprogbar();
 		vbar.onresize();
 		mpl.announce();
 		return true;
@@ -3567,6 +4164,7 @@ function eval_hash() {
 
 	var media = scan_hash(v);
 	if (media) {
+		console.log('got media in hash')
 		var mtype = media[0],
 			id = media[1],
 			ts = media[2];
@@ -3633,7 +4231,6 @@ function eval_hash() {
 			d.setAttribute('href', '#');
 			d.setAttribute('class', 'ayjump');
 			d.innerHTML = a ? L.ay_path : L.ay_files;
-			document.body.insertBefore(d, ebi('ops'));
 			d.onclick = function (e) {
 				ev(e);
 				if (a)
@@ -3645,13 +4242,16 @@ function eval_hash() {
 			};
 		})(a);
 
-	// account-info label
-	var d = mknod('div', 'acc_info');
-	document.body.insertBefore(d, ebi('ops'));
-
 	// folder nav
-	ebi('goh').parentElement.appendChild(mknod('span', null,
-		'<a href="#" id="gop" tt="' + L.gop + '</a>/<a href="#" id="gou" tt="' + L.gou + '</a>/<a href="#" id="gon" tt="' + L.gon + '</a>'));
+	// from https://www.svgrepo.com/collection/iconcino-interface-icons/
+	var svg_left = svg_box + '<path d="M11 6L5 12M5 12L11 18M5 12H19" ' + svg_options +'/>';
+	var svg_right = svg_box + '<path d="M13 6L19 12M19 12L13 18M19 12H5" ' + svg_options +'/>';
+	var svg_up = svg_box + '<path d="M12 19V5M18 11L12 5L6 11" ' + svg_options +'/>';
+
+	ebi('gop').innerHTML = svg_left;
+	ebi('gon').innerHTML = svg_right;
+	ebi('gou').innerHTML = svg_up;
+	
 	ebi('gop').onclick = function () { tree_neigh(-1); }
 	ebi('gon').onclick = function () { tree_neigh(1); }
 	ebi('gou').onclick = function () { tree_up(true); }
@@ -4800,7 +5400,7 @@ var fileman = (function () {
 		t_paste = setTimeout(r.paste, 50);
 	};
 
-	r.paste = function () {
+	r.paste = function (justgo) {
 		if (!r.clip.length)
 			return toast.err(5, L.fp_ecut);
 
@@ -4893,6 +5493,8 @@ var fileman = (function () {
 			for (var a = 0; a < f.length; a++)
 				src.push(f[a].src);
 
+			if (justgo)
+				return okgo();
 			return modal.confirm((r.ccp ? L.fcp_confirm : L.fp_confirm).format(f.length) + '<ul>' + uricom_adec(src, true).join('') + '</ul>', okgo, null);
 		}
 
@@ -5523,32 +6125,70 @@ var showfile = (function () {
 })();
 
 
-var thegrid = (function () {
+window.thegrid = (function () {
 	var lfiles = ebi('files'),
 		gfiles = mknod('div', 'gfiles');
 
 	gfiles.style.display = 'none';
 	gfiles.innerHTML = (
 		'<div id="ghead" class="ghead">' +
-		'<a href="#" class="tgl btn" id="gridvau" tt="' + L.gt_vau + '</a> ' +
-		'<a href="#" class="tgl btn" id="gridsel" tt="' + L.gt_msel + '</a> ' +
-		'<a href="#" class="tgl btn" id="gridcrop" tt="' + L.gt_crop + '</a> ' +
-		'<a href="#" class="tgl btn" id="grid3x" tt="' + L.gt_3x + '</a> ' +
-		'<span>' + L.gt_zoom + ': ' +
-		'<a href="#" class="btn" z="-1.1" tt="Hotkey: shift-A">&ndash;</a> ' +
-		'<a href="#" class="btn" z="1.1" tt="Hotkey: shift-D">+</a></span> <span>' + L.gt_chop + ': ' +
-		'<a href="#" class="btn" l="-1" tt="' + L.gt_c1 + '">&ndash;</a> ' +
-		'<a href="#" class="btn" l="1" tt="' + L.gt_c2 + '">+</a></span> <span>' + L.gt_sort + ': ' +
-		'<a href="#" s="href">' + L.gt_name + '</a> ' +
-		'<a href="#" s="sz">' + L.gt_sz + '</a> ' +
-		'<a href="#" s="ts">' + L.gt_ts + '</a> ' +
-		'<a href="#" s="ext">' + L.gt_ext + '</a>' +
-		'</span></div>' +
+			'<a href="#" id="listicon_template" class="grdbtn gb_lst svgIcon tgl btn" tt="' + L.wt_grid + '"></a>' +
+			'<a href="#" id="gridicon_template" class="grdbtn gb_grd svgIcon tgl btn on" tt="' + L.wt_grid + '"></a>' +
+			'<a href="#" id="galleryicon_template" class="grdbtn gb_glr svgIcon tgl btn" tt="' + L.wt_gallery + '"></a>' +
+			'<a href="#" class="tgl btn" id="gridsel" tt="' + L.gt_msel + '</a> ' +
+			'<a href="#" class="tgl btn" id="gridvau" tt="' + L.gt_vau + '</a> ' +
+			'<a href="#" class="tgl btn" id="gridcrop" tt="' + L.gt_crop + '</a> ' +
+			'<a href="#" class="tgl btn" id="gridupscale" tt="' + L.gt_upscale + '">↕</a> ' +
+			'<a href="#" class="tgl btn" id="grid3x" tt="' + L.gt_3x + '</a> ' +
+			'<span id="gridzoom">' + L.gt_zoom + ': ' +
+				'<a href="#" class="btn" z="-1.1" tt="Hotkey: shift-A">&ndash;</a> ' +
+				'<a href="#" class="btn" z="1.1" tt="Hotkey: shift-D">+</a>' +
+			'</span> <span id="gridchop">' + L.gt_chop + ': ' +
+				'<a href="#" class="btn" l="-1" tt="' + L.gt_c1 + '">&ndash;</a> ' +
+				'<a href="#" class="btn" l="1" tt="' + L.gt_c2 + '">+</a>' +
+			'</span> <span id="gridsort">' + L.gt_sort + ': ' +
+				'<a href="#" s="href">' + L.gt_name + '</a> ' +
+				'<a href="#" s="sz">' + L.gt_sz + '</a> ' +
+				'<a href="#" s="ts">' + L.gt_ts + '</a> ' +
+				'<a href="#" s="ext">' + L.gt_ext + '</a>' +
+			'</span>' +
+		'</div>' +
 		'<div id="ggrid"></div>'
 	);
 	lfiles.parentNode.insertBefore(gfiles, lfiles);
 	var ggrid = ebi('ggrid');
 
+	var svg_list = svg_box + '<path fill-rule="evenodd" clip-rule="evenodd" d="M9 6C9 4.34315 7.65685 3 6 3H4C2.34315 3 1 4.34315 1 6V8C1 9.65685 2.34315 11 4 11H6C7.65685 11 9 9.65685 9 8V6ZM7 6C7 5.44772 6.55228 5 6 5H4C3.44772 5 3 5.44772 3 6V8C3 8.55228 3.44772 9 4 9H6C6.55228 9 7 8.55228 7 8V6Z" fill="currentColor"/><path fill-rule="evenodd" clip-rule="evenodd" d="M9 16C9 14.3431 7.65685 13 6 13H4C2.34315 13 1 14.3431 1 16V18C1 19.6569 2.34315 21 4 21H6C7.65685 21 9 19.6569 9 18V16ZM7 16C7 15.4477 6.55228 15 6 15H4C3.44772 15 3 15.4477 3 16V18C3 18.5523 3.44772 19 4 19H6C6.55228 19 7 18.5523 7 18V16Z" fill="currentColor"/><path d="M11 7C11 6.44772 11.4477 6 12 6H22C22.5523 6 23 6.44772 23 7C23 7.55228 22.5523 8 22 8H12C11.4477 8 11 7.55228 11 7Z" fill="currentColor"/><path d="M11 17C11 16.4477 11.4477 16 12 16H22C22.5523 16 23 16.4477 23 17C23 17.5523 22.5523 18 22 18H12C11.4477 18 11 17.5523 11 17Z" fill="currentColor"/></svg>'
+	var svg_grid = svg_box + '<rect x="4" y="4" width="7" height="7" rx="1" fill="currentColor"/><rect x="4" y="13" width="7" height="7" rx="1" fill="currentColor"/><rect x="13" y="4" width="7" height="7" rx="1" fill="currentColor"/><rect x="13" y="13" width="7" height="7" rx="1" fill="currentColor"/></svg>'
+	var svg_gallery = svg_box + '<path d="M4 17L7.58959 13.7694C8.38025 13.0578 9.58958 13.0896 10.3417 13.8417L11.5 15L15.0858 11.4142C15.8668 10.6332 17.1332 10.6332 17.9142 11.4142L20 13.5M11 9C11 9.55228 10.5523 10 10 10C9.44772 10 9 9.55228 9 9C9 8.44772 9.44772 8 10 8C10.5523 8 11 8.44772 11 9ZM6 20H18C19.1046 20 20 19.1046 20 18V6C20 4.89543 19.1046 4 18 4H6C4.89543 4 4 4.89543 4 6V18C4 19.1046 4.89543 20 6 20Z"' + svg_options + '/></svg>'
+	ebi('listicon_template').innerHTML = svg_list;
+	ebi('gridicon_template').innerHTML = svg_grid;
+	ebi('galleryicon_template').innerHTML = svg_gallery;
+
+	var ico1 = ebi('listicon_template').cloneNode(true);
+	var ico2 = ebi('gridicon_template').cloneNode(true);
+	clmod(ico1, 'on', true);
+	clmod(ico2, 'on', false);
+
+	// file list header
+	ebi('wtc').innerHTML = (
+		ico1.outerHTML +
+		ico2.outerHTML +
+		'<details id="hcol_dd">' +
+			'<summary id="h_hidden">' + L.cl_hiddenc + '</summary>' +
+		'<div id="hcol_content" class="setting">' +
+			'<a class="btn tgl" href="#" id="hcolsh">' + L.cl_hidec + '</a>' +
+			'<a class="btn" id="hcolsr">' + L.cl_reset + '</a>' +
+			'<div class="divider_h"></div>' +
+			'<div id="hcols"></div>' +
+		'</div>' +
+		'</details>'
+	);
+
+	ebi('h_hidden').onclick = function () {
+		clmod(this.parentElement, 'open', 't');
+	}
+
 	var r = {
 		'sz': clamp(fcfg_get('gridsz', 10), 4, 80),
 		'ln': clamp(icfg_get('gridln', 3), 1, 7),
@@ -5560,7 +6200,11 @@ var thegrid = (function () {
 		ev(e);
 		var s = this.getAttribute('s'),
 			z = this.getAttribute('z'),
-			l = this.getAttribute('l');
+			l = this.getAttribute('l'),
+			grdbtn = clgot(this, 'grdbtn');
+
+		if(grdbtn)
+			return;
 
 		if (z)
 			return setsz(z > 0 ? r.sz * z : r.sz / (-z));
@@ -5598,8 +6242,11 @@ var thegrid = (function () {
 		var vis = has(perms, "read");
 		gfiles.style.display = vis && r.en ? '' : 'none';
 		lfiles.style.display = vis && !r.en ? '' : 'none';
+		ebi('wtc').style.display = lfiles.style.display;
 		clmod(ggrid, 'crop', r.crop);
 		clmod(ggrid, 'nocrop', !r.crop);
+		clmod(ggrid, 'gallery', r.gallery);
+		clmod(ggrid, 'noupscale', !r.upscale);
 		ebi('pro').style.display = ebi('epi').style.display = ebi('lazy').style.display = ebi('treeul').style.display = ebi('treepar').style.display = '';
 		ebi('bdoc').style.display = 'none';
 		clmod(ebi('wrap'), 'doc');
@@ -5607,10 +6254,12 @@ var thegrid = (function () {
 		if (treectl)
 			treectl.textmode(false);
 
-		if (filecols)
-			filecols.uivis();
+		var imgs = QSA('#ggrid>a img');
+		for (var a = 0, aa = imgs.length; a < aa; a++) {
+			set_loaded(imgs[a], r.thumbs && imgs[a].complete, true);
+		}
 
-		aligngriditems();
+		setTimeout(aligngriditems, 1);
 		restore_scroll();
 	};
 
@@ -5651,13 +6300,17 @@ var thegrid = (function () {
 			setTimeout(r.tippen, 20);
 		}
 		setcvar('--grid-sz', r.sz + 'em');
-		aligngriditems();
+		setTimeout(aligngriditems, 1);
 	}
 	setsz();
 
 	function gclick1(e) {
 		if (ctrl(e) && !treectl.csel && !r.sel)
 			return true;
+		else if (e.altKey){
+			ev(e);
+			return;
+		}
 
 		return gclick.call(this, e, false);
 	}
@@ -5686,6 +6339,7 @@ var thegrid = (function () {
 			tr = td.parentNode;
 
 		if (!is_srch && ((r.sel && !dbl && !ctrl(e)) || (treectl.csel && (e.shiftKey || ctrl(e))))) {
+			ev(e);
 			td.onclick.call(td, e);
 			if (e.shiftKey)
 				return r.loadsel();
@@ -5710,8 +6364,9 @@ var thegrid = (function () {
 			window.open(qhref, '_blank');
 
 		else {
-			if (!dbl)
+			if (!dbl){
 				return true;
+			}
 
 			setTimeout(function () {
 				r.sel = true;
@@ -5748,11 +6403,10 @@ var thegrid = (function () {
 			if (!ref)
 				continue;
 			var cl = ebi(ref).closest('tr').className || '';
-
-			if (noq_href(ths[a]).endsWith('/'))
-				cl += ' dir';
-
 			ths[a].className = cl;
+
+			var chk = ths[a].getElementsByTagName('input')[0];
+			if(chk) chk.checked = cl.match(/\bsel\b/);
 		}
 
 		var sp = ['unsearch', 'moar'];
@@ -5828,8 +6482,8 @@ var thegrid = (function () {
 				ext0 = '',
 				name = uricom_dec(vsplit(href)[1]),
 				ref = ao.getAttribute('id'),
-				isdir = href.endsWith('/'),
-				ac = isdir ? ' class="dir"' : '',
+				isdir = clgot(ao.parentElement.parentElement, 'dir'),
+				ac = ao.parentElement.parentElement.classList,
 				ihref = ohref;
 
 			if (need_ext && href != "#") {
@@ -5840,10 +6494,9 @@ var thegrid = (function () {
 				ar.reverse();
 				ext0 = ar[0];
 				for (var b = 0; b < Math.min(2, ar.length); b++) {
-					if (ar[b].length > 7)
-						break;
-
 					ext = ext ? (ar[b] + '.' + ext) : ar[b];
+					if (ar[b].length > 2)
+						break;
 				}
 				if (!ext)
 					ext = 'unk';
@@ -5854,7 +6507,7 @@ var thegrid = (function () {
 			}
 			else if (r.thumbs) {
 				ihref = addq(ihref, 'th=' + (
-					have_jxl  ? 'x' :
+					have_jxl ? 'x' :
 					have_webp ? 'w' :
 					'j'
 				));
@@ -5865,26 +6518,30 @@ var thegrid = (function () {
 				if (href == "#")
 					ihref = SR + '/.cpr/ico/' + (ref == 'moar' ? '++' : 'exit');
 			}
-			else if (isdir) {
-				ihref = SR + '/.cpr/ico/folder';
-			}
 			else {
-				if (!svgs.has(ext)) {
-					if (svgs.size < max_svgs)
-						svgs.add(ext);
-					else
-						ext = "unk";
-				}
-				ihref = SR + '/.cpr/ico/' + ext;
+				ihref = '';
 			}
-			ihref = addq(ihref, 'cache=i&_=' + ACB + TS);
-			if (CHROME)
-				ihref += "&raster";
 
+			if(ihref){
+				ihref = addq(ihref, 'cache=i&_=' + ACB + TS);
+
+				var accent = getComputedStyle(document.body).getPropertyValue('--a');
+				if (!accent)
+					accent = '#07c';
+				ihref += '&a=' + parseColor(accent).replace(/ /g, '');
+			}
 			html.push('<a href="' + ohref + '" ref="' + ref +
-				'"' + ac + ' ttt="' + esc(name) + '"><img style="height:' +
-				(r.sz / 1.25) + 'em" loading="lazy" onload="th_onload(this)" src="' +
-				ihref + '" /><span' + ac + '>' + ao.innerHTML + '</span></a>');
+				'" class="' + ac + '" ttt="' + esc(name) + '">' +
+				'<div class="imgcontainer">' +
+				'<input type="checkbox" class="gselchk"></input>' +
+				'<svg class="thumb" width="100%" height="100%" version="1.1"><use href="#' +
+					(isdir ? 'folder' : 'file') + '-icon" color="' +
+					(ext == 'unk' || ext.startsWith('/') ? '#0000' : intToHSL(hashCode(ext))) + '"/></svg>' +
+				(isdir || ext == 'unk' || ext.startsWith('/') ? '' :
+					'<span class="th_ext" style="font-size: ' + (r.sz / 5) +'em; font-size:calc(var(--grid-sz) / 5 * ' +
+					(ext.length > 3 ? 1 / (3 + ext.length * .4) * 3 : 1) + ')">' + ext + '</span>') +
+				'<img loading="lazy" onload="th_onload(this)" src="' +
+				ihref + '" /></div><span class="' + ac + '">' + ao.innerHTML + '</span></a>');
 		}
 		ggrid.innerHTML = html.join('\n');
 		clmod(ggrid, 'crop', r.crop);
@@ -5903,20 +6560,41 @@ var thegrid = (function () {
 			ths[a].onclick = gclick1;
 		}
 
+		var imgs = QSA('#ggrid>a img');
+		for (var a = 0, aa = imgs.length; a < aa; a++) {
+			set_loaded(imgs[a], r.thumbs && imgs[a].complete, true);
+		}
+
+		var chks = QSA('.gselchk');
+		for (var a = 0, aa = chks.length; a < aa; a++) {
+			chks[a].onclick = function (e) {
+				var oth = ebi(this.closest('a').getAttribute('ref')),
+					td = oth.closest('td').nextSibling;
+				if(td && td.onclick)
+					td.onclick.call(td, e);
+				else
+					rcm.show(e);
+			}
+		}
+
 		r.dirty = false;
-		r.bagit('#ggrid');
 		r.loadsel();
-		aligngriditems();
+		if(window.baguetteBox != undefined)
+			r.bagit();
+		setTimeout(aligngriditems, 1);
 		setTimeout(r.tippen, 20);
+		drag.initgrid();
 	}
 
 	r.bagit = function (isrc) {
-		if (!window.baguetteBox)
-			return;
-
+		console.log('init image viewer');
+		
 		if (r.bbox)
 			baguetteBox.destroy();
 
+		if(!isrc)
+			isrc = thegrid.en ? '#ggrid' : '#files'
+
 		var br = baguetteBox.run(isrc, {
 			noScrollbars: true,
 			duringHide: r.onhide,
@@ -5936,8 +6614,9 @@ var thegrid = (function () {
 				}
 			}
 		});
-		r.bbox = true;
 		r.bbox_opts = br[1];
+		r.bbox = true;
+		eval_hash()
 	};
 
 	r.onhide = function () {
@@ -6014,6 +6693,9 @@ var thegrid = (function () {
 	bcfg_bind(r, 'ihop', 'ihop', true);
 	bcfg_bind(r, 'vau', 'gridvau', false);
 	bcfg_bind(r, 'crop', 'gridcrop', !dcrop.endsWith('n'), r.set_crop);
+	bcfg_bind(r, 'upscale', 'gridupscale', true, function (v) {
+		clmod(ggrid, 'noupscale', !v)
+	});
 	bcfg_bind(r, 'x3', 'grid3x', dth3x.endsWith('y'), r.set_x3);
 	bcfg_bind(r, 'sel', 'gridsel', false, r.loadsel);
 	bcfg_bind(r, 'en', 'griden', dgrid, function (v) {
@@ -6021,7 +6703,7 @@ var thegrid = (function () {
 		pbar.onresize();
 		vbar.onresize();
 	});
-	bcfg_bind(r, 'gaen', 'gauto', !!dgauto, function(v) {
+	bcfg_bind(r, 'gaen', 'gauto', !!dgauto, function (v) {
 		if (r.en && sread("griden") != 1) {
 			r.en = false;
 			r.setvis(true);
@@ -6032,16 +6714,74 @@ var thegrid = (function () {
 		var n = parseInt(this.value);
 		swrite('ga_thresh', r.gathr = (isNum(n) ? n : 0) || 70);
 	};
-	ebi('wtgrid').onclick = ebi('griden').onclick;
+
+	var gbtn = QSA('.gb_grd');
+	for(var a = 0; a < gbtn.length; a++)
+		gbtn[a].onclick = function(){
+			if(!thegrid.en)
+				ebi('griden').click();
+		}
+
+	var lsbtn = QSA('.gb_lst');
+	for(var a = 0; a < lsbtn.length; a++)
+		lsbtn[a].onclick = function(){
+			if(thegrid.en)
+				ebi('griden').click();
+		}
+
+	bcfg_bind(r, 'gallery', 'galleryicon_template', false, function (v) {
+		clmod(ebi('ggrid'), 'gallery', v);
+	});
 
 	return r;
 })();
 
-
 function th_onload(el) {
-	el.style.height = '';
+	set_loaded(el, true, false)
 }
 
+function set_loaded(el, state, dblcheck) {
+	if(state && dblcheck) {
+		testImage(el);
+		return;
+	}
+	var p = el.parentElement.parentElement
+	clmod(p, 'thumbed', state)
+	var a = p.getAttribute('ref')
+	if(a){
+		var b = ebi(a)
+		if(b){
+			var c = b.closest('tr')
+			if(c)
+				clmod(c, 'thumbed', state)
+		}
+	}
+}
+
+function testImage(el) {
+	var URL = el.src
+    var tester=new Image();
+    tester.onload=
+		function imageFound() {
+			set_loaded(el, true, false)
+		};
+    tester.onerror=
+		function imageFound() {
+			set_loaded(el, false, false)
+		};
+    tester.src=URL;
+}
+
+function hashCode (str) {
+	var hash = 0;
+	for(var i = 0; i < str.length; i++){
+		hash = str.charCodeAt(i) + 130 * ((hash << 5) - hash);
+	}
+	return hash
+}
+function intToHSL(i){
+	return 'hsl(' + i % 360 + 'deg 100% 50%)'
+}
 
 function tree_scrollto(e) {
 	ev(e);
@@ -6191,7 +6931,7 @@ function fselfunw(e, ae, d, rem) {
 	}
 	selfun();
 }
-var konmai = 0, konmak = (function() {
+var konmai = 0, konmak = (function () {
 	var u = "arrowup",
 		d = "arrowdown",
 		l = "arrowleft",
@@ -6223,7 +6963,7 @@ var ahotkeys = function (e) {
 	if (konmai < 0)
 		noop();
 	else if (konmak[konmai] != kl)
-		konmai = konmai && kl == konmak[0] ? (konmai<3?konmai:1):0;
+		konmai = konmai && kl == konmak[0] ? (konmai < 3 ? konmai : 1) : 0;
 	else if (++konmai >= konmak.length) {
 		konmai = -1;
 		document.documentElement.scrollTop = 0;
@@ -6231,7 +6971,7 @@ var ahotkeys = function (e) {
 		start_actx();
 		sfx_nice();
 		toast.inf(9, 'omega clearance granted', null, 'top');
-		setTimeout(function() {
+		setTimeout(function () {
 			apply_perms(treectl.lsc);
 			fileman.render();
 		}, 573);
@@ -6257,6 +6997,9 @@ var ahotkeys = function (e) {
 		if (ebi('sh_abrt'))
 			return ebi('sh_abrt').click();
 
+		if (QS('#music.vis'))
+			return ebi('cl_mu').click();
+
 		if (QS('.opview.act'))
 			return QS('#ops>a').click();
 
@@ -6335,7 +7078,7 @@ var ahotkeys = function (e) {
 	if (k == '?')
 		return hkhelp();
 
-	if (!sh && ctrl(e)) {
+	if (!sh && ctrl(e) || k.endsWith('Delete')) {
 		var sel = window.getSelection && window.getSelection() || {};
 		sel = sel && !sel.isCollapsed && sel.direction != 'none';
 
@@ -6348,7 +7091,7 @@ var ahotkeys = function (e) {
 		if (kl == 'v')
 			return fileman.d_paste(e);
 
-		if (kl == 'k')
+		if (kl == 'k' || k.endsWith('Delete'))
 			return fileman.delete(e);
 
 		return;
@@ -6442,35 +7185,35 @@ var ahotkeys = function (e) {
 var search_ui = (function () {
 	var sconf = [
 		[
-			L.s_sz,
-			["szl", "sz_min", L.s_s1, "14", ""],
-			["szu", "sz_max", L.s_s2, "14", ""]
+			L.s_fn,
+			["name", "name", L.s_f1, "td_s", ".exe$"]
 		],
 		[
-			L.s_dt,
-			["dtl", "dt_min", L.s_d1, "14", "1997-08-15, 01:00"],
-			["dtu", "dt_max", L.s_d2, "14", "2020"]
+			L.s_rd,
+			["path", "path", L.s_r1, "td_w", "windows  -system32"]
 		],
 		[
-			L.s_rd,
-			["path", "path", L.s_r1, "30", "windows  -system32"]
+			L.s_sz,
+			["szl", "sz_min", L.s_s1, "td_s", ""],
+			["szu", "sz_max", L.s_s2, "td_s", ""]
 		],
 		[
-			L.s_fn,
-			["name", "name", L.s_f1, "30", ".exe$"]
+			L.s_dt,
+			["dtl", "dt_min", L.s_d1, "td_s", "1997-08-15, 01:00", "date"],
+			["dtu", "dt_max", L.s_d2, "td_s", "2020", "date"]
 		],
 		[
 			L.s_ta,
-			["tags", "tags", L.s_t1, "30", "^irui$"]
+			["tags", "tags", L.s_t1, "td_w", "^irui$"]
 		],
 		[
 			L.s_ad,
-			["adv", "adv", L.s_a1, "30", "key>=1A  key<=2B  .bpm>165"]
+			["adv", "adv", L.s_a1, "td_w", "key>=1A  key<=2B  .bpm>165"]
 		],
 		[
 			L.s_ua,
-			["utl", "ut_min", L.s_u1, "14", "2007-04-08"],
-			["utu", "ut_max", L.s_u2, "14", "2038-01-19"]
+			["utl", "ut_min", L.s_u1, "td_s", "2007-04-08", "date"],
+			["utu", "ut_max", L.s_u2, "td_s", "2038-01-19", "date"]
 		]
 	];
 
@@ -6484,13 +7227,14 @@ var search_ui = (function () {
 		var html = ['<tr id="tsrch_' + sconf[a][1][0] + '"><td><br />' + sconf[a][0] + '</td>'];
 		for (var b = 1; b < 3; b++) {
 			var hn = "srch_" + sconf[a][b][0],
-				csp = (sconf[a].length == 2) ? 2 : 1;
+				csp = (sconf[a].length == 2) ? 2 : 1,
+				type = sconf[a][b].length >= 6 ? sconf[a][b][5] : "text";
 
 			html.push(
 				'<td colspan="' + csp + '"><input id="' + hn + 'c" type="checkbox">\n' +
 				'<label for="' + hn + 'c">' + sconf[a][b][2] + '</label>\n' +
-				'<br /><input id="' + hn + 'v" type="text" style="width:' + sconf[a][b][3] +
-				'em" name="' + sconf[a][b][1] + '" placeholder="' + sconf[a][b][4] + '" /></td>');
+				'<br /><input id="' + hn + 'v" type="' + type + '" class="' + sconf[a][b][3] +
+				'" name="' + sconf[a][b][1] + '" placeholder="' + sconf[a][b][4] + '" /></td>');
 			if (csp == 2)
 				break;
 		}
@@ -6510,6 +7254,58 @@ var search_ui = (function () {
 		o[a].onkeydown = ev_search_keydown;
 	}
 
+	var folderSearch = ebi('folder_search');
+	folderSearch.placeholder = L.s_dir;
+	folderSearch.onfocus = function(){
+		ebi('srch_pathc').checked = true;
+		var path = decodeURI(get_evpath());
+		ebi('srch_pathv').value = path.slice(1) || '/';
+	}
+	if(IE)
+		folderSearch.onclick = function() {
+			clmod(ebi('srch_quickopts'), 'act', 't');
+		}
+	folderSearch.oninput = function(){
+		var v = unsmart(this.value);
+		if(IE && !v)
+			return;
+		var nsearch = ebi('srch_namev');
+		nsearch.value = v;
+		nsearch.oninput();
+	}
+	folderSearch.onkeydown = ev_search_keydown;
+
+	var expand = sread('s_ex') == 'true';
+	exp_search(expand);
+	function exp_search (e) {
+		clmod(ebi('op_search'), 'vis', e);
+
+		var ms = ebi('moresearch');
+		if(e){
+			window.scrollTo(0, 0);
+			ms.innerHTML = '▴';
+		}
+		else{
+			ms.innerHTML = '▾';
+		}
+	}
+	ebi('moresearch').onclick = function () {
+		expand = !expand;
+		swrite('s_ex', expand);
+		exp_search(expand);
+	};
+
+	ebi('closesearch').onclick = function (e) {
+		ebi('opa_srch').click();
+		folderSearch.value = '';
+		if(ebi('unsearch'))
+			ebi('unsearch').click();
+	}
+
+	var recur_c = ebi('srch_recursivec');
+	recur_c.oninput = ev_search_input;
+	ebi('srch_recursivelbl').innerHTML = L.s_rec;
+
 	function srch_msg(err, txt) {
 		var o = ebi('srch_q');
 		o.textContent = txt;
@@ -6569,7 +7365,12 @@ var search_ui = (function () {
 		srch_msg(false, (q == vq) ? '' : L.sm_prev + (vq ? vq : '(*)'));
 	}
 
+	function onlyUnique(value, index, array) {
+		return array.indexOf(value) == index && value.length > 0;
+	}
+
 	function encode_query() {
+		var recursive = ebi('srch_recursivec').checked;
 		var q = '';
 		for (var a = 0; a < sconf.length; a++) {
 			for (var b = 1; b < sconf[a].length; b++) {
@@ -6578,8 +7379,23 @@ var search_ui = (function () {
 					vs = unsmart(ebi('srch_' + k + 'v').value),
 					tvs = [];
 
-				if (a == 1)
-					vs = vs.trim().replace(/ +/, 'T');
+				if(k == 'path' && vs.endsWith('/') && !vs.match('"')){
+					vs = vs.slice(0, -1);
+					vs = '"' + vs + (recursive ? '*' : '') + '"';
+					tvs.push(vs);
+					vs = '';
+				}
+
+				var match = vs.match(/\B("(?:[^"]|\\")*[^\\]")\B/g);
+				if(match != null){
+					var immune = match.filter(onlyUnique)
+					for(var i = 0; i < immune.length; i++){
+						if(immune[i].length > 0){
+							tvs.push(immune[i]);
+							vs = vs.replace(immune[i], '')
+						}
+					}
+				}
 
 				while (vs) {
 					vs = vs.trim();
@@ -6598,7 +7414,8 @@ var search_ui = (function () {
 						}
 					}
 					else {
-						var vp = vs.split(/ +(.*)/);
+						// split at spaces
+						var vp = vs.split(/\s+(.*)/);
 						v = vp[0].replace(/\\"/g, '"');
 						vs = vp[1] || '';
 					}
@@ -6608,12 +7425,17 @@ var search_ui = (function () {
 				if (!ebi(chk).checked)
 					continue;
 
+				if(q.length > 0)
+					q += ' and ';
+
+				q += ' ( ';
 				for (var c = 0; c < tvs.length; c++) {
 					var tv = tvs[c];
 					if (!tv.length)
 						break;
 
-					q += ' and ';
+					if(c > 0)
+						q += ' or ';
 
 					if (k == 'adv') {
 						q += tv.replace(/ +/g, " and ").replace(/([=!><]=?)/, " $1 ");
@@ -6635,27 +7457,38 @@ var search_ui = (function () {
 						if (tv.slice(0, 1) == '^') {
 							tv = tv.slice(1);
 						}
-						else {
+						else if (!tv.match(' ') && !tv.startsWith('"')){
 							tv = '*' + tv;
 						}
 
 						if (tv.slice(-1) == '$') {
 							tv = tv.slice(0, -1);
 						}
-						else {
+						else if(!tv.match(' ') && !tv.endsWith('"')){
 							tv += '*';
 						}
 
-						if (tv.indexOf(' ') + 1) {
+						if (tv.match(' ') && !tv.match('"')) {
 							tv = '"' + tv + '"';
 						}
 
+						var quote = tv.match('"') ? '"' : '';
+						var match;
+						while ( (match = tv.match(/[^\*\"\s]\*[^\*\"\s]/)) && match[0]){
+							console.log(match)
+							tv = tv.replace(
+								match[0],
+								match[0].replace('*', '*' + quote + ' and ' + k + ' like ' + quote + '*')
+							)
+						}
+
 						q += not + k + ' like ' + tv;
 					}
 				}
+				q += ' ) ';
 			}
 		}
-		ebi('q_raw').value = q.slice(5);
+		ebi('q_raw').value = q.trim();
 	}
 
 	function do_search() {
@@ -6721,7 +7554,7 @@ var search_ui = (function () {
 				ext = '%';
 
 			var links = linksplit(r.rp + '', null, id).join('<span>/</span>'),
-				nodes = ['<tr><td>-</td><td><div>' + links +
+				nodes = ['<tr class="' + (img_re.exec(r.rp) ? 'img ' : '') + '"><td>-</td><td><div>' + links +
 					'</div></td><td sortv="' + sz + '">' + hsz];
 
 			for (var b = 0; b < tagord.length; b++) {
@@ -6820,7 +7653,7 @@ function render_m3u() {
 		dur = 1,
 		artist = '',
 		title = '',
-		ret = {'hits': [], 'tag_order': ['artist', 'title', '.dur'], 'trunc': false};
+		ret = { 'hits': [], 'tag_order': ['artist', 'title', '.dur'], 'trunc': false };
 
 	for (var a = 0; a < lines.length; a++) {
 		var ln = lines[a].trim();
@@ -6856,7 +7689,7 @@ function render_m3u() {
 			"ts": 946684800 + n,
 			"sz": 100000 + n,
 			"rp": url,
-			"tags": {".dur": dur, "artist": artist, "title": title}
+			"tags": { ".dur": dur, "artist": artist, "title": title }
 		});
 		dur = 1;
 		artist = title = '';
@@ -6871,7 +7704,6 @@ function render_m3u() {
 		el.click();
 }
 
-
 function aligngriditems() {
 	if (!treectl)
 		return;
@@ -6895,10 +7727,12 @@ function aligngriditems() {
 	if (((griditemcount * em2px) * gridsz) + totalgapwidth < gridwidth) {
 		val = 'left';
 	} else {
-		val = treectl.hidden ? 'center' : 'space-between';
+		val = 'center';// treectl.hidden ? 'center' : 'space-between';
 	}
 	if (st.justifyContent != val)
 		st.justifyContent = val;
+
+	onwidgetresize();
 }
 onresize100.add(aligngriditems);
 
@@ -6919,6 +7753,67 @@ var filecolwidth = (function () {
 })();
 onresize100.add(filecolwidth, true);
 
+function onwidgetresize(){
+	var mumodal = QS('#music.vis');
+	var widget = ebi('widget');
+	var bar = ebi('pctl');
+	var pbarthinpos = ebi('pbarthinpos');
+
+	if(mumodal){
+		var pb_container = ebi('mu_pbb');
+		pb_container.appendChild(ebi('progbar'));
+		pb_container.appendChild(ebi('altprogbar'));
+		ebi('altprogbar').maxWidth = '';
+		ebi('mu_vol').appendChild(ebi('pvolbg'));
+		pbar.onresize();
+		return;
+	}
+
+	var width = widget.offsetWidth;
+
+	var thin = width < 800; //px
+
+	clmod(ebi('pathBar'), 'thin', thin);
+	clmod(ebi('wrap'), 'thin', thin);
+
+	thin = thin || IE;
+
+	var gtc = 'max-content max-content max-content ' + (thin ? '' : '20%') + ' auto max-content max-content max-content';
+	if(!thin && bar.children.length < gtc.split(' ').length){
+		try{
+			//wide
+			ebi('trackname').after(ebi('progbar'));
+			ebi('trackname').after(ebi('altprogbar'));
+			bar.style.paddingTop = '0';
+		}
+		catch (e) {
+			// unnacounted old browser fallback
+			console.log(e);
+			thin = true;
+		}
+	}
+	if(thin && pbarthinpos.children.length < 2){
+		//thin
+		pbarthinpos.appendChild(ebi('progbar'));
+		pbarthinpos.appendChild(ebi('altprogbar'));
+		bar.style.paddingTop = '.3em';
+	}
+	ebi('altprogbar').maxWidth = thin ? '' : '40vw'
+	bar.style.gridTemplateColumns = gtc;
+
+	clmod(widget, 'thin', thin);
+
+	if(ebi('mu_vol').children.length > 0){
+		bar.appendChild(ebi('pvolbg'));
+	}
+
+	pbar.onresize();
+
+	// keep path scrolled right
+	ebi('path').onresize = keep_right(ebi('path'));
+}
+window.addEventListener('resize', onwidgetresize);
+onwidgetresize();
 
 var treectl = (function () {
 	var r = {
@@ -6998,22 +7893,40 @@ var treectl = (function () {
 			swrite('entreed', 'tree');
 
 		get_tree("", get_evpath(), true);
-		r.show();
+		r.show(nostore);
+
+		clmod(ebi('treeToggleBtn'), 'on', true)
 	}
 
-	r.show = function () {
+	r.show = function (instant) {
 		r.hidden = false;
 		if (!entreed) {
 			ebi('path').style.display = nonav ? 'none' : 'inline-block';
 			return;
 		}
 
-		ebi('path').style.display = 'none';
-		ebi('tree').style.display = 'block';
+		var tree = ebi('tree')
+		tree.style.display = 'block';
+		tree.style.width = 0;
+		clmod(ebi('wfp'), 'shifted', false);
 		window.addEventListener('scroll', onscroll);
 		window.addEventListener('resize', onresize);
-		onresize();
-		aligngriditems();
+
+		if(!instant){
+			// makes animation work by waiting for next frame
+			setTimeout(function () {
+				onresize();
+				aligngriditems();
+			}, 10);
+		}
+		else {
+			tree.style.transition = 'none';
+			onresize();
+			setTimeout(function(){
+				aligngriditems();
+				tree.style.transition = '';
+			}, 1)
+		}
 	};
 
 	r.detree = function (e, nw) {
@@ -7025,16 +7938,34 @@ var treectl = (function () {
 		r.hide();
 		if (!nonav)
 			ebi('path').style.display = '';
+
+		clmod(ebi('treeToggleBtn'), 'on', false)
+	};
+
+	r.toggleTree = function (e, nostore) {
+		if(entreed){
+			r.detree(e, nostore);
+		}
+		else{
+			r.entree(e, nostore);
+		}
 	};
 
 	r.hide = function () {
 		r.hidden = true;
-		ebi('path').style.display = 'none';
-		ebi('tree').style.display = 'none';
+		ebi('tree').style.width = ebi('tree_footer').style.width = '0';
+		ebi('tree_footer').style.display = 'none';
+		ebi('widget').style.marginLeft = '0';
 		ebi('wrap').style.marginLeft = '';
+		clmod(ebi('wfp'), 'shifted', true);
 		window.removeEventListener('resize', onresize);
 		window.removeEventListener('scroll', onscroll);
 		aligngriditems();
+
+		// wait for animation to finish (.15s), then set display to none if width still 0
+		setTimeout(function () {
+			onresize();
+		}, 170);
 	};
 
 	function unmenter() {
@@ -7085,7 +8016,7 @@ var treectl = (function () {
 			compy();
 		}
 
-		if (!r.parpane || !r.pdir.length || y >= r.pdir.slice(-1)[0][0] || y <= r.pdir[0][0]) {
+		if (!r.parpane || !r.pdir.length) {
 			clmod(parp, 'off', 1);
 			r.pdirh = null;
 		}
@@ -7109,48 +8040,19 @@ var treectl = (function () {
 				for (var a = 0, aa = els.length; a < aa; a++)
 					els[a].onclick = bad_proxy;
 			}
-			y = ebi('treeh').offsetHeight;
-			if (!fixedpos)
-				y += tree.offsetTop - yscroll();
-
-			y = (y - 3) + 'px';
+			y = ebi('treesuperh').offsetHeight + 'px';
 			if (parp.style.top != y)
 				parp.style.top = y;
 		}
-
-		if (wraptop === null)
-			return;
-
-		prev_atop = atop;
-		prev_winh = winh;
-
-		if (fixedpos && atop >= 0) {
-			tree.style.position = 'absolute';
-			tree.style.bottom = '';
-			fixedpos = false;
-		}
-		else if (!fixedpos && atop < 0) {
-			tree.style.position = 'fixed';
-			tree.style.height = 'auto';
-			fixedpos = true;
-		}
-
-		if (fixedpos) {
-			tree.style.top = Math.max(0, parseInt(atop)) + 'px';
-		}
-		else {
-			var top = Math.max(0, wraptop),
-				treeh = winh - atop;
-
-			tree.style.top = top + 'px';
-			tree.style.height = treeh < 10 ? '' : Math.floor(treeh) + 'px';
-		}
 	}
 	timer.add(onscroll2, true);
 
 	function onresize(e) {
-		if (!entreed || r.hidden)
+		if (!entreed || r.hidden){
+			if(ebi('tree').style.width == '0px')
+				ebi('tree').style.display = 'none';
 			return;
+		}
 
 		var q = '#tree',
 			nq = -3;
@@ -7164,12 +8066,16 @@ var treectl = (function () {
 		nq = Math.max(nq, get_evpath().split('/').length - 2);
 		var iw = (treesz + Math.max(0, nq)),
 			w = iw + 'em',
-			w2 = (iw + 2) + 'em';
+			w2 = (iw + 1) + 'em';
 
 		setcvar('--nav-sz', w);
 		ebi('tree').style.width = w;
-		ebi('wrap').style.marginLeft = w2;
-		onscroll();
+		ebi('tree_footer').style.width = (iw - 2) + 'em';
+		ebi('tree_footer').style.display = 'block';
+		ebi('wrap').style.marginLeft = w;
+		ebi('widget').style.marginLeft = (iw /1.4) + 'em';
+		onwidgetresize();
+		setTimeout(onscroll, 1);
 	}
 
 	r.find = function (txt) {
@@ -7291,6 +8197,10 @@ var treectl = (function () {
 				console.log("dir_cb failed", ex);
 			}
 		}
+
+		var dirs = QSA("#treeul li a:nth-child(2)");
+		for (var i = 0; i < dirs.length; i++)
+			drag.mktarget(dirs[i]);
 	};
 
 	function reload_tree() {
@@ -7355,16 +8265,20 @@ var treectl = (function () {
 	function menter(e) {
 		var p = this.offsetParent,
 			pp = p.offsetParent,
-			ppy = pp.offsetTop,
-			y = this.offsetTop + p.offsetTop + ppy - p.scrollTop - pp.scrollTop - (ppy ? document.documentElement.scrollTop : 0);
+			ppy = pp ? pp.offsetTop : 0,
+			y = this.offsetTop + p.offsetTop + ppy - p.scrollTop - (pp ? pp.scrollTop : 0) - (ppy ? document.documentElement.scrollTop : 0);
 
 		this.style.top = y + 'px';
 		this.style.position = 'fixed';
+		this.style.width = 'auto';
+		this.style.minWidth = ebi('tree').offsetWidth + p.offsetLeft - 5 + 'px';
 		mentered = this;
 	}
 
 	function mleave(e) {
 		this.style.position = '';
+		this.style.minWidth = '';
+		this.style.width = '';
 		mentered = null;
 	}
 
@@ -7509,9 +8423,12 @@ var treectl = (function () {
 			clmod(ebi('griden'), 'on', thegrid.en = dgrid);
 
 		srvinf = res.srvinf;
-		if (rtt !== null)
+		ebi('spaceFree').innerHTML = res.space_free + ' free of ' + res.space_total ;
+		ebi('spaceUsed_bar').width = res.space_used_percent + '%';
+		if (rtt !== null){
 			srvinf += (srvinf ? '</span> // <span>rtt: ' : 'rtt: ') + rtt;
-
+			ebi('rtt_latency').innerHTML = 'latency: ' + rtt + 'ms';
+		}
 		var o = ebi('srv_info2');
 		if (o)
 			o.innerHTML = ebi('srv_info').innerHTML = '<span>' + srvinf + '</span>';
@@ -7519,6 +8436,7 @@ var treectl = (function () {
 		if (res.ufavico && (!favico.en || !ebi('icot').value)) {
 			while (qsr('head>link[rel~="icon"]')) { }
 			document.head.insertAdjacentHTML('beforeend', res.ufavico);
+            ebi('favico_onpage').innerHTML = res.ufavico;
 		}
 
 		if (this.hpush && !showfile.active())
@@ -7556,7 +8474,7 @@ var treectl = (function () {
 		if (lg1 === Ls.eng.f_empty)
 			lg1 = L.f_empty;
 
-		sandbox(ebi('pro'), sb_lg, sba_lg,'', lg0);
+		sandbox(ebi('pro'), sb_lg, sba_lg, '', lg0);
 		if (dirchg)
 			sandbox(ebi('epi'), sb_lg, sba_lg, '', lg1);
 
@@ -7584,6 +8502,12 @@ var treectl = (function () {
 			fun();
 		}
 
+		if (drag.is_dragging) {
+			fileman.paste(true);
+			drag.is_dragging = false;
+		}
+		drag.initfiles();
+
 		if (can_shr && in_shr && QS('#op_unpost.act'))
 			goto('unpost');
 	}
@@ -7601,6 +8525,9 @@ var treectl = (function () {
 
 	r.gentab = function (top, res) {
 		showfile.untail();
+		for (var a = 0; a < res.dirs.length; a++)
+			res.dirs[a].cls = 'dir';
+
 		var nodes = res.dirs.concat(res.files),
 			html = mk_files_header(res.taglist),
 			sel = msel.hist[top],
@@ -7668,8 +8595,8 @@ var treectl = (function () {
 					'" rel="nofollow" class="doc' + (lang ? ' bri' : '') +
 					'" hl="' + id + '" name="' + hname + '">-txt-</a>';
 
-			var cl = /\.PARTIAL$/.exec(fname) ? ' class="fade"' : '',
-				ln = ['<tr' + cl + '><td>' + tn.lead + '</td><td><a href="' +
+			var cl = (/\.PARTIAL$/.exec(fname) ? 'fade ' : '') + (img_re.exec(fname) ? 'img ' : '') + (tn.cls || ''),
+				ln = ['<tr class="' + cl + '"><td>' + tn.lead + '</td><td><a href="' +
 					top + tn.href + '" id="' + id + '">' + hname +
 					'</a></td><td sortv="' + tn.sz + '">' + filesizefun(tn.sz)];
 
@@ -7773,6 +8700,7 @@ var treectl = (function () {
 		pbar.onresize();
 		vbar.onresize();
 		showfile.addlinks();
+		drag.initfiles();
 		setTimeout(eval_hash, 1);
 	};
 
@@ -7909,13 +8837,16 @@ var treectl = (function () {
 		if (!isNum(treesz))
 			treesz = 16;
 
-		treesz = clamp(treesz, 2, 120);
+		treesz = clamp(treesz, 6, 120);
 		swrite('treesz', treesz);
 		onresize();
 	}
 
-	ebi('entree').onclick = r.entree;
-	ebi('detree').onclick = r.detree;
+	var svg_hamburger = svg_box + '<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g id="Menu"><rect id="Rectangle" fill-rule="nonzero" x="0" y="0" width="24" height="24"></rect><line x1="5" y1="7" x2="19" y2="7" id="Path" ' + svg_options + '></line><line x1="5" y1="17" x2="19" y2="17" id="Path" ' + svg_options + '></line><line x1="5" y1="12" x2="19" y2="12" id="Path" ' + svg_options + '></line></g></g></svg>'
+	ebi('treeToggleBtn').innerHTML = svg_hamburger;
+	ebi('treeToggleBtn').setAttribute('tt', L.tt_entree);
+
+	ebi('treeToggleBtn').onclick = r.toggleTree;
 	ebi('visdir').onclick = tree_scrollto;
 	ebi('twig').onclick = scaletree;
 	ebi('twobytwo').onclick = scaletree;
@@ -7982,7 +8913,7 @@ var wfp_debounce = (function () {
 			r.n = 1;
 			clearTimeout(r.t);
 			r.t = setTimeout(r.reset, 300);
-			ebi('wfp').style.opacity = 0.1;
+			//ebi('wfp').style.opacity = 0.1;
 		}
 	};
 	r.show = function () {
@@ -8047,24 +8978,44 @@ function apply_perms(res) {
 	if (idp_login && acct == "*")
 		dst = idp_login.replace(/\{dst\}/g, get_evpath());
 
-	ebi('acc_info').innerHTML = '<span id="srv_info2"><span>' + srvinf +
-		'</span></span><span' + aclass + axs + L.access + '</span>' + (acct != '*' ?
-			'<form id="flogout" method="post" enctype="multipart/form-data"><input type="hidden" name="act" value="logout" /><input id="blogout" type="submit" value="' + L.logout + acct + '"></form>' :
-			'<a href="' + dst + '">' + L.login + '</a>');
+	function goHome(){
+		window.location.href = dst;
+	}
+
+	if(acct != '*'){
+		ebi('acc_name').innerHTML = acct;
+		ebi('acc_pfp').innerHTML = acct.substring(0, 1);
+		ebi('accessType').innerHTML = '<span' + aclass + axs + L.access + '</span>';
+		ebi('blogout').value = L.logout;
+		ebi('acc_button').onclick = function(){};
+	}
+	else{
+		ebi('blogout').style.display = 'none';
+		ebi('acc_name').innerHTML = L.login;
+		ebi('acc_pfp').innerHTML = fun_tgl ? '👤' : 'acc';
+		ebi('acc_button').onclick = goHome;
+	}
+	clmod(ebi('acc_pfp'), 'placeholder', acct == '*');
 
 	var o = QSA('#ops>a[data-perm]');
 	for (var a = 0; a < o.length; a++) {
 		var display = '';
+		var enabled = true;
 		var needed = o[a].getAttribute('data-perm').split(' ');
 		for (var b = 0; b < needed.length; b++) {
 			if (!has(perms, needed[b])) {
-				display = 'none';
+				enabled = false;
+				if(needed[b] != 'write')
+					display = 'none';
 			}
 		}
+		clmod(o[a], 'disabled', !enabled);
 		o[a].style.display = display;
 	}
+	clmod(ebi('up_quick'), 'disabled', !has(perms, 'write'));
+	ebi('bup_tgl').style.display = has(perms, 'write') ? '' : 'none';
 
-	var o = QSA('#ops>a[data-dep], #u2conf td[data-dep]');
+	var o = QSA('#ops>a[data-dep], #u2conf div[data-dep]');
 	for (var a = 0; a < o.length; a++)
 		o[a].style.display = (
 			o[a].getAttribute('data-dep') != 'idx' || have_up2k_idx
@@ -8082,7 +9033,7 @@ function apply_perms(res) {
 	var have_write = has(perms, "write"),
 		have_read = has(perms, "read"),
 		de = document.documentElement,
-		tds = QSA('#u2conf td');
+		tds = QSA('#u2conf div');
 
 	shr_who = res.shr_who || shr_who;
 	can_shr = acct != '*' && (have_read || have_write) && (
@@ -8113,8 +9064,14 @@ function apply_perms(res) {
 
 	widget.setvis();
 	thegrid.setvis();
-	if (!have_read && have_write)
+
+	var up_only = !have_read && have_write;
+	if (up_only){
 		goto('up2k');
+		clmod(document.documentElement, 'noscroll', false);
+	}
+	clmod(ebi('up2k'), 'unmodal', up_only);
+	clmod(ebi('opa_mkd'), 'vis', up_only);
 }
 
 
@@ -8152,7 +9109,7 @@ function find_file_col(txt) {
 function mk_files_header(taglist) {
 	var html = [
 		'<thead><tr>',
-		'<th name="lead"><span>c</span></th>',
+		'<th name="lead"><span>!</span></th>',
 		'<th name="href"><span>File Name</span></th>',
 		'<th name="sz" sort="int"><span>Size</span></th>'
 	];
@@ -8169,7 +9126,7 @@ function mk_files_header(taglist) {
 		html.push(tag + '</span></th>');
 	}
 	html = html.concat([
-		'<th name="ext"><span>T</span></th>',
+		'<th name="ext"><span>Ext</span></th>',
 		'<th name="ts"><span>Date</span></th>',
 		'</tr></thead>',
 	]);
@@ -8210,11 +9167,6 @@ var filecols = (function () {
 		r.toggle(t.textContent);
 	}
 
-	r.uivis = function () {
-		var hcols = ebi('hcols');
-		hcols.previousSibling.style.display = hcols.style.display = ((!thegrid || !thegrid.en) && (hidden.length || MOBILE)) ? 'block' : 'none';
-	};
-
 	r.set_style = function (unhide) {
 		hidden.sort();
 
@@ -8232,7 +9184,6 @@ var filecols = (function () {
 		}
 		hcols.innerHTML = html.join('\n');
 		hcols.onclick = hcols_click;
-		r.uivis();
 		r.add_btns();
 
 		var ohidden = [],
@@ -8291,26 +9242,28 @@ var filecols = (function () {
 		r.reset(true);
 	};
 
-	if (MOBILE)
-		ebi('hcolsh').onclick = function (e) {
-			ev(e);
-			if (r.picking)
-				return r.unpick();
+	ebi('hcolsh').onclick = function (e) {
+		clmod(this, 'on', !r.picking)
+		if (r.picking)
+			return r.unpick();
 
-			var lbs = QSA('#files>thead th');
-			for (var a = 0; a < lbs.length; a++) {
-				lbs[a].onclick = function (e) {
-					ev(e);
-					if (toast.tag == 'pickhide')
-						toast.hide();
+		var lbs = QSA('#files>thead th');
+		for (var a = 0; a < lbs.length; a++) {
+			lbs[a].onclick = function (e) {
+				ev(e);
+				if (toast.tag == 'pickhide')
+					toast.hide();
 
+				if(e.target.lastChild)
+					r.hide(e.target.lastChild.textContent)
+				else
 					r.hide(e.target.textContent);
-				};
 			};
-			r.picking = true;
-			clmod(ebi('files'), 'hhpick', 1);
-			toast.inf(0, L.cl_hpick, 'pickhide');
 		};
+		r.picking = true;
+		clmod(ebi('files'), 'hhpick', 1);
+		toast.inf(0, L.cl_hpick, 'pickhide');
+	};
 
 	r.unpick = function () {
 		r.picking = false;
@@ -8475,15 +9428,16 @@ var settheme = (function () {
 		chldr = !SPINNER_CSS && SPINNER == tre;
 
 	r.ldr = {
-		'4':['🌴'],
-		'5':['🌭', 'padding:0 0 .7em .7em;filter:saturate(3)'],
-		'6':['📞', 'padding:0;filter:brightness(2) sepia(1) saturate(3) hue-rotate(60deg)'],
-		'7':['▲', 'font-size:3em'], //cp437
+		'4': ['🌴'],
+		'5': ['🌭', 'padding:0 0 .7em .7em;filter:saturate(3)'],
+		'6': ['📞', 'padding:0;filter:brightness(2) sepia(1) saturate(3) hue-rotate(60deg)'],
+		'7': ['▲', 'font-size:3em'], //cp437
 	};
 
 	theme = sread('cpp_thm') || 'a';
-	if (!/^[a-x][yz]/.exec(theme))
+	if (!/^[a-x][yz]/.exec(theme)){
 		theme = dtheme;
+	}
 
 	themen = theme.split(/ /)[0];
 	light = !!(theme.indexOf('y') + 1);
@@ -8502,7 +9456,7 @@ var settheme = (function () {
 		var html = [],
 			cb = ebi('themes'),
 			itheme = ax.indexOf(theme[0]) * 2 + (light ? 1 : 0),
-			names = ['classic dark', 'classic light', 'pm-monokai', 'flat light', 'vice', 'hotdog stand', 'hacker', 'hi-con', 'phi95 dark', 'phi95'];
+			names = ['flat dark', 'flat light', 'fancy dark', 'fancy light', 'vice', 'hotdog stand', 'hacker', 'hi-con', 'phi95 dark', 'phi95'];
 
 		for (var a = 0; a < themes; a++)
 			html.push('<option value="{0}">{0} ┃ {1}</option>'.format(a, names[a] || 'custom'));
@@ -8642,12 +9596,12 @@ var arcfmt = (function () {
 			o.setAttribute("href", m[1] + arg + m[4]);
 			o.textContent = fmt.split('_')[0];
 		}
-		ebi('selzip').textContent = fmt.split('_')[0];
+		ebi('selzip').textContent = '⬇️' + fmt.split('_')[0];
 		ebi('selzip').setAttribute('fmt', arg);
 
 		QS('#zip1 span').textContent = fmt.split('_')[0];
 		ebi('zip1').setAttribute("href",
-			get_evpath() + (dk ? '?k=' + dk + '&': '?') + arg);
+			get_evpath() + (dk ? '?k=' + dk + '&' : '?') + arg);
 
 		if (!have_zip) {
 			ebi('zip1').style.display = 'none';
@@ -8785,7 +9739,8 @@ var msel = (function () {
 			delete r.hist[get_evpath()];
 	};
 	r.seltgl = function (e) {
-		ev(e);
+		e.stopPropagation();
+
 		var tr = this.parentNode,
 			id = tr2id(tr);
 
@@ -9137,7 +10092,7 @@ function show_md(md, name, div, url, depth) {
 		if (depth) {
 			clmod(div, 'raw', 1);
 			div.textContent = "--[ " + name + " ]---------\r\n" + md;
-			return toast.warn(10, errmsg + (WebAssembly ? 'failed to load marked.js' : 'your browser is too old'));
+			return toast.warn(3, errmsg + (WebAssembly ? 'failed to load marked.js' : 'your browser is too old'));
 		}
 
 		wfp_debounce.n--;
@@ -9349,7 +10304,7 @@ if (sb_lg && logues.length) {
 			var td = tr[a].cells[1],
 				ao = td.firstChild,
 				href = noq_href(ao),
-				isdir = href.endsWith('/'),
+				isdir = clgot(tr[a], 'dir'),
 				txt = ao.textContent;
 
 			td.setAttribute('sortv', (isdir ? '\t' : '') + txt);
@@ -9611,6 +10566,34 @@ ebi('path').onclick = function (e) {
 	return ev(e);
 };
 
+function scroll_v_to_h (e, o) {
+  ev(e);
+  var delta = e.deltaY || e.deltaX;
+  var maxScrollLeft = o.scrollWidth - o.clientWidth;
+
+  o.scrollLeft = Math.max(0, Math.min(maxScrollLeft, o.scrollLeft + delta));
+}
+function keep_right (o) {
+	o.scrollLeft = o.scrollWidth - o.clientWidth;
+}
+
+ebi('path').addEventListener('wheel', function (e) {
+	scroll_v_to_h(e, this);
+});
+
+ebi('ghead').addEventListener('wheel', function (e) {
+	scroll_v_to_h(e, this);
+});
+
+ebi('treeh').addEventListener('wheel', function (e) {
+	scroll_v_to_h(e, this);
+});
+
+if(FIREFOX && MOBILE){
+	// disable glitchy ::after gradient (scrollhint) (2026-04-26)
+	clmod(ebi('ghead'), 'noa', true);
+	clmod(ebi('treeh'), 'noa', true);
+}
 
 var scroll_y = -1;
 var scroll_vp = '\n';
@@ -9677,8 +10660,9 @@ ebi('files').onclick = ebi('docul').onclick = function (e) {
 		if (sz < 1024 * 1024 || showfile.taildoc)
 			fun();
 		else
-			modal.confirm(L.f_bigtxt.format(f2f(sz / 1024 / 1024, 1)), fun, function() {
-				modal.confirm(L.f_bigtxt2, tfun, null)});
+			modal.confirm(L.f_bigtxt.format(f2f(sz / 1024 / 1024, 1)), fun, function () {
+				modal.confirm(L.f_bigtxt2, tfun, null)
+			});
 
 		return ev(e);
 	}
@@ -9694,12 +10678,9 @@ ebi('files').onclick = ebi('docul').onclick = function (e) {
 
 
 var rcm = (function () {
-	if (MOBILE)
-		return {enabled: false}
-
 	var r = {};
-	bcfg_bind(r, 'enabled', 'rcm_en', drcm.charAt(0)=='y');
-	bcfg_bind(r, 'double', 'rcm_db', drcm.charAt(1)=='y');
+	bcfg_bind(r, 'enabled', 'rcm_en', drcm.charAt(0) == 'y');
+	bcfg_bind(r, 'double', 'rcm_db', drcm.charAt(1) == 'y');
 
 	var menu = ebi('rcm');
 	var nsFile = {
@@ -9714,64 +10695,9 @@ var rcm = (function () {
 	};
 	var selFile = jcp(nsFile);
 
-	function mktemp(is_dir) {
-		qsr('#rcm_tmp');
-		if (!thegrid.en) {
-			var row = mknod('tr', 'rcm_tmp',
-				'<td>-new-</td><td colspan="' + (QSA("#files thead th").length - 1) + '"><input id="tempname" class="i" type="text" placeholder="' + (is_dir ? 'Folder' : 'File') + ' Name"></td>');
-			QS("#files tbody").appendChild(row);
-		}
-		else {
-			var row = mknod('a', 'rcm_tmp',
-				'<span class="dir" style="align-self:end"><input id="tempname" class="dir" type="text" placeholder="' + (is_dir ? 'Folder' : 'File') + ' Name"></span>');
-			if (is_dir)
-				row.className = 'dir';
-			row.style.display = 'flex';
-			QS("#ggrid").appendChild(row);
-		}
-
-		function sendit(name) {
-			name = ('' + name).trim();
-			if (!name)
-				return;
-			var data = new FormData();
-			data.set("act", is_dir ? "mkdir" : "new_md");
-			data.set("name", name);
-
-			var req = new XHR();
-			req.open("POST", get_evpath());
-			req.onload = req.onerror = function() {
-				if (req.status == 405 || req.status == 500)
-					return toast.err(3, "a " + (is_dir ? "folder" : "file") + " with that name already exists.");
-				if (req.status < 200 || req.status > 399)
-					return toast.err(3, "couldn't create " + (is_dir ? "folder" : "file") + ": <br><code>" + esc(req.responseText) + '</code>');
-				treectl.goto();
-			};
-			req.send(data);
-		}
-
-		var input = ebi("tempname");
-		input.onblur = function() {
-			sendit(input.value);
-			// Chrome blurs elements when calling remove for some reason
-			input.onblur = null;
-			row.remove();
-		};
-		input.onkeydown = function(e) {
-			if (e.key == "Enter")
-				sendit(input.value);
-			if (e.key == "Enter" || e.key == "Escape") {
-				input.onblur = null;
-				row.remove();
-				ev(e);
-			}
-		};
-		input.focus();
-	}
-
 	var opts = QSA('#rcm a');
 	for (var i = 0; i < opts.length; i++) {
-		opts[i].onclick = function(e) {
+		opts[i].onclick = function (e) {
 			ev(e);
 			switch(e.target.id.slice(1)) {
 				case 'opn':
@@ -9784,7 +10710,7 @@ var rcm = (function () {
 				case 'pla': play('f-' + selFile.id); break;
 				case 'txt': showfile.show(selFile.name); break;
 				case 'md': location = selFile.path + (has(selFile.path, '?') ? '&v' : '?v'); break;
-				case 'cpl': cliptxt(selFile.url, function() {toast.ok(2, L.clipped)}); break;
+				case 'cpl': cliptxt(selFile.url, function () { toast.ok(2, L.clipped) }); break;
 				case 'dl': ebi('seldl').click(); break;
 				case 'zip': ebi('selzip').click(); break;
 				case 'del': fileman.delete(); break;
@@ -9866,13 +10792,38 @@ var rcm = (function () {
 		clmod(shr, 'hide', !can_shr || !get_evpath().indexOf(have_shr));
 		shr.innerHTML = has_sel ? L.rc_shs : L.rc_shf;
 
-		menu.style.left = x + 5 + 'px';
-		menu.style.top = y + 5 + 'px';
+		if(MOBILE){
+			clmod(menu, 'large', true);
+		}
+		var vh = document.documentElement.clientHeight;
+		var vw = document.documentElement.clientWidth;
+
+		var maxh = Math.min(y, vh / 2);
+		menu.style.maxHeight = 'calc(100% - ' + maxh + 'px - 2em)';
+
+		if(y > vh / 2){
+			// low click => menu upwards
+			menu.style.top = '';
+			menu.style.bottom = (vh - y) + 'px';
+		}
+		else{
+			menu.style.top = y + 'px';
+			menu.style.bottom = '';
+		}
+		if(x > vw / 2){
+			// far right click => menu leftwards
+			menu.style.left = '';
+			menu.style.right = (vw - x) + 'px';
+		}
+		else{
+			menu.style.left = x + 'px';
+			menu.style.right = '';
+		}
 		menu.style.display = 'block';
 		menu.focus();
 	}
 
-	r.hide = function(force) {
+	r.hide = function (force) {
 		if (!menu.style.display || (!force && menu.contains(document.activeElement)))
 			return;
 		if (selFile.elem && !selFile.no_dsel) {
@@ -9883,7 +10834,7 @@ var rcm = (function () {
 		menu.style.display = '';
 	}
 
-	ebi('wrap').oncontextmenu = function(e) {
+	r.show = function (e) {
 		if (!r.enabled || e.shiftKey || (r.double && menu.style.display) || /doc=/.exec(location.search)) {
 			r.hide(true);
 			return true;
@@ -9895,10 +10846,109 @@ var rcm = (function () {
 		}
 		ev(e);
 		var gfile = thegrid.en && e.target && e.target.closest('#ggrid > a');
-		show(xscroll() + e.clientX, yscroll() + e.clientY, gfile || e.target, gfile);
+		show(e.clientX, e.clientY, gfile || e.target, gfile);
 		return false;
+	}
+
+	ebi('wrap').oncontextmenu = function (e) {
+		r.show(e);
+	};
+	menu.onblur = function () { setTimeout(r.hide) };
+
+	return r;
+})();
+
+var drag = (function() {
+	var r = {is_dragging: false, no_warn: false};
+	bcfg_bind(r, "enabled", "den", true, function() {setTimeout(reload_browser, 1)});
+	var current = null, currLink = null;
+
+	r.mktarget = function(elem) {
+		if (!r.enabled) return;
+
+		elem.ondragenter = elem.ondragleave = elem.ondragover = function(e) {
+			if (!r.enabled) return;
+			var elemHref = basenames((elem.tagName == "A" ? elem : elem.querySelector("td:nth-child(2) a")).href.split("?")[0])
+			if (current == elem || elemHref == get_evpath() || currLink == elemHref) // Prevent folders being dragged into themselves
+				return;
+			ev(e);
+			clmod(elem, "dtarget", e.type != "dragleave");
+		};
+
+		elem.ondrop = function(e) {
+			ev(e);
+			clmod(elem, "dtarget");
+			clmod(current, "sel", true);
+			msel.selui();
+			fileman.clip = [];
+			fileman.cut();
+			msel.evsel();
+
+			if (fileman.clip.length) {
+				r.is_dragging = true;
+				(elem.tagName == "TR" ? elem.querySelector("a[id]") : elem).click();
+			}
+		};
+	}
+
+	r.initfiles = function() {
+		if (!r.enabled) return;
+
+		var files = QSA("#files tbody tr");
+		for (var i = 0; i < files.length; i++) {
+			var f = files[i];
+			f.draggable = true;
+			f.ondragstart = function(e) {
+				try{
+					currLink = basenames(e.target.querySelector("td:nth-child(2) a").href.split("?"));
+					current = e.target;
+					r.no_warn = true;
+				}
+				catch(ex){
+					console.log(e.target)
+					console.log(ex)
+				}
+			};
+			f.ondragend = function() {
+				r.no_warn = false;
+			};
+
+			var links = f.querySelectorAll("a");
+			for (var j = 0; j < links.length; j++)
+				links[j].draggable = false;
+
+			if (clgot(f, 'dir'))
+				r.mktarget(f);
+		}
+	};
+
+	r.initgrid = function() {
+		if (!r.enabled) return;
+
+		var files = QSA("#ggrid a");
+		for (var i = 0; i < files.length; i++) {
+			var f = files[i];
+			f.draggable = true;
+			f.ondragstart = function(e) {
+				try{
+					var a = ebi(e.target.getAttribute("ref"));
+					current = a.closest("tr");
+					currLink = basenames(a.href.split("?"));
+					r.no_warn = true;
+				}
+				catch(ex){
+					console.log(e.target)
+					console.log(ex)
+				}
+			}
+			f.ondragend = function() {
+				r.no_warn = false;
+			};
+
+			if (clgot(f, 'dir'))
+				r.mktarget(f);
+		}
 	};
-	menu.onblur = function() {setTimeout(r.hide)};
 
 	return r;
 })();
@@ -9935,12 +10985,10 @@ function reload_browser() {
 	filecols.set_style();
 
 	var parts = get_evpath().split('/'),
-		rm = ebi('entree'),
 		ftab = ebi('files'),
 		link = '', o;
 
-	while (rm.nextSibling)
-		rm.parentNode.removeChild(rm.nextSibling);
+	ebi('path').innerHTML = "";
 
 	for (var a = 0; a < parts.length - 1; a++) {
 		link += parts[a] + '/';
@@ -9948,11 +10996,16 @@ function reload_browser() {
 
 		o = mknod('a');
 		o.setAttribute('href', link2);
-		o.textContent = uricom_dec(parts[a]) || '/';
-		ebi('path').appendChild(mknod('i'));
+		o.textContent = uricom_dec(parts[a]) || (fun_tgl ? '🏠' : 'home');
 		ebi('path').appendChild(o);
+		ebi('path').appendChild(mknod('i'));
+		drag.mktarget(o);
 	}
 
+	setTimeout(function () {
+		ebi('path').scrollLeft = ebi('path').scrollWidth - ebi('path').clientWidth;
+	}, 100);
+
 	reload_mp();
 	try { showsort(ftab); } catch (ex) { }
 	makeSortable(ftab, function () {
@@ -9973,7 +11026,7 @@ function reload_browser() {
 	msel.render();
 }
 
-(function() {
+(function () {
 	var is_selma = false;
 	var dragging = false;
 
@@ -9982,19 +11035,19 @@ function reload_browser() {
 	var selbox = null;
 	var ttimer = null;
 
-	var lpdelay = 250; 
+	var lpdelay = 250;
 	var mvthresh = 44;
 
 	function unbox() {
 		qsr('.selbox');
 		ebi('gfiles').style.removeProperty('pointer-events')
 		ebi('wrap').style.removeProperty('user-select')
-		
+
 		if (selbox) {
 			console.log(selbox)
 			window.getSelection().removeAllRanges();
 		}
-		
+
 		is_selma = false;
 		dragging = false;
 		fwrap = null;
@@ -10015,6 +11068,9 @@ function reload_browser() {
 			if (ehidden) {
 				var tr = ehidden.closest('tr');
 				if (tr) clmod(tr, 'sel', m);
+
+				var chk = el.getElementsByTagName('input')[0];
+				if(chk) chk.checked = m;
 			}
 		}
 	}
@@ -10025,9 +11081,15 @@ function reload_browser() {
 	}
 
 	function sel_start(e) {
-		if (e.button !== 0 && e.type !== 'touchstart') return;
-		if (!thegrid.en || !treectl.dsel) return;
-		if (e.target.closest('#widget,#ops,.opview,.doc')) return;
+		try{
+			if (e.button !== 0 && e.type !== 'touchstart') return;
+			if (!thegrid.en || !treectl.dsel) return;
+			if (e.target.closest('#widget,#ops,.opview,.doc,#ggrid>a')) return;
+		}
+		catch(ex){
+			console.log(ex);
+			return;
+		}
 
 		if (e.target.closest('#gfiles'))
 			ebi('gfiles').style.userSelect = "none"
@@ -10037,15 +11099,15 @@ function reload_browser() {
 		starty = pos.y;
 		is_selma = true;
 		ttimer = null;
-		
+
 		if (e.type === 'touchstart') {
-			ttimer = setTimeout(function() {
+			ttimer = setTimeout(function () {
 				ttimer = null;
 				start_drag();
 			}, lpdelay);
 		}
 	}
-	
+
 	function start_drag() {
 		if (dragging) return;
 
@@ -10056,7 +11118,7 @@ function reload_browser() {
 
 		ebi('gfiles').style.pointerEvents = 'none';
 	}
-	
+
 	function sel_move(e) {
 		if (!is_selma) return;
 		var pos = getpp(e);
@@ -10071,7 +11133,7 @@ function reload_browser() {
 			return;
 		}
 		if (!dragging && dist > mvthresh && !window.getSelection().toString()) {
-			if (fwrap = e.target.closest('#wrap')) 
+			if (fwrap = e.target.closest('#wrap'))
 				fwrap.style.userSelect = 'none';
 			else return;
 			start_drag();
@@ -10113,18 +11175,18 @@ function reload_browser() {
 		window.addEventListener('touchmove', sel_move, { passive: false });
 		window.addEventListener('touchend', sel_end, { passive: true });
 
-		window.addEventListener('dragstart', function(e) {
+		window.addEventListener('dragstart', function (e) {
 			if (treectl.dsel && (is_selma || dragging)) {
 				e.preventDefault();
 			}
 		});
 	}
-	
+
 	dsel_init();
 })();
 
 
-var mpss = (function() {
+var mpss = (function () {
 	var r = {}, config, ssint, npaint = 0;
 
 	r.load = function () {
@@ -10162,7 +11224,7 @@ var mpss = (function() {
 
 		var gain = afilt.ssg.gain;
 		var duration = ae.duration || 0;
-	
+
 		var slimit = duration * (config.sthresh / 100);
 		var elimit = duration * (1 - (config.etresh / 100));
 		var in_limits = ae.currentTime < slimit || ae.currentTime > elimit;
diff --git a/copyparty/web/md.css b/copyparty/web/md.css
index e964865f..ade08a5c 100644
--- a/copyparty/web/md.css
+++ b/copyparty/web/md.css
@@ -320,7 +320,7 @@ blink {
 	}
 	html.z #toc,
 	html.z #mw {
-		scrollbar-color: #b80 #282828;
+		scrollbar-color: rgba(203, 203, 203, 0.634) #282828;
 	}
 	html.z #toc::-webkit-scrollbar-track {
 		background: #282828;
diff --git a/copyparty/web/md.js b/copyparty/web/md.js
index 9ecfca4b..7bde61b2 100644
--- a/copyparty/web/md.js
+++ b/copyparty/web/md.js
@@ -41,7 +41,7 @@ var dbg = function () { };
         link += parts[a] + (a < aa ? '/' : '');
         o = mknod('a');
         o.setAttribute('href', link);
-        o.textContent = uricom_dec(parts[a].split('?')[0]) || 'top';
+        o.textContent = uricom_dec(parts[a].split('?')[0]) || '🏠';
         dom_nav.appendChild(o);
     }
 })();
diff --git a/copyparty/web/mde.js b/copyparty/web/mde.js
index e44c9803..840aa036 100644
--- a/copyparty/web/mde.js
+++ b/copyparty/web/mde.js
@@ -9,7 +9,7 @@ var dom_md = ebi('mt');
 (function () {
     var n = location + '';
     n = (n.slice(n.indexOf('//') + 2).split('?')[0] + '?v').split('/');
-    n[0] = 'top';
+    n[0] = '🏠';
     var loc = [];
     var nav = [];
     for (var a = 0; a < n.length; a++) {
diff --git a/copyparty/web/splash.css b/copyparty/web/splash.css
index 832ef566..33abc871 100644
--- a/copyparty/web/splash.css
+++ b/copyparty/web/splash.css
@@ -5,60 +5,152 @@ html {
 	font-family: var(--font-main), sans-serif;
 	touch-action: manipulation;
 }
+
+#homebtn {
+	font-size: x-large; 
+	top: 1em;
+	left: 1em;
+	margin: 0 0 .3em 0;
+	padding: .4em .5em;
+	border-radius: .3em; 
+	background: var(--bg-u2);
+	border-left: var(--bg-u5) solid 1px;
+	border-top: var(--bg-u5) solid 1px;
+	border-right: var(--bg-u5) solid 1px;
+	border-bottom: 2px solid rgb(7, 130, 212);
+	position: fixed;
+	z-index: 10;
+	box-shadow: 0 0 1em color-mix(in oklab, var(--bg-max) 60%, transparent 40%);
+}
+#homebtn:hover, #homebtn:focus-visible {
+	background: var(--bg-u5);
+}
+
+#outer {
+	top: 0;
+	left: 0;
+	bottom: 0;
+	right: 0;
+	position: absolute;
+	display: flex;
+	flex-direction: column;
+	height: 100%;
+	width: 100%;
+}
+#middle {
+	display: flex;
+	flex-direction: column;
+	margin: auto;
+	justify-content: center;
+}
 #wrap {
-	max-width: 40em;
-	margin: 2em auto;
-	padding: 0 1em 3em 1em;
+	position: relative;
+	max-width: 80vw;
+	margin: 1.5em 2em;
+	margin-bottom: 3em;
+	padding: 1.5em;
+	padding-bottom: 0em;
 	line-height: 1.3em;
+	background: #282827;
+	border-radius: .5em;
+	border: var(--bg-u5) solid 1px;
+	box-shadow: 0 0 2em color-mix(in oklab, var(--bg-max) 60%, transparent 40%);
+}
+html.y #wrap {
+	background: color-mix(in oklab, var(--a-gray) 18%, var(--bg-max));
 }
 #wrap.w {
 	max-width: 96%;
 }
 h1 {
-	border-bottom: 1px solid #ccc;
-	margin: 2em 0 .4em 0;
+	margin: 1.5em 0 .4em 0;
 	padding: 0;
 	line-height: 1em;
+	font-size: x-large;
 	font-weight: normal;
 }
+#top_L {
+	display: flex;
+}
+#l {
+	margin-top: 0;
+	text-align: center;
+}
+#login {
+	border: var(--bg-u5) solid 1px;
+	border-radius: .3em;
+	padding: 1em;
+	margin: 2em auto 0 auto;
+	max-width: 25em;
+}
 li {
 	margin: 1em 0;
 }
+p {
+  	margin: 0 .2em;
+}
 #lo,
 a {
-	color: #047;
-	background: #fff;
+	color: #fff;
+	background: rgba(5, 92, 184, 0.69);
 	text-decoration: none;
 	white-space: nowrap;
-	border-bottom: 1px solid #8ab;
+	border-bottom: 2px solid rgb(3, 50, 112);
 	border-radius: .2em;
 	padding: .2em .6em;
 	margin: 0 .3em;
 }
+#lo:hover, #lo:focus-visible,
+a:hover, a:focus-visible {
+	background: rgb(10, 134, 206);
+}
 td a {
 	margin: 0;
 }
 #wb,
 #w {
 	color: #fff;
-	background: #940;
-	border-color: #b70;
+	background: rgba(50, 158, 4, 0.69);
+	border-color: rgb(20, 90, 3);
+}
+#wb:hover, #wb:focus-visible,
+#w:hover, #w:focus-visible {
+	background: rgb(93, 180, 12);
 }
 .af,
 .logout {
 	float: right;
 	margin: -.2em 0 0 .8em;
 }
+
+#a {
+	background: transparent;
+	border: var(--bg-u5) solid 1px;
+	font-weight: bold;
+	padding: .2em .5em;
+}
+#a:hover, #a:focus-visible {
+	background: var(--bg-u5);
+}
+html.y #a {
+	color: #222;
+}
 #lo,
 .logout,
 a.r {
-	color: #c04;
-	border-color: #c7a;
-}
-a.g {
-	color: #0a0;
-	border-color: #3a0;
-	box-shadow: 0 .3em 1em #4c0;
+	background: rgba(230, 3, 3, 0.61);
+	border-color: rgb(178, 5, 66);
+}
+#lo:hover, #lo:focus-visible,
+.logout:hover, .logout:focus-visible,
+a.r:hover, a.r:focus-visible {
+	background: rgb(209, 4, 4);
+}
+#a.g {
+	background: rgb(254, 207, 20);
+	border-color: rgb(224, 177, 7);
+	box-shadow: 0 .3em 1em rgba(240, 149, 3, 0.584);
+	color: #000;
 }
 #repl,
 #pb a {
@@ -69,14 +161,14 @@ a.g {
 }
 #repl {
 	position: fixed;
-	bottom: .25em;
-	left: .2em;
+	bottom: .5em;
+	left: .5em;
 }
 #pb {
 	opacity: .5;
 	position: fixed;
-	bottom: .25em;
-	right: .3em;
+	bottom: .5em;
+	right: .5em;
 }
 #pb span {
 	opacity: .6;
@@ -85,7 +177,9 @@ a.g {
 	margin: 0;
 }
 table {
-	border-collapse: collapse;
+	overflow-x: auto;
+	display: block;
+	overflow-y: hidden;
 }
 .vols td,
 .vols th {
@@ -125,7 +219,7 @@ table {
 .agr a,
 .agr form {
 	margin: 0 .5em 0 0;
-	line-height: 4em;
+	line-height: 2.5em;
 }
 .agr form,
 .agr input {
@@ -199,48 +293,45 @@ html.z {
 html.z h1 {
 	border-color: #777;
 }
-html.z #lo,
-html.z a {
-	color: #fff;
-	background: #057;
-	border-color: #37a;
-}
-html.z .logout,
-html.z #lo,
-html.z a.r {
-	background: #804;
-	border-color: #c28;
-}
-html.z a.g {
-	background: #470;
-	border-color: #af4;
-	box-shadow: 0 .3em 1em #7d0;
-}
 form {
 	line-height: 2.5em;
+	display: flex;
+	flex-direction: column;
+	margin: auto;
+}
+#lp {
+	margin: 1em 0;
+	background: none;
+	padding: .5em;
+}
+#lp::placeholder {
+	font-size: medium;
 }
 #x,
 input {
-	color: #a50;
-	background: #fff;
-	border: 1px solid #a50;
+	color: #fff;
+	background: rgb(39, 130, 204);
+	border-color: rgb(72, 182, 255);
 	border-radius: .3em;
-	padding: .25em .6em;
-	margin: 0 .3em 0 0;
+	padding: .4em .6em;
+	margin: 0;
 	font-size: 1em;
 }
+#x:hover, #x:focus-visible,
+input:hover, input:focus-visible {
+	background: linear-gradient(-10deg,  rgb(10, 77, 145), rgb(39, 130, 204));
+}
 input::placeholder {
 	font-size: 1.2em;
-	font-style: italic;
 	letter-spacing: .04em;
 	opacity: 0.64;
-	color: #930;
+	color: #000;
 }
-#x,
-html.z input {
-	color: #fff;
-	background: #626;
-	border-color: #c2c;
+input:autofill {
+  box-shadow: 0 0 0 40px #1f3b67 inset;
+}
+html.y input:autofill {
+  box-shadow: 0 0 0 40px #a2c9e6 inset;
 }
 html.z input::placeholder {
 	color: #fff;
@@ -257,3 +348,13 @@ html.bz {
 html.bz .vols img {
 	filter: sepia(0.8) hue-rotate(180deg);
 }
+
+@media (max-width: 55em){
+	#homebtn {
+		position: initial;
+		display: inline-block;
+	}
+	#login {
+		margin-top: .7em;
+	}
+}
diff --git a/copyparty/web/splash.html b/copyparty/web/splash.html
index 47f4d664..d28843ce 100644
--- a/copyparty/web/splash.html
+++ b/copyparty/web/splash.html
@@ -13,196 +13,201 @@
 </head>
 
 <body>
-	<div id="wrap">
-		{%- if not in_shr %}
-		<a id="a" href="{{ r }}/?h{{ re }}" class="af">refresh</a>
-		<a id="v" href="{{ r }}/?hc" class="af">connect</a>
-
-			{%- if this.uname == '*' %}
-		<p id="b">howdy stranger &nbsp; <small>(you're not logged in)</small></p>
-			{%- else %}
-				{%- if this.args.idp_logout %}
-		<a id="c" href="{{ this.args.idp_logout }}" class="logout">logout</a>
-				{%- else %}
-		<a id="c" href="{{ r }}/?pw=x" class="logout">logout</a>
+	<div id="outer">
+		<div id="middle">
+			<div id="wrap">
+				<a id="homebtn" href="/">🏠</a>
+
+				{%- if not in_shr %}
+				<a id="a" href="{{ r }}/?h{{ re }}" class="af" tt="toggle auto-refresh">↻</a>
+				<a id="v" href="{{ r }}/?hc" class="af">Connect</a>
+
+					{%- if this.uname == '*' %}
+				<p id="b">howdy stranger &nbsp; <small>(you're not logged in)</small></p>
+					{%- else %}
+						{%- if this.args.idp_logout %}
+				<a id="c" href="{{ this.args.idp_logout }}" class="logout">Logout</a>
+						{%- else %}
+				<a id="c" href="{{ r }}/?pw=x" class="logout">Logout</a>
+						{%- endif %}
+				<p><span id="m">welcome back,</span> <strong id="un">{{ this.uname|e }}</strong></p>
+					{%- endif %}
 				{%- endif %}
-		<p><span id="m">welcome back,</span> <strong id="un">{{ this.uname|e }}</strong></p>
-			{%- endif %}
-		{%- endif %}
 
-		{%- if msg %}
-		<div id="msg">
-			{{ msg }}
-		</div>
-		{%- endif %}
-
-		{%- if ups %}
-		<h1 id="aa">incoming files:</h1>
-			<table class="vols">
-				<thead><tr><th>%</th><th>speed</th><th>eta</th><th>idle</th><th>dir</th><th>file</th></tr></thead>
-				<tbody>
-					{%- for u in ups %}
-					<tr><td>{{ u[0] }}</td><td>{{ u[1] }}</td><td>{{ u[2] }}</td><td>{{ u[3] }}</td><td><a href="{{ r }}{{ u[4] }}">{{ u[5]|e }}</a></td><td>{{ u[6]|e }}</td></tr>
-					{%- endfor %}
-				</tbody>
-			</table>
-		{%- endif %}
-
-		{%- if dls %}
-		<h1 id="ae">active downloads:</h1>
-			<table class="vols">
-				<thead><tr><th>%</th><th>sent</th><th>speed</th><th>eta</th><th>idle</th><th></th><th>dir</th><th>file</th></tr></thead>
-				<tbody>
-					{%- for u in dls %}
-					<tr><td>{{ u[0] }}</td><td>{{ u[1] }}</td><td>{{ u[2] }}</td><td>{{ u[3] }}</td><td>{{ u[4] }}</td><td>{{ u[5] }}</td><td><a href="{{ r }}{{ u[6] }}">{{ u[7]|e }}</a></td><td>{{ u[8] }}</td></tr>
-					{%- endfor %}
-				</tbody>
-			</table>
-		{%- endif %}
-
-		{%- if avol %}
-		<h1>admin panel:</h1>
-		<table><tr><td> <!-- hehehe -->
-			<table class="num">
-				<tr><td>scanning</td><td>{{ scanning }}</td></tr>
-				<tr><td>hash-q</td><td>{{ hashq }}</td></tr>
-				<tr><td>tag-q</td><td>{{ tagq }}</td></tr>
-				<tr><td>mtp-q</td><td>{{ mtpq }}</td></tr>
-				<tr><td>db-act</td><td id="u">{{ dbwt }}</td></tr>
-			</table>
-		</td><td>
-			<table class="vols">
-				<thead><tr><th>vol</th><th id="t">action</th><th>status</th></tr></thead>
-				<tbody>
-					{%- for mp in avol %}
-					{%- if mp in vstate and vstate[mp] %}
-					<tr><td><a href="{{ r }}{{ mp }}{{ url_suf }}">{{ mp }}</a></td><td><a class="s" href="{{ r }}{{ mp }}?scan">rescan</a></td><td>{{ vstate[mp] }}</td></tr>
+				<div id="login">
+					{%- if in_shr %}
+					<h1 id="z">Unlock this share</h1>
+					<div>
+						<form id="lf" method="post" enctype="multipart/form-data" action="{{ r }}/{{ qvpath }}">
+							<input type="hidden" id="la" name="act" value="login" />
+							<input type="password" id="lp" name="cppwd" placeholder="Password" />
+							<input type="hidden" name="uhash" id="uhash" value="x" />
+							<input type="submit" id="ls" value="Unlock" />
+							{%- if ahttps %}
+							<a id="w" href="{{ ahttps }}">Switch to https</a>
+							{%- endif %}
+							<div id="lm"></div>
+						</form>
+					</div>
+					{%- else %}
+						{%- if this.uname == '*' %}
+					<h1 id="l">Login for more</h1>
+						{%- else %}
+					<h1 id="l">Change account</h1>
+						{%- endif %}
+					<div>
+						{%- if this.args.idp_login %}
+						<ul><li>
+							<a href="{{ this.args.idp_login | replace("{dst}",r+"/"+qvpath) }}">{{ this.args.idp_login_t }}</a>
+							{%- if this.args.ao_have_pw %}or alternatively{%- endif %}
+						</li></ul>
+						{%- endif %}
+						{%- if this.args.ao_have_pw %}
+						<form id="lf" method="post" enctype="multipart/form-data" action="{{ r }}/{{ qvpath }}">
+							<input type="hidden" id="la" name="act" value="login" />
+							{%- if this.args.usernames %}
+							<input type="text" id="lu" name="uname" placeholder="Username" size="12" />
+							<input type="password" id="lp" name="cppwd" placeholder="Password" size="12" />
+							{%- else %}
+							<input type="password" id="lp" name="cppwd" placeholder="Password" />
+							{%- endif %}
+							<input type="hidden" name="uhash" id="uhash" value="x" />
+							<input type="submit" id="ls" value="Login" />
+							{%- if chpw %}
+							<a id="x" href="#">Change password</a>
+							{%- endif %}
+							<div id="lm"></div>
+						</form>
+						{%- endif %}
+					</div>
 					{%- endif %}
-					{%- endfor %}
-				</tbody>
-			</table>
-		</td></tr></table>
-		<div class="btns">
-			<a id="d" href="{{ r }}/?stack">dump stack</a>
-			<a id="e" href="{{ r }}/?reload=cfg">reload cfg</a>
-		</div>
-		{%- endif %}
-
-		{%- if rvol %}
-		<h1 id="f">you can browse:</h1>
-		<ul>
-			{%- for mp in rvol %}
-			<li><a href="{{ r }}{{ mp }}{{ url_suf }}">{{ mp }}</a></li>
-			{%- endfor %}
-		</ul>
-		{%- endif %}
-
-		{%- if wvol %}
-		<h1 id="g">you can upload to:</h1>
-		<ul>
-			{%- for mp in wvol %}
-			<li><a href="{{ r }}{{ mp }}{{ url_suf }}">{{ mp }}</a></li>
-			{%- endfor %}
-		</ul>
-		{%- endif %}
-
-		{%- if in_shr %}
-		<h1 id="z">unlock this share:</h1>
-		<div>
-			<form id="lf" method="post" enctype="multipart/form-data" action="{{ r }}/{{ qvpath }}">
-				<input type="hidden" id="la" name="act" value="login" />
-				<input type="password" id="lp" name="cppwd" placeholder=" password" />
-				<input type="hidden" name="uhash" id="uhash" value="x" />
-				<input type="submit" id="ls" value="Unlock" />
-				{%- if ahttps %}
-				<a id="w" href="{{ ahttps }}">switch to https</a>
+				</div>
+
+				{%- if msg %}
+				<div id="msg">
+					{{ msg }}
+				</div>
 				{%- endif %}
-				<div id="lm"></div>
-			</form>
-		</div>
-		{%- else %}
-			{%- if this.uname == '*' %}
-		<h1 id="l">login for more:</h1>
-			{%- else %}
-		<h1 id="l">change account:</h1>
-			{%- endif %}
-		<div>
-			{%- if this.args.idp_login %}
-			<ul><li>
-				<a href="{{ this.args.idp_login | replace("{dst}",r+"/"+qvpath) }}">{{ this.args.idp_login_t }}</a>
-				{%- if this.args.ao_have_pw %}or alternatively:{%- endif %}
-			</li></ul>
-			{%- endif %}
-			{%- if this.args.ao_have_pw %}
-			<form id="lf" method="post" enctype="multipart/form-data" action="{{ r }}/{{ qvpath }}">
-				<input type="hidden" id="la" name="act" value="login" />
-				{%- if this.args.usernames %}
-				<input type="text" id="lu" name="uname" placeholder=" username" size="12" />
-				<input type="password" id="lp" name="cppwd" placeholder=" password" size="12" />
-				{%- else %}
-				<input type="password" id="lp" name="cppwd" placeholder=" password" />
+
+				{%- if ups %}
+				<h1 id="aa">Incoming files</h1>
+					<table class="vols">
+						<thead><tr><th>%</th><th>Speed</th><th>Eta</th><th>Idle</th><th>Dir</th><th>File</th></tr></thead>
+						<tbody>
+							{%- for u in ups %}
+							<tr><td>{{ u[0] }}</td><td>{{ u[1] }}</td><td>{{ u[2] }}</td><td>{{ u[3] }}</td><td><a href="{{ r }}{{ u[4] }}">{{ u[5]|e }}</a></td><td>{{ u[6]|e }}</td></tr>
+							{%- endfor %}
+						</tbody>
+					</table>
 				{%- endif %}
-				<input type="hidden" name="uhash" id="uhash" value="x" />
-				<input type="submit" id="ls" value="login" />
-				{%- if chpw %}
-				<a id="x" href="#">change password</a>
+
+				{%- if dls %}
+				<h1 id="ae">Active downloads</h1>
+					<table class="vols">
+						<thead><tr><th>%</th><th>Sent</th><th>Speed</th><th>Eta</th><th>Idle</th><th></th><th>Dir</th><th>File</th></tr></thead>
+						<tbody>
+							{%- for u in dls %}
+							<tr><td>{{ u[0] }}</td><td>{{ u[1] }}</td><td>{{ u[2] }}</td><td>{{ u[3] }}</td><td>{{ u[4] }}</td><td>{{ u[5] }}</td><td><a href="{{ r }}{{ u[6] }}">{{ u[7]|e }}</a></td><td>{{ u[8] }}</td></tr>
+							{%- endfor %}
+						</tbody>
+					</table>
 				{%- endif %}
-				{%- if ahttps %}
-				<a id="w" href="{{ ahttps }}">switch to https</a>
+
+				{%- if avol %}
+				<h1>Admin panel</h1>
+				<table><tr><td> <!-- hehehe -->
+					<table class="num">
+						<tr><td>scanning</td><td>{{ scanning }}</td></tr>
+						<tr><td>hash-q</td><td>{{ hashq }}</td></tr>
+						<tr><td>tag-q</td><td>{{ tagq }}</td></tr>
+						<tr><td>mtp-q</td><td>{{ mtpq }}</td></tr>
+						<tr><td>db-act</td><td id="u">{{ dbwt }}</td></tr>
+					</table>
+				</td><td>
+					<table class="vols">
+						<thead><tr><th>vol</th><th id="t">action</th><th>status</th></tr></thead>
+						<tbody>
+							{%- for mp in avol %}
+							{%- if mp in vstate and vstate[mp] %}
+							<tr><td><a href="{{ r }}{{ mp }}{{ url_suf }}">{{ mp }}</a></td><td><a class="s" href="{{ r }}{{ mp }}?scan">rescan</a></td><td>{{ vstate[mp] }}</td></tr>
+							{%- endif %}
+							{%- endfor %}
+						</tbody>
+					</table>
+				</td></tr></table>
+				<div class="btns">
+					<a id="d" href="{{ r }}/?stack">Dump stack</a>
+					<a id="e" href="{{ r }}/?reload=cfg">Reload cfg</a>
+				</div>
 				{%- endif %}
-				<div id="lm"></div>
-			</form>
-			{%- endif %}
-		</div>
-		{%- endif %}
 
-		<h1 id="cc">other stuff:</h1>
-		<div class="agr">
-			{%- if ahttps %}
-			<a id="wb" href="{{ ahttps }}">switch to https</a><br />
-			{%- endif %}
+				{%- if rvol %}
+				<h1 id="f">You can browse</h1>
+				<ul>
+					{%- for mp in rvol %}
+					<li><a href="{{ r }}{{ mp }}{{ url_suf }}">{{ mp }}</a></li>
+					{%- endfor %}
+				</ul>
+				{%- endif %}
 
-			<a id="af" href="{{ r }}/?ru">show recent uploads</a><br />
+				{%- if wvol %}
+				<h1 id="g">You can upload to</h1>
+				<ul>
+					{%- for mp in wvol %}
+					<li><a href="{{ r }}{{ mp }}{{ url_suf }}">{{ mp }}</a></li>
+					{%- endfor %}
+				</ul>
+				{%- endif %}
 
-			{%- if this.uname != '*' and this.args.shr %}
-			<a id="y" href="{{ r }}/?shares">edit shares</a><br />
-			{%- endif %}
+				<h1 id="cc">Other stuff</h1>
+				<div class="agr">
+					{%- if ahttps %}
+					<a id="wb" href="{{ ahttps }}">Switch to https</a><br />
+					{%- endif %}
 
-            {%- if this.uname in this.args.idp_adm_set %}
-			<a id="ag" href="{{ r }}/?idp">view idp cache</a><br />
-			{%- endif %}
+					<a id="af" href="{{ r }}/?ru">Show recent uploads</a><br />
 
-			<a id="k" href="{{ r }}/?reset" class="r" onclick="localStorage.clear();return true">reset client settings</a><br />
+					{%- if this.uname != '*' and this.args.shr %}
+					<a id="y" href="{{ r }}/?shares">Edit shares</a><br />
+					{%- endif %}
 
-			{%- if this.uname != '*' and not in_shr %}
-			<form method="post" enctype="multipart/form-data">
-				<input type="hidden" name="act" value="logout" />
-				<input type="submit" id="lo" value="logout “{{ this.uname|e }}” everywhere" />
-			</form>
-			{%- endif %}
-		</div>
-		<ul>
-			{%- if k304 or k304vis %}
-			{%- if k304 %}
-			<li><a id="h" href="{{ r }}/?cc&setck=k304=n">disable k304</a> (currently enabled)
-			{%- else %}
-			<li><a id="i" href="{{ r }}/?cc&setck=k304=y" class="r">enable k304</a> (currently disabled)
-			{%- endif %}
-			<blockquote id="j">enabling k304 will disconnect your client on every HTTP 304, which can prevent some buggy proxies from getting stuck (suddenly not loading pages), <em>but</em> it will also make things slower in general</blockquote></li>
-			{%- endif %}
-
-			{%- if no304 or no304vis %}
-			{%- if no304 %}
-			<li><a id="ab" href="{{ r }}/?cc&setck=no304=n">disable no304</a> (currently enabled)
-			{%- else %}
-			<li><a id="ac" href="{{ r }}/?cc&setck=no304=y" class="r">enable no304</a> (currently disabled)
-			{%- endif %}
-			<blockquote id="ad">enabling no304 will disable all caching; try this if k304 wasn't enough. This will waste a huge amount of network traffic!</blockquote></li>
-			{%- endif %}
-		</ul>
+					{%- if this.uname in this.args.idp_adm_set %}
+					<a id="ag" href="{{ r }}/?idp">View idp cache</a><br />
+					{%- endif %}
+
+					<a id="k" href="{{ r }}/?reset" class="r" onclick="localStorage.clear();return true">Reset client settings</a><br />
+
+					{%- if this.uname != '*' and not in_shr %}
+					<form method="post" enctype="multipart/form-data">
+						<input type="hidden" name="act" value="logout" />
+						<input type="submit" id="lo" value="Logout “{{ this.uname|e }}” everywhere" />
+					</form>
+					{%- endif %}
+				</div>
+				<ul>
+					{%- if k304 or k304vis %}
+					{%- if k304 %}
+					<li><a id="h" href="{{ r }}/?cc&setck=k304=n">disable k304</a> (currently enabled)
+					{%- else %}
+					<li><a id="i" href="{{ r }}/?cc&setck=k304=y" class="r">enable k304</a> (currently disabled)
+					{%- endif %}
+					<blockquote id="j">enabling k304 will disconnect your client on every HTTP 304, which can prevent some buggy proxies from getting stuck (suddenly not loading pages), <em>but</em> it will also make things slower in general</blockquote></li>
+					{%- endif %}
 
+					{%- if no304 or no304vis %}
+					{%- if no304 %}
+					<li><a id="ab" href="{{ r }}/?cc&setck=no304=n">disable no304</a> (currently enabled)
+					{%- else %}
+					<li><a id="ac" href="{{ r }}/?cc&setck=no304=y" class="r">enable no304</a> (currently disabled)
+					{%- endif %}
+					<blockquote id="ad">enabling no304 will disable all caching; try this if k304 wasn't enough. This will waste a huge amount of network traffic!</blockquote></li>
+					{%- endif %}
+				</ul>
+
+			</div>
+		</div>
 	</div>
-	<a href="#" id="repl">π</a>
+	<a href="#" id="repl" style="opacity: .4;">π</a>
 	{%- if not this.args.nb %}
 	<span id="pb"><span>powered by</span> <a href="{{ this.args.pb_url }}">copyparty {{ver}}</a></span>
 	{%- endif %}
diff --git a/copyparty/web/svcs.html b/copyparty/web/svcs.html
index bf1c1517..ba242776 100644
--- a/copyparty/web/svcs.html
+++ b/copyparty/web/svcs.html
@@ -14,6 +14,8 @@
 </head>
 
 <body>
+    <a id="homebtn" href="/?h">⬅️</a>
+
 	<div id="wrap" class="w">
         <div class="cn">
             <p class="btns"><a href="/{{ rvp }}">browse files</a> // <a href="{{ r }}/?h">control panel</a></p>
diff --git a/copyparty/web/tl/chi.js b/copyparty/web/tl/chi.js
index ac7184f5..6298f8ea 100644
--- a/copyparty/web/tl/chi.js
+++ b/copyparty/web/tl/chi.js
@@ -5,7 +5,7 @@ Ls.chi = {
 	"tt": "中文",
 
 	"cols": {
-		"c": "操作按钮",
+		"!": "操作按钮",
 		"dur": "时长",
 		"q": "质量 / 比特率",
 		"Ac": "音频编码",
@@ -14,7 +14,7 @@ Ls.chi = {
 		"Ahash": "音频校验和",
 		"Vhash": "视频校验和",
 		"Res": "分辨率",
-		"T": "文件类型",
+		"Ext": "文件类型",
 		"aq": "音频质量 / 比特率",
 		"vq": "视频质量 / 比特率",
 		"pixfmt": "子采样 / 像素结构",
@@ -33,7 +33,7 @@ Ls.chi = {
 			["G", "切换列表 / 网格视图"],
 			["T", "切换缩略图 / 图标"],
 			["⇧ A/D", "缩略图大小"],
-			["ctrl-K", "删除选中项"],
+			["ctrl-K/Del", "删除选中项"],
 			["ctrl-X", "剪切选中项到剪贴板"],
 			["ctrl-C", "复制选中项到剪贴板"],
 			["ctrl-V", "粘贴（移动/复制）到此处"],
@@ -107,9 +107,9 @@ Ls.chi = {
 	"ht_and": "又 ",
 
 	"goh": "控制面板",
-	"gop": '上一个同级文件夹">前',
-	"gou": '上一级文件夹">上',
-	"gon": '下一个文件夹">后',
+	"gop": '上一个同级文件夹',
+	"gou": '上一级文件夹',
+	"gon": '下一个文件夹',
 	"logout": "登出 ",
 	"login": "登录",
 	"access": " 权限",
@@ -157,7 +157,7 @@ Ls.chi = {
 	"ut_u2ts": "将最后修改的时间戳$N从你的文件系统复制到服务器\">📅",
 	"ut_ow": "覆盖服务器上的现有文件？$N🛡️：不要覆盖（会生成新文件名）$N🕒：如果服务器文件较旧则覆盖$N♻️：只要文件内容不同就覆盖$N⏭️：无条件跳过所有已有文件",
 	"ut_mt": "在上传时继续哈希其他文件$N$N如果你的 CPU 或硬盘是瓶颈，可能需要禁用",
-	"ut_ask": '上传开始前询问确认">💭',
+	"ut_ask": '上传开始前询问确认',
 	"ut_pot": "通过简化界面来$N提高慢设备上的上传速度",
 	"ut_srch": "不会真的上传，而是检查文件是否$N已经存在于服务器上（将扫描你可以读取的所有文件夹）",
 	"ut_par": "设置为 0 可暂停上传$N$N如果你的网络很慢/延迟很高，请增加该值$N$N在局域网内/瓶颈在服务器硬盘时，请保持该值为 1",
@@ -288,9 +288,9 @@ Ls.chi = {
 	"ml_drc": "动态范围压缩器",
 	"ml_ss": "无声段自动快进",
 
-	"mt_loop": "单曲循环\">🔁",
+	"mt_loop": "单曲循环",
 	"mt_one": "播完一首歌曲后停止\">1️⃣",
-	"mt_shuf": "随机播放各文件夹中的歌曲\">🔀",
+	"mt_shuf": "随机播放各文件夹中的歌曲",
 	"mt_aplay": "如果链接中有歌曲 ID，则自动播放$N$N禁用此选项将不再在播放音乐时更新页面 URL 中的歌曲 ID，以防止设置丢失但 URL 保留时又自动播放起来\">自▶",
 	"mt_preload": "在歌曲快结束时开始加载下一首歌，以实现无缝播放\">预载",
 	"mt_prescan": "在最后一首歌结束之前自动跳转到下一个文件夹$N以防止浏览器换页时停止播放\">预扫",
@@ -305,7 +305,7 @@ Ls.chi = {
 	"mt_follow": "切换歌曲时，将正在播放的曲目滚动到视野内\">🎯",
 	"mt_compact": "紧凑的控制按钮\">⟎",
 	"mt_uncache": "清除缓存&nbsp;$N（如果你的浏览器因缓存歌曲损坏而无法播放，请尝试此操作）\">清缓",
-	"mt_mloop": "循环播放当前播放中的文件夹\">🔁 循环",
+	"mt_mloop": "循环播放当前播放中的文件夹",
 	"mt_mnext": "加载下一个文件夹并继续播放\">📂 继续",
 	"mt_mstop": "停止播放\">⏸ 停止",
 	"mt_cflac": "将 flac / wav 转换为 {0}\">flac",
diff --git a/copyparty/web/tl/cze.js b/copyparty/web/tl/cze.js
index bab572b5..cd94c269 100644
--- a/copyparty/web/tl/cze.js
+++ b/copyparty/web/tl/cze.js
@@ -5,7 +5,7 @@ Ls.cze = {
 	"tt": "Čeština",
 
 	"cols": {
-		"c": "tlačítka akcí",
+		"!": "tlačítka akcí",
 		"dur": "doba trvání",
 		"q": "kvalita / bitrate",
 		"Ac": "audio kodek",
@@ -14,7 +14,7 @@ Ls.cze = {
 		"Ahash": "kontrolní součet audia",
 		"Vhash": "kontrolní součet videa",
 		"Res": "rozlišení",
-		"T": "typ souboru",
+		"Ext": "typ souboru",
 		"aq": "kvalita zvuku / bitrate",
 		"vq": "kvalita videa / bitrate",
 		"pixfmt": "podvzorkování / struktura pixelů",
@@ -33,7 +33,7 @@ Ls.cze = {
 			["G", "přepnout seznam / zobrazení mřížky"],
 			["T", "přepnout náhledy / ikony"],
 			["⇧ A/D", "velikost náhledů"],
-			["ctrl-K", "smazat vybrané"],
+			["ctrl-K/Del", "smazat vybrané"],
 			["ctrl-X", "vyjmout výběr do schránky"],
 			["ctrl-C", "kopírovat výběr do schránky"],
 			["ctrl-V", "vložit (přesunout/kopírovat) zde"],
@@ -111,9 +111,9 @@ Ls.cze = {
 	"ht_and": " a ",
 
 	"goh": "ovládací panel",
-	"gop": 'předchozí sourozenec">předchozí',
-	"gou": 'nadřazená složka">nahoru',
-	"gon": 'následující složka">následující',
+	"gop": 'předchozí sourozenec',
+	"gou": 'nadřazená složka',
+	"gon": 'následující složka',
 	"logout": "Odhlásit ",
 	"login": "Přihlásit se", //m
 	"access": " přístup",
@@ -161,7 +161,7 @@ Ls.cze = {
 	"ut_u2ts": "kopírovat časovou značku poslední změny$Nz vašeho souborového systému na server\">📅",
 	"ut_ow": "přepsat existující soubory na serveru?$N🛡️: nikdy (místo toho vytvoří nový název souboru)$N🕒: přepsat pokud je soubor na serveru starší než váš$N♻️: vždy přepsat pokud se soubory liší$N⏭️: bezpodmínečně přeskočit všechny existující soubory", //m
 	"ut_mt": "pokračovat v hashování ostatních souborů během nahrávání$N$Nmožná zakázat pokud je vaše CPU nebo HDD bottleneckem",
-	"ut_ask": 'požádat o potvrzení před zahájením nahrávání">💭',
+	"ut_ask": 'požádat o potvrzení před zahájením nahrávání',
 	"ut_pot": "zlepšit rychlost nahrávání na pomalých zařízeních$Nzjednodušením UI",
 	"ut_srch": "skutečně nenahrávat, místo toho zkontrolovat zda soubory již $N existují na serveru (prohledá všechny složky které můžete číst)",
 	"ut_par": "pozastavit nahrávání nastavením na 0$N$Nzvýšit pokud je vaše připojení pomalé / vysoká latence$N$Nponechat na 1 v LAN nebo pokud je HDD serveru bottleneckem",
@@ -292,9 +292,9 @@ Ls.cze = {
 	"ml_drc": "kompresor dynamického rozsahu",
 	"ml_ss": "přeskočit ticho", //m
 
-	"mt_loop": "smyčka/opakovat jednu skladbu\">🔁",
+	"mt_loop": "smyčka/opakovat jednu skladbu",
 	"mt_one": "zastavit po jedné skladbě\">1️⃣",
-	"mt_shuf": "zamíchat skladby v každé složce\">🔀",
+	"mt_shuf": "zamíchat skladby v každé složce",
 	"mt_aplay": "automatické přehrávání pokud je ID skladby v odkazu kterým jste přišli na server$N$Nzakázání toho také zastaví aktualizaci URL stránky s ID skladby při přehrávání hudby, aby se zabránilo automatickému přehrávání pokud se tato nastavení ztratí ale URL zůstane\">a▶",
 	"mt_preload": "začít načítat následující skladbu před koncem pro plynulé přehrávání\">přednahrání",
 	"mt_prescan": "přejít do následující složky před tím než$Nskončí poslední skladba, aby byl webprohlížeč$Nspokojen aby nezastavil přehrávání\">nav",
@@ -309,7 +309,7 @@ Ls.cze = {
 	"mt_follow": "udržet přehrávanou stopu v zobrazení\">🎯",
 	"mt_compact": "kompaktní ovládání\">⟎",
 	"mt_uncache": "vymazat cache &nbsp;(zkuste to, pokud váš prohlížeč uložil$Nporušenou kopii písně a odmítá ji přehrát)\">uncache",
-	"mt_mloop": "opakovat otevřenou složku\">🔁 loop",
+	"mt_mloop": "opakovat otevřenou složku",
 	"mt_mnext": "načíst další složku a pokračovat\">📂 next",
 	"mt_mstop": "zastavit přehrávání\">⏸ stop",
 	"mt_cflac": "převést flac / wav na {0}\">flac",
diff --git a/copyparty/web/tl/deu.js b/copyparty/web/tl/deu.js
index cc7cffc7..00ccf05f 100644
--- a/copyparty/web/tl/deu.js
+++ b/copyparty/web/tl/deu.js
@@ -5,7 +5,7 @@ Ls.deu = {
 	"tt": "Deutsch",
 
 	"cols": {
-		"c": "Aktionen",
+		"!": "Aktionen",
 		"dur": "Dauer",
 		"q": "Qualität / Bitrate",
 		"Ac": "Audiocodec",
@@ -14,7 +14,7 @@ Ls.deu = {
 		"Ahash": "Audio Checksumme",
 		"Vhash": "Video Checksumme",
 		"Res": "Auflösung",
-		"T": "Dateityp",
+		"Ext": "Dateityp",
 		"aq": "Audioqualität / Bitrate",
 		"vq": "Videoqualität / Bitrate",
 		"pixfmt": "Subsampling / Pixelstruktur",
@@ -107,9 +107,9 @@ Ls.deu = {
 	"ht_and": " und ",
 
 	"goh": "Einstellungen",
-	"gop": 'zum vorherigen Ordner springen">vorh.',
-	"gou": 'zum übergeordneter Ordner springen">hoch',
-	"gon": 'zum nächsten Ordner springen">nächst.',
+	"gop": 'zum vorherigen Ordner springen',
+	"gou": 'zum übergeordneter Ordner springen',
+	"gon": 'zum nächsten Ordner springen',
 	"logout": "Abmelden ",
 	"login": "Anmelden",
 	"access": " Zugriff",
@@ -157,7 +157,7 @@ Ls.deu = {
 	"ut_u2ts": "Zuletzt geändert-Zeitstempel von$Ndeinem Dateisystem auf den Server übertragen\">📅",
 	"ut_ow": "Existierende Dateien auf dem Server überschreiben?$N🛡️: Nie (generiert einen neuen Dateinamen)$N🕒: Überschreiben, wenn Server-Datei älter ist als meine$N♻️: Überschreiben, wenn der Dateiinhalt anders ist$N⏭️: Vorhandene Dateien immer überspringen",
 	"ut_mt": "Andere Dateien während des Uploads hashen$N$Nsolltest du deaktivieren, falls deine CPU oder Festplatte zum Flaschenhals werden könnte",
-	"ut_ask": 'Vor dem Upload nach Bestätigung fragen">💭',
+	"ut_ask": 'Vor dem Upload nach Bestätigung fragen',
 	"ut_pot": "Verbessert Upload-Geschwindigkeit$Nindem das UI weniger komplex gemacht wird",
 	"ut_srch": "nicht wirklich hochladen, stattdessen prüfen ob Datei bereits auf dem Server existiert (scannt alle Ordner, die du lesen kannst)",
 	"ut_par": "setze auf 0 zum Pausieren$N$Nerhöhe, wenn deine Verbindung langsam / instabil ist$N$lass auf 1 im LAN oder wenn die Festplatte auf dem Server ein Flaschenhals ist",
@@ -288,9 +288,9 @@ Ls.deu = {
 	"ml_drc": "Dynamic Range Compressor",
 	"ml_ss": "Stille Überspringen", //m
 
-	"mt_loop": "Song wiederholen\">🔁",
+	"mt_loop": "Song wiederholen",
 	"mt_one": "Wiedergabe nach diesem Song beenden\">1️⃣",
-	"mt_shuf": "Zufällige Wiedergabe im Ordner\">🔀",
+	"mt_shuf": "Zufällige Wiedergabe im Ordner",
 	"mt_aplay": "automatisch abspielen, wenn der Link, mit dem du auf den Server zugreifst, eine Titel-ID enthält$N$NDeaktivieren verhindert auch, dass die Seiten-URL bei Musikwiedergabe mit Titel-IDs aktualisiert wird, um Autoplay zu verhindern, falls diese Einstellungen verloren gehen, die URL aber bestehen bleibt\">a▶",
 	"mt_preload": "nächsten Titel gegen Ende vorladen für nahtlose Wiedergabe\">Vorladen",
 	"mt_prescan": "vor Ende des letzten Titels zum nächsten Ordner wechseln,$Ndamit der Browser die$NWiedergabe nicht stoppt\">Navigation",
@@ -305,7 +305,7 @@ Ls.deu = {
 	"mt_follow": "den spielenden Titel im Blick behalten\">🎯",
 	"mt_compact": "kompakte Steuerelemente\">⟎",
 	"mt_uncache": "Cache leeren &nbsp;(probier das, wenn dein Browser$Neine defekte Kopie eines Titels zwischenspeichert und sich weigert, ihn abzuspielen)\">Cache leeren",
-	"mt_mloop": "offenen Ordner wiederholen\">🔁 Schleife",
+	"mt_mloop": "offenen Ordner wiederholen",
 	"mt_mnext": "nächsten Ordner laden und fortfahren\">📂 nächster",
 	"mt_mstop": "Wiedergabe beenden\">⏸ Stop",
 	"mt_cflac": "FLAC / WAV zu {0} konvertierebn\">flac",
diff --git a/copyparty/web/tl/epo.js b/copyparty/web/tl/epo.js
index 8280b4be..1828ab96 100644
--- a/copyparty/web/tl/epo.js
+++ b/copyparty/web/tl/epo.js
@@ -5,7 +5,7 @@ Ls.epo = {
 	"tt": "Esperanto",
 
 	"cols": {
-		"c": "ago-butonoj",
+		"!": "ago-butonoj",
 		"dur": "daŭro",
 		"q": "kvalito / bitrapido",
 		"Ac": "sonkodeko",
@@ -14,7 +14,7 @@ Ls.epo = {
 		"Ahash": "kontrolsumo de aŭdio",
 		"Vhash": "kontrolsumo de video",
 		"Res": "distingivo",
-		"T": "dosiertipo",
+		"Ext": "dosiertipo",
 		"aq": "kvalito / bitrapido de aŭdio",
 		"vq": "kvalito / bitrapido de video",
 		"pixfmt": "specimenado / strukturo de bilderoj",
@@ -107,9 +107,9 @@ Ls.epo = {
 	"ht_and": " kaj ",
 
 	"goh": "stirpanelo",
-	"gop": 'malsekva dosierujo">malsekva',
-	"gou": 'supra dosierujo">supren',
-	"gon": 'sekva dosierujo">sekva',
+	"gop": 'malsekva dosierujo',
+	"gou": 'supra dosierujo',
+	"gon": 'sekva dosierujo',
 	"logout": "Adiaŭi kiel ",
 	"login": "Ensaluti",
 	"access": " atingo",
@@ -157,7 +157,7 @@ Ls.epo = {
 	"ut_u2ts": "kopii la tempon de lasta modifo$Nel via dosiersistemo al la servilo\">📅",
 	"ut_ow": "ĉu anstataŭigi dosierojn ĉe la servilo?$N🛡️: neniam (dosiero estos alŝutita kun nova dosiernomo)$N🕒: anstataŭigi, se servila dosiero estas pli malnova ol via$N♻️: ĉiam anstataŭigi, se dosieroj estas malsamaj$N⏭️: senkondiĉe preterlasi ĉiujn ekzistantajn dosierojn",
 	"ut_mt": "daŭri kalkuladon de kontrolsumoj por aliaj dosieroj dum alŝutado$N$Nmalŝaltinda, se via procesoro aŭ disko ne estas sufiĉe rapidaj",
-	"ut_ask": 'peti konfirmon antaŭ komenco de alŝutado">💭',
+	"ut_ask": 'peti konfirmon antaŭ komenco de alŝutado',
 	"ut_pot": "plirapidigi alŝutadon por malrapidaj komputiloj$Nper malkomplikado de fasado",
 	"ut_srch": "ne alŝuti ion ajn, nur kontroli, ke la dosieroj $N jam ekzistas ĉe la servilo (ĉiuj dosierujoj, kiuj vi povas legi, estos skanitaj)",
 	"ut_par": "paŭzi alŝutadon per agordado kiel 0$N$Npligrandigi, se via konekto estas malrapida aŭ malfruema$N$Nagordi kiel 1, se la loka reto aŭ servila disko ne estas sufiĉe rapidaj",
@@ -288,9 +288,9 @@ Ls.epo = {
 	"ml_drc": "kompresoro",
 	"ml_ss": "preterpasi silenton",
 
-	"mt_loop": "ripeti unu kanton\">🔁",
+	"mt_loop": "ripeti unu kanton",
 	"mt_one": "haltigi post unu kanto\">1️⃣",
-	"mt_shuf": "ludi ĉiu dosierujo en hazarda ordo\">🔀",
+	"mt_shuf": "ludi ĉiu dosierujo en hazarda ordo",
 	"mt_aplay": "ludi aŭtomate, se ligilo enhavas identigilon de kanto$N$Nmalŝaltado de ĉi tiu agordo ankaŭ malŝaltas ĝisdatigadon de paĝ-adreso, por ke ludado ne rekomenciĝas, se la paĝo estos poste malfermita sen aliaj agordoj\">a▶",
 	"mt_preload": "komenci ŝargadon de sekva kanto antaŭ la fino de la nuna, por kontinua ludado\">antaŭŝarg.",
 	"mt_prescan": "eniri la sekvan dosierujon antaŭ la fino de la lasta kanto, $Npor ke la retumilo ne interrompis la ludadon\">nav",
@@ -305,7 +305,7 @@ Ls.epo = {
 	"mt_follow": "rulumi la pagon, por ke la ludanta kanto restas videbla\">🎯",
 	"mt_compact": "kompaktaj ruliloj\">⟎",
 	"mt_uncache": "malplenigi kaŝmemoron &nbsp;(uzinda, se via retumilo kaŝmemoris$Ndifektitan kopion de kanto, kaj ne povas ludi ĝin)\">🗑️ kaŝmem.",
-	"mt_mloop": "ripeti la nunan dosierujon\">🔁 ripeti",
+	"mt_mloop": "ripeti la nunan dosierujon",
 	"mt_mnext": "ŝargi la sekvan dosierujon kaj daŭrigi\">📂 sekva",
 	"mt_mstop": "haltigi ludadon\">⏸ haltigi",
 	"mt_cflac": "konverti el flac / wav al {0}\">flac",
diff --git a/copyparty/web/tl/fin.js b/copyparty/web/tl/fin.js
index 05d41252..3d5d074b 100644
--- a/copyparty/web/tl/fin.js
+++ b/copyparty/web/tl/fin.js
@@ -5,7 +5,7 @@ Ls.fin = {
 	"tt": "Suomi",
 
 	"cols": {
-		"c": "toimintopainikkeet",
+		"!": "toimintopainikkeet",
 		"dur": "kesto",
 		"q": "laatu / bittinopeus",
 		"Ac": "äänikoodekki",
@@ -14,7 +14,7 @@ Ls.fin = {
 		"Ahash": "äänen tarkistussumma",
 		"Vhash": "videon tarkistussumma",
 		"Res": "resoluutio",
-		"T": "tiedostotyyppi",
+		"Ext": "tiedostotyyppi",
 		"aq": "äänenlaatu / bittinopeus",
 		"vq": "kuvalaatu / bittinopeus",
 		"pixfmt": "alinäytteistys / pikselirakenne",
@@ -33,7 +33,7 @@ Ls.fin = {
 			["G", "vaihda lista/kuvanäkymään"],
 			["T", "vaihda pienoiskuviin/kuvakkeisiin"],
 			["⇧ A/D", "pienoiskuvien koko"],
-			["ctrl-K", "poista valitut"],
+			["ctrl-K/Del", "poista valitut"],
 			["ctrl-X", "siirrä valitut leikepöydälle"],
 			["ctrl-C", "kopioi valitut leikepöydälle"],
 			["ctrl-V", "siirrä tai kopioi tähän"],
@@ -107,9 +107,9 @@ Ls.fin = {
 	"ht_and": " ja ",
 
 	"goh": "hallintapaneeli",
-	"gop": 'viereinen hakemisto">edell',
-	"gou": 'ylempi hakemisto">ylös',
-	"gon": 'seuraava hakemisto">seur',
+	"gop": 'viereinen hakemisto',
+	"gou": 'ylempi hakemisto',
+	"gon": 'seuraava hakemisto',
 	"logout": "Kirjaudu ulos ",
 	"login": "Kirjaudu sisään",
 	"access": " -oikeudet",
@@ -157,7 +157,7 @@ Ls.fin = {
 	"ut_u2ts": "kopioi viimeksi muokattu aikaleima$Ntiedostojärjestelmästäsi palvelimelle\">📅",
 	"ut_ow": "korvaa olemassa olevat tiedostot palvelimella?$N🛡️: ei koskaan (luo sen sijaan uuden tiedostonimen)$N🕒: korvaa jos palvelintiedosto on vanhempi kuin omasi$N♻️: korvaa aina jos tiedostot ovat erilaisia$N⏭️: ohita kaikki olemassa olevat tiedostot ehdottomasti",
 	"ut_mt": "jatka muiden tiedostojen tiivisteiden laskemista latauksen aikana$N$Nkannattanee poistaa käytöstä, mikäli prosessori tai kovalevy on vanhempaa mallia",
-	"ut_ask": 'kysy vahvistusta ennen latauksen aloittamista">💭',
+	"ut_ask": 'kysy vahvistusta ennen latauksen aloittamista',
 	"ut_pot": "paranna latausnopeutta hitailla laitteilla$Nvähentämällä käyttöliittymän monimutkaisuutta",
 	"ut_srch": "lataamisen sijaan tarkista, ovatko tiedostot jo $N olemassa palvelimella (käy läpi kaikki hakemistot, joihin sinulla on read-oikeudet)",
 	"ut_par": "keskeytä lataukset asettamalla se nollaan$N$Nnosta, jos yhteytesi on hidas tai viive on suuri$N$Npidä se 1:ssä lähiverkossa tai jos palvelimen kovalevy on pullonkaula",
@@ -288,9 +288,9 @@ Ls.fin = {
 	"ml_drc": "dynaaminen alueen kompressori",
 	"ml_ss": "ohita hiljaiset kohdat",
 
-	"mt_loop": "toista samaa kappaletta\">🔁",
+	"mt_loop": "toista samaa kappaletta",
 	"mt_one": "lopeta yhden toiston jälkeen\">1️⃣",
-	"mt_shuf": "aktivoi satunnaistoisto\">🔀",
+	"mt_shuf": "aktivoi satunnaistoisto",
 	"mt_aplay": "automaattitoisto jos linkissä jolla pääsit palvelimelle oli kappale-ID$N$Ntämän poistaminen käytöstä pysäyttää myös sivun URL:n päivittämisen kappale-ID:lla musiikkia toistettaessa, estääksesi automaattitoiston jos nämä asetukset menetetään mutta URL säilyy\">a▶",
 	"mt_preload": "aloita seuraavan kappaleen lataaminen lähellä loppua, mahdollistaen saumattoman toiston\">esilataus",
 	"mt_prescan": "siirry seuraavaan hakemistoon ennen viimeisen kappaleen$Nloppumista, pitäen verkkoselaimen tyytyväisenä$Njotta se ei pysäytä toistoa\">nav",
@@ -305,7 +305,7 @@ Ls.fin = {
 	"mt_follow": "pidä soiva kappale näkyvissä\">🎯",
 	"mt_compact": "kompaktit säätimet\">⟎",
 	"mt_uncache": "tyhjennä välimuisti &nbsp;(kokeile tätä jos selaimesi välimuistissa on$Nrikkinäinen kopio kappaleesta)\">uncache",
-	"mt_mloop": "toista avoinna olevaa hakemistoa loputtomasti\">🔁 alkuun",
+	"mt_mloop": "toista avoinna olevaa hakemistoa loputtomasti",
 	"mt_mnext": "lataa seuraava hakemisto ja jatka\">📂 seuraava",
 	"mt_mstop": "pysäytä toisto\">⏸ pysäytä",
 	"mt_cflac": "muunna flac / wav {0}-muotoon\">flac",
diff --git a/copyparty/web/tl/fra.js b/copyparty/web/tl/fra.js
index 2c56ed69..bdb05b46 100644
--- a/copyparty/web/tl/fra.js
+++ b/copyparty/web/tl/fra.js
@@ -5,7 +5,7 @@ Ls.fra = {
 	"tt": "français",
 
 	"cols": {
-		"c": "bouton d'action",
+		"!": "bouton d'action",
 		"dur": "durée",
 		"q": "qualité / débit binaire",
 		"Ac": "codec audio",
@@ -14,7 +14,7 @@ Ls.fra = {
 		"Ahash": "somme de contrôle audio",
 		"Vhash": "somme de contrôle vidéo",
 		"Res": "résolution",
-		"T": "type de fichier",
+		"Ext": "type de fichier",
 		"aq": "qualité audio / débit binaire",
 		"vq": "qualité vidéo / débit binaire",
 		"pixfmt": "sous-échantillonnage / structure de pixel",
@@ -33,7 +33,7 @@ Ls.fra = {
 			["G", "activer vue en liste / vue en grille"],
 			["T", "activer les miniatures / icônes"],
 			["⇧ A/D", "taille des miniatures"],
-			["ctrl-K", "suprimer la sélection"],
+			["ctrl-K/Del", "suprimer la sélection"],
 			["ctrl-X", "couper la sélection au presse-papier"],
 			["ctrl-C", "copier la sélection au presse-papier"],
 			["ctrl-V", "coller (déplacer/copier) ici"],
@@ -107,9 +107,9 @@ Ls.fra = {
 	"ht_and": " et ",
 
 	"goh": "panneau-de-commande",
-	"gop": 'élément "frère" précédent">précédent',
-	"gou": 'dossier parent">haut',
-	"gon": 'dossier suivant">suivant',
+	"gop": 'élément "frère" précédent',
+	"gou": 'dossier parent',
+	"gon": 'dossier suivant',
 	"logout": "Déconnexion ",
 	"login": "Se connecter", //m
 	"access": " accès",
@@ -157,7 +157,7 @@ Ls.fra = {
 	"ut_u2ts": "copier l'horodatage de dernière modification$Nde votre système de fichiers vers le serveur\">📅",
 	"ut_ow": "écraser les fichiers existants sur le serveur?$N🛡️: jamais (générera un nouveau nom de fichier à la place)$N🕒: écraser si le fichier sur le serveur est plus ancien que le vôtre$N♻️: toujours écraser si les fichiers sont différents$N⏭️: ignorer systématiquement tous les fichiers existants", //m
 	"ut_mt": "continuer à calculer la somme de contrôle d'autres fichiers pendant le téléversement$N$Npeut-être désactiver si votre CPU ou HDD est la cause de perte de performances",
-	"ut_ask": 'demander confirmation avant le début du téléversement">💭',
+	"ut_ask": 'demander confirmation avant le début du téléversement',
 	"ut_pot": "améliorer la vitesse de téléversement sur les appareils lents$Nen simplifiant l'interface utilisateur",
 	"ut_srch": "ne pas réellement téléverser, mais vérifier si les fichiers existent déjà$N sur le serveur (scannera tous les dossiers que vous pouvez lire)",
 	"ut_par": "mettre en pause les téléversements en le réglant sur 0$N$Naugmenter si votre connexion est lente / à forte latence$N$Nle garder à 1 sur le LAN ou si le HDD du serveur est un goulot d'étranglement",
@@ -288,9 +288,9 @@ Ls.fra = {
 	"ml_drc": "compresseur de plage dynamique",
 	"ml_ss": "ignorer les silences", //m
 
-	"mt_loop": "répéter en boucle une musique\">🔁",
+	"mt_loop": "répéter en boucle une musique",
 	"mt_one": "stopper après une musique\">1️⃣",
-	"mt_shuf": "mélanger les musiques dans chaque dossiers\">🔀",
+	"mt_shuf": "mélanger les musiques dans chaque dossiers",
 	"mt_aplay": "jouer automatiquement si le lien utilisé pour accéder au serveur a un song-ID $N$N, désactiver cela arrêtera également la mise à jour de l'URL de la page avec les song-IDs lors de la lecture de la musique, pour éviter la lecture automatique si ces paramètres sont perdus mais que l'URL reste\">a▶",
 	"mt_preload": "commencer à charger la prochaine chanson près de la fin pour une lecture sans interruption\">preload",
 	"mt_prescan": "explorer le dossier suivant avant la dernière musique$Nne finisse, pour garder le navigateur content$Npour qu'il n'arrête pas la lecture\">nav",
@@ -305,7 +305,7 @@ Ls.fra = {
 	"mt_follow": "garder la piste en cours défilée dans la vue\">🎯",
 	"mt_compact": "contrôles compacts\">⟎",
 	"mt_uncache": "effacer le cache &nbsp;(essayez ceci si votre navigateur a mis en cache$Nun copie défectueuse d'une chanson, ce qui empêche sa lecture)\">uncache",
-	"mt_mloop": "lire en boucle le dossier ouvert\">🔁 loop",
+	"mt_mloop": "lire en boucle le dossier ouvert",
 	"mt_mnext": "charger le dossier suivant et continuer\">📂 next",
 	"mt_mstop": "arrêter la lecture\">⏸ stop",
 	"mt_cflac": "convertir flac / wav en {0}\">flac",
diff --git a/copyparty/web/tl/grc.js b/copyparty/web/tl/grc.js
index 3b62c97a..7000176c 100644
--- a/copyparty/web/tl/grc.js
+++ b/copyparty/web/tl/grc.js
@@ -5,7 +5,7 @@ Ls.grc = {
 	"tt": "Ελληνικά",
 
 	"cols": {
-		"c": "κουμπιά ενεργειών",
+		"!": "κουμπιά ενεργειών",
 		"dur": "διάρκεια",
 		"q": "ποιότητα / bitrate",
 		"Ac": "κωδικοποιητής ήχου",
@@ -14,7 +14,7 @@ Ls.grc = {
 		"Ahash": "checksum ήχου",
 		"Vhash": "checksum βίντεο",
 		"Res": "ανάλυση",
-		"T": "τύπος αρχείου",
+		"Ext": "τύπος αρχείου",
 		"aq": "ποιότητα ήχου / bitrate",
 		"vq": "ποιότητα βίντεο / bitrate",
 		"pixfmt": "subsampling / δομή εικονοστοιχείων",
@@ -33,7 +33,7 @@ Ls.grc = {
 			["G", "εναλλαγή λίστας / πλέγματος"],
 			["T", "εναλλαγή μικρογραφιών / εικονιδίων"],
 			["⇧ A/D", "μέγεθος μικρογραφιών"],
-			["ctrl-K", "διαγραφή επιλεγμένων"],
+			["ctrl-K/Del", "διαγραφή επιλεγμένων"],
 			["ctrl-X", "αποκοπή επιλογής στο πρόχειρο"],
 			["ctrl-C", "αντιγραφή επιλογής στο πρόχειρο"],
 			["ctrl-V", "επικόλληση (μετακίνηση/αντιγραφή) εδώ"],
@@ -107,9 +107,9 @@ Ls.grc = {
 	"ht_and": " και ",
 
 	"goh": "πίνακας ελέγχου",
-	"gop": 'προηγούμενος φάκελος στο ίδιο επίπεδο">προηγούμενο',
-	"gou": 'γονικός φάκελος">πάνω',
-	"gon": 'επόμενος φάκελος">επόμενο',
+	"gop": 'προηγούμενος φάκελος στο ίδιο επίπεδο',
+	"gou": 'γονικός φάκελος',
+	"gon": 'επόμενος φάκελος',
 	"logout": "Αποσύνδεση ",
 	"login": "Σύνδεση", //m
 	"access": " πρόσβαση",
@@ -157,7 +157,7 @@ Ls.grc = {
 	"ut_u2ts": "αντιγραφή της τελευταίας τροποποιημένης χρονοσφραγίδας αλλαγής$Nαπό το σύστημά σου στον server\">📅",
 	"ut_ow": "αντικατάσταση σε ήδη υπάρχοντα αρχεία του server?$N🛡️: ποτέ (θα δημιουργηθεί νέο όνομα)$N🕒: αν το αρχείο του server είναι παλαιότερο$N♻️: πάντα να αντικαθίστανται αν διαφέρουν$N⏭️: παράλειψη όλων των υπαρχόντων αρχείων χωρίς όρους", //m
 	"ut_mt": "συνέχιση υπολογισμού hash για άλλα αρχεία κατά τη μεταφόρτωση$N$Nαπενεργοποίησέ το αν η CPU ή ο δίσκος σου ζορίζονται",
-	"ut_ask": 'επιβεβαίωση πριν ξεκινήσει η μεταφόρτωση">💭',
+	"ut_ask": 'επιβεβαίωση πριν ξεκινήσει η μεταφόρτωση',
 	"ut_pot": "βελτίωση ταχύτητας μεταφόρτωσης σε αργές συσκευές$Nμε απλοποίηση του UI",
 	"ut_srch": "μην ανεβάζεις, έλεγξε αν τα αρχεία$Nυπάρχουν ήδη στον server (ψάχνει σε όλους τους φακέλους που έχεις πρόσβαση)",
 	"ut_par": "κάνε παύση στις μεταφορτώσεις βάζοντάς το 0$N$Nαύξησε το αν έχεις αργή/μεγάλη καθυστέρηση σύνδεσης$N$Nκράτα το 1 σε LAN ή αν ο server έχει αργό δίσκο",
@@ -288,9 +288,9 @@ Ls.grc = {
 	"ml_drc": "συμπιεστής δυναμικής εμβέλειας",
 	"ml_ss": "παράβλεψη σιωπής", //m
 
-	"mt_loop": "επανάληψη ενός τραγουδιού\">🔁",
+	"mt_loop": "επανάληψη ενός τραγουδιού",
 	"mt_one": "σταμάτα μετά από ένα τραγούδι\">1️⃣",
-	"mt_shuf": "τυχαία σειρά τραγουδιών σε κάθε φάκελο\">🔀",
+	"mt_shuf": "τυχαία σειρά τραγουδιών σε κάθε φάκελο",
 	"mt_aplay": "αυτόματη αναπαραγωγή αν υπάρχει song-ID στη διεύθυνση που μπήκες στο διακομιστή$N$Nη απενεργοποίηση αυτού, σταματά το URL από το να ενημερώνεται με τα song-ID ενώ παίζει η μουσική για να αποτραπεί η αυτόματη αναπαραγωγή αν χαθούν αυτές οι ρυθμίσεις αλλά το URL παραμείνει το ίδιο\">a▶",
 	"mt_preload": "ξεκίνα  τη φόρτωση του επόμενου τραγουδιού κοντά στο τέλος για συνεχόμενη ακρόαση\">προφόρτωση",
 	"mt_prescan": "πήγαινε στον επόμενο φάκελο πριν τελειώσει το τελευταίο τραγούδι$Nγια να μη σταματήσει το πρόγραμμα περιήγησης να παίζει μουσική\">nav",
@@ -305,7 +305,7 @@ Ls.grc = {
 	"mt_follow": "κρατά το τρέχον κομμάτι ορατό κατά την κύλιση\">🎯",
 	"mt_compact": "συμπαγή κουμπιά ελέγχου\">⟎",
 	"mt_uncache": "καθάρισε την προσωρινή μνήμη &nbsp;(δοκίμασε αυτό αν ο browser έχει αποθηκεύσει$Nχαλασμένο αντίγραφο τραγουδιού και αρνείται να παίξει)\">εκκαθάριση",
-	"mt_mloop": "τυχαία αναπαραγωγή στον ανοικτό φάκελο\">🔁 τυχαία αναπαραγωγή",
+	"mt_mloop": "τυχαία αναπαραγωγή στον ανοικτό φάκελο",
 	"mt_mnext": "φόρτωση επόμενου φακέλου και συνέχιση\">📂 επόμενο",
 	"mt_mstop": "σταμάτησε την αναπαραγωγή\">⏸ σταμάτημα",
 	"mt_cflac": "μετατροπή flac / wav σε {0}\">flac",
diff --git a/copyparty/web/tl/hun.js b/copyparty/web/tl/hun.js
index 6e3005d1..b9404c82 100644
--- a/copyparty/web/tl/hun.js
+++ b/copyparty/web/tl/hun.js
@@ -2,7 +2,7 @@ Ls.hun = {
 	"tt": 'Magyar',
 
 	"cols": {
-		"c": 'műveletek',
+		"!": 'műveletek',
 		"dur": 'hossz',
 		"q": 'minőség / bitrate',
 		"Ac": 'audió kodek',
@@ -11,7 +11,7 @@ Ls.hun = {
 		"Ahash": 'audió hash',
 		"Vhash": 'videó hash',
 		"Res": 'felbontás',
-		"T": 'típus',
+		"Ext": 'típus',
 		"aq": 'audió minőség / bitrate',
 		"vq": 'videó minőség / bitrate',
 		"pixfmt": 'színkódolás / pixel',
@@ -30,7 +30,7 @@ Ls.hun = {
 			['G', 'lista / rács nézet'],
 			['T', 'ikon / indexkép váltás'],
 			['⇧ A/D', 'méret módosítása'],
-			['ctrl-K', 'kijelöltek törlése'],
+			['ctrl-K/Del', 'kijelöltek törlése'],
 			['ctrl-X', 'kivágás vágólapra'],
 			['ctrl-C', 'másolás vágólapra'],
 			['ctrl-V', 'beillesztés ide'],
@@ -109,9 +109,9 @@ Ls.hun = {
 	"ht_and": ' és ',
 
 	"goh": 'irányítópult',
-	"gop": 'előző mappába">előző',
-	"gou": 'szülőmappa">fel',
-	"gon": 'következő mappába">következő',
+	"gop": 'előző mappába',
+	"gou": 'szülőmappa',
+	"gon": 'következő mappába',
 	"logout": 'Kilépés ',
 	"login": 'Belépés',
 	"access": ' hozzáférés',
@@ -159,7 +159,7 @@ Ls.hun = {
 	"ut_u2ts": 'helyi dátumok$Nátvitele a szerverre">📅',
 	"ut_ow": 'felülírás?$N🛡️: soha (új nevet ad)$N🕒: csak ha a tiéd újabb$N♻️: mindig, ha más a tartalom$N⏭️: létezőket kihagy',
 	"ut_mt": 'háttérben hashelés feltöltés alatt$N$Nkapcsold ki, ha fagy a géped',
-	"ut_ask": 'megerősítés feltöltés előtt">💭',
+	"ut_ask": 'megerősítés feltöltés előtt',
 	"ut_pot": 'feltöltés gyorsítása (egyszerűbb UI)',
 	"ut_srch": 'csak létezés ellenőrzése$N(nem tölt fel semmit)',
 	"ut_par": '0 = szünet$N$Nnöveld, ha lassú a net$N$NHDD limit vagy LAN esetén hagyd 1-en',
@@ -289,9 +289,9 @@ Ls.hun = {
 	"ml_drc": 'dinamikatartomány-tömörítő',
 	"ml_ss": 'csönd átugrása',
 
-	"mt_loop": 'egy szám ismétlése">🔁',
+	"mt_loop": 'egy szám ismétlése',
 	"mt_one": 'leállás egy szám után">1️⃣',
-	"mt_shuf": 'véletlenszerű lejátszás mappánként">🔀',
+	"mt_shuf": 'véletlenszerű lejátszás mappánként',
 	"mt_aplay": 'automatikus kezdés a link alapján$N$Nha kikapcsolod, a linkek sem fognak szám-azonosítót tartalmazni">a▶',
 	"mt_preload": 'következő szám betöltése a végén (gapless)">preload',
 	"mt_prescan": 'mappaváltás az utolsó szám vége előtt, hogy a böngésző ne álljon le">nav',
@@ -306,7 +306,7 @@ Ls.hun = {
 	"mt_follow": 'fókuszban tartja az aktuális számot">🎯',
 	"mt_compact": 'kompakt vezérlők">⟎',
 	"mt_uncache": 'gyorsítótár ürítése (próbáld ezt, ha a böngésző hibás fájlt mentett el és nem játssza le)">uncache',
-	"mt_mloop": 'mappa ismétlése">🔁 ismétlés',
+	"mt_mloop": 'mappa ismétlése',
 	"mt_mnext": 'következő mappa betöltése és folytatás">📂 tovább',
 	"mt_mstop": 'stop">⏸ stop',
 	"mt_cflac": 'flac / wav konvertálása ide: {0}">flac',
diff --git a/copyparty/web/tl/ita.js b/copyparty/web/tl/ita.js
index f65af456..86639777 100644
--- a/copyparty/web/tl/ita.js
+++ b/copyparty/web/tl/ita.js
@@ -5,7 +5,7 @@ Ls.ita = {
 	"tt": "Italiano",
 
 	"cols": {
-		"c": "pulsanti azione",
+		"!": "pulsanti azione",
 		"dur": "durata",
 		"q": "qualità / bitrate",
 		"Ac": "codec audio",
@@ -14,7 +14,7 @@ Ls.ita = {
 		"Ahash": "checksum audio",
 		"Vhash": "checksum video",
 		"Res": "risoluzione",
-		"T": "tipo file",
+		"Ext": "tipo file",
 		"aq": "qualità audio / bitrate",
 		"vq": "qualità video / bitrate",
 		"pixfmt": "subsampling / struttura pixel",
@@ -33,7 +33,7 @@ Ls.ita = {
 			["G", "alterna vista lista / griglia"],
 			["T", "alterna miniature / icone"],
 			["⇧ A/D", "dimensione miniature"],
-			["ctrl-K", "elimina selezionati"],
+			["ctrl-K/Del", "elimina selezionati"],
 			["ctrl-X", "taglia selezione negli appunti"],
 			["ctrl-C", "copia selezione negli appunti"],
 			["ctrl-V", "incolla (sposta/copia) qui"],
@@ -107,9 +107,9 @@ Ls.ita = {
 	"ht_and": " e ",
 
 	"goh": "control-panel",
-	"gop": 'cartella sorella precedente">prec',
-	"gou": 'cartella genitore">su',
-	"gon": 'prossima cartella">succ',
+	"gop": 'cartella sorella precedente',
+	"gou": 'cartella genitore',
+	"gon": 'prossima cartella',
 	"logout": "Logout ",
 	"login": "Accedi", //m
 	"access": " accesso",
@@ -157,7 +157,7 @@ Ls.ita = {
 	"ut_u2ts": "copia il timestamp di ultima modifica$Ndal tuo filesystem al server\">📅",
 	"ut_ow": "sovrascrivere file esistenti sul server?$N🛡️: mai (genererà un nuovo nome file)$N🕒: sovrascrivi se il file del server è più vecchio del tuo$N♻️: sovrascrivi sempre se i file sono diversi$N⏭️: ignora sempre tutti i file esistenti", //m
 	"ut_mt": "continua l'hashing di altri file durante il caricamento$N$NProva a disabilitare se la tua CPU o HDD è un collo di bottiglia",
-	"ut_ask": 'chiedi conferma prima che inizi il caricamento">💭',
+	"ut_ask": 'chiedi conferma prima che inizi il caricamento',
 	"ut_pot": "migliora la velocità di caricamento su dispositivi lenti$Nrendendo l'interfaccia meno complessa",
 	"ut_srch": "non caricare realmente, invece controlla se i file esistono già $N sul server (scansionerà tutte le cartelle che puoi leggere)",
 	"ut_par": "metti in pausa i caricamenti impostandolo a 0$N$NAumenta se la tua connessione è lenta / alta latenza$N$NMantienilo a 1 su LAN o se l'HDD del server è un collo di bottiglia",
@@ -288,9 +288,9 @@ Ls.ita = {
 	"ml_drc": "compressore gamma dinamica",
 	"ml_ss": "salta i silenzi", //m
 
-	"mt_loop": "loop/ripeti una canzone\">🔁",
+	"mt_loop": "loop/ripeti una canzone",
 	"mt_one": "fermati dopo una canzone\">1️⃣",
-	"mt_shuf": "mescola le canzoni in ogni cartella\">🔀",
+	"mt_shuf": "mescola le canzoni in ogni cartella",
 	"mt_aplay": "autoplay se c'è un song-ID nel link che hai cliccato per accedere al server$N$NDisabilitando questo fermerà anche l'aggiornamento dell'URL della pagina con song-ID quando riproduci musica, per prevenire autoplay se queste impostazioni vengono perse ma l'URL rimane\">a▶",
 	"mt_preload": "inizia a caricare la prossima canzone verso la fine per riproduzione senza interruzioni\">preload",
 	"mt_prescan": "vai alla prossima cartella prima che finisca l'ultima canzone$Nmantenendo felice il browser web$Ncosì non si ferma la riproduzione\">nav",
@@ -305,7 +305,7 @@ Ls.ita = {
 	"mt_follow": "mantieni la traccia in riproduzione scorrevole nella vista\">🎯",
 	"mt_compact": "controlli compatti\">⟎",
 	"mt_uncache": "pulisci cache &nbsp;(prova ad attivare se il tuo browser ha messo in cache$Nuna copia rotta di una canzone e si rifiuta di riprodurla)\">uncache",
-	"mt_mloop": "loop della cartella aperta\">🔁 loop",
+	"mt_mloop": "loop della cartella aperta",
 	"mt_mnext": "carica la prossima cartella e continua\">📂 succ",
 	"mt_mstop": "ferma riproduzione\">⏸ stop",
 	"mt_cflac": "converti flac / wav in {0}\">flac",
diff --git a/copyparty/web/tl/jpn.js b/copyparty/web/tl/jpn.js
index cf59813c..5d616c33 100644
--- a/copyparty/web/tl/jpn.js
+++ b/copyparty/web/tl/jpn.js
@@ -5,7 +5,7 @@ Ls.jpn = {
 	"tt": "日本語",
 
 	"cols": {
-		"c": "アクションボタン",
+		"!": "アクションボタン",
 		"dur": "間隔",
 		"q": "品質 / ビットレート",
 		"Ac": "オーディオコーデック",
@@ -14,7 +14,7 @@ Ls.jpn = {
 		"Ahash": "オーディオチェックサム",
 		"Vhash": "ビデオチェックサム",
 		"Res": "解像度",
-		"T": "ファイル形式",
+		"Ext": "ファイル形式",
 		"aq": "オーディオ 品質 / ビットレート",
 		"vq": "ビデオ 品質 / ビットレート",
 		"pixfmt": "サブサンプリング / ピクセル構造",
@@ -33,7 +33,7 @@ Ls.jpn = {
 			["G", "リスト / グリッド表示を切り替える"],
 			["T", "サムネイル / アイコンを切り替える"],
 			["⇧ A/D", "サムネイルサイズ"],
-			["ctrl-K", "選択した項目を削除"],
+			["ctrl-K/Del", "選択した項目を削除"],
 			["ctrl-X", "選択範囲をクリップボードに切り取る"],
 			["ctrl-C", "選択範囲をクリップボードにコピー"],
 			["ctrl-V", "ここに貼り付け（移動/コピー）"],
@@ -107,9 +107,9 @@ Ls.jpn = {
 	"ht_and": " と ",
 
 	"goh": "コントロールパネル",
-	"gop": '前のフォルダ">prev',
-	"gou": '親フォルダ">up',
-	"gon": '次のフォルダ">next',
+	"gop": '前のフォルダ',
+	"gou": '親フォルダ',
+	"gon": '次のフォルダ',
 	"logout": "ログアウト ",
 	"login": "ログイン",
 	"access": " アクセス",
@@ -157,7 +157,7 @@ Ls.jpn = {
 	"ut_u2ts": "最終更新日時のタイムスタンプ$Nファイルシステムからサーバーへコピーする\">📅",
 	"ut_ow": "サーバー上の既存のファイルを上書きする？$N🛡️: しない（代わりに新しいファイル名を生成する）$N🕒: サーバーのファイルが古い場合は上書きする$N♻️: ファイルが異なる場合は常に上書きする$N⏭️: 既存のファイルをすべて無条件にスキップする",
 	"ut_mt": "アップロード中に他のファイルのハッシュを継続する$N$NCPUやHDDがボトルネックになっている場合は無効にしてください",
-	"ut_ask": 'aアップロードを開始する前に確認を求める">💭',
+	"ut_ask": 'aアップロードを開始する前に確認を求める',
 	"ut_pot": "UIをシンプルにすることで$N低速デバイスでのアップロード速度を向上させる",
 	"ut_srch": "実際にはアップロードせず、代わりにファイルが既にアップロードされているかどうかを確認 $N すでにサーバー上に存在（読み取り可能なすべてのフォルダをスキャン）",
 	"ut_par": "0に設定するとアップロードを一時停止$N$N接続が遅い / 遅延が大きい場合は増やす$N$NLANやサーバーのHDDがボトルネックになっている場合は1にする",
@@ -288,9 +288,9 @@ Ls.jpn = {
 	"ml_drc": "ダイナミックレンジコンプレッサー",
 	"ml_ss": "無音をスキップ", //m
 
-	"mt_loop": "1曲をループ/リピート再生\">🔁",
+	"mt_loop": "1曲をループ/リピート再生",
 	"mt_one": "1曲で止める\">1️⃣",
-	"mt_shuf": "各フォルダ内の曲をシャッフルする\">🔀",
+	"mt_shuf": "各フォルダ内の曲をシャッフルする",
 	"mt_aplay": "サーバーにアクセスするためにクリックしたリンクに曲IDがある場合は自動再生されます$N$Nこれを無効にすると、音楽を再生するときにページのURLが曲IDで更新されなくなります。これにより設定が失われてもURLが残っている場合の自動再生が防止されます。\">a▶",
 	"mt_preload": "ギャップレス再生のために曲の終わり近くに次の曲の読み込みを開始する\">preload",
 	"mt_prescan": "最後の曲が終了する前に次のフォルダへ移動し$Nウェブブラウザが$N再生を停止しないようにする\">nav",
@@ -305,7 +305,7 @@ Ls.jpn = {
 	"mt_follow": "再生中の曲をスクロールして表示したままにする\">🎯",
 	"mt_compact": "コントローラーを小さく\">⟎",
 	"mt_uncache": "キャッシュクリア &nbsp;（ブラウザが破損した曲のコピーをキャッシュしているために$N再生できない場合はこれを試してください）\">uncache",
-	"mt_mloop": "開いているフォルダをループ\">🔁 ループ",
+	"mt_mloop": "開いているフォルダをループ",
 	"mt_mnext": "次のフォルダを読み込んで続行\">📂 次",
 	"mt_mstop": "再生を停止\">⏸ 停止",
 	"mt_cflac": "flac / wavを{0}に変換\">flac",
diff --git a/copyparty/web/tl/kor.js b/copyparty/web/tl/kor.js
index e2f4b122..cfc1f510 100644
--- a/copyparty/web/tl/kor.js
+++ b/copyparty/web/tl/kor.js
@@ -5,7 +5,7 @@ Ls.kor = {
 	"tt": "한국어",
 
 	"cols": {
-		"c": "작업 버튼",
+		"!": "작업 버튼",
 		"dur": "길이",
 		"q": "품질/비트레이트",
 		"Ac": "오디오 코덱",
@@ -14,7 +14,7 @@ Ls.kor = {
 		"Ahash": "오디오 체크섬",
 		"Vhash": "비디오 체크섬",
 		"Res": "해상도",
-		"T": "파일 유형",
+		"Ext": "파일 유형",
 		"aq": "오디오 품질/비트레이트",
 		"vq": "비디오 품질/비트레이트",
 		"pixfmt": "서브샘플링/픽셀 구조",
@@ -33,7 +33,7 @@ Ls.kor = {
 			["G", "목록/그리드 보기 전환"],
 			["T", "썸네일/아이콘 전환"],
 			["⇧ A/D", "썸네일 이미지 크기"],
-			["ctrl-K", "선택 항목 삭제"],
+			["ctrl-K/Del", "선택 항목 삭제"],
 			["ctrl-X", "선택 항목 잘라내기"],
 			["ctrl-C", "선택 항목 복사"],
 			["ctrl-V", "여기에 붙여넣기 (이동/복사)"],
@@ -107,9 +107,9 @@ Ls.kor = {
 	"ht_and": " ",
 
 	"goh": "제어판",
-	"gop": '이전 형제 폴더">이전',
-	"gou": '상위 폴더">위로',
-	"gon": '다음 폴더">다음',
+	"gop": '이전 형제 폴더',
+	"gou": '상위 폴더',
+	"gon": '다음 폴더',
 	"logout": "로그아웃 ",
 	"login": "로그인", //m
 	"access": " 액세스",
@@ -157,7 +157,7 @@ Ls.kor = {
 	"ut_u2ts": "사용자 파일 시스템의 마지막 수정 타임스탬프를$N서버에 복사\">📅",
 	"ut_ow": "서버에 있는 기존 파일을 덮어쓸까요?$N🛡️: 안 함 (대신 새 파일 이름 생성)$N🕒: 서버 파일이 더 오래된 경우 덮어쓰기$N♻️: 파일이 다르면 항상 덮어쓰기$N⏭️: 기존 파일을 모두 무조건 건너뜀", //m
 	"ut_mt": "업로드 중 다른 파일 해싱 계속하기$N$NCPU 또는 HDD가 병목 현상을 일으키는 경우 비활성화하세요",
-	"ut_ask": '업로드 시작 전 확인 요청">💭',
+	"ut_ask": '업로드 시작 전 확인 요청',
 	"ut_pot": "느린 기기에서 UI를 단순화하여$N업로드 속도 향상",
 	"ut_srch": "실제로 업로드하는 대신, 파일이 이미 서버에 있는지 확인합니다$N(읽을 수 있는 모든 폴더를 스캔합니다)",
 	"ut_par": "0으로 설정하여 업로드 일시정지$N$N연결이 느리거나 지연 시간이 길면 늘리세요$N$NLAN 환경이거나 서버 HDD가 병목 현상을 일으키면 1로 유지하세요",
@@ -288,9 +288,9 @@ Ls.kor = {
 	"ml_drc": "다이내믹 레인지 압축기",
 	"ml_ss": "무음 건너뛰기", //m
 
-	"mt_loop": "한 곡 반복 재생\">🔁",
+	"mt_loop": "한 곡 반복 재생",
 	"mt_one": "한 곡 재생 후 중지\">1️⃣",
-	"mt_shuf": "각 폴더의 곡을 무작위 재생\">🔀",
+	"mt_shuf": "각 폴더의 곡을 무작위 재생",
 	"mt_aplay": "서버에 접속한 링크에 곡 ID가 있으면 자동 재생$N$N이것을 비활성화하면 음악 재생 시 페이지 URL이 곡 ID로 업데이트되지 않아, 이 설정이 손실되고 URL이 남아있을 경우 자동 재생되는 것을 방지합니다.\">a▶",
 	"mt_preload": "끊김 없는 재생을 위해 다음 곡을 미리 불러오기 시작\">미리로드",
 	"mt_prescan": "마지막 곡이 끝나기 전에 다음 폴더로 이동하여$N웹브라우저가 재생을 멈추지 않도록 합니다.\">탐색",
@@ -305,7 +305,7 @@ Ls.kor = {
 	"mt_follow": "재생 중인 트랙이 보이도록 스크롤 유지\">🎯",
 	"mt_compact": "컴팩트 컨트롤\">⟎",
 	"mt_uncache": "캐시 지우기 (브라우저가 곡의 깨진 사본을 캐시하여$N재생이 안되는 경우 시도해보세요)\">캐시삭제",
-	"mt_mloop": "열린 폴더 반복\">🔁 반복",
+	"mt_mloop": "열린 폴더 반복",
 	"mt_mnext": "다음 폴더 불러오고 계속\">📂 다음",
 	"mt_mstop": "재생 중지\">⏸ 중지",
 	"mt_cflac": "flac/wav를 {0}로 변환\">flac",
diff --git a/copyparty/web/tl/nld.js b/copyparty/web/tl/nld.js
index 373b62a7..0a6d1186 100644
--- a/copyparty/web/tl/nld.js
+++ b/copyparty/web/tl/nld.js
@@ -5,7 +5,7 @@ Ls.nld = {
 	"tt": "Nederlands",
 
 	"cols": {
-		"c": "Action knoppen",
+		"!": "Action knoppen",
 		"dur": "Duratie",
 		"q": "Kwaliteit / bitrate",
 		"Ac": "Audio codec",
@@ -14,7 +14,7 @@ Ls.nld = {
 		"Ahash": "Audio checksum",
 		"Vhash": "Video checksum",
 		"Res": "Resolution",
-		"T": "Bestandstype",
+		"Ext": "Bestandstype",
 		"aq": "Audio kwaliteit / bitrate",
 		"vq": "Video kwaliteit / bitrate",
 		"pixfmt": "Subsampling / pixel structure",
@@ -33,7 +33,7 @@ Ls.nld = {
 			["G", "Verwissel tussen list / grid weergave"],
 			["T", "Verwissel tussen miniaturen / iconen"],
 			["⇧ A/D", "Thumbnail formaat"],
-			["ctrl-K", "Verwijder geselecteerde"],
+			["ctrl-K/Del", "Verwijder geselecteerde"],
 			["ctrl-X", "Knip selectie naar klembord"],
 			["ctrl-C", "Kopieer selectie naar klembord"],
 			["ctrl-V", "Hier plakken (verplaatsen/kopieëren)"],
@@ -107,9 +107,9 @@ Ls.nld = {
 	"ht_and": " en ",
 
 	"goh": "Beheer-paneel",
-	"gop": 'Vorige map">Vorige',
-	"gou": 'Bovenligende map">Omhoog',
-	"gon": 'Volgende map">Volgende',
+	"gop": 'Vorige map',
+	"gou": 'Bovenligende map',
+	"gon": 'Volgende map',
 	"logout": "Uitloggen ",
 	"login": "Inloggen", //m
 	"access": " Toegang",
@@ -157,7 +157,7 @@ Ls.nld = {
 	"ut_u2ts": "Kopieer de laatste-gewijzigde tijdstamp$Nvan je bestandsysteem naar de server\">📅",
 	"ut_ow": "Overschrijf bestaande bestanden op de server?$N🛡️: nooit (zal in plaats daarvan een nieuwe bestandsnaam genereren)$N🕒: overschrijven als de server-bestand ouder is dan het geüploade bestand$N♻️: altijd overschrijven als de bestanden verschillend zijn$N⏭️: alle bestaande bestanden onvoorwaardelijk overslaan", //m
 	"ut_mt": "Ga door met hashen van andere bestanden tijdens het uploaden$N$Moet je misschien uitschakelen als je CPU of HDD het niet aan kan",
-	"ut_ask": 'Vraag voor bevestiging voordat het uploaden start">💭',
+	"ut_ask": 'Vraag voor bevestiging voordat het uploaden start',
 	"ut_pot": "Verbeter de uploadsnelheid voor langzame apparaten$Ndoor de interface minder complex te maken",
 	"ut_srch": "Niet uploaden, maar check of de bestanden als op de server bestaan$N (checkt alle mappen die waar jij toegang op hebt)",
 	"ut_par": "Pauzeer bij zetten het op 0$N$Nverhoog als je verbinding traag is$N$Nhou het op 1 als je netwerk of server HDD het niet aankan",
@@ -288,9 +288,9 @@ Ls.nld = {
 	"ml_drc": "Dynamisch bereikcompressor",
 	"ml_ss": "Stiltes overslaan", //m
 
-	"mt_loop": "Loop/herhaal een nummer\">🔁",
+	"mt_loop": "Loop/herhaal een nummer",
 	"mt_one": "Stop na een nummer\">1️⃣",
-	"mt_shuf": "Shuffle alle muziek in alle mappen\">🔀",
+	"mt_shuf": "Shuffle alle muziek in alle mappen",
 	"mt_aplay": "Autoplay als er een song-ID staat in de link waarop je hebt geklikt om naar de server te gaan$N$NAls u dit uitschakelt, wordt de pagina-URL ook niet meer bijgewerkt met nummer-ID's tijdens het afspelen van muziek. Dit voorkomt automatisch afspelen als deze instellingen verloren gaan, maar de URL behouden blijft.\">a▶",
 	"mt_preload": "Begin het laden van de volgende nummer vlak voordat de huidige nummer het einde bereikt voor gapless playback\">preload",
 	"mt_prescan": "Ga naar de volgende map voordat de laatste nummer eindigd$NMaakt de webbrower blij$NZo het afspelen van muziek niet gestopt word\">nav",
@@ -305,7 +305,7 @@ Ls.nld = {
 	"mt_follow": "Het afgespeelde nummer in beeld houden\">🎯",
 	"mt_compact": "Compacte bedieningselementen\">⟎",
 	"mt_uncache": "Cache wissen &nbsp;(Probeer dit als uw browser een kapotte kopie van een nummer heeft gecached, waardoor het niet afgespeeld kan worden)\">uncache",
-	"mt_mloop": "De open map herhalen\">🔁 loop",
+	"mt_mloop": "De open map herhalen",
 	"mt_mnext": "Laad de volgende map en ga verder\">📂 next",
 	"mt_mstop": "Stoppen met afspelen\">⏸ stop",
 	"mt_cflac": "flac / wav omzetten naar {0}\">flac",
diff --git a/copyparty/web/tl/nno.js b/copyparty/web/tl/nno.js
index d6342f68..c74d4a7b 100644
--- a/copyparty/web/tl/nno.js
+++ b/copyparty/web/tl/nno.js
@@ -2,7 +2,7 @@ Ls.nno = {
 	"tt": "Nynorsk",
 
 	"cols": {
-		"c": "handlingsknappar",
+		"!": "handlingsknappar",
 		"dur": "varigheit",
 		"q": "kvalitet / bitrate",
 		"Ac": "lydformat",
@@ -11,7 +11,7 @@ Ls.nno = {
 		"Ahash": "lydkontrollsum",
 		"Vhash": "videokontrollsum",
 		"Res": "oppløysing",
-		"T": "filtype",
+		"Ext": "filtype",
 		"aq": "lydkvalitet / bitrate",
 		"vq": "videokvalitet / bitrate",
 		"pixfmt": "fargekoding / detaljnivå",
@@ -30,7 +30,7 @@ Ls.nno = {
 			["G", "listevisning eller ikon"],
 			["T", "miniatyrbilder på/av"],
 			["⇧ A/D", "ikonstorleik"],
-			["ctrl-K", "slett valde"],
+			["ctrl-K/Del", "slett valde"],
 			["ctrl-X", "klipp ut valde"],
 			["ctrl-C", "kopiér åt utklippstavle"],
 			["ctrl-V", "lim inn (flytt/kopiér)"],
@@ -104,9 +104,9 @@ Ls.nno = {
 	"ht_and": " og ",
 
 	"goh": "kontrollpanel",
-	"gop": 'navigér åt mappa før den her">forr.',
-	"gou": 'navigér eitt nivå opp">opp',
-	"gon": 'navigér åt mappa etter den her">neste',
+	"gop": 'navigér åt mappa før den her',
+	"gou": 'navigér eitt nivå opp',
+	"gon": 'navigér åt mappa etter den her',
 	"logout": "Logg ut ",
 	"login": "Logg inn",
 	"access": " åtgang",
@@ -154,7 +154,7 @@ Ls.nno = {
 	"ut_u2ts": "gje fila på serveren same$Ntidsstempel som lokalt hos deg\">📅",
 	"ut_ow": "overskrive eksisterande filer på serveren?$N🛡️: aldri (finn på eit nytt filnamn i staden for)$N🕒: overskriv viss fila åt serveren er eldre$N♻️: alltid, gitt at innhaldet er annleis$N⏭️: hopp over alle eksisterande filer",
 	"ut_mt": "fortsett å synfare køa mens opplasting føregår$N$Nskru denne av dersom du har ein$Ntreig prosessor eller harddisk",
-	"ut_ask": 'bekreft filutvalg før opplasting startar">💭',
+	"ut_ask": 'bekreft filutvalg før opplasting startar',
 	"ut_pot": "forbetre ytinga på treige einheiter ved å$Nforenkle brukergrensesnittet",
 	"ut_srch": "gjer eit søk i staden for å laste opp --$Nleitar gjennom alle mappane du har lov åt å sjå",
 	"ut_par": "sett åt 0 for å midlertidig stoppe opplasting$N$Nhøge verdier (4 eller 8) kan gje betre yting,$Nspesielt på treige internettlinjer$N$Nbør ikkje vere høgare enn 1 på LAN$Neller viss serveren sin harddisk er treig",
@@ -285,9 +285,9 @@ Ls.nno = {
 	"ml_drc": "compressor (volumutjevning)",
 	"ml_ss": "spol forbi stillheit",
 
-	"mt_loop": "spel den same songen om og om igjen\">🔁",
+	"mt_loop": "spel den same songen om og om igjen",
 	"mt_one": "spel kun éin song\">1️⃣",
-	"mt_shuf": "songane i kvar mappe$Nspelast i tilfeldig rekkefølge\">🔀",
+	"mt_shuf": "songane i kvar mappe$Nspelast i tilfeldig rekkefølge",
 	"mt_aplay": "prøv å starte avspeling viss linken du trykte på for å åpne nettsida inneheld ein song-ID$N$Nviss denne deaktiverast så vil heller ikkje nettside-URL'en bli oppdatert med song-ID'er når musikk spelast, i tilfelle innstillingane skulle gå tapt og nettsida lastast på ny\">a▶",
 	"mt_preload": "hent ned litt av neste song i forkant,$Nslik at pausa i overgangen blir mindre\">forsyn",
 	"mt_prescan": "ved behov, bla åt neste mappe$Nslik at nettlesaren lar oss$Nfortsetja å spele musikk\">bla",
@@ -302,7 +302,7 @@ Ls.nno = {
 	"mt_follow": "bla slik at songen som spelast alltid er synleg\">🎯",
 	"mt_compact": "tettpakka spelarpanel\">⟎",
 	"mt_uncache": "prøv denne viss ein song ikkje spelar riktig\">oppfrisk",
-	"mt_mloop": "repetér heile mappa\">🔁 gjenta",
+	"mt_mloop": "repetér heile mappa",
 	"mt_mnext": "hopp åt neste mappe og fortsett\">📂 neste",
 	"mt_mstop": "stopp avspeling\">⏸ stopp",
 	"mt_cflac": "konvertér flac / wav-filer åt {0}\">flac",
diff --git a/copyparty/web/tl/nor.js b/copyparty/web/tl/nor.js
index 76b2c35c..c550de47 100644
--- a/copyparty/web/tl/nor.js
+++ b/copyparty/web/tl/nor.js
@@ -2,7 +2,7 @@ Ls.nor = {
 	"tt": "Norsk",
 
 	"cols": {
-		"c": "handlingsknapper",
+		"!": "handlingsknapper",
 		"dur": "varighet",
 		"q": "kvalitet / bitrate",
 		"Ac": "lyd-format",
@@ -11,7 +11,7 @@ Ls.nor = {
 		"Ahash": "lyd-kontrollsum",
 		"Vhash": "video-kontrollsum",
 		"Res": "oppløsning",
-		"T": "filtype",
+		"Ext": "filtype",
 		"aq": "lydkvalitet / bitrate",
 		"vq": "videokvalitet / bitrate",
 		"pixfmt": "fargekoding / detaljenivå",
@@ -30,7 +30,7 @@ Ls.nor = {
 			["G", "listevisning eller ikoner"],
 			["T", "miniatyrbilder på/av"],
 			["⇧ A/D", "ikonstørrelse"],
-			["ctrl-K", "slett valgte"],
+			["ctrl-K/Del", "slett valgte"],
 			["ctrl-X", "klipp ut valgte"],
 			["ctrl-C", "kopiér til utklippstavle"],
 			["ctrl-V", "lim inn (flytt/kopiér)"],
@@ -104,9 +104,9 @@ Ls.nor = {
 	"ht_and": " og ",
 
 	"goh": "kontrollpanel",
-	"gop": 'naviger til mappen før denne">forr.',
-	"gou": 'naviger ett nivå opp">opp',
-	"gon": 'naviger til mappen etter denne">neste',
+	"gop": 'naviger til mappen før denne',
+	"gou": 'naviger ett nivå opp',
+	"gon": 'naviger til mappen etter denne',
 	"logout": "Logg ut ",
 	"login": "Logg inn",
 	"access": " tilgang",
@@ -154,7 +154,7 @@ Ls.nor = {
 	"ut_u2ts": "gi filen på serveren samme$Ntidsstempel som lokalt hos deg\">📅",
 	"ut_ow": "overskrive eksisterende filer på serveren?$N🛡️: aldri (finner på et nytt filnavn istedenfor)$N🕒: overskriv hvis serverens fil er eldre$N♻️: alltid, gitt at innholdet er forskjellig$N⏭️: hopp over alle eksisterende filer",
 	"ut_mt": "fortsett å befare køen mens opplastning foregår$N$Nskru denne av dersom du har en$Ntreg prosessor eller harddisk",
-	"ut_ask": 'bekreft filutvalg før opplastning starter">💭',
+	"ut_ask": 'bekreft filutvalg før opplastning starter',
 	"ut_pot": "forbedre ytelsen på trege enheter ved å$Nforenkle brukergrensesnittet",
 	"ut_srch": "utfør søk istedenfor å laste opp --$Nleter igjennom alle mappene du har lov til å se",
 	"ut_par": "sett til 0 for å midlertidig stanse opplastning$N$Nhøye verdier (4 eller 8) kan gi bedre ytelse,$Nspesielt på trege internettlinjer$N$Nbør ikke være høyere enn 1 på LAN$Neller hvis serveren sin harddisk er treg",
@@ -285,9 +285,9 @@ Ls.nor = {
 	"ml_drc": "compressor (volum-utjevning)",
 	"ml_ss": "spol forbi stillhet",
 
-	"mt_loop": "spill den samme sangen om og om igjen\">🔁",
+	"mt_loop": "spill den samme sangen om og om igjen",
 	"mt_one": "spill kun én sang\">1️⃣",
-	"mt_shuf": "sangene i hver mappe$Nspilles i tilfeldig rekkefølge\">🔀",
+	"mt_shuf": "sangene i hver mappe$Nspilles i tilfeldig rekkefølge",
 	"mt_aplay": "forsøk å starte avspilling hvis linken du klikket på for å åpne nettsiden inneholder en sang-ID$N$Nhvis denne deaktiveres så vil heller ikke nettside-URL'en bli oppdatert med sang-ID'er når musikk spilles, i tilfelle innstillingene skulle gå tapt og nettsiden lastes på ny\">a▶",
 	"mt_preload": "hent ned litt av neste sang i forkant,$Nslik at pausen i overgangen blir mindre\">forles",
 	"mt_prescan": "ved behov, bla til neste mappe$Nslik at nettleseren lar oss$Nfortsette å spille musikk\">bla",
@@ -302,7 +302,7 @@ Ls.nor = {
 	"mt_follow": "bla slik at sangen som spilles alltid er synlig\">🎯",
 	"mt_compact": "tettpakket avspillerpanel\">⟎",
 	"mt_uncache": "prøv denne hvis en sang ikke spiller riktig\">oppfrisk",
-	"mt_mloop": "repeter hele mappen\">🔁 gjenta",
+	"mt_mloop": "repeter hele mappen",
 	"mt_mnext": "hopp til neste mappe og fortsett\">📂 neste",
 	"mt_mstop": "stopp avspilling\">⏸ stopp",
 	"mt_cflac": "konverter flac / wav-filer til {0}\">flac",
diff --git a/copyparty/web/tl/pol.js b/copyparty/web/tl/pol.js
index 88fa3f23..949a0640 100644
--- a/copyparty/web/tl/pol.js
+++ b/copyparty/web/tl/pol.js
@@ -5,7 +5,7 @@ Ls.pol = {
 	"tt": "Polski",
 
 	"cols": {
-		"c": "przyciski akcji",
+		"!": "przyciski akcji",
 		"dur": "czas trwania",
 		"q": "jakość / bitrate",
 		"Ac": "kodek audio",
@@ -14,7 +14,7 @@ Ls.pol = {
 		"Ahash": "suma kontrolna audio",
 		"Vhash": "suma kontrolna wideo",
 		"Res": "rozdzielczość",
-		"T": "rodzaj pliku",
+		"Ext": "rodzaj pliku",
 		"aq": "jakość / bitrate audio",
 		"vq": "jakość / bitrate wideo",
 		"pixfmt": "podpróbkowanie / struktura pikseli",
@@ -33,7 +33,7 @@ Ls.pol = {
 			["G", "przełącz widok lista / siatka"],
 			["T", "przełącz miniaturki / ikony"],
 			["⇧ A/D", "wielkość miniaturki"],
-			["ctrl-K", "usuń zaznaczone"],
+			["ctrl-K/Del", "usuń zaznaczone"],
 			["ctrl-X", "wytnij zaznaczone do schowka"],
 			["ctrl-C", "skopiuj zaznaczone do schowka"],
 			["ctrl-V", "wklej (przenieś/skopiuj) tutaj"],
@@ -110,9 +110,9 @@ Ls.pol = {
 	"ht_and": " i ",
 
 	"goh": "panel sterowania",
-	"gop": 'poprzedni plik/folder">poprzedni',
-	"gou": 'nadrzędny folder">w górę',
-	"gon": 'następny folder">następny',
+	"gop": 'poprzedni plik/folder',
+	"gou": 'nadrzędny folder',
+	"gon": 'następny folder',
 	"logout": "Wyloguj ",
 	"login": "Zaloguj się", //m
 	"access": " dostęp",
@@ -160,7 +160,7 @@ Ls.pol = {
 	"ut_u2ts": "kopiuj znacznik ostatniej modyfikacji$Nz twojego systemu plików na serwer\">📅",
 	"ut_ow": "nadpisywać istniejące pliki na serwerzę?$N🛡️: nigdy (wygeneruje nową nazwę)$N🕒: nadpisz jeśli pliki na serwerze są starsze niż przesyłane$N♻️: zawsze nadpisuj jeśli zawartość plików się różni$N⏭️: bezwarunkowo pomiń wszystkie istniejące pliki", //m
 	"ut_mt": "hashuj inne pliki podczas przesyłania$N$Nmożna wyłączyć w przypadku wystąpienia wąskiego gardła na CPU lub HDD",
-	"ut_ask": 'pytaj o potwierdzenie rozpoczęcia przesyłania">💭',
+	"ut_ask": 'pytaj o potwierdzenie rozpoczęcia przesyłania',
 	"ut_pot": "przyspiesz przesyłanie na słabszych urządzeniach,$Nupraszczając interfejs",
 	"ut_srch": "nie przesyłaj plików, jedynie sprawdź czy istnieją$Njuż na serwerze (przeskanuje wszystkie foldery dostępne do odczytu)",
 	"ut_par": "zatrzymuje przesyłanie jeśli wynosi 0$N$Nzwiększ w przypadku jeśli twoja sieć jest wolna / ma duże opóźnienia$N$Nustaw wartość 1 w sieci lokalnej lub w przypadku wolnego dysku serwerowego",
@@ -291,9 +291,9 @@ Ls.pol = {
 	"ml_drc": "kompresor zasięgu dynamiki",
 	"ml_ss": "pomijaj ciszę", //m
 
-	"mt_loop": "pętla/powtarzaj jeden utwór\">🔁",
+	"mt_loop": "pętla/powtarzaj jeden utwór",
 	"mt_one": "zatrzymaj po jednym utworze\">1️⃣",
-	"mt_shuf": "odtwarzaj losowo w każdym folderze\">🔀",
+	"mt_shuf": "odtwarzaj losowo w każdym folderze",
 	"mt_aplay": "autoodtwarzanie po kliknięciu linku do tego serwera, zawierającego identyfikator utworu$N$Nwyłączenie tej opcji zapobiegnie aktualizowaniu adresu strony podczas odtwarzania muzyki, aby zapobiec autoodtwarzaniu przy utracie ustawień\">a▶",
 	"mt_preload": "rozpocznij ładowanie kolejnego utworu blisko końca aktualnego w celu uzyskania odtwarzania bez przerw\">preload",
 	"mt_prescan": "przechodzi do następnego folderu przed zakończeniem ostatniego utworu,$Naby udobruchać przeglądarkę,$Nżeby nie zatrzymała odtwarzania\">naw",
@@ -308,7 +308,7 @@ Ls.pol = {
 	"mt_follow": "podążaj za odtwarzanym utworem przewijając widok\">🎯",
 	"mt_compact": "kompaktowe sterowanie\">⟎",
 	"mt_uncache": "wyczyść pamięć podręczną &nbsp;(spróbuj jeśli przeglądarka$Nzachowała zepsutą kopię utworu, przez co nie odtwarza się ona)\">uncache",
-	"mt_mloop": "odtwarzaj utwory w folderze w pętli\">🔁 loop",
+	"mt_mloop": "odtwarzaj utwory w folderze w pętli",
 	"mt_mnext": "wczytaj następny folder i kontynuuj\">📂 next",
 	"mt_mstop": "zatrzymaj odtwarzanie\">⏸ stop",
 	"mt_cflac": "przekonwertuj format flac / wav na {0}\">flac",
diff --git a/copyparty/web/tl/por.js b/copyparty/web/tl/por.js
index b13a557f..99515fff 100644
--- a/copyparty/web/tl/por.js
+++ b/copyparty/web/tl/por.js
@@ -5,7 +5,7 @@ Ls.por = {
 	"tt": "Português",
 
 	"cols": {
-		"c": "botões de ação",
+		"!": "botões de ação",
 		"dur": "duração",
 		"q": "qualidade / bitrate",
 		"Ac": "codec de áudio",
@@ -14,7 +14,7 @@ Ls.por = {
 		"Ahash": "checksum de áudio",
 		"Vhash": "checksum de vídeo",
 		"Res": "resolução",
-		"T": "tipo de arquivo",
+		"Ext": "tipo de arquivo",
 		"aq": "qualidade / bitrate de áudio",
 		"vq": "qualidade / bitrate de vídeo",
 		"pixfmt": "subamostragem / estrutura de pixel",
@@ -33,7 +33,7 @@ Ls.por = {
 			["G", "alternar entre visualização de lista / grade"],
 			["T", "alternar entre miniaturas / ícones"],
 			["⇧ A/D", "tamanho da miniatura"],
-			["ctrl-K", "excluir selecionados"],
+			["ctrl-K/Del", "excluir selecionados"],
 			["ctrl-X", "recortar seleção para a área de transferência"],
 			["ctrl-C", "copiar seleção para a área de transferência"],
 			["ctrl-V", "colar (mover/copiar) aqui"],
@@ -107,9 +107,9 @@ Ls.por = {
 	"ht_and": " e ",
 
 	"goh": "painel de controle",
-	"gop": 'pai anterior">anterior',
-	"gou": 'pasta pai">acima',
-	"gon": 'próxima pasta">próximo',
+	"gop": 'pai anterior',
+	"gou": 'pasta pai',
+	"gon": 'próxima pasta',
 	"logout": "Sair ",
 	"login": "Fazer login",
 	"access": " acesso",
@@ -157,7 +157,7 @@ Ls.por = {
 	"ut_u2ts": "copiar o carimbo de data/hora de última modificação$Ndo seu sistema de arquivos para o servidor\">📅",
 	"ut_ow": "substituir arquivos existentes no servidor?$N🛡️: nunca (irá gerar um novo nome de arquivo em vez disso)$N🕒: substituir se o arquivo no servidor for mais antigo que o seu$N♻️: sempre substituir se os arquivos forem diferentes$N⏭️: ignorar incondicionalmente todos os arquivos existentes",
 	"ut_mt": "continuar a fazer o hash de outros arquivos enquanto faz upload$N$Ntalvez desativar se sua CPU ou HDD for um gargalo",
-	"ut_ask": 'pedir confirmação antes do upload começar">💭',
+	"ut_ask": 'pedir confirmação antes do upload começar',
 	"ut_pot": "melhorar a velocidade de upload em dispositivos lentos$Ntornando a UI menos complexa",
 	"ut_srch": "não fazer upload, em vez disso verificar se os arquivos já$N existem no servidor (irá escanear todas as pastas que você pode ler)",
 	"ut_par": "pausar uploads definindo para 0$N$Naumentar se sua conexão for lenta / alta latência$N$Nmanter em 1 em LAN ou se o HDD do servidor for um gargalo",
@@ -288,9 +288,9 @@ Ls.por = {
 	"ml_drc": "compressor de faixa dinâmica",
 	"ml_ss": "ignorar silêncio", //m
 
-	"mt_loop": "loop/repetir uma música\">🔁",
+	"mt_loop": "loop/repetir uma música",
 	"mt_one": "parar depois de uma música\">1️⃣",
-	"mt_shuf": "embaralhar as músicas em cada pasta\">🔀",
+	"mt_shuf": "embaralhar as músicas em cada pasta",
 	"mt_aplay": "reproduzir automaticamente se houver um ID de música no link que você clicou para acessar o servidor$N$Ndesativar isso também impedirá que a URL da página seja atualizada com IDs de música ao tocar música, para evitar a reprodução automática se essas configurações forem perdidas mas a URL permanecer\">a▶",
 	"mt_preload": "começar a carregar a próxima música perto do final para uma reprodução sem interrupções\">preload",
 	"mt_prescan": "ir para a próxima pasta antes que a última música$Ntermine, mantendo o navegador feliz$Npara que ele não pare a reprodução\">nav",
@@ -305,7 +305,7 @@ Ls.por = {
 	"mt_follow": "manter a faixa que está tocando rolando à vista\">🎯",
 	"mt_compact": "controles compactos\">⟎",
 	"mt_uncache": "limpar cache &nbsp;(tente isso se seu navegador armazenou em cache$Numa cópia quebrada de uma música e se recusa a tocar)\">uncache",
-	"mt_mloop": "loop na pasta aberta\">🔁 loop",
+	"mt_mloop": "loop na pasta aberta",
 	"mt_mnext": "carregar a próxima pasta e continuar\">📂 próximo",
 	"mt_mstop": "parar reprodução\">⏸ parar",
 	"mt_cflac": "converter flac / wav para {0}\">flac",
diff --git a/copyparty/web/tl/rus.js b/copyparty/web/tl/rus.js
index 4a3ebec8..d59aeaa1 100644
--- a/copyparty/web/tl/rus.js
+++ b/copyparty/web/tl/rus.js
@@ -5,7 +5,7 @@ Ls.rus = {
 	"tt": "Русский",
 
 	"cols": {
-		"c": "кнопки действий",
+		"!": "кнопки действий",
 		"dur": "длительность",
 		"q": "качество / битрейт",
 		"Ac": "аудио кодек",
@@ -14,7 +14,7 @@ Ls.rus = {
 		"Ahash": "контрольная сумма аудио",
 		"Vhash": "контрольная сумма видео",
 		"Res": "разрешение",
-		"T": "тип файла",
+		"Ext": "тип файла",
 		"aq": "качество аудио / битрейт",
 		"vq": "качество видео / битрейт",
 		"pixfmt": "сабсемплинг / пиксельный формат",
@@ -33,7 +33,7 @@ Ls.rus = {
 			["G", "переключиться между списком / плиткой"],
 			["T", "переключиться между миниатюрами / иконками"],
 			["⇧ A/D", "размер миниатюры"],
-			["ctrl-K", "удалить выделенное"],
+			["ctrl-K/Del", "удалить выделенное"],
 			["ctrl-X", "вырезать выделенное в буфер"],
 			["ctrl-C", "копировать выделенное в буфер"],
 			["ctrl-V", "вставить (переместить/копировать) сюда"],
@@ -107,9 +107,9 @@ Ls.rus = {
 	"ht_and": " и ",
 
 	"goh": "панель управления",
-	"gop": 'предыдущая папка">пред',
-	"gou": 'родительская папка">вверх',
-	"gon": 'следующая папка">след',
+	"gop": 'предыдущая папка',
+	"gou": 'родительская папка',
+	"gon": 'следующая папка',
 	"logout": "Выйти ",
 	"login": "Войти", //m
 	"access": " доступ",
@@ -157,7 +157,7 @@ Ls.rus = {
 	"ut_u2ts": "копировать время последнего изменения$Nиз вашей файловой системы на сервер\">📅",
 	"ut_ow": "перезаписывать существующие файлы на сервере?$N🛡️: нет (для повторяющихся файлов будут создаваться новые имена)$N🕒: перезаписать файлы с датой изменения старее, чем у загружаемых$N♻️: всегда перезаписывать (если файлы различаются по содержанию)$N⏭️: безусловно пропускать все существующие файлы", //m
 	"ut_mt": "продолжать хешировать другие файлы во время загрузки$N$Nесть смысл отключить при медленном диске или процессоре",
-	"ut_ask": 'требовать подтверждения перед началом загрузки">💭',
+	"ut_ask": 'требовать подтверждения перед началом загрузки',
 	"ut_pot": "улучшить скорость загрузки на слабых устройства$Nс помощью упрощения интерфейса",
 	"ut_srch": "не загружать, а проверять, существуют ли данные файлы $N на сервере (проверка всех доступных вам папок)",
 	"ut_par": "при 0 загрузка встанет на паузу$N$Nследует повысить, если ваше подключение медленное$N$Nоставьте 1, если используется локальная сеть или диск сервера медленный",
@@ -288,9 +288,9 @@ Ls.rus = {
 	"ml_drc": "компрессор",
 	"ml_ss": "пропускать тишину", //m
 
-	"mt_loop": "повторять один трек\">🔁",
+	"mt_loop": "повторять один трек",
 	"mt_one": "остановить после этого трека\">1️⃣",
-	"mt_shuf": "перемешать треки во всех папках\">🔀",
+	"mt_shuf": "перемешать треки во всех папках",
 	"mt_aplay": "автоматически играть треки по нажатии на ссылки с их ID$N$Nпри отключении адрес сайта также перестанет обновляться в соответствии с текущим треком\">a▶",
 	"mt_preload": "подгружать следующий трек перед концом текущего для бесшовного переключения\">предзагр.",
 	"mt_prescan": "переходить в следующую папку перед окончанием последнего трека$Nне даёт браузеру прервать следующий плейлист\">нав.",
@@ -305,7 +305,7 @@ Ls.rus = {
 	"mt_follow": "держать фокус на играющем треке\">🎯",
 	"mt_compact": "компактный плеер\">⟎",
 	"mt_uncache": "очистить кеш &nbsp;(если браузер кешировал повреждённый$Nтрек и отказывается его запускать)\">уд. кеш",
-	"mt_mloop": "повторять треки в папке\">🔁 цикл",
+	"mt_mloop": "повторять треки в папке",
 	"mt_mnext": "загрузить следующую папку и продолжить в ней\">📂 след.",
 	"mt_mstop": "приостановить воспроизведение\">⏸ стоп",
 	"mt_cflac": "конвертировать flac / wav в {0}\">flac",
diff --git a/copyparty/web/tl/spa.js b/copyparty/web/tl/spa.js
index 41ac34ad..8590b675 100644
--- a/copyparty/web/tl/spa.js
+++ b/copyparty/web/tl/spa.js
@@ -5,7 +5,7 @@ Ls.spa = {
 	"tt": "Español",
 
 	"cols": {
-		"c": "acciones",
+		"!": "acciones",
 		"dur": "duración",
 		"q": "calidad / bitrate",
 		"Ac": "códec de audio",
@@ -14,7 +14,7 @@ Ls.spa = {
 		"Ahash": "checksum de audio",
 		"Vhash": "checksum de vídeo",
 		"Res": "resolución",
-		"T": "tipo de archivo",
+		"Ext": "tipo de archivo",
 		"aq": "calidad de audio / bitrate",
 		"vq": "calidad de vídeo / bitrate",
 		"pixfmt": "submuestreo / estructura de píxel",
@@ -33,7 +33,7 @@ Ls.spa = {
 			["G", "alternar vista de lista / cuadrícula"],
 			["T", "alternar miniaturas / iconos"],
 			["⇧ A/D", "tamaño de miniatura"],
-			["ctrl-K", "eliminar seleccionados"],
+			["ctrl-K/Del", "eliminar seleccionados"],
 			["ctrl-X", "cortar selección al portapapeles"],
 			["ctrl-C", "copiar selección al portapapeles"],
 			["ctrl-V", "pegar (mover/copiar) aquí"],
@@ -107,9 +107,9 @@ Ls.spa = {
 	"ht_and": " y ",
 
 	"goh": "panel de control",
-	"gop": 'hermano anterior">anterior',
-	"gou": 'carpeta de nivel superior">subir',
-	"gon": 'siguiente carpeta">siguiente',
+	"gop": 'hermano anterior',
+	"gou": 'carpeta de nivel superior',
+	"gon": 'siguiente carpeta',
 	"logout": "Cerrar sesión ",
 	"login": "Iniciar sesión", //m
 	"access": " acceso",
@@ -157,7 +157,7 @@ Ls.spa = {
 	"ut_u2ts": 'copiar la fecha de última modificación$Nde tu sistema de archivos al servidor">📅',
 	"ut_ow": "sobrescribir archivos existentes en el servidor?$N🛡️: nunca (generará un nuevo nombre de archivo en su lugar)$N🕒: sobrescribir si el archivo del servidor es más antiguo que el tuyo$N♻️: siempre sobrescribir si los archivos son diferentes$N⏭️: omitir incondicionalmente todos los archivos existentes", //m
 	"ut_mt": "continuar generando hashes de otros archivos mientras se sube$N$Nquizás desactivar si tu CPU o HDD es un cuello de botella",
-	"ut_ask": 'pedir confirmación antes de iniciar la subida">💭',
+	"ut_ask": 'pedir confirmación antes de iniciar la subida',
 	"ut_pot": "mejorar la velocidad de subida en dispositivos lentos$Nsimplificando la interfaz de usuario",
 	"ut_srch": "no subir, en su lugar comprobar si los archivos ya $N existen en el servidor (escaneará todas las carpetas que puedas leer)",
 	"ut_par": "pausar subidas poniéndolo a 0$N$Naumentar si tu conexión es lenta / de alta latencia$N$Nmantener en 1 en LAN o si el HDD del servidor es un cuello de botella",
@@ -287,9 +287,9 @@ Ls.spa = {
 	"ml_drc": "compresor de rango dinámico",
 	"ml_ss": "saltar silencios", //m
 
-	"mt_loop": 'poner en bucle/repetir una canción">🔁',
+	"mt_loop": 'poner en bucle/repetir una canción',
 	"mt_one": 'parar después de una canción">1️⃣',
-	"mt_shuf": 'reproducir aleatoriamente las canciones en cada carpeta">🔀',
+	"mt_shuf": 'reproducir aleatoriamente las canciones en cada carpeta',
 	"mt_aplay": 'reproducir automaticamente si hay un ID de canción en el enlace en el que hiciste clic para acceder al servidor$N$Ndesactivar esto también evitará que la URL de la página se actualice con IDs de canción al reproducir música, para prevenir la reproducción automática si se pierden estos ajustes pero la URL permanece">a▶',
 	"mt_preload": 'empezar a cargar la siguiente canción cerca del final para una reproducción sin pausas">precarga',
 	"mt_prescan": 'ir a la siguiente carpeta antes de que la última canción$Ntermine, manteniendo contento al navegador$Npara que no detenga la reproducción">nav',
@@ -304,7 +304,7 @@ Ls.spa = {
 	"mt_follow": 'mantener la pista en reproducción visible en pantalla">🎯',
 	"mt_compact": 'controles compactos">⟎',
 	"mt_uncache": 'limpiar caché &nbsp;(prueba esto si tu navegador guardó en caché$Nuna copia rota de una canción que se niega a reproducir)">limpiar caché',
-	"mt_mloop": 'repetir la carpeta actual">🔁 bucle',
+	"mt_mloop": 'repetir la carpeta actual',
 	"mt_mnext": 'cargar la siguiente carpeta y continuar">📂 sig',
 	"mt_mstop": 'detener reproducción">⏸ parar',
 	"mt_cflac": 'convertir flac / wav a {0}">flac',
diff --git a/copyparty/web/tl/swe.js b/copyparty/web/tl/swe.js
index ed4f5327..0b2fcfd1 100644
--- a/copyparty/web/tl/swe.js
+++ b/copyparty/web/tl/swe.js
@@ -5,7 +5,7 @@ Ls.swe = {
 	"tt": "Svenska",
 
 	"cols": {
-		"c": "aktion",
+		"!": "aktion",
 		"dur": "längd",
 		"q": "kvalitet / bitrate",
 		"Ac": "ljudkodek",
@@ -14,7 +14,7 @@ Ls.swe = {
 		"Ahash": "ljudchecksumma",
 		"Vhash": "videochecksumma",
 		"Res": "upplösning",
-		"T": "filtyp",
+		"Ext": "filtyp",
 		"aq": "ljudkvalitet / bitrate",
 		"vq": "videokvalitet / bitrate",
 		"pixfmt": "subsampling / pixelstruktur",
@@ -33,7 +33,7 @@ Ls.swe = {
 			["G", "växla mellan listvy / rutnät"],
 			["T", "växla mellan miniatyrer / ikoner"],
 			["⇧ A/D", "miniatyrstorlek"],
-			["ctrl-K", "radera urval"],
+			["ctrl-K/Del", "radera urval"],
 			["ctrl-X", "klipp urval till urklipp"],
 			["ctrl-C", "kopiera urval till urklipp"],
 			["ctrl-V", "klistra in (kopiera/flytta) hit"],
@@ -107,9 +107,9 @@ Ls.swe = {
 	"ht_and": " och ",
 
 	"goh": "kontrollpanel",
-	"gop": 'föregående mapp">föreg.',
-	"gou": 'överordnad mapp">upp',
-	"gon": 'nästa mapp">nästa',
+	"gop": 'föregående mapp',
+	"gou": 'överordnad mapp',
+	"gon": 'nästa mapp',
 	"logout": "Logga ut ",
 	"login": "Logga in", //m
 	"access": "-rättighet",
@@ -157,7 +157,7 @@ Ls.swe = {
 	"ut_u2ts": "bevara tidsstämpeln för senaste ändring$Nfrån ditt filsystem till servern\">📅",
 	"ut_ow": "skriv över existerande filer på servern?$N🛡️: aldrig (skapar ett nytt filnamn istället)$N🕒: skriv över om serverns fil är äldre än din$N♻️: skriv alltid över om filerna skiljer sig$N⏭️: hoppa ovillkorligen över alla befintliga filer", //m
 	"ut_mt": "fortsätt hasha filer under uppladdningens gång$N$Nstäng av om din CPU eller disk är en flaskhals",
-	"ut_ask": 'bekräfta innan uppladdningar påbörjas">💭',
+	"ut_ask": 'bekräfta innan uppladdningar påbörjas',
 	"ut_pot": "förbättra uppladdningshastigheten på långsamma enheter$Ngenom att förenkla användargränssnittet",
 	"ut_srch": "ladda inte upp; kolla istället om filerna redan existerar på $N servern (detta kommer att skanna alla mappar med läsrättighet)",
 	"ut_par": "du kan pausa all uppladdning genom att sätta detta till 0$N$Nöka denna om din uppkoppling är långsam eller har hög latens$N$Nsätt till 1 över lokala nätverk eller om serverns disk är en flaskhals",
@@ -288,9 +288,9 @@ Ls.swe = {
 	"ml_drc": "dynamikkompressor",
 	"ml_ss": "hoppa över tystnad", //m
 
-	"mt_loop": "upprepa en låt\">🔁",
+	"mt_loop": "upprepa en låt",
 	"mt_one": "stoppa uppspelningen efter en låt\">1️⃣",
-	"mt_shuf": "blanda låtarna i varje mapp\">🔀",
+	"mt_shuf": "blanda låtarna i varje mapp",
 	"mt_aplay": "spela automatiskt om det finns en låt-ID i länkar du har klickat på för att öppna sidan$N$Nom detta är avstängt kommer sidans adress inte att bli uppdaterad med en låt-ID om du spelar musik, för att förhindra automatisk uppspelning om dessa inställningar går förlorade men webbadressen återstår\">a▶",
 	"mt_preload": "påbörja nedladdning av nästa låt i förväg för gapfri uppspelning\">ladda",
 	"mt_prescan": "hoppa till nästa mapp i förväg så att webbläsaren$Nförblir glad och inte avbryter uppspelningen\">nav",
@@ -305,7 +305,7 @@ Ls.swe = {
 	"mt_follow": "skrolla vyn till den spelande låten\">🎯",
 	"mt_compact": "kompakt kontrollpanel\">⟎",
 	"mt_uncache": "rensa cachen &nbsp;(prova detta om din webbläsare har cachat$Nen trasig kopia av en låt och den vägrar spela upp den)\">rensa",
-	"mt_mloop": "upprepa den öppna mappen\">🔁 upprepa",
+	"mt_mloop": "upprepa den öppna mappen",
 	"mt_mnext": "ladda nästa mapp och fortsätt\">📂 nästa",
 	"mt_mstop": "stoppa uppspelningen\">⏸ stopp",
 	"mt_cflac": "konvertera flac / wav till {0}\">flac",
diff --git a/copyparty/web/tl/tur.js b/copyparty/web/tl/tur.js
index 1cbfde9f..7fc3d468 100644
--- a/copyparty/web/tl/tur.js
+++ b/copyparty/web/tl/tur.js
@@ -5,7 +5,7 @@ Ls.tur = {
 	"tt": "Türkçe",
 
 	"cols": {
-		"c": "işlem butonları",
+		"!": "işlem butonları",
 		"dur": "süre",
 		"q": "kalite / bitrate",
 		"Ac": "ses kodlaması",
@@ -14,7 +14,7 @@ Ls.tur = {
 		"Ahash": "ses denetim toplamı",
 		"Vhash": "video denetim toplamı",
 		"Res": "çözünürlük",
-		"T": "dosya türü",
+		"Ext": "dosya türü",
 		"aq": "ses kalitesi / bitrate",
 		"vq": "video kalitesi / bitrate",
 		"pixfmt": "subsampling / pixel yapısı",
@@ -33,7 +33,7 @@ Ls.tur = {
 			["G", "liste / ızgara görünümü arasında geçiş yap"],
 			["T", "küçük resimler / simgeler arasında geçiş yap"],
 			["⇧ A/D", "küçük resim boyutu"],
-			["ctrl-K", "seçileni sil"],
+			["ctrl-K/Del", "seçileni sil"],
 			["ctrl-X", "seçimi panoya kes"],
 			["ctrl-C", "seçimi panoya kopyala"],
 			["ctrl-V", "buraya yapıştır (taşı/kopyala)"],
@@ -107,9 +107,9 @@ Ls.tur = {
 	"ht_and": " ve ",
 
 	"goh": "kontrol paneli",
-	"gop": 'önceki kardeş">önceki',
-	"gou": 'üst klasör">üst',
-	"gon": 'sonraki klasör">sonraki',
+	"gop": 'önceki kardeş',
+	"gou": 'üst klasör',
+	"gon": 'sonraki klasör',
 	"logout": "Çıkış ",
 	"login": "Giriş",
 	"access": " erişim",
@@ -157,7 +157,7 @@ Ls.tur = {
 	"ut_u2ts": "kendi dosyalarınızdan sunucuya$Nzaman damgasını kopyala\">📅",
 	"ut_ow": "sunucudaki mevcut dosyaları üzerine yazmak mı?$N🛡️: asla (yerine yeni bir dosya adı oluşturur)$N🕒: sunucu dosyası sizinkinden daha eskiyse üzerine yaz$N♻️: dosyalar farklıysa her zaman üzerine yaz$N⏭️: mevcut tüm dosyaları koşulsuz atla", //m
 	"ut_mt": "yükleme yaparken diğer dosyaların hash'lenmesini durdur$N$kötü bir CPU veya HDD'ye sahipseniz kullanabilirsiniz.",
-	"ut_ask": 'yüklemeye başlamadan önce doğrulama mesajı göster">💭',
+	"ut_ask": 'yüklemeye başlamadan önce doğrulama mesajı göster',
 	"ut_pot": "arayüzü daha az karmaşık hale getirerek$Nyükleme hızını yavaş cihazlarda artır",
 	"ut_srch": "gerçekten yükleme yapma, bunun yerine dosyaların $N sunucuda var olup olmadığını kontrol et (okuma izniniz olan tüm klasörleri tarar)",
 	"ut_par": "0'a ayarlayarak yüklemeleri durdur$N$Nbağlantınız yavaşsa değeri artırın$N$NLAN'daysanız veya sunucu HDD'si darboğaz yapıyorsa 1'de tutun",
@@ -288,9 +288,9 @@ Ls.tur = {
 	"ml_drc": "dinamik aralık sıkıştırıcı",
 	"ml_ss": "sessizliği atla", //m
 
-	"mt_loop": "bir şarkıyı döngüye al / tekrar et\">🔁",
+	"mt_loop": "bir şarkıyı döngüye al / tekrar et",
 	"mt_one": "bir şarkıdan sonra dur\">1️⃣",
-	"mt_shuf": "klasörlerdeki şarkıları karıştır\">🔀",
+	"mt_shuf": "klasörlerdeki şarkıları karıştır",
 	"mt_aplay": "sunucuya erişmek için kullandığın bağlantıda geçerli bir şarkı varsa otomatik oynat$N$Nbunu etkisiz kılmak aynı zamanda müzik oynatıldığında sayfa URL'nin değişmesini de engeller\">a▶",
 	"mt_preload": "aralıksız oynatma için sıradaki şarkıyı önceden yüklemeye başla\">ön yükleme",
 	"mt_prescan": "son şarkı bitmeden önce bir sonraki klasöre git$Nweb tarayıcısını mutlu tutar$Nbu nedenle oynatmayı durdurmaz\">nav",
@@ -305,7 +305,7 @@ Ls.tur = {
 	"mt_follow": "oynatılan müzik ibaresini görünümde tut\">🎯",
 	"mt_compact": "kompakt kontroller\">⟎",
 	"mt_uncache": "önbelleği temizle &nbsp;(bunu, tarayıcınızın bozuk bir şarkı kopyasını önbelleğe alması nedeniyle çalmayı reddettiğinde deneyin)\">önbelleği temizle",
-	"mt_mloop": "açık klasörü döngüye al\">🔁 döngü",
+	"mt_mloop": "açık klasörü döngüye al",
 	"mt_mnext": "bir sonraki klasörü yükle ve devam et\">📂 sonraki",
 	"mt_mstop": "oynatmayı durdur\">⏸ durdur",
 	"mt_cflac": "flac / wav'ı {0}'a dönüştür\">flac",
diff --git a/copyparty/web/tl/ukr.js b/copyparty/web/tl/ukr.js
index 9c7b54d8..4ca0cdec 100644
--- a/copyparty/web/tl/ukr.js
+++ b/copyparty/web/tl/ukr.js
@@ -5,7 +5,7 @@ Ls.ukr = {
 	"tt": "Українська",
 
 	"cols": {
-		"c": "кнопки дій",
+		"!": "кнопки дій",
 		"dur": "тривалість",
 		"q": "якість / бітрейт",
 		"Ac": "аудіо кодек",
@@ -14,7 +14,7 @@ Ls.ukr = {
 		"Ahash": "контрольна сума аудіо",
 		"Vhash": "контрольна сума відео",
 		"Res": "роздільність",
-		"T": "тип файлу",
+		"Ext": "тип файлу",
 		"aq": "якість аудіо / бітрейт",
 		"vq": "якість відео / бітрейт",
 		"pixfmt": "підвибірка / структура пікселів",
@@ -33,7 +33,7 @@ Ls.ukr = {
 			["G", "перемкнути список / сітку"],
 			["T", "перемкнути мініатюри / іконки"],
 			["⇧ A/D", "розмір мініатюр"],
-			["ctrl-K", "видалити вибране"],
+			["ctrl-K/Del", "видалити вибране"],
 			["ctrl-X", "вирізати до буфера"],
 			["ctrl-C", "копіювати до буфера"],
 			["ctrl-V", "вставити (перемістити/копіювати) сюди"],
@@ -107,9 +107,9 @@ Ls.ukr = {
 	"ht_and": " і ",
 
 	"goh": "панель керування",
-	"gop": 'попередній сусід">назад',
-	"gou": 'батьківська папка">вгору',
-	"gon": 'наступна папка">далі',
+	"gop": 'попередній сусід',
+	"gou": 'батьківська папка',
+	"gon": 'наступна папка',
 	"logout": "Вийти ",
 	"login": "увійти", //m
 	"access": " доступ",
@@ -157,7 +157,7 @@ Ls.ukr = {
 	"ut_u2ts": "копіювати часову мітку останньої зміни$Nз вашої файлової системи на сервер\">📅",
 	"ut_ow": "перезаписати існуючі файли на сервері?$N🛡️: ніколи (замість цього створить нове ім'я файлу)$N🕒: перезаписати, якщо файл на сервері старіший за ваш$N♻️: завжди перезаписувати, якщо файли відрізняються$N⏭️: безумовно пропускати всі наявні файли", //m
 	"ut_mt": "продовжувати хешування інших файлів під час завантаження$N$Nможливо, вимкніть, якщо ваш CPU або HDD є вузьким місцем",
-	"ut_ask": 'запитати підтвердження перед початком завантаження">💭',
+	"ut_ask": 'запитати підтвердження перед початком завантаження',
 	"ut_pot": "покращити швидкість завантаження на повільних пристроях$Nроблячи інтерфейс менш складним",
 	"ut_srch": "не завантажувати, а перевірити, чи файли вже $N існують на сервері (сканує всі папки, які ви можете читати)",
 	"ut_par": "призупинити завантаження, встановивши 0$N$Nзбільшіть, якщо ваше з'єднання повільне / висока затримка$N$Nзалишіть 1 в локальній мережі або якщо HDD сервера є вузьким місцем",
@@ -288,9 +288,9 @@ Ls.ukr = {
 	"ml_drc": "компресор динамічного діапазону",
 	"ml_ss": "пропускати тишу", //m
 
-	"mt_loop": "зациклити/повторити одну пісню\">🔁",
+	"mt_loop": "зациклити/повторити одну пісню",
 	"mt_one": "зупинити після однієї пісні\">1️⃣",
-	"mt_shuf": "перемішати пісні в кожній папці\">🔀",
+	"mt_shuf": "перемішати пісні в кожній папці",
 	"mt_aplay": "автовідтворення, якщо є ID пісні в посиланні, по якому ви клацнули для доступу до сервера$N$Nвідключення цього також зупинить оновлення URL сторінки з ID пісень під час відтворення музики, щоб запобігти автовідтворенню, якщо ці налаштування втрачені, але URL залишається\">a▶",
 	"mt_preload": "почати завантаження наступної пісні ближче до кінця для безперервного відтворення\">preload",
 	"mt_prescan": "перейти до наступної папки перед тим, як остання пісня$Nзакінчиться, підтримуючи веб-браузер у робочому стані$Nщоб він не зупинив відтворення\">nav",
@@ -305,7 +305,7 @@ Ls.ukr = {
 	"mt_follow": "тримати трек, що відтворюється, у полі зору\">🎯",
 	"mt_compact": "компактні елементи керування\">⟎",
 	"mt_uncache": "очистити кеш &nbsp;(спробуйте це, якщо ваш браузер закешував$Nпошкоджену копію пісні, тому відмовляється її відтворювати)\">uncache",
-	"mt_mloop": "зациклити відкриту папку\">🔁 loop",
+	"mt_mloop": "зациклити відкриту папку",
 	"mt_mnext": "завантажити наступну папку і продовжити\">📂 next",
 	"mt_mstop": "зупинити відтворення\">⏸ stop",
 	"mt_cflac": "конвертувати flac / wav в {0}\">flac",
diff --git a/copyparty/web/tl/vie.js b/copyparty/web/tl/vie.js
index e47cd04e..476fbcda 100644
--- a/copyparty/web/tl/vie.js
+++ b/copyparty/web/tl/vie.js
@@ -2,7 +2,7 @@ Ls.vie = {
 	"tt": "Tiếng Việt",
 
 	"cols": {
-		"c": "nút hành động",
+		"!": "nút hành động",
 		"dur": "thời lượng",
 		"q": "chất lượng / bitrate",
 		"Ac": "codec âm thanh",
@@ -11,7 +11,7 @@ Ls.vie = {
 		"Ahash": "checksum âm thanh",
 		"Vhash": "checksum video",
 		"Res": "độ phân giải",
-		"T": "loại tệp",
+		"Ext": "loại tệp",
 		"aq": "chất lượng âm thanh / bitrate",
 		"vq": "chất lượng video / bitrate",
 		"pixfmt": "subsampling / pixel structure",
@@ -30,7 +30,7 @@ Ls.vie = {
 			["G", "chuyển đổi chế độ xem danh sách / lưới"],
 			["T", "chuyển đổi ảnh thu nhỏ / biểu tượng"],
 			["⇧ A/D", "kích thước ảnh thu nhỏ"],
-			["ctrl-K", "xoá mục đã chọn"],
+			["ctrl-K/Del", "xoá mục đã chọn"],
 			["ctrl-X", "cắt mục đã chọn vào bảng nhớ tạm"],
 			["ctrl-C", "sao chép mục đã chọn vào bảng nhớ tạm"],
 			["ctrl-V", "dán (di chuyển/sao chép) tại đây"],
@@ -102,9 +102,9 @@ Ls.vie = {
 	"ht_and": " và ",
 
 	"goh": "bảng điều khiển",
-	"gop": 'thư mục trước">trước',
-	"gou": 'thư mục cha">lên',
-	"gon": 'thư mục sau">tiếp',
+	"gop": 'thư mục trước',
+	"gou": 'thư mục cha',
+	"gon": 'thư mục sau',
 	"logout": "Đăng xuất ",
 	"login": "Đăng nhập",
 	"access": "quyền truy cập",
@@ -154,7 +154,7 @@ Ls.vie = {
 	"ut_u2ts": "sao chép dấu thời gian chỉnh sửa cuối$Ntừ hệ thống tệp của bạn lên máy chủ\">📅",
 	"ut_ow": "ghi đè các tệp đã có trên máy chủ?$N🛡️: không bao giờ (sẽ tạo tên tệp mới)$N🕒: ghi đè nếu tệp trên máy chủ cũ hơn$N♻️: luôn ghi đè nếu hai tệp khác nhau$N⏭️: bỏ qua vô điều kiện tất cả các tệp hiện có", //m
 	"ut_mt": "tiếp tục hash các tệp khác trong khi tải lên$N$NCó thể tắt nếu CPU hoặc HDD của bạn bị nghẽn",
-	"ut_ask": 'yêu cầu xác nhận trước khi bắt đầu tải lên">💭',
+	"ut_ask": 'yêu cầu xác nhận trước khi bắt đầu tải lên',
 	"ut_pot": "cải thiện tốc độ tải lên trên các thiết bị chậm$Nbằng cách đơn giản hoá giao diện người dùng",
 	"ut_srch": "không tải lên, chỉ kiểm tra xem tệp$Nđã tồn tại trên máy chủ hay chưa (sẽ quét toàn bộ thư mục bạn có quyền đọc)",
 	"ut_par": "tạm dừng tải lên bằng cách đặt thành 0$N$NTăng lên nếu kết nối chậm hoặc độ trễ cao$N$NGiữ ở mức 1 khi dùng LAN hoặc nếu ổ cứng máy chủ bị nghẽn",
@@ -292,9 +292,9 @@ Ls.vie = {
 	"ml_drc": "bộ nén dải động",
 	"ml_ss": "bỏ qua khoảng lặng", //m
 
-	"mt_loop": "lặp lại một bài\">🔁",
+	"mt_loop": "lặp lại một bài",
 	"mt_one": "dừng sau một bài\">1️⃣",
-	"mt_shuf": "trộn các bài trong thư mụcr\">🔀",
+	"mt_shuf": "trộn các bài trong thư mụcr",
 	"mt_aplay": "tự động phát nếu có ID bài trong link bạn nhấp để truy cập máy chủ$N$Ntắt tuỳ chọn sẽ ngăn URL của trang cập nhật theo ID bài khi phát nhạc, tránh tự động phát nếu cài đặt mất nhưng URL còn\">a▶",
 	"mt_preload": "bắt đầu tải bài hát tiếp theo khi gần hết bài để phát liền mạch\">preload",
 	"mt_prescan": "chuyển đến thư mục tiếp theo trước khi bài cuối cùng $Nkết thúc, giúp giữ trình duyệt hoạt động $N và không dừng phát nhạc\">nav",
@@ -309,7 +309,7 @@ Ls.vie = {
 	"mt_follow": "giữ bài đang phát trong tầm nhìn\">🎯",
 	"mt_compact": "giao diện điều khiển thu gọn\">⟎",
 	"mt_uncache": "xoá bộ nhớ đệm &nbsp;(thử nếu trình duyệt lưu trữ đệm $Nmột bản nhạc bị lỗi và không thể phát)\">uncache",
-	"mt_mloop": "lặp trong thư mục đang mở\">🔁 loop",
+	"mt_mloop": "lặp trong thư mục đang mở",
 	"mt_mnext": "tải thư mục tiếp theo và tiếp tục\">📂 next",
 	"mt_mstop": "dừng phát\">⏸ stop",
 	"mt_cflac": "chuyển flac / wav sang {0}\">flac",
diff --git a/copyparty/web/ui.css b/copyparty/web/ui.css
index a20b5074..92ceb749 100644
--- a/copyparty/web/ui.css
+++ b/copyparty/web/ui.css
@@ -1,21 +1,110 @@
 :root {
+	color-scheme: dark;
+
 	--font-main: sans-serif;
 	--font-serif: serif;
 	--font-mono: 'scp';
 
-	--fg: #ccc;
 	--fg-max: #fff;
-	--bg-u2: #2b2b2b;
-	--bg-u5: #444;
+	--bg-max: #080808;
+	--a: #fc5;
+	accent-color: var(--a);
+	--radius: 7px;
+	
+	--fg-max: #fefefe;
+	--bg-max: #010101;
+
+	--a-hil: rgb(255, 215, 121);
+	--a-dark: rgb(235, 165, 37); /* warning text etc */
+	--a-gray: #ccc;
+
+	--fg: #efefef;
+	--fg-weak: #c4c4c4;
+
+	--bg: #1f1f1f;
+	--bg-half: #01010182;
+	--bg-u1: #212121;
+	--bg-u2: #353535;
+	--bg-u3: #404040;
+	--bg-u5: #4e4e4e;
+	--bg-d1: #111111;
+	--bg-d2: #0e0e0e;
+	--bg-d3: #0b0b0b;
+
+	--bgg: var(--bg);
 }
 html.y {
-	--fg: #222;
+	color-scheme: light;
+
 	--fg-max: #000;
-	--bg-u2: #f7f7f7;
-	--bg-u5: #ccc;
+	--bg-max: #fff;
+	color-scheme: light;
+
+	--a: #07c;
+	
+	--a-hil: rgb(121, 193, 255);
+	--a-dark: rgb(7, 95, 183); /* warning text etc */
+	--a-gray: #ccc;
+
+	--fg: #101010;
+	--fg-weak: #323232;
+
+	--bg: #eeeeee;
+	--bg-half: #eeeeee82;
+	--bg-u1: #e3e3e3;
+	--bg-u2: #d6d6d6;
+	--bg-u3: #c7c7c7;
+	--bg-u5: #bcbcbc;
+	--bg-d1: #f4f4f4;
+	--bg-d2: #f5f5f5;
+	--bg-d3: #f6f6f6;
+
+	--chk-fg: var(--fg);
+	--txt-sh: #aaa;
+	--txt-bg: var(--bg-d1);
+	--mp-sh: #0002;
+
+	text-shadow: none;
 }
-html.bz {
-	--bg-u2: #202231;
+@supports (background: hsl(from #ccc, h s l)){
+	:root {
+		--a-hil: hsl(from var(--a) h calc(s * 1.2) l);
+		--a-dark: hsl(from var(--a) h calc(s * 1.3) l); /* warning text etc */
+		--a-gray: hsl(from var(--a) h calc(s * 0.1) l);
+	}
+}
+@supports (background: color-mix(in oklab, black, white)){
+	:root, html.y {
+		/* accent color in everything */
+		--fg-max: color-mix(in oklab, #fefefe 95%, var(--a) 5%);
+		--bg-max: color-mix(in oklab, #010101 95%, var(--a) 5%);
+
+		--a-hil: hsl(from color-mix(in oklab, var(--a) 80%, var(--fg-max) 20%) h calc(s * 1.2) l);
+		--a-dark: hsl(from color-mix(in oklab, var(--a) 60%, var(--bg-max) 40%) h calc(s * 1.3) l); /* warning text etc */
+		--a-gray: hsl(from var(--a) h calc(s * 0.1) l);
+
+		--fg: color-mix(in oklab, var(--fg-max) 90%, var(--bg-max) 10%);
+		--fg-weak: color-mix(in oklab, var(--fg-max) 70%, var(--bg-max) 30%);
+
+		--bg: color-mix(in oklab, var(--bg-max) 85%, var(--fg-max) 15%);
+		--bg-half: color-mix(in oklab, var(--bg) 50%, transparent 50%);
+		--bg-u1: color-mix(in oklab, var(--bg-max) 80%, var(--fg-max) 20%);
+		--bg-u2: color-mix(in oklab, var(--bg-max) 75%, var(--fg-max) 25%);
+		--bg-u3: color-mix(in oklab, var(--bg-max) 70%, var(--fg-max) 30%);
+		--bg-u5: color-mix(in oklab, var(--bg-max) 65%, var(--fg-max) 35%);
+		--bg-d1: color-mix(in oklab, var(--bg-max) 90%, var(--fg-max) 10%);
+		--bg-d2: color-mix(in oklab, var(--bg-max) 92%, var(--fg-max) 8%);
+		--bg-d3: color-mix(in oklab, var(--bg-max) 95%, var(--fg-max) 5%);
+	}
+	html.y {
+		--bg-max: color-mix(in oklab, #fefefe 95%, var(--a) 5%);
+		--fg-max: color-mix(in oklab, #010101 95%, var(--a) 5%);
+		
+		--bg-u1: color-mix(in oklab, var(--bg-max) 92%, var(--fg-max));
+		--bg-u2: color-mix(in oklab, var(--bg-max) 95%, var(--fg-max));
+		--bg-u5: color-mix(in oklab, var(--bg-max) 82%, var(--fg-max));
+		--bg: color-mix(in oklab, var(--bg-max) 98%, var(--fg-max));
+	}
 }
 @font-face {
 	font-family: 'scp';
@@ -54,9 +143,8 @@ html {
 	bottom: 5em;
 	right: -1em;
 	line-height: 1.5em;
-	padding: 1em 1.3em;
-	margin-left: 3em;
-	border-width: .4em 0;
+	padding: 1em 2em 1em 1em;
+	border-width: 1px;
 	overflow-wrap: break-word;
 	transform: translateX(100%);
 	transition:
@@ -92,17 +180,16 @@ html {
 	display: inline-block;
 	position: absolute;
 	overflow: hidden;
-	left: 0;
-	width: 0;
+	right: 0;
+	top: 0;
 	opacity: 0;
 	padding: .3em 0;
-	margin: -.3em 0 0 0;
 	line-height: 1.3em;
 	color: #000;
 	border: none;
 	outline: none;
 	text-shadow: none;
-	border-radius: .5em 0 0 .5em;
+	border-radius: .4em;
 	transition: left .3s, width .3s, padding .3s, opacity .3s;
 }
 #toastb {
@@ -130,9 +217,7 @@ html {
 	transform: initial;
 }
 #toast.vis #toastc {
-	left: -2em;
-	width: .4em;
-	padding: .3em .8em;
+	padding: .3em .5em;
 	opacity: 1;
 }
 #toast.inf {
@@ -200,17 +285,18 @@ html {
 }
 #tt.show {
 	padding: 1em 1.3em;
-	border-width: .4em 0;
+	border-width: 1px;
 	height: auto;
 	opacity: 1;
 }
 #tt.show.b {
 	padding: 1.5em 2em;
-	border-width: .5em 0;
+	/* border-width: .5em 0; */
 }
 .logue code,
 #modalc code,
-#tt code {
+#tt code,
+.opview code{
 	color: #eee;
 	color: var(--fg-max);
 	background: #444;
@@ -220,12 +306,12 @@ html {
 	line-height: 1.7em;
 }
 #tt em {
-	color: #f6a;
+	color: var(--a);
 }
 html.y #tt {
 	border-color: #888 #000 #777 #000;
 }
-html.bz #tt {
+html.az #tt {
 	border-color: #3b3f58;
 }
 html.y #tt,
@@ -237,9 +323,6 @@ html.y #toast {
 	background: transparent;
 	border: 1px solid #ccc;
 }
-html.y #tt em {
-	color: #d38;
-}
 html.y #tth {
 	color: #000;
 	background: #fff;
@@ -361,27 +444,20 @@ html.y #tth {
 	border: .25em solid #ccc;
 	border-radius: .4em;
 }
-#modali:focus {
+#modali:focus-visible {
 	border-color: #06d;
 }
 #repl_pre {
 	max-width: 24em;
 }
-*:focus,
-*:focus+label,
-#pctl *:focus,
-.btn:focus {
-	box-shadow: 0 .1em .2em #fc0 inset;
-	outline: #fc0 solid .1em;
+*:focus-visible,
+*:focus-visible+label,
+.pctl *:focus-visible,
+.btn:focus-visible {
+	/* box-shadow: 0 .1em .2em #fc0 inset; */
+	outline: var(--a) solid .1em;
 	border-radius: .2em;
 }
-html.y *:focus,
-html.y *:focus+label,
-html.y #pctl *:focus,
-html.y .btn:focus {
-	box-shadow: 0 .1em .2em #037 inset;
-	outline: #037 solid .1em;
-}
 input, button {
 	font-family: var(--font-main), sans-serif;
 }
@@ -391,12 +467,7 @@ input[type="submit"] {
 input[type="text"]:focus,
 input:not([type]):focus,
 textarea:focus {
-	box-shadow: 0 .1em .3em #fc0, 0 -.1em .3em #fc0;
-}
-html.y input[type="text"]:focus,
-html.y input:not([type]):focus,
-html.y textarea:focus {
-	box-shadow: 0 .1em .3em #037, 0 -.1em .3em #037;
+	box-shadow: 0 .1em .3em var(--a), 0 -.1em .3em var(--a);
 }
 
 
@@ -565,7 +636,7 @@ hr {
 		color: #fff;
 		background: #444;
 		font-weight: normal;
-		border-top: .4em solid #fb0;
+		border-top: .4em solid rgba(203, 203, 203, 0.634);
 		border-bottom: .4em solid #777;
 		border-radius: 0 1em 0 1em;
 		margin: 3em 0 1em 0;
@@ -611,10 +682,10 @@ hr {
 	}
 	html.z .mdo h1 {
 		background: #383838;
-		border-top: .4em solid #b80;
+		border-top: .4em solid rgba(203, 203, 203, 0.634);
 		border-bottom: .4em solid #4c4c4c;
 	}
-	html.bz .mdo h1 {
+	html.az .mdo h1 {
 		background: #202231;
 		border: 1px solid #2d2f45;
 		border-width: 0 0 .4em 0;
@@ -623,8 +694,8 @@ hr {
 		background: #444;
 		border-bottom: .22em solid #555;
 	}
-	html.bz .mdo h2,
-	html.bz .mdo h3 {
+	html.az .mdo h2,
+	html.az .mdo h3 {
 		background: transparent;
 		border-color: #3b3f58;
 	}
diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js
index 4750765b..7edac231 100644
--- a/copyparty/web/up2k.js
+++ b/copyparty/web/up2k.js
@@ -50,8 +50,21 @@ catch (ex) {
         up2k = up2k_init(false);
     }
     catch (ex) {
+        ebi('h_up2kcfg').style.display = 
+        ebi('u2btn_ct').style.display = 
+        ebi('u2c3t').style.display = 
+        ebi('up_info').style.display = 
+        ebi('opa_up').style.display = 
+            'none'
+
+        ebi('uq_up').onclick = function(){
+            modaltoggle('bup', true);
+            ebi('bup_btn').click();
+        }
+
         console.log('up2k init failed:', ex);
-        toast.err(10, 'could not initialize up2k\n\n' + basenames(ex));
+        toast.err(3, 'could not initialize up2k\n\n' + basenames(ex));
+
     }
 }
 treectl.onscroll();
@@ -826,6 +839,7 @@ function up2k_init(subtle) {
 
     var loading_deps = false;
     function init_deps() {
+        console.log('up2k init deps');
         if (!loading_deps && !got_deps()) {
             var fn = 'sha512.' + sha_js + '.js',
                 m = L.u_https1 + ' <a href="' + (location + '').replace(':', 's:') + '">' + L.u_https2 + '</a> ' + L.u_https3;
@@ -871,7 +885,7 @@ function up2k_init(subtle) {
         return false;
     }
 
-    setmsg(suggest_up2k, 'msg');
+    //setmsg(suggest_up2k, 'msg');
 
     var u2szs = u2sz.split(','),
         u2sz_min = parseInt(u2szs[0]),
@@ -904,7 +918,9 @@ function up2k_init(subtle) {
     uc.ow = parseInt(sread('u2ow', ['0', '1', '2', '3']) || u2ow);
     uc.owt = ['🛡️', '🕒', '♻️', '⏭️'];
     function set_ow() {
-        QS('label[for="u2ow"]').innerHTML = uc.owt[uc.ow];
+        var lbls = QSA('label[for="u2ow"]');
+        for(var i=0; i<lbls.length; i++)
+            lbls[i].innerHTML = uc.owt[uc.ow];
         ebi('u2ow').checked  = true; //cosmetic
     }
     ebi('u2ow').onclick = function (e) {
@@ -1015,7 +1031,7 @@ function up2k_init(subtle) {
 
         modal.confirm(L.u_nav_m, uf, ud, null, L.u_nav_b);
     }
-    ebi('u2btn').onclick = nav;
+    ebi('uq_up').onclick = ebi('u2btn').onclick = nav;
 
     var nenters = 0;
     function ondrag(e) {
@@ -1054,6 +1070,20 @@ function up2k_init(subtle) {
     function onoverbtn(e) {
         return onovercmn(this, e, true);
     }
+    function checkDropMode(){
+        if(ebi('fsearch').checked){
+            ebi('srch_zd').style.display = '';
+            ebi('up_zd').style.display = 'none';
+            ebi('srch_dz').style.display = '';
+            ebi('up_dz').style.display = 'none';
+        }
+        else{
+            ebi('srch_zd').style.display = 'none';
+            ebi('up_zd').style.display = '';
+            ebi('srch_dz').style.display = 'none';
+            ebi('up_dz').style.display = '';
+        }
+    }
     function onovercmn(self, e, btn) {
         try {
             var ok = false, dt = e.dataTransfer.types;
@@ -1066,7 +1096,7 @@ function up2k_init(subtle) {
                         if (toast.txt == L.u_uri)
                             toast.hide();
                     }
-                    else
+                    else if (!window.drag || !drag.no_warn)
                         return toast.inf(10, L.u_uri) || true;
                 }
 
@@ -1087,6 +1117,7 @@ function up2k_init(subtle) {
         if (btn)
             return;
 
+        checkDropMode();
         clmod(ebi('drops'), 'vis', 1);
         var v = self.getAttribute('v');
         if (v)
@@ -1100,6 +1131,7 @@ function up2k_init(subtle) {
             clmod(ebi(v), 'hl');
 
         if (--nenters <= 0) {
+            checkDropMode();
             clmod(ebi('drops'), 'vis');
             clmod(ebi('up_dz'), 'hl');
             clmod(ebi('srch_dz'), 'hl');
@@ -1158,10 +1190,10 @@ function up2k_init(subtle) {
         ev(e);
         nenters = 0;
         offdrag.call(this);
-        var dz = this && this.getAttribute('id');
-        if (!dz && e && e.clientY)
-            // cuo2duo fallback
-            dz = e.clientY < window.innerHeight / 2 ? 'up_dz' : 'srch_dz';
+        // var dz = this && this.getAttribute('id');
+        // if (!dz && e && e.clientY)
+        //     // cuo2duo fallback
+        //     dz = e.clientY < window.innerHeight / 2 ? 'up_dz' : 'srch_dz';
 
         var err = this.getAttribute('err');
         if (err)
@@ -1169,11 +1201,11 @@ function up2k_init(subtle) {
 
         toast.inf(0, L.u_scan);
 
-        if ((dz == 'up_dz' && uc.fsearch) || (dz == 'srch_dz' && !uc.fsearch))
-            tgl_fsearch();
+        // if ((dz == 'up_dz' && uc.fsearch) || (dz == 'srch_dz' && !uc.fsearch))
+        //     tgl_fsearch();
 
-        if (!QS('#op_up2k.act'))
-            goto('up2k');
+        if(!uc.fsearch)
+            up2k.init_deps();
 
         var files,
             is_itemlist = false;
@@ -1978,7 +2010,7 @@ function up2k_init(subtle) {
             ng = pvis.ctr.ng,
             spd = Math.floor(st.bytes.finished / st.time.busy),
             suf = '\n\n{0} @ {1}/s'.format(shumantime(st.time.busy), humansize(spd)),
-            t = uc.ask_up ? 0 : 10;
+            t = 10; // uc.ask_up ? 0 : 10;
 
         console.log('toast', ok, ng);
 
@@ -3019,41 +3051,6 @@ function up2k_init(subtle) {
     ///   config ui
     //
 
-    function onresize(e) {
-        // 10x faster than matchMedia('(min-width
-        var bar = ebi('ops'),
-            wpx = window.innerWidth,
-            fpx = parseInt(getComputedStyle(bar)['font-size']),
-            wem = wpx * 1.0 / fpx,
-            wide = wem > 57 ? 'w' : '',
-            parent = ebi(wide ? 'u2btn_cw' : 'u2btn_ct'),
-            btn = ebi('u2btn');
-
-        if (btn.parentNode !== parent) {
-            parent.appendChild(btn);
-            ebi('u2conf').className = ebi('u2cards').className = ebi('u2etaw').className = wide;
-        }
-
-        wide = wem > 86 ? 'ww' : wide;
-        parent = ebi(wide == 'ww' ? 'u2c3w' : 'u2c3t');
-        var its = [ebi('u2etaw'), ebi('u2cards')];
-        if (its[0].parentNode !== parent) {
-            ebi('u2conf').className = wide;
-            for (var a = 0; a < 2; a++) {
-                parent.appendChild(its[a]);
-                its[a].className = wide;
-            }
-        }
-    }
-    onresize100.add(onresize, true);
-
-    if (MOBILE) {
-        // android-chrome wobbles for a bit; firefox / iOS-safari are OK
-        setTimeout(onresize, 20);
-        setTimeout(onresize, 100);
-        setTimeout(onresize, 500);
-    }
-
     var o = QSA('#u2conf .c *[tt]');
     for (var a = o.length - 1; a >= 0; a--) {
         o[a].parentNode.getElementsByTagName('input')[0].setAttribute('tt', o[a].getAttribute('tt'));
@@ -3284,7 +3281,10 @@ function up2k_init(subtle) {
 
         try {
             clmod(ebi('u2c3w'), 's', !can_write);
-            QS('label[for="fsearch"]').style.display = QS('#fsearch').style.display = fixed ? 'none' : '';
+            QS('#fsearch').style.display = fixed ? 'none' : '';
+            var lbls = QSA('label[for="fsearch"]');
+            for(var i=0; i<lbls.length; i++)
+                lbls[i].style.display = fixed ? 'none' : '';
         }
         catch (ex) { }
 
@@ -3293,6 +3293,7 @@ function up2k_init(subtle) {
                 desc = uc.fsearch ? L.ul_btns : L.ul_btnu;
 
             clmod(ebi('op_up2k'), 'srch', uc.fsearch);
+            clmod(ebi('u2conf'), 'srch', uc.fsearch);
             ebi('u2bm').innerHTML = ico + '&nbsp; <sup>' + desc + '</sup>';
         }
         catch (ex) { }
@@ -3308,7 +3309,6 @@ function up2k_init(subtle) {
 
         draw_turbo();
         draw_life();
-        onresize();
     }
 
     function apply_flag_cfg() {
@@ -3440,8 +3440,8 @@ function warn_uploader_busy(e) {
 tt.init();
 favico.init();
 ebi('ico1').onclick = function () {
-    var a = favico.txt == this.textContent;
-    swrite('icot', a ? 'c' : this.textContent);
+    var a = favico.txt == '🎉';
+    swrite('icot', a ? 'c' : '🎉');
     swrite('icof', a ? 'fc5' : '000');
     swrite('icob', a ? '222' : '');
     favico.init();
diff --git a/copyparty/web/util.js b/copyparty/web/util.js
index 8870f22e..c3aa1fe9 100644
--- a/copyparty/web/util.js
+++ b/copyparty/web/util.js
@@ -1314,8 +1314,12 @@ function bcfg_upd_ui(name, val) {
     if (!o)
         return val;
 
-    if (o.getAttribute('type') == 'checkbox')
+    if (o.getAttribute('type') == 'checkbox'){
         o.checked = val;
+        var lbls = QSA('label[for="' + o.id +'"]');
+        for(var i=0; i<lbls.length; i++)
+            clmod(lbls[i], 'on', val);
+    }
     else if (o) {
         clmod(o, 'on', val);
     }
@@ -1580,6 +1584,18 @@ var tt = (function () {
         return el.getAttribute('tt');
     };
 
+    r.parse = function(msg){
+        if(msg == null || msg.length == 0)
+            return msg;
+        if (msg.startsWith('`')) {
+            var x = false;
+            msg = msg.slice(1);
+            while (msg.indexOf('`') + 1)
+                msg = msg.replace('`', (x = !x) ? '<code>' : '</code>');
+        }
+        return msg.replace(/\$N/g, "<br />");
+    }
+
     r.show = function () {
         clearTimeout(tev);
         if (r.skip) {
@@ -1590,13 +1606,6 @@ var tt = (function () {
         if (!msg)
             return;
 
-        if (msg.startsWith('`')) {
-            var x = false;
-            msg = msg.slice(1);
-            while (msg.indexOf('`') + 1)
-                msg = msg.replace('`', (x = !x) ? '<code>' : '</code>')
-        }
-
         r.el = this;
         var pos = this.getBoundingClientRect(),
             dir = this.getAttribute('ttd') || '',
@@ -1612,7 +1621,7 @@ var tt = (function () {
         r.tt.style.left = '0';
         r.tt.style.top = '0';
 
-        r.tt.innerHTML = msg.replace(/\$N/g, "<br />");
+        r.tt.innerHTML = r.parse(msg);
         r.el.addEventListener('mouseleave', r.hide);
         window.addEventListener('scroll', r.hide);
         clmod(r.tt, 'show', 1);
@@ -1633,6 +1642,10 @@ var tt = (function () {
 
     r.hide = function (e) {
         //ev(e);  // eats checkbox-label clicks
+
+        r.show.bind(null);
+        r.el = null;
+
         clearTimeout(tev);
         window.removeEventListener('scroll', r.hide);
 
@@ -1806,7 +1819,7 @@ var toast = (function () {
             setcvar('--tmstep', Math.floor(sec * 20));
             html += '<div id="toastt"></div>';
         }
-        obj.innerHTML = html + '<a href="#" id="toastc">x</a><div id="toastb">' + lf2br(txt) + '</div>';
+        obj.innerHTML = html + '<a href="#" id="toastc">✕</a><div id="toastb">' + lf2br(txt) + '</div>';
         obj.className = cl;
         sec += obj.offsetWidth;
         obj.className += ' vis';
@@ -2254,7 +2267,7 @@ var favico = (function () {
 
     var gx = function (txt) {
         return (svg_decl +
-            '<svg version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">\n' +
+            '<svg version="1.1" viewBox="0 0 70 70" xmlns="http://www.w3.org/2000/svg">\n' +
             (r.bg ? '<rect width="100%" height="100%" rx="16" fill="#' + r.bg + '" />\n' : '') +
             '<text x="50%" y="55%" dominant-baseline="middle" text-anchor="middle"' +
             ' font-family="sans-serif" font-weight="bold" font-size="64px"' +
@@ -2291,6 +2304,11 @@ var favico = (function () {
             document.head.appendChild(r.tag);
         }
         r.tag.href = 'data:image/svg+xml;base64,' + b64;
+
+        var fiop = ebi('favico_onpage');
+        if(fiop != null){
+            fiop.innerHTML = svg ? atob(b64) : gx(r.txt);
+        }
     };
 
     r.init = function () {
@@ -2304,8 +2322,7 @@ var favico = (function () {
         scfg_bind(r, 'bg', 'icob', bg, r.upd);
         r.upd();
     };
-
-    r.to = setTimeout(r.init, 100);
+    r.init();
     return r;
 })();
 
diff --git a/docs/changelog.md b/docs/changelog.md
index e7427dde..402db3bb 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,3 +1,74 @@
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀  
+# 2026-0428-0907 `v1.21.0` UI V2
+
+## 😴 tl;dr
+
+* the web UI changed a LOT
+* nice mobile layout
+* try setting an accent color in the theme settings
+* drag n drop within copyparty
+* the used storage metric is now at the bottom of the folder tree
+* the account details and control panel link are now in the account popup (top right)
+* media player settings and normal settings have merged
+* new file / new folder have moved from the top bar to the [+] button / right click menu (also accessible via long press on mobile)
+
+## 🧪 new features
+
+* [Add moving files into other folders by dragging](https://github.com/tilse/copyparty-uiV1.5/pull/1) within the browser window to move files or folders
+* custom accent color setting added. works best for light and dark themes (the first 4 in the list)
+* right click (long press) on mobile is now possible
+* selection checkboxes on items in grid view
+* the tree and path can be visible at the same time
+* new design for placeholder thumbnails
+* #386 gallery view toggle for smaller margins / bigger image previews
+* settings and upload are now a popup/modal
+* settings can be navigated via sections and former tooltip info is now always visible
+* new floating [+] button in bottom right for quickly creating files / folders / uploading
+* searching folders / subfolders is now possible, and is the new default when clicking the search button. extended search options are accessible via down arrow in the search box
+* storage capacity progress bar at bottom of folder tree
+* account button with popup in the top right
+* search in "quotes with spaces" is now possible to find file names including spaces
+* new simpler audio progress bar slider added as option
+* quick setting for changing loop mode via bottom media player bar
+* mute toggle button
+* name of playing audio is now displayed
+* audio equalizer can be operated via sliders
+* image viewer has nearest neighbor scale mode toggle
+* toggle to scale up small grid thumbnails to fit
+
+## 🩹 bugfixes
+
+* #1455 tooltips disappear more consistently when element is no longer hovered
+* scrollable tree header so all options are accessible independent of tree width
+* #1378 improved mobile layout
+* media player has "fade" option now to disable fade in / fade out, which fixes play / pause on iOS lockscreens
+* #1002 proper overflow handling for text files or readmes (svg editor still overflows, but it doesn't break the page layout anymore)
+
+## 🔧 other changes
+
+* media player settings have moved to the main settings modal
+* creating files / folders is now done via right click menu, or the plus button in the bottom right
+* grid view toggle is now in grid header
+* default file sizes in MB
+* control panel button now lives in the account popup in the top bar
+* searching for files via drag n drop is now only possible when the search mode is toggled in the up2k UI
+* bup is an optional dropdown in the up2k modal
+* many mobile layout usability issues
+* more consistent areas for clicking to navigate left / right in the image viewer (they don't depend on image fill mode anymore)
+* "folder up" / "next sibling" / "previous sibling" are now icon buttons at the top
+* new look for the login screen
+* file list makes it easier to identify folders via an added folder emoji to folder names. to disable this, add the following style: `tr:has(a.dir) td:nth-child(2) a::before { display: none; }`
+* pm-monokai theme has become "flat dark"
+
+## 🌠 fun facts
+
+* all themes should keep working, even the Windows95 ones
+
+## 😔 unfun facts
+
+* #1209 (partially), #711 added a setting that gets rid of (most) emojis
+
+
 ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀  
 # 2026-0323-0328  `v1.20.13`  dothidden
 
diff --git a/scripts/make-sfx.sh b/scripts/make-sfx.sh
index af4060b7..3f8a7434 100755
--- a/scripts/make-sfx.sh
+++ b/scripts/make-sfx.sh
@@ -406,6 +406,16 @@ git describe --tags >/dev/null 2>/dev/null && {
 	}
 
 	dt="$(git log -1 --format=%cd --date=short | sed -E 's/-0?/, /g')"
+}
+
+[ "$PRTY_SFX_VER" ] && {
+	# PRTY_SFX_VER='1.20.14-5-g139ef185' PRTY_SFX_DT='2026, 5, 8'
+	# PRTY_SFX_VER='2026-0510-2303' PRTY_SFX_DT='2026, 5, 10'
+	ver="$PRTY_SFX_VER"
+	dt="$PRTY_SFX_DT"
+}
+
+[ "$ver" ] && {
 	printf 'git %3s: \033[36m%s\033[0m\n' ver "$ver" dt "$dt"
 	sed -ri '
 		s/^(VERSION =)(.*)/#\1\2\n\1 ('"$t_ver"')/;
diff --git a/scripts/tl.js b/scripts/tl.js
index cfee97b8..06013c0a 100644
--- a/scripts/tl.js
+++ b/scripts/tl.js
@@ -37,7 +37,7 @@ Ls.hmn = {
 	"tt": "Hymmnos",
 
 	"cols": {
-		"c": "action buttons",
+		"!": "action buttons",
 		"dur": "duration",
 		"q": "quality / bitrate",
 		"Ac": "audio codec",
@@ -46,7 +46,7 @@ Ls.hmn = {
 		"Ahash": "audio checksum",
 		"Vhash": "video checksum",
 		"Res": "resolution",
-		"T": "filetype",
+		"Ext": "filetype",
 		"aq": "audio quality / bitrate",
 		"vq": "video quality / bitrate",
 		"pixfmt": "subsampling / pixel structure",
@@ -65,7 +65,7 @@ Ls.hmn = {
 			["G", "toggle list / grid view"],
 			["T", "toggle thumbnails / icons"],
 			["⇧ A/D", "thumbnail size"],
-			["ctrl-K", "delete selected"],
+			["ctrl-K/Del", "delete selected"],
 			["ctrl-X", "cut selection to clipboard"],
 			["ctrl-C", "copy selection to clipboard"],
 			["ctrl-V", "paste (move/copy) here"],
@@ -139,9 +139,9 @@ Ls.hmn = {
 	"ht_and": " and ",
 
 	"goh": "control-panel",
-	"gop": 'previous sibling">prev',
-	"gou": 'parent folder">up',
-	"gon": 'next folder">next',
+	"gop": 'previous sibling',
+	"gou": 'parent folder',
+	"gon": 'next folder',
 	"logout": "Logout ",
 	"login": "Login",
 	"access": " access",
@@ -189,7 +189,7 @@ Ls.hmn = {
 	"ut_u2ts": "copy the last-modified timestamp$Nfrom your filesystem to the server\">📅",
 	"ut_ow": "overwrite existing files on the server?$N🛡️: never (will generate a new filename instead)$N🕒: overwrite if server-file is older than yours$N♻️: always overwrite if the files are different$N⏭️: unconditionally skip all existing files",
 	"ut_mt": "continue hashing other files while uploading$N$Nmaybe disable if your CPU or HDD is a bottleneck",
-	"ut_ask": 'ask for confirmation before upload starts">💭',
+	"ut_ask": 'ask for confirmation before upload starts',
 	"ut_pot": "improve upload speed on slow devices$Nby making the UI less complex",
 	"ut_srch": "don't actually upload, instead check if the files already $N exist on the server (will scan all folders you can read)",
 	"ut_par": "pause uploads by setting it to 0$N$Nincrease if your connection is slow / high latency$N$Nkeep it 1 on LAN or if the server HDD is a bottleneck",
@@ -237,12 +237,12 @@ Ls.hmn = {
 	"u_nav_m": '<h6>aight, what do you have?</h6><code>Enter</code> = Files (one or more)\n<code>ESC</code> = One folder (including subfolders)',
 	"u_nav_b": '<a href="#" id="modal-ok">Files</a><a href="#" id="modal-ng">One folder</a>',
 
-	"cl_opts": "switches",
+	"cl_opts": "general",
 	"cl_hfsz": "filesize",
 	"cl_themes": "theme",
 	"cl_langs": "language",
 	"cl_ziptype": "folder download",
-	"cl_uopts": "up2k switches",
+	"cl_uopts": "upload",
 	"cl_favico": "favicon",
 	"cl_bigdir": "big dirs",
 	"cl_hsort": "#sort",
@@ -317,7 +317,7 @@ Ls.hmn = {
 	"ml_drc": "dynamic range compressor",
 	"ml_ss": "skip silence",
 
-	"mt_loop": "loop/repeat one song\">🔁",
+	"mt_loop": "loop/repeat one song",
 	"mt_one": "stop after one song\">1️⃣",
 	"mt_shuf": "shuffle the songs in each folder\">🔀",
 	"mt_aplay": "autoplay if there is a song-ID in the link you clicked to access the server$N$Ndisabling this will also stop the page URL from being updated with song-IDs when playing music, to prevent autoplay if these settings are lost but the URL remains\">a▶",
@@ -547,6 +547,7 @@ Ls.hmn = {
 	"s_f1": "name contains &nbsp; (negate with -nope)",
 	"s_t1": "tags contains &nbsp; (^=start, end=$)",
 	"s_a1": "specific metadata properties",
+	"s_dir": "search this folder",
 
 	"md_eshow": "cannot render ",
 	"md_off": "[📜<em>readme</em>] disabled in [⚙️] -- document hidden",
