a69b6195d1
Implements FLIP (First, Last, Invert, Play) animations for tab reordering, opening, and closing in the tab bar. Tabs now animate smoothly when added, removed, or reordered, improving visual feedback and user experience. CSS classes and keyframes for enter and exit transitions are introduced, and the tab rendering logic is updated to measure and animate tab positions.
366 lines
6.6 KiB
CSS
366 lines
6.6 KiB
CSS
html, body {
|
|
height: 100%;
|
|
margin: 0;
|
|
padding: 0;
|
|
background: #111;
|
|
color: white;
|
|
font-family: 'Segoe UI', sans-serif;
|
|
}
|
|
|
|
/* TAB STRIP */
|
|
#tab-bar {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
gap: 2px;
|
|
padding: 2px 6px 0 6px; /* slimmer top padding */
|
|
background: #1b1c20; /* strip background like modern browsers */
|
|
border-bottom: 1px solid #2a2c33; /* hairline under tabs */
|
|
overflow-x: auto; /* scroll when many tabs */
|
|
scrollbar-color: #444 #2a2a3c; /* thumb and track for Firefox */
|
|
scrollbar-width: thin; /* slimmer track */
|
|
}
|
|
|
|
/* NAVBAR LAYOUT */
|
|
#nav {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 6px 10px;
|
|
background: #1e1e2e;
|
|
gap: 12px;
|
|
/* flatter header to reduce paint cost */
|
|
box-shadow: none;
|
|
}
|
|
|
|
.nav-left,
|
|
.nav-center,
|
|
.nav-right {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.nav-center {
|
|
flex: 1;
|
|
background: #2a2a3c;
|
|
padding: 4px 6px;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
#favicon {
|
|
width: 16px;
|
|
height: 16px;
|
|
margin-right: 4px;
|
|
}
|
|
|
|
#url {
|
|
flex: 1;
|
|
background: transparent;
|
|
border: none;
|
|
color: white;
|
|
font-size: 14px;
|
|
outline: none;
|
|
}
|
|
|
|
#url::placeholder {
|
|
color: rgba(255, 255, 255, 0.5);
|
|
}
|
|
|
|
#nav button {
|
|
background: #333;
|
|
color: white;
|
|
border: none;
|
|
padding: 6px 10px;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
transition: background 120ms ease;
|
|
}
|
|
|
|
#nav button:hover {
|
|
background: #555;
|
|
}
|
|
|
|
/* MENU DROPDOWN */
|
|
.menu-wrapper {
|
|
position: relative;
|
|
}
|
|
|
|
#menu-popup {
|
|
position: absolute;
|
|
top: 30px;
|
|
right: 0;
|
|
background: #2a2a3c;
|
|
border-radius: 4px;
|
|
padding: 4px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-width: 200px; /* wider dropdown */
|
|
box-shadow: 0 2px 6px rgba(0,0,0,0.4);
|
|
z-index: 100;
|
|
}
|
|
|
|
#menu-popup button {
|
|
background: none;
|
|
border: none;
|
|
color: white;
|
|
text-align: left;
|
|
padding: 6px 10px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
#menu-popup button:hover {
|
|
background: #444;
|
|
}
|
|
|
|
.hidden {
|
|
display: none;
|
|
}
|
|
|
|
#menu-popup.hidden {
|
|
display: none;
|
|
}
|
|
|
|
/* WEBVIEWS */
|
|
#webviews {
|
|
flex: 1;
|
|
display: flex;
|
|
width: 100%;
|
|
position: relative;
|
|
}
|
|
#webviews.hidden {
|
|
display: none;
|
|
}
|
|
|
|
#webviews webview {
|
|
flex: 1;
|
|
width: 100%;
|
|
height: 100%;
|
|
border: none;
|
|
display: none;
|
|
}
|
|
#webviews webview.active {
|
|
display: flex;
|
|
}
|
|
/* When webviews is hidden, collapse its flex size */
|
|
#webviews.hidden {
|
|
flex: 0;
|
|
}
|
|
|
|
/* HOME CONTAINER */
|
|
#home-container {
|
|
flex: 1;
|
|
display: none;
|
|
width: 100%;
|
|
position: relative;
|
|
}
|
|
|
|
#home-container.active {
|
|
display: flex;
|
|
}
|
|
|
|
#home-webview {
|
|
width: 100%;
|
|
height: 100%;
|
|
border: none;
|
|
display: none;
|
|
flex: 1;
|
|
}
|
|
/* Show home webview when container is active */
|
|
#home-container.active > #home-webview {
|
|
display: flex;
|
|
}
|
|
|
|
/* TABS */
|
|
.tab {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 4px 8px; /* slimmer padding */
|
|
margin: 0;
|
|
height: 28px; /* reduce overall tab height */
|
|
color: #ddd;
|
|
/* use flat background to avoid gradient paints */
|
|
background: #24262b;
|
|
border: 1px solid #2b2d34;
|
|
border-bottom: none; /* let it visually merge with the strip line */
|
|
border-radius: 6px 6px 0 0; /* slightly tighter radius */
|
|
cursor: pointer;
|
|
user-select: none;
|
|
max-width: 260px;
|
|
min-width: 120px;
|
|
flex: 0 1 180px; /* like Chrome: shrink when crowded */
|
|
overflow: hidden;
|
|
transition: background 120ms ease, color 120ms ease;
|
|
}
|
|
|
|
.tab:hover { background: #2a2c33; }
|
|
|
|
.tab.active {
|
|
color: #fff;
|
|
background: #2f323a;
|
|
/* remove expensive inner shadows */
|
|
box-shadow: none;
|
|
}
|
|
|
|
.tab .tab-favicon {
|
|
width: 16px;
|
|
height: 16px;
|
|
border-radius: 2px;
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.tab .tab-title {
|
|
flex: 1 1 auto;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.tab .tab-close {
|
|
flex: 0 0 auto;
|
|
width: 22px;
|
|
height: 22px;
|
|
display: grid;
|
|
place-items: center;
|
|
border: none;
|
|
border-radius: 11px;
|
|
background: transparent;
|
|
color: #b5b5b5;
|
|
opacity: 0; /* hidden by default */
|
|
transition: background 120ms ease, color 120ms ease, opacity 120ms ease;
|
|
}
|
|
|
|
.tab:hover .tab-close,
|
|
.tab.active .tab-close { opacity: 1; }
|
|
.tab .tab-close:hover { background: #3b3e47; color: #fff; }
|
|
.tab .tab-close:active { background: #2e3139; }
|
|
|
|
/* New tab (+) button aligned to the right end of the strip */
|
|
.new-tab-button {
|
|
margin-left: 6px;
|
|
flex: 0 0 auto;
|
|
width: 24px; /* tighter button */
|
|
height: 24px;
|
|
display: grid;
|
|
place-items: center;
|
|
border-radius: 12px;
|
|
border: 1px solid #2b2d34;
|
|
background: #23252b;
|
|
color: #d5d5d5;
|
|
cursor: pointer;
|
|
transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
|
|
}
|
|
.new-tab-button:hover { background: #2b2d34; color: #fff; border-color: #3a3d46; }
|
|
.new-tab-button:active { background: #262830; }
|
|
|
|
/* ZOOM CONTROLS */
|
|
.zoom-controls {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 6px 10px;
|
|
}
|
|
.zoom-controls .zoom-label {
|
|
flex: 1;
|
|
font-size: 14px;
|
|
}
|
|
.zoom-controls button {
|
|
background: none;
|
|
border: none;
|
|
color: white;
|
|
font-size: 16px;
|
|
cursor: pointer;
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
}
|
|
.zoom-controls button:hover {
|
|
background: #444;
|
|
}
|
|
#zoom-percent {
|
|
min-width: 36px;
|
|
text-align: center;
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* window controls (Windows only) */
|
|
#window-controls {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
display: flex;
|
|
gap: 2px;
|
|
padding: 4px;
|
|
z-index: 200;
|
|
}
|
|
#window-controls button {
|
|
width: 46px;
|
|
height: 28px;
|
|
background: transparent;
|
|
border: none;
|
|
color: white;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
transition: background 120ms ease;
|
|
}
|
|
#window-controls button:hover {
|
|
background: rgba(255,255,255,0.1);
|
|
}
|
|
#window-controls #close-btn:hover {
|
|
background: #e81123;
|
|
}
|
|
|
|
#tab-bar::-webkit-scrollbar {
|
|
height: 8px; /* horizontal scrollbar height */
|
|
}
|
|
#tab-bar::-webkit-scrollbar-track {
|
|
background: #2a2a3c;
|
|
border-radius: 4px;
|
|
}
|
|
#tab-bar::-webkit-scrollbar-thumb {
|
|
background: #444;
|
|
border-radius: 4px;
|
|
}
|
|
#tab-bar::-webkit-scrollbar-thumb:hover {
|
|
background: #555;
|
|
}
|
|
|
|
/* Tab animations */
|
|
.tab--flip {
|
|
transition: transform 180ms cubic-bezier(0.2, 0, 0, 1);
|
|
}
|
|
.tab--enter {
|
|
animation: tab-enter 160ms ease-out both;
|
|
}
|
|
.tab--closing {
|
|
animation: tab-exit 140ms ease-in both;
|
|
}
|
|
|
|
@keyframes tab-enter {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(6px) scale(0.98);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: none;
|
|
}
|
|
}
|
|
|
|
@keyframes tab-exit {
|
|
to {
|
|
opacity: 0;
|
|
transform: translateY(-6px) scale(0.95);
|
|
}
|
|
}
|
|
|
|
/* Respect reduced motion preferences */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
* {
|
|
animation: none !important;
|
|
transition: none !important;
|
|
scroll-behavior: auto !important;
|
|
}
|
|
}
|