Files
bitvid/css/style.css
T

1408 lines
30 KiB
CSS

@import "./tokens.css";
:root {
--scrollbar-width: 0.5rem;
--scrollbar-track: var(--color-white-soft);
--scrollbar-thumb: var(--color-white-softer);
--scrollbar-thumb-hover: var(--color-white-softest);
/* Sidebar stack must remain below modal overlays. */
--z-sidebar-overlay: 10;
--z-sidebar: 20;
--z-modal-root: 100;
--z-modal-overlay: 110;
--z-modal-content: 120;
--z-modal-player: 130;
--sidebar-width-expanded: 16rem;
--sidebar-width-collapsed: 4rem;
--sidebar-width: var(--sidebar-width-expanded);
--sidebar-control-size: 2.75rem;
--sidebar-content-gap: 1rem;
}
html {
font-size: 100%;
}
@media (min-width: 1024px) {
html {
font-size: 75%;
}
}
/* Global scrollbar styling */
* {
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-thumb) transparent;
}
*::-webkit-scrollbar {
width: var(--scrollbar-width);
height: var(--scrollbar-width);
}
*::-webkit-scrollbar-track {
background: var(--scrollbar-track);
}
*::-webkit-scrollbar-thumb {
background: var(--scrollbar-thumb);
border-radius: 0.25rem;
}
*::-webkit-scrollbar-thumb:hover {
background: var(--scrollbar-thumb-hover);
}
/* Core Styles */
body {
font-family: var(--font-family-sans);
background-color: var(--color-page);
color: var(--color-text-strong);
line-height: 1.5;
margin: 0;
padding: 0;
overflow-x: hidden; /* Disable horizontal scrolling */
}
#nip71TagsFieldset > legend,
#editNip71TagsFieldset > legend {
margin-left: 0;
padding: 0;
}
#app {
/*
Keep the primary content surface aligned with the page background so the
sidebar styling does not bleed into the video grid.
*/
background-color: var(--color-page);
color: inherit;
}
header {
margin-bottom: 2rem;
padding: 1rem 0;
display: flex;
justify-content: flex-start;
}
header img {
height: 6rem;
width: auto;
max-width: none;
}
.container {
max-width: 92.5rem;
margin: 0 auto;
padding: 1rem;
}
/* --------------------------------------------------------------------------
Legacy component compatibility shims
--------------------------------------------------------------------------
These selectors bridge existing markup to the token-backed primitives while
templates migrate to the new utility classes. Remove once all views are
updated. The shared token mappings now live in `css/tailwind.source.css`
so this file only maintains bespoke overrides.
--------------------------------------------------------------------------- */
.video-card[data-owner-is-viewer="false"][data-url-health-state="offline"][data-stream-health-state="unhealthy"] {
display: none;
}
.video-card.video-card--owner-private {
box-shadow:
0 0 0 0.125rem var(--color-ring-private),
var(--shadow-md);
}
.video-card.video-card--owner-private:hover {
box-shadow:
0 0 0 0.125rem var(--color-ring-private-hover),
var(--shadow-lg);
}
.video-card.video-card--nsfw-owner {
background-color: var(--color-black);
box-shadow:
0 0 0 0.0625rem var(--color-ring-critical),
var(--shadow-md);
}
.video-card.video-card--nsfw-owner:hover {
box-shadow:
0 0 0 0.0625rem var(--color-ring-critical-strong),
var(--shadow-lg);
}
.video-card img.video-card__thumbnail--blurred {
filter: blur(18px);
transform: scale(1.05);
transition:
filter 200ms ease,
transform 200ms ease;
}
.video-card[data-owner-is-viewer="true"][data-url-health-state="offline"][data-stream-health-state="unhealthy"] {
box-shadow:
0 0 0 0.0625rem var(--color-ring-critical-soft),
var(--shadow-md);
}
.video-card[data-owner-is-viewer="true"][data-url-health-state="offline"][data-stream-health-state="unhealthy"]:hover {
box-shadow:
0 0 0 0.0625rem var(--color-ring-critical-hover),
var(--shadow-lg);
}
.video-card--enter {
opacity: 0;
animation: video-card-fade-in 220ms ease-out forwards;
}
.video-visibility-toggle__option {
min-width: 5.5rem;
letter-spacing: 0.08em;
}
.video-visibility-toggle__option.is-disabled[data-active="true"] {
opacity: 0.65;
}
.video-visibility-toggle__option[data-active="true"] {
background: linear-gradient(
135deg,
var(--color-gradient-visibility-start),
var(--color-gradient-visibility-end)
);
}
/*
The modal action buttons reuse the shared `.icon-button` primitive which
previously layered Tailwind's `.btn-ghost` helper on top. The helper adds
responsive padding/height rules that collapse when the flex container
tightens, so the glyphs shrank while the back button (a fixed-size button)
stayed stable. Reset every dimension here so the icons always render with
the same 40px square footprint as the back control, regardless of flex
squeezing or inherited ghost styles.
*/
.modal-nav .icon-button {
box-shadow: none;
padding: 0;
gap: 0;
width: 2.5rem;
height: 2.5rem;
min-width: 2.5rem;
min-height: 2.5rem;
border: none;
}
/* Watch history cards */
@keyframes video-card-fade-in {
from {
opacity: 0;
transform: translateY(0.5rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/*
Thumbnails start transparent and fade in the first time they finish loading.
`data-thumbnail-loaded` is cleared by js/index.js once the animation completes
so re-rendering the same element later does not replay the transition and cause
a distracting flash.
*/
[data-video-thumbnail][data-thumbnail-loaded="true"] {
animation: video-thumbnail-fade-in 220ms ease-out forwards;
}
@keyframes video-thumbnail-fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/*
Generic fade-in utility for chrome elements (sidebar, header controls, etc.).
js/index.js listens for the `interface-fade-in` animation finishing and removes
the temporary classes so that once an element has gracefully appeared it stays
opaque even if the DOM is re-used or re-parented later.
*/
.fade-in {
opacity: 0;
animation: interface-fade-in 280ms ease-out forwards;
animation-delay: var(--fade-in-delay, 0ms);
}
.fade-in-delay-100 {
--fade-in-delay: 100ms;
}
.fade-in-delay-200 {
--fade-in-delay: 200ms;
}
.fade-in-delay-300 {
--fade-in-delay: 300ms;
}
.fade-in-delay-400 {
--fade-in-delay: 400ms;
}
@keyframes interface-fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.video-card--enter,
.fade-in {
opacity: 1;
animation: none;
}
[data-video-thumbnail][data-thumbnail-loaded="true"] {
animation: none;
opacity: 1;
}
}
.video-card:hover {
transform: translateY(-0.25rem);
box-shadow: var(--shadow-lg);
}
.video-card .thumbnail-container {
position: relative;
padding-top: 56.25%;
background-color: var(--color-surface);
overflow: hidden;
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}
.video-card img.thumbnail {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.video-card .details {
padding: 1.25rem;
}
.video-card h3 {
font-size: 1.125rem;
font-weight: 600;
color: var(--color-text);
margin-bottom: 0.75rem;
}
/* Ensure modal portals always sit above the sidebar stack */
#modalContainer {
position: fixed;
inset: 0;
z-index: var(--z-modal-root);
pointer-events: none;
isolation: isolate;
}
#modalContainer > * {
pointer-events: auto;
}
#modalContainer > [id$="Modal"]:not(#playerModal) {
z-index: var(--z-modal-root);
}
#modalContainer > [id$="Modal"]:not(#playerModal) > .bv-modal-backdrop {
z-index: var(--z-modal-overlay);
}
#modalContainer > [id$="Modal"]:not(#playerModal) .bv-modal__panel {
z-index: var(--z-modal-content);
}
#modalContainer > #playerModal {
z-index: var(--z-modal-player);
}
#modalContainer > #playerModal .player-modal__container,
#modalContainer > #playerModal .player-modal__content,
#modalContainer > #playerModal .video-modal__container,
#modalContainer > #playerModal .video-modal__panel {
z-index: var(--z-modal-content);
}
/* Modal Player */
#playerModal {
position: fixed;
inset: 0;
z-index: var(--z-modal-player);
display: none;
flex-direction: column;
align-items: stretch;
justify-content: stretch;
width: 100vw;
height: 100vh;
background-color: var(--color-surface);
color: var(--color-subtle-text);
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
}
#nostrFormModal,
#profileModal,
#uploadModal {
backdrop-filter: blur(0.625rem);
-webkit-backdrop-filter: blur(0.625rem); /* For Safari */
}
/* If you ever want to show it, add ".flex" class dynamically */
#playerModal.flex {
display: flex;
}
.video-modal__panel,
#playerModal .player-modal__content {
animation: fadeIn var(--modal-motion-duration) ease-out;
}
.video-modal__video,
#playerModal .player-modal__video {
padding: clamp(0.75rem, 3.5vw, 2.5rem);
border-bottom: 0.0625rem solid var(--color-border-translucent);
}
.video-modal__media,
#playerModal .player-modal__video video {
box-shadow: 0 1.125rem 2.75rem var(--color-shadow-floating);
max-height: min(80vh, calc(100vw * 9 / 16));
}
.video-modal__info,
#playerModal .player-modal__info {
padding: clamp(1.5rem, 3vw, 2.5rem);
padding-bottom: clamp(2.5rem, 6vw, 4rem);
box-shadow: inset 0 1px 0 var(--color-divider-strong);
}
.modal-meta {
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.modal-view-count {
display: inline-flex;
align-items: center;
gap: 0.25rem;
font-size: 0.875rem;
line-height: 1.25rem;
color: var(--color-muted-alt);
white-space: nowrap;
}
.view-count-text {
white-space: nowrap;
color: var(--color-muted-strong);
}
html.modal-open {
overflow: hidden;
}
body.modal-open {
overflow: hidden;
}
html.modal-open,
body.modal-open {
height: 100%;
}
body.modal-open #app {
overflow: hidden;
}
body.modal-open #sidebar,
body.modal-open #sidebarOverlay {
pointer-events: none;
opacity: 0;
visibility: hidden;
}
body.modal-open #sidebar {
z-index: var(--z-sidebar-overlay);
}
body.modal-open #sidebarOverlay {
z-index: calc(var(--z-sidebar-overlay) - 1);
}
#sidebar.is-modal-hidden,
#sidebarOverlay.is-modal-hidden {
pointer-events: none;
opacity: 0;
visibility: hidden;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(1.25rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (prefers-reduced-motion: reduce) {
.video-modal__panel,
#playerModal .player-modal__content {
animation-duration: 1ms;
}
}
/* Modal Video */
#modalVideo {
width: 100%;
aspect-ratio: 16/9;
background-color: var(--color-black);
}
/* Responsive Adjustments */
@media (min-width: 768px) {
#playerModal .player-modal__content {
max-width: none;
border-radius: 0;
}
}
#modalNav.modal-nav,
.modal-nav,
.video-modal__nav {
background-color: var(--color-bg);
border-bottom: 0.0625rem solid var(--color-border-translucent-strong);
box-shadow: 0 0.75rem 2rem var(--color-shadow-elevated);
}
.modal-nav .flex {
position: relative;
gap: 0.75rem;
}
.modal-actions__overflow {
position: relative;
}
.modal-actions__overflow,
[data-more-menu-wrapper] {
overflow: visible;
}
[data-more-menu="true"] {
z-index: 70;
}
.popover__panel[data-variant="zap"] {
background: var(--color-overlay-veil);
color: var(--color-subtle);
border: 1px solid var(--color-border-translucent-stronger);
box-shadow: 0 22px 48px -18px var(--color-shadow-intense);
-webkit-backdrop-filter: blur(12px);
backdrop-filter: blur(12px);
}
/* Mobile-specific styles */
@media (max-width: 767px) {
#playerModal {
padding: 0;
}
}
/* Progress Bars */
.progress-bar {
width: 100%;
height: 0.5rem;
background-color: var(--color-white-soft);
border-radius: 9999px;
overflow: hidden;
}
.progress-bar-fill {
height: 100%;
background-color: var(--color-primary);
transition: width 0.3s ease-out;
}
/* Forms & Inputs */
input,
textarea {
width: 100%;
padding: 0.75rem;
background-color: var(--color-bg);
border: 0.0625rem solid var(--color-white-soft);
border-radius: 0.5rem;
color: var(--color-text);
transition: border-color 0.2s;
}
input:focus,
textarea:focus {
outline: none;
border-color: var(--color-primary);
ring: 0.125rem var(--color-primary);
}
/* -------------------------------------------
COMMENTED OUT the 'button:not(.icon-button)'
global rule that overrides your circles
--------------------------------------------
button:not(.icon-button) {
padding: 0.75rem 1.5rem;
background-color: var(--color-primary);
color: white;
border-radius: 0.5rem;
font-weight: 500;
transition: all 0.2s;
}
button:not(.icon-button):hover {
background-color: var(--color-secondary);
transform: translateY(-0.0625rem);
}
button:not(.icon-button):focus {
outline: none;
ring: 0.125rem var(--color-primary);
}
*/
/* Utility Classes */
.line-clamp-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.hidden {
display: none;
}
/* Notifications */
#notificationPortal {
position: fixed;
top: calc(env(safe-area-inset-top, 0px) + 1.5rem);
left: 50%;
transform: translateX(-50%);
z-index: 400; /* Keep notifications above the highest modal overlays */
width: min(90vw, 32rem);
display: flex;
flex-direction: column;
gap: 0.75rem;
pointer-events: none;
}
#notificationPortal > * {
width: 100%;
margin-bottom: 0;
pointer-events: auto;
border-radius: 0.75rem;
box-shadow: 0 1.25rem 3rem var(--color-shadow-notification);
}
/* Base styling without a forced display */
#errorContainer,
#successContainer {
border-radius: 0.5rem;
padding: 1rem;
margin-bottom: 1rem;
align-items: center; /* Keep the rest of your styling */
}
/* When not hidden, display as flex */
#errorContainer:not(.hidden),
#successContainer:not(.hidden) {
display: flex;
}
.status-spinner--inline {
animation: spin 1s linear infinite;
border: 0.125rem solid var(--color-border-info-soft);
border-radius: 9999px;
border-top-color: var(--color-info);
display: inline-block;
height: 1rem;
width: 1rem;
}
.sidebar-loading-wrapper {
display: flex;
justify-content: center;
align-items: center;
padding: 3rem 0;
width: 100%;
grid-column: 1 / -1;
}
.sidebar-loading-indicator {
display: inline-flex;
align-items: center;
gap: 0.75rem;
color: var(--color-muted-strong);
font-size: 0.875rem;
font-weight: 500;
letter-spacing: 0.01em;
}
.sidebar-loading-text {
white-space: nowrap;
}
.status-banner {
align-items: center;
background-color: var(--color-overlay-panel);
border-radius: 0.5rem;
color: var(--color-subtle);
display: flex;
gap: 0.75rem;
margin-bottom: 1rem;
padding: 1rem;
}
.status-banner .status-spinner {
animation: spin 1s linear infinite;
border: 0.125rem solid var(--color-border-neutral-soft);
border-radius: 9999px;
border-top-color: var(--color-page-alt);
height: 1.25rem;
width: 1.25rem;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* Responsive Design */
@media (max-width: 640px) {
.container {
padding: 0.75rem;
}
}
footer {
border-top: 0.0625rem solid var(--color-white-soft);
margin-top: 4rem;
padding-top: 2rem;
}
footer a {
text-decoration: none;
}
footer a:hover {
text-decoration: underline;
}
/* Disclaimer Modal Styles */
#disclaimerModal {
overscroll-behavior: contain;
}
#disclaimerModal.hidden {
display: none !important;
}
#disclaimerModal .bv-modal__panel {
width: min(60rem, calc(100% - 2rem));
max-height: min(90vh, 51.25rem);
display: flex;
flex-direction: column;
background-color: var(--color-bg);
box-shadow: 0 1.5625rem 3.125rem -0.75rem var(--color-shadow-sidebar);
}
#disclaimerModal .modal-header {
min-height: 1.5rem;
}
#disclaimerModal .modal-body {
padding: 1.5rem;
flex: 1;
overflow-y: auto;
}
#disclaimerModal .modal-footer {
padding: 1.25rem 1.5rem 1.75rem;
background-color: var(--color-overlay);
border-top: 0.0625rem solid var(--color-white-soft);
}
/* Responsive Adjustments for Disclaimer Modal */
@media (min-width: 768px) {
#disclaimerModal {
padding: 2rem;
align-items: center;
justify-content: center;
}
#disclaimerModal .modal-body {
padding: 2rem 2.5rem 1.5rem;
max-height: calc(90vh - 5rem);
}
#disclaimerModal .modal-footer {
padding: 1.5rem 2.5rem 2rem;
}
}
/* Mobile-specific styles for Disclaimer Modal */
@media (max-width: 767px) {
#disclaimerModal {
padding: 0;
}
#disclaimerModal .bv-modal__panel {
min-height: 100vh;
border-radius: 0;
max-height: none;
width: 100%;
}
#disclaimerModal .modal-body {
padding: 1.5rem 1.5rem 1rem;
max-height: none;
}
#disclaimerModal .modal-footer {
padding: 1rem 1.5rem 2rem;
}
}
/* Override default button styles for back button */
.back-button {
background: var(--color-overlay-strong) !important;
padding: 0 !important;
color: var(--color-subtle-text) !important;
transform: none !important;
border: 0.0625rem solid var(--color-border-translucent-strongest) !important;
box-shadow: none;
}
.back-button:hover {
background: var(--color-overlay-banner) !important;
color: var(--color-white) !important;
border-color: var(--color-border-translucent-glow) !important;
}
/* Modal Container */
.modal-container {
padding: 0;
}
@media (min-width: 768px) {
.modal-container {
padding: 2rem;
}
}
/* Video info cards */
.player-modal__info .bg-gray-800\/50 {
background-color: var(--color-overlay-panel-tint);
backdrop-filter: blur(0.25rem);
}
/* Circular Icon Buttons */
.icon-button {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2.5rem; /* 40px */
height: 2.5rem; /* 40px */
min-width: 2.5rem; /* Prevent flex shrink */
min-height: 2.5rem; /* Prevent flex shrink */
flex: 0 0 2.5rem;
line-height: 0;
background-color: var(--color-neutral-700); /* Gray 700 */
color: var(--color-white);
border: none;
border-radius: 9999px;
cursor: pointer;
transition:
background-color 0.2s,
box-shadow 0.2s;
}
.icon-button:hover {
background-color: var(--color-neutral-600); /* Gray 600 */
}
.icon-button:focus,
.icon-button:active {
outline: none;
box-shadow: 0 0 0 0.1875rem var(--color-ring-alert);
}
.icon-image {
width: 1.25rem; /* 20px */
height: 1.25rem; /* 20px */
pointer-events: none;
}
/* Ratio 16:9 Container */
.ratio-16-9 {
position: relative;
width: 100%;
padding-top: 56.25%;
background-color: var(--color-card);
}
.ratio-16-9 > img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.video-card .ratio-16-9 {
border-radius: 0.75rem;
overflow: hidden;
}
.video-card .ratio-16-9 > [data-video-thumbnail] {
border-radius: inherit;
}
/* Sidebar default states */
#sidebarContainer {
position: relative;
overflow: visible;
}
#sidebar {
position: fixed;
top: 0;
left: 0;
width: var(--sidebar-width);
min-width: var(--sidebar-width);
height: 100vh;
height: 100dvh;
background-color: transparent;
color: var(--color-text);
overflow-x: visible;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
overscroll-behavior: contain;
scrollbar-gutter: stable both-edges;
transition:
width 200ms ease,
transform 0.3s ease,
box-shadow 0.3s ease;
/* Keep below modal stacks so dialogs overlay the drawer. */
z-index: var(--z-sidebar);
box-shadow: none;
}
#sidebar .sidebar__inner {
display: flex;
flex-direction: column;
height: 100%;
padding: 1.5rem 1.25rem 1.75rem;
position: relative;
width: 100%;
/*
Allow the gradient panel shadow to breathe outside the rail while a nested
scroll container handles overflow.
*/
overflow: visible;
}
/*
The scroll wrapper keeps nav + footer together while leaving overflow
visible so the gradient card shadow is never clipped.
*/
.sidebar-scroll {
display: flex;
flex-direction: column;
gap: 1.5rem;
width: 100%;
height: 100%;
min-height: 0;
flex: 1 1 auto;
overflow: visible;
}
.sidebar-panel {
background: linear-gradient(
160deg,
var(--color-overlay-panel-gradient-start) 0%,
var(--color-overlay-panel-gradient-end) 100%
);
border: 1px solid var(--color-border-translucent);
border-radius: 1rem;
box-shadow: 0 1.25rem 2.5rem var(--color-shadow-panel);
padding: 1.25rem 1rem;
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.sidebar-panel--primary {
flex: 1 1 auto;
min-height: 0;
}
.sidebar-panel__header {
display: none;
justify-content: flex-end;
margin-bottom: 1rem;
}
.sidebar-collapse-toggle {
display: none;
align-items: center;
justify-content: center;
width: var(--sidebar-control-size);
height: var(--sidebar-control-size);
border-radius: 9999px;
border: 1px solid var(--color-border-translucent-medium);
background: var(--color-surface-tint-subtle);
color: inherit;
cursor: pointer;
transition:
background 180ms ease,
color 180ms ease,
border-color 180ms ease;
flex-shrink: 0;
box-sizing: border-box;
}
.sidebar-collapse-toggle:hover {
background: var(--color-border-translucent);
border-color: var(--color-border-translucent-stronger);
color: var(--color-text);
}
.sidebar-collapse-toggle:focus-visible {
outline: 0.125rem solid var(--color-secondary);
outline-offset: 0.25rem;
}
.sidebar-collapse-toggle__icon {
width: 1.125rem;
height: 1.125rem;
transition: transform 200ms ease;
}
.sidebar-nav {
display: flex;
flex-direction: column;
gap: 0.25rem;
opacity: 1;
transition: opacity 160ms ease;
width: 100%;
}
.sidebar-nav-link {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.625rem 0.875rem;
min-height: var(--sidebar-control-size);
border-radius: 0.875rem;
font-size: 0.95rem;
font-weight: 600;
color: var(--color-text-frosted-strong);
text-decoration: none;
transition:
background 160ms ease,
color 160ms ease,
transform 160ms ease;
width: 100%;
box-sizing: border-box;
}
.sidebar-nav-link:hover {
background: var(--color-border-translucent);
color: var(--color-text);
}
.sidebar-nav-link:focus-visible {
outline: 0.125rem solid var(--color-secondary);
outline-offset: 0.25rem;
}
.sidebar-nav-link--sub {
font-size: 0.85rem;
font-weight: 500;
color: var(--color-text-frosted-soft);
padding-block: 0.55rem;
}
.sidebar-icon {
/* Lock icon sizing so the glyphs remain steady during collapse/expand. */
width: 1.5rem;
height: 1.5rem;
min-width: 1.5rem;
min-height: 1.5rem;
flex-shrink: 0;
display: block;
}
.sidebar-footer {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-top: auto;
position: relative;
z-index: 2;
}
.sidebar-dropup-trigger {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
width: 100%;
padding: 0.75rem 0.875rem;
min-height: var(--sidebar-control-size);
border-radius: 0.875rem;
border: 1px solid var(--color-border-translucent);
background: var(--color-overlay-panel-glass);
color: var(--color-text-frosted);
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
transition:
background 160ms ease,
border-color 160ms ease,
color 160ms ease;
box-sizing: border-box;
flex-shrink: 0;
}
.sidebar-dropup-trigger:hover {
background: var(--color-overlay-banner);
border-color: var(--color-border-translucent-bright);
color: var(--color-text);
}
.sidebar-dropup-trigger:focus-visible {
outline: 0.125rem solid var(--color-secondary);
outline-offset: 0.25rem;
}
.sidebar-dropup-trigger__glyph {
width: 1.25rem;
height: 1.25rem;
opacity: 0.9;
}
.sidebar-dropup-trigger__chevron {
width: 1.125rem;
height: 1.125rem;
transition: transform 180ms ease;
}
.sidebar-dropup-trigger__chevron.is-rotated,
.sidebar-dropup-trigger[aria-expanded="true"] .sidebar-dropup-trigger__chevron {
transform: rotate(180deg);
}
.sidebar-dropup-panel {
background: var(--color-overlay-darker);
border: 1px solid var(--color-border-translucent);
border-radius: 0.875rem;
box-shadow: 0 1.5rem 3rem var(--color-shadow-panel);
padding: 0.75rem 0.5rem;
position: absolute;
left: 0;
right: 0;
bottom: calc(100% + 0.75rem);
opacity: 0;
visibility: hidden;
pointer-events: none;
transform: translateY(0.5rem);
transition:
opacity 160ms ease,
transform 160ms ease,
visibility 160ms ease;
z-index: 5;
}
.sidebar-dropup-panel[data-state="expanded"] {
opacity: 1;
visibility: visible;
pointer-events: auto;
transform: translateY(0);
}
.sidebar-dropup-panel__inner {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
#sidebar[data-footer-state="expanded"] .sidebar-nav {
opacity: 0;
pointer-events: none;
}
#sidebar[data-footer-state="collapsed"] .sidebar-nav {
opacity: 1;
}
#sidebar.sidebar-open {
box-shadow: 0 0.75rem 1.5rem var(--color-shadow-panel);
}
#sidebarOverlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--color-overlay-muted);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
/* Sits above page chrome but below modals and the sidebar itself. */
z-index: var(--z-sidebar-overlay);
}
body.sidebar-open #sidebarOverlay {
opacity: 1;
pointer-events: auto;
}
/* Mobile (max-width: 767px): Hide sidebar by default */
@media (max-width: 767px) {
#sidebar {
transform: translate3d(-100%, 0, 0);
width: min(var(--sidebar-width-expanded), calc(100vw - 3rem));
}
/* When the sidebar-open class is added, slide the sidebar in */
#sidebar.sidebar-open {
transform: translate3d(0, 0, 0);
}
body.sidebar-open {
overflow: hidden;
}
}
/* Desktop (min-width: 768px): Always show the sidebar */
@media (min-width: 768px) {
.sidebar-panel__header {
display: flex;
}
.sidebar-collapse-toggle {
display: inline-flex;
}
#sidebar {
transform: translateX(0) !important;
width: var(--sidebar-width);
overflow: visible;
}
#sidebar.sidebar-open {
box-shadow: none;
}
#sidebarOverlay {
display: none;
}
#app {
box-sizing: border-box;
transition:
margin-left 200ms ease,
width 200ms ease,
max-width 200ms ease;
}
#app[data-sidebar-state="collapsed"] {
margin-left: calc(
var(--sidebar-width-collapsed) + var(--sidebar-content-gap)
);
width: calc(
100vw - var(--sidebar-width-collapsed) - var(--sidebar-content-gap)
);
max-width: calc(
100vw - var(--sidebar-width-collapsed) - var(--sidebar-content-gap)
);
}
#app[data-sidebar-state="expanded"] {
margin-left: calc(
var(--sidebar-width-expanded) + var(--sidebar-content-gap)
);
width: calc(
100vw - var(--sidebar-width-expanded) - var(--sidebar-content-gap)
);
max-width: calc(
100vw - var(--sidebar-width-expanded) - var(--sidebar-content-gap)
);
}
body.sidebar-collapsed,
#sidebar.sidebar-collapsed {
--sidebar-width: var(--sidebar-width-collapsed);
}
body.sidebar-expanded,
#sidebar.sidebar-expanded {
--sidebar-width: var(--sidebar-width-expanded);
}
body.sidebar-collapsed #sidebar .sidebar-nav-link,
#sidebar.sidebar-collapsed .sidebar-nav-link {
/*
Keep icons centered in the collapsed rail without resizing them.
*/
justify-content: center;
width: var(--sidebar-control-size);
padding: 0;
margin-inline: auto;
border-radius: 9999px;
}
body.sidebar-expanded #sidebar .sidebar-nav-link,
#sidebar.sidebar-expanded .sidebar-nav-link {
justify-content: flex-start;
}
body.sidebar-collapsed #sidebar .sidebar-text,
#sidebar.sidebar-collapsed .sidebar-text {
display: none;
}
body.sidebar-collapsed #sidebar .sidebar__inner,
#sidebar.sidebar-collapsed .sidebar__inner {
/*
Keep enough breathing room for the panel shadow while widening the
interior track so var(--sidebar-control-size) controls stay perfectly
round.
*/
padding-inline: 0.25rem;
}
body.sidebar-collapsed #sidebar .sidebar-panel,
#sidebar.sidebar-collapsed .sidebar-panel {
/*
Mirror the outer adjustment so the gradient card retains its rounded
edges without squeezing the icon rail or clipping the control diameter.
*/
padding-inline: 0.375rem;
}
body.sidebar-collapsed #sidebar .sidebar-panel__header,
#sidebar.sidebar-collapsed .sidebar-panel__header {
justify-content: center;
}
body.sidebar-collapsed #sidebar .sidebar-collapse-toggle,
#sidebar.sidebar-collapsed .sidebar-collapse-toggle {
margin-inline: auto;
}
#sidebar .sidebar-toggle-icon--rotated {
transform: rotate(180deg);
}
body.sidebar-collapsed #sidebar .sidebar-toggle-icon--rotated,
#sidebar.sidebar-collapsed .sidebar-toggle-icon--rotated {
transform: rotate(0deg);
}
body.sidebar-collapsed #sidebar .sidebar-dropup-trigger {
/*
Align the "More" control with the centered icon rail while keeping its
padding consistent so the glyph does not scale between states.
*/
justify-content: center;
width: var(--sidebar-control-size);
height: var(--sidebar-control-size);
padding: 0;
margin-inline: auto;
border-radius: 9999px;
}
body.sidebar-collapsed #sidebar .sidebar-dropup-trigger .sidebar-text,
#sidebar.sidebar-collapsed .sidebar-dropup-trigger .sidebar-text {
display: none;
}
body.sidebar-collapsed #sidebar .sidebar-dropup-trigger__chevron {
display: none;
}
body.sidebar-collapsed #sidebar .sidebar-dropup-trigger__glyph,
#sidebar.sidebar-collapsed .sidebar-dropup-trigger__glyph {
margin: 0;
}
}
.edit-field-button {
align-items: center;
background-color: var(--color-panel);
border-radius: 0.5rem;
color: var(--color-subtle-text);
display: inline-flex;
font-size: 0.75rem;
font-weight: 600;
justify-content: center;
padding: 0.5rem 0.85rem;
transition:
background-color 0.2s ease,
color 0.2s ease,
transform 0.2s ease;
}
.edit-field-button:hover,
.edit-field-button:focus {
background-color: var(--color-panel-hover);
color: var(--color-text);
transform: translateY(-0.0625rem);
}
.locked-input {
background-color: var(--color-overlay-panel-soft) !important;
border-color: var(--color-border-sidebar-strong) !important;
color: var(--color-muted) !important;
cursor: default;
}
.locked-input:focus {
outline: none;
box-shadow: none;
}