From 0de50f40eb826c2a127bb4b12b4d3c11f0c90f15 Mon Sep 17 00:00:00 2001 From: Nikhil M Warrier Date: Sat, 5 Sep 2026 21:22:09 +0530 Subject: Reskin file manager UI with Linear-style polish - Refresh design tokens and dark/light palette (accent #5e6ad2, #0a0a0a dark) - Glass sticky header, targeted hover/transition, focus rings, reduced-motion support - Swap all icons to Lucide stroke icons (CSS drives color via vars) - Animate menu/more popovers closed; enforce only one open at a time - Right-align desktop header toolbar; even icon spacing - Single shared subgrid for table header + rows so columns align exactly --- assets/index.css | 308 ++++++++++++++++++++++++++++++++++++++++++++++-------- assets/index.html | 96 ++++++++--------- assets/index.js | 44 +++++--- 3 files changed, 338 insertions(+), 110 deletions(-) diff --git a/assets/index.css b/assets/index.css index 181e333..601e274 100644 --- a/assets/index.css +++ b/assets/index.css @@ -1,5 +1,7 @@ * { - box-sizing: border-box; + box-sizing: border-box; + scrollbar-width: thin; + scrollbar-color: var(--border-secondary) transparent; } :root { @@ -7,16 +9,20 @@ --bg-primary: #fff; --bg-secondary: #fafafa; --bg-tertiary: #fff; - --bg-hover: #fafafa; - --text-primary: #24292e; - --text-secondary: #5c5c5c; - --text-tertiary: #586069; - --text-accent: #0366d6; - --svg-primary: #24292e; - --svg-secondary: rgba(3, 47, 98, 0.5); - --svg-tertiary: #24292e; - --border-primary: #ddd; - --border-secondary: #ced4da; + --bg-hover: #f5f5f5; + --text-primary: #0a0a0a; + --text-secondary: #606060; + --text-tertiary: #8a8a8a; + --text-accent: #111; + --svg-primary: #0a0a0a; + --svg-secondary: #666; + --svg-tertiary: #666; + --border-primary: rgba(0, 0, 0, 0.09); + --border-secondary: #e5e5e5; + --accent: #5e6ad2; + --shadow-pop: 0 8px 24px rgba(0, 0, 0, 0.08); + --ease-out: cubic-bezier(0.23, 1, 0.32, 1); + --duration-fast: 120ms; } html { @@ -31,7 +37,12 @@ body { } svg { - fill: var(--svg-primary); + fill: none; + stroke: var(--svg-primary); + stroke-width: 2; + stroke-linecap: round; + stroke-linejoin: round; + transition: stroke var(--duration-fast) ease; } .hidden { @@ -48,21 +59,36 @@ svg { position: sticky; top: 0; background-color: var(--bg-tertiary); + border-bottom: 1px solid var(--border-primary); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); +} + +@supports ((backdrop-filter: blur(0px)) or (-webkit-backdrop-filter: blur(0px))) { + .head { + background-color: color-mix(in srgb, var(--bg-tertiary) 85%, transparent); + -webkit-backdrop-filter: blur(12px) saturate(180%); + backdrop-filter: blur(12px) saturate(180%); + } } .breadcrumb { font-size: 1.25em; padding-right: 0.6em; word-break: break-all; + font-weight: 600; + letter-spacing: -0.01em; } .breadcrumb>a { color: var(--text-accent); text-decoration: none; + text-decoration-color: transparent; + text-underline-offset: 3px; } .breadcrumb>a:hover { text-decoration: underline; + text-decoration-color: currentColor; } /* final breadcrumb */ @@ -77,7 +103,7 @@ svg { .breadcrumb svg { height: 100%; - fill: var(--svg-secondary); + stroke: var(--svg-secondary); } .toolbox { @@ -110,13 +136,18 @@ svg { justify-content: center; flex-wrap: nowrap; background-color: var(--bg-secondary); - transition: all .15s; + transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out); border: 1px var(--border-primary) solid; border-radius: 15px; margin-bottom: 2px; padding-left: 0.5rem; } +.searchbar:focus-within { + border-color: var(--accent); + box-shadow: 0 0 0 3px rgba(94, 106, 210, 0.18); +} + .searchbar #search { box-sizing: border-box; width: 100%; @@ -138,15 +169,18 @@ svg { } .searchbar svg { - fill: var(--svg-tertiary); + stroke: var(--svg-tertiary); } .main { - padding: 0 1em; + padding: 0; } .empty-folder { - font-style: italic; + color: var(--text-tertiary); + text-align: center; + padding: 3rem 1rem; + animation: fade-in 200ms ease-out; } .uploaders-table th { @@ -169,29 +203,71 @@ svg { display: inline-block; } -.paths-header-row, +@media (min-width: 768px) { + .paths-table { + display: grid; + grid-template-columns: 24px minmax(0, 1fr) 120px 70px 130px; + column-gap: 1.5em; + align-items: center; + } + + .paths-header, + .paths-body { + display: contents; + } + + .paths-header-row, + .path-item { + display: grid; + grid-column: 1 / -1; + grid-template-columns: subgrid; + align-items: center; + } +} + .path-item { - display: grid; - grid-template-columns: 24px minmax(0, 1fr) 120px 70px 130px; - align-items: center; - column-gap: 1.5em; - padding: 0.4em 0; + padding: 0.4em; + border-radius: 6px; + transition: background-color var(--duration-fast) ease; } -.path-item:hover { - background-color: var(--bg-hover); +@media (hover: hover) and (pointer: fine) { + .path-item:hover { + background-color: var(--bg-hover); + } + + .path-item .cell-actions { + opacity: 0.4; + transition: opacity var(--duration-fast) ease; + } + + .path-item:hover .cell-actions { + opacity: 1; + } } .paths-header-row { + padding: 0.4em 1em; color: var(--text-secondary); font-weight: unset; border-bottom: 1px solid var(--border-primary); + font-size: 0.9em; + letter-spacing: 0.02em; } .paths-header-row .h-sort { color: unset; text-decoration: none; white-space: nowrap; + transition: color var(--duration-fast) ease; +} + +.paths-header-row .h-sort:hover { + color: var(--text-primary); +} + +.paths-header-row .h-sort.active { + color: var(--accent); } .paths-header-row .h-sort>span { @@ -211,6 +287,7 @@ svg { .path-item .cell-actions { display: flex; align-items: center; + justify-content: flex-start; } .path-item .cell-more { @@ -221,7 +298,7 @@ svg { .path svg, .path-item .cell-icon svg { height: 16px; - fill: var(--svg-secondary); + stroke: var(--svg-secondary); vertical-align: text-top; } @@ -236,15 +313,30 @@ svg { overflow: hidden; display: block; text-decoration: none; + text-decoration-color: transparent; + text-underline-offset: 2px; + font-weight: 500; } .path-item .cell-name a:hover { text-decoration: underline; + text-decoration-color: currentColor; } .action-btn { padding-right: 0.3em; cursor: pointer; + transition: transform 100ms ease-out, opacity var(--duration-fast) ease; +} + +.action-btn:active { + transform: scale(0.9); +} + +@media (hover: hover) and (pointer: fine) { + .action-btn:hover svg { + stroke: var(--accent); + } } .uploaders-table { @@ -263,6 +355,25 @@ svg { color: var(--text-primary); outline: none; padding: 5px; + transition: border-color var(--duration-fast) ease, box-shadow var(--duration-fast) ease; +} + +.editor:focus { + border-color: var(--accent); + box-shadow: 0 0 0 3px rgba(94, 106, 210, 0.18); +} + +a:focus-visible, +.control:focus-visible, +.login-btn:focus-visible, +.logout-btn:focus-visible, +.save-btn:focus-visible, +.action-btn:focus-visible, +.menu-btn:focus-visible, +.more-btn:focus-visible +{ + outline: 2px solid var(--accent); + outline-offset: 2px; } .toolbox-right { @@ -287,7 +398,9 @@ svg { } .user-name { - padding-left: 3px; + padding-left: 0.5em; + font-size: 0.9rem; + color: var(--text-secondary); } .not-editable { @@ -299,6 +412,10 @@ svg { } @media (min-width: 768px) { + .cell-icon { + margin-right: -1.75em; + } + .menu, .menu-content { display: contents; @@ -308,6 +425,49 @@ svg { .menu-btn { display: none; } + + .toolbox { + margin-left: auto; + gap: 1em; + } + + .toolbox .control { + padding-left: 0; + } + + .searchbar { + margin-right: 10px; + } + + .toolbox-right { + margin-left: 0; + margin-right: 0; + } + + .toolbox .control, + .toolbox-right>div, + .toolbox>a { + transition: transform 100ms ease-out, background-color var(--duration-fast) ease; + border-radius: 6px; + } + + .toolbox .control:hover, + .toolbox-right>div:hover, + .toolbox>a:hover { + background-color: var(--bg-hover); + } + + .toolbox .control:hover svg, + .toolbox-right>div:hover svg, + .toolbox>a:hover svg { + stroke: var(--accent); + } + + .toolbox .control:active, + .toolbox-right>div:active, + .toolbox>a:active { + transform: scale(0.9); + } } @media (max-width: 767.98px) { @@ -330,22 +490,32 @@ svg { } .menu-content { - display: none; position: absolute; right: 0; top: calc(100% + 6px); z-index: 100; + display: flex; flex-direction: column; min-width: 250px; padding: 0.4em; background-color: var(--bg-tertiary); border: 1px solid var(--border-primary); border-radius: 10px; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); + box-shadow: var(--shadow-pop); + opacity: 0; + visibility: hidden; + transform: translateY(-4px) scale(0.96); + transform-origin: top right; + pointer-events: none; + transition: opacity 150ms var(--ease-out), transform 150ms var(--ease-out), visibility 0s linear 150ms; } .menu-toggle:checked ~ .menu-content { - display: flex; + opacity: 1; + visibility: visible; + transform: translateY(0) scale(1); + pointer-events: auto; + transition-delay: 0s; } .menu-content .searchbar { @@ -459,24 +629,34 @@ svg { } .more-panel { - display: none; position: absolute; right: 0; top: 100%; z-index: 100; + display: flex; flex-direction: column; gap: 0.5em; padding: 0.6em; background-color: var(--bg-tertiary); border: 1px solid var(--border-primary); - border-radius: 6px; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); + border-radius: 8px; + box-shadow: var(--shadow-pop); min-width: 180px; white-space: nowrap; + opacity: 0; + visibility: hidden; + transform: translateY(-4px) scale(0.96); + transform-origin: top right; + pointer-events: none; + transition: opacity 150ms var(--ease-out), transform 150ms var(--ease-out), visibility 0s linear 150ms; } .more-toggle:checked ~ .more-panel { - display: flex; + opacity: 1; + visibility: visible; + transform: translateY(0) scale(1); + pointer-events: auto; + transition-delay: 0s; } .more-row { @@ -508,18 +688,54 @@ svg { @media (prefers-color-scheme: dark) { :root { color-scheme: dark; - --bg-primary: #000; + --bg-primary: #0a0a0a; --bg-secondary: #111; - --bg-tertiary: #111; - --bg-hover: #1a1a1a; - --text-primary: #fff; - --text-secondary: #ccc; - --text-tertiary: #586069; /*Unchanged in both color schemes*/ - --text-accent: #3191ff; - --svg-primary: #fff; - --svg-secondary: #fff; - --svg-tertiary: #fff6; - --border-primary: #fff6; - --border-secondary: #ced4da; /*Unchanged in both color schemes*/ + --bg-tertiary: #0f0f10; + --bg-hover: #161617; + --text-primary: #ededed; + --text-secondary: #9a9a9a; + --text-tertiary: #71717a; + --text-accent: #ededed; + --svg-primary: #ededed; + --svg-secondary: #a1a1aa; + --svg-tertiary: #a1a1aa; + --border-primary: rgba(255, 255, 255, 0.12); + --border-secondary: #2a2a2b; + --shadow-pop: 0 8px 24px rgba(0, 0, 0, 0.5); + } +} + +@keyframes fade-in { + from { + opacity: 0; + transform: translateY(2px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.status-swap { + animation: fade-in 200ms ease-out; +} + +.cell-icon { + display: flex; + align-items: center; + justify-content: center; +} + +.path-basename { + font-weight: 500; +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; } } diff --git a/assets/index.html b/assets/index.html index 79487e3..280101b 100644 --- a/assets/index.html +++ b/assets/index.html @@ -17,69 +17,71 @@