Modify the authentication handler to return an unauthorized error when an invalid or disabled bearer token is provided, rather than silently falling back to an anonymous request. This ensures that clients attempting to authenticate but failing (due to expired, malformed, or disabled tokens) are explicitly notified of the auth failure instead of proceeding anonymously. True anonymous requests without any Authorization header remain supported.
282 lines
4.7 KiB
CSS
282 lines
4.7 KiB
CSS
.app-shell {
|
|
width: min(86rem, calc(100% - 2rem));
|
|
margin: 0 auto;
|
|
padding: 2rem 0;
|
|
display: grid;
|
|
grid-template-columns: 14rem minmax(0, 1fr);
|
|
gap: 1.5rem;
|
|
}
|
|
|
|
.app-sidebar {
|
|
position: sticky;
|
|
top: 5rem;
|
|
align-self: start;
|
|
display: grid;
|
|
gap: 0.5rem;
|
|
padding: 0.75rem;
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius);
|
|
background: rgba(24, 24, 27, 0.58);
|
|
}
|
|
|
|
.sidebar-link {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.55rem;
|
|
padding: 0.62rem 0.75rem;
|
|
border: 1px solid transparent;
|
|
border-radius: var(--radius);
|
|
color: var(--muted-foreground);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.sidebar-link:hover,
|
|
.sidebar-link.is-active {
|
|
border-color: var(--border);
|
|
background: var(--muted);
|
|
color: var(--foreground);
|
|
}
|
|
|
|
.admin-shell .app-sidebar {
|
|
border-color: rgba(125, 211, 252, 0.28);
|
|
background: linear-gradient(180deg, rgba(8, 47, 73, 0.22), rgba(24, 24, 27, 0.58));
|
|
}
|
|
|
|
.admin-shell .sidebar-link.is-active {
|
|
border-color: rgba(125, 211, 252, 0.42);
|
|
background: rgba(14, 116, 144, 0.24);
|
|
}
|
|
|
|
.admin-shell .kicker {
|
|
color: #7dd3fc;
|
|
}
|
|
|
|
.sidebar-logout {
|
|
display: grid;
|
|
margin: 0.75rem 0 0;
|
|
}
|
|
|
|
.sidebar-logout .button {
|
|
width: 100%;
|
|
}
|
|
|
|
.collection-create {
|
|
display: grid;
|
|
gap: 0.6rem;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.app-main {
|
|
min-width: 0;
|
|
display: grid;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.settings-stack {
|
|
display: grid;
|
|
gap: 1rem;
|
|
max-width: 44rem;
|
|
}
|
|
|
|
.settings-panel {
|
|
box-shadow: none;
|
|
}
|
|
|
|
.compact-upload .drop-zone {
|
|
min-height: 11rem;
|
|
}
|
|
|
|
.dashboard-options {
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
}
|
|
|
|
.collection-tabs,
|
|
.inline-controls {
|
|
display: flex;
|
|
align-items: end;
|
|
flex-wrap: wrap;
|
|
gap: 0.65rem;
|
|
}
|
|
|
|
.inline-controls input,
|
|
.inline-controls select {
|
|
min-width: 15rem;
|
|
}
|
|
|
|
.compact-input {
|
|
width: 10rem;
|
|
}
|
|
|
|
.settings-form {
|
|
display: grid;
|
|
gap: 1.5rem;
|
|
}
|
|
|
|
.settings-form-narrow {
|
|
grid-template-columns: minmax(0, 1fr);
|
|
gap: 0.9rem;
|
|
}
|
|
|
|
.settings-form label {
|
|
display: grid;
|
|
gap: 0.35rem;
|
|
color: var(--muted-foreground);
|
|
font-size: 0.82rem;
|
|
}
|
|
|
|
.settings-form .checkbox-field {
|
|
grid-column: 1 / -1;
|
|
}
|
|
|
|
.settings-form button {
|
|
justify-self: start;
|
|
}
|
|
|
|
|
|
/* Tab navigation */
|
|
.tabs-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.75rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.tab-list {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 0.3rem;
|
|
}
|
|
|
|
.tab {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
height: 2rem;
|
|
padding: 0 0.75rem;
|
|
border-radius: 999px;
|
|
border: 1px solid transparent;
|
|
color: var(--muted-foreground);
|
|
font-size: 0.84rem;
|
|
font-weight: 500;
|
|
text-decoration: none;
|
|
transition: background 120ms, color 120ms, border-color 120ms;
|
|
}
|
|
|
|
.tab:hover {
|
|
background: var(--muted);
|
|
color: var(--foreground);
|
|
}
|
|
|
|
.tab.is-active {
|
|
border-color: var(--border);
|
|
background: var(--muted);
|
|
color: var(--foreground);
|
|
font-weight: 650;
|
|
}
|
|
|
|
/* Sidebar structure */
|
|
.sidebar-sep {
|
|
height: 1px;
|
|
border: 0;
|
|
background: var(--border);
|
|
margin: 0.5rem 0;
|
|
}
|
|
|
|
.sidebar-nav {
|
|
display: grid;
|
|
gap: 0.25rem;
|
|
}
|
|
|
|
/* Collection create dropdown */
|
|
.new-collection-drop {
|
|
position: relative;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.new-collection-drop > summary {
|
|
list-style: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.new-collection-drop > summary::-webkit-details-marker { display: none; }
|
|
|
|
.new-collection-body {
|
|
position: absolute;
|
|
right: 0;
|
|
top: calc(100% + 0.5rem);
|
|
z-index: 10;
|
|
width: 15rem;
|
|
padding: 1rem;
|
|
background: color-mix(in srgb, var(--card) 97%, #000);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius);
|
|
box-shadow: var(--shadow);
|
|
display: grid;
|
|
gap: 0.65rem;
|
|
}
|
|
|
|
.new-collection-body label {
|
|
display: grid;
|
|
gap: 0.35rem;
|
|
color: var(--muted-foreground);
|
|
font-size: 0.82rem;
|
|
}
|
|
|
|
/* Copyable URL field */
|
|
.copy-field {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
align-items: center;
|
|
margin-top: 0.75rem;
|
|
}
|
|
|
|
.copy-field input {
|
|
flex: 1;
|
|
min-width: 0;
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
|
font-size: 0.8rem;
|
|
color: var(--muted-foreground);
|
|
}
|
|
|
|
/* Settings sections */
|
|
.settings-section {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: 0.9rem;
|
|
}
|
|
|
|
.settings-section-title {
|
|
grid-column: 1 / -1;
|
|
margin: 0;
|
|
padding-bottom: 0.6rem;
|
|
border-bottom: 1px solid var(--border);
|
|
font-size: 0.875rem;
|
|
font-weight: 650;
|
|
color: var(--foreground);
|
|
}
|
|
|
|
.settings-section .checkbox-field {
|
|
grid-column: 1 / -1;
|
|
}
|
|
|
|
.settings-section label {
|
|
display: grid;
|
|
gap: 0.35rem;
|
|
color: var(--muted-foreground);
|
|
font-size: 0.82rem;
|
|
}
|
|
|
|
/* Quota form in admin users table */
|
|
.quota-form {
|
|
display: flex;
|
|
gap: 0.4rem;
|
|
align-items: center;
|
|
margin: 0;
|
|
}
|
|
|
|
.quota-form input {
|
|
width: 6.5rem;
|
|
min-width: 0;
|
|
}
|