Files
anonymous_github/public/css/style.css
T
tdurieuxandClaude Fable 5.1 a02e83e48c feat: clarify the menus and rework the settings page
"Report an issue" in the navbar read like a way to report an anonymized
repository, and it opened a blank GitHub issue instead of the template
that asks reporters to confirm the issue is about the service. The user
menu offered "Default settings" and "Logout" with no hint of what lives
behind them, and the Claim page was unreachable from any menu.

The settings page never loaded quotas (the bars stayed in their striped
loading state), mixed serif checkbox labels with sans forms, used
Bootstrap alert colours, and described options in jargon ("Proxy mode",
"Github page", "Line of code").

- Navbar: "Report a bug" links to the issue template with a tooltip that
  names the service; the user menu shows who is signed in and lists
  Settings, Claim an anonymization, Report a bug, Source code, Sign out,
  each with a one-line hint. Icon links get aria-labels.
- Settings: quotas load through a shared quotaService (also used by the
  dashboard); sections match the side navigation, which now follows
  scrolling via a small paperScrollspy directive; copy explains each
  option; account card with Sign out; delete moved into a danger zone;
  Save shows Saving/Saved and the error alert uses the paper palette.
- Conferences list and detail: sort and status buttons show their state,
  hidden statuses appear as chips with a count line, Remove is a button
  behind a divider, dates spell the month, expiry column matches the
  dashboard, detail page gets an Edit button and plan/cost meta.
- New conference: validation errors only appear after a field is touched
  or the form submitted; pricing copy matches how price is computed.
- Status page: progress label no longer overlaps the details below it;
  "Report a bug" points at the template and says whom it is for.
- Claim: single rule, constrained width, explains when to use it.
- Anonymize: shorter placeholder, consistent Auto-update label.
- Mock server gains the endpoints these pages need and an ANON mode.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 20:55:22 +02:00

6803 lines
166 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ===== Paper design tokens =====
Editorial minimal — warm neutrals, single indigo accent.
Serif display (Instrument Serif), Inter body, JetBrains Mono. */
.dark-mode {
/* Warm ink canvas — same temperature as the light paper palette so
cards (#25231F) and borders (#33302B) sit on a matching base. */
--canvas-bg-color: #1B1916;
--sidebar-bg-color: #1A1918;
--main-bg-color: #1B1916;
--header-bg-color: #1A1918;
--hover-bg-color: rgba(255, 255, 255, 0.05);
--header-color: #FAF9F6;
--color: #D6D1C5;
--link-color: #A7B2FF;
--link-hover-color: #C8CEFF;
--border-color: #33302B;
--border-soft: #2A2825;
--btn-color: #FAF9F6;
--input-color: #E6E1D8;
--input-bg: #25231F;
--primary-bg: #FAF9F6;
--primary-hover-bg: #FFFFFF;
--primary-color: #1A1815;
--primary-active-color: #1A1815;
--accent: #A7B2FF;
--accent-soft: rgba(167, 178, 255, 0.12);
/* --ink-muted is used for small text: 6.5:1 on the canvas.
--ink-faint is for non-text (icons, rules, dots), never for copy. */
--ink-muted: #A39D92;
--ink-faint: #8A857C;
--ink-soft: #B5AFA2;
/* Semantic status colours (text/dot/border on canvas ≥ 4.5:1) */
--status-ready: #5FB27A;
--status-progress: #E0A94A;
--status-error: #F08A82;
--status-inactive: #8A857C;
--status-error-soft: rgba(240, 138, 130, 0.08);
--status-error-soft-hover: rgba(240, 138, 130, 0.14);
--admin-nav-bg: #1A1918;
--admin-nav-active: rgba(167, 178, 255, 0.12);
--admin-stat-bg: #25231F;
--paper-card: #25231F;
--paper-bg-alt: #201E1B;
--highlight: #3A341E;
background-color: var(--canvas-bg-color);
color: var(--color);
}
body {
/* Paper palette */
--canvas-bg-color: #FAF9F6;
--sidebar-bg-color: #FFFFFF;
--header-bg-color: #FAF9F6;
--header-color: #1A1815;
--main-bg-color: #FAF9F6;
--hover-bg-color: rgba(26, 24, 21, 0.05);
--input-color: #1A1815;
--color: #1A1815;
--link-color: #3B4AD6;
--link-hover-color: #2E3BB8;
--border-color: #E6E1D8;
--border-soft: #EDE9E1;
--btn-color: #1A1815;
--input-bg: #FFFFFF;
--primary-bg: #1A1815;
--primary-hover-bg: #000000;
--primary-color: #FAF9F6;
--primary-active-color: #FAF9F6;
--accent: #3B4AD6;
--accent-soft: #EEF0FF;
/* --ink-muted is used for small text: 5.1:1 on the paper canvas.
--ink-faint is for non-text (icons, rules, dots), never for copy. */
--ink-muted: #6F6A61;
--ink-faint: #8A857C;
--ink-soft: #4A4641;
--paper-bg-alt: #F3F1EC;
--paper-card: #FFFFFF;
--highlight: #FFF3C4;
/* Semantic status colours (text/dot/border on canvas ≥ 4.5:1) */
--status-ready: #2F7A44;
--status-progress: #946512;
--status-error: #B42318;
--status-inactive: #8A857C;
--status-error-soft: rgba(180, 35, 24, 0.04);
--status-error-soft-hover: rgba(180, 35, 24, 0.08);
/* Two-step radius system: controls and surfaces. Chips/badges are pills. */
--radius-control: 6px;
--radius-surface: 10px;
--font-serif: 'Instrument Serif', 'Iowan Old Style', Georgia, serif;
--font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
background-color: var(--canvas-bg-color);
color: var(--color);
font-family: var(--font-sans);
font-size: 14px;
letter-spacing: -0.005em;
line-height: 1.5;
}
.fadeIn {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.6s;
}
@keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* Keyboard focus: a visible 2px accent ring only when focus came from the
keyboard (:focus-visible); pointer clicks get no ring. The ring is ≥ 3:1
against both canvases (indigo 6.4:1 light, periwinkle 8.7:1 dark). */
.btn:focus,
.btn:active {
box-shadow: none;
}
:focus:not(:focus-visible) {
outline: none;
}
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.btn:focus-visible,
.form-control:focus-visible,
.dropdown-item:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
box-shadow: none;
}
input:hover,
input:active {
box-shadow: none !important;
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
border-color: var(--border-color);
-webkit-text-fill-color: var(--color);
-webkit-box-shadow: none;
transition: background-color 1000s ease-in-out 0s;
}
input:-internal-autofill-selected,
.form-control,
.custom-select {
color: var(--input-color);
background-color: var(--input-bg) !important;
border-color: var(--border-color);
}
.form-control:focus {
border-color: var(--border-color);
}
html,
body {
position: relative;
height: 100%;
overflow-x: hidden;
}
body {
overflow-y: hidden;
}
/* Angular removes the ng-view attribute after compiling the route. Target the
element so it remains the scroll container below the fixed-height header. */
ng-view {
display: block;
flex: 1 1 auto;
min-height: 0;
overflow-x: hidden !important;
overflow-y: auto !important;
max-width: 100%;
}
.markdown-body a,
a {
color: var(--link-color);
}
.markdown-body a:hover,
a:hover {
text-decoration: none;
color: var(--link-hover-color);
}
.dropdown-menu a.dropdown-item {
color: var(--color);
}
.dropdown-menu a.dropdown-item:hover {
color: var(--color);
text-decoration: none;
}
.markdown-body .emoji {
height: 1.3em;
margin: 0;
vertical-align: -0.1em;
}
.navbar.navbar-expand-lg {
background: var(--header-bg-color) !important;
border-bottom: 1px solid var(--border-color);
transition: background-color 0.5s ease;
padding: 10px max(20px, calc((100vw - 1200px) / 2));
font-family: var(--font-sans);
}
.navbar-toggler {
border: 1px solid var(--border-color) !important;
color: var(--color) !important;
}
.navbar-toggler .navbar-toggler-icon {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='%231A1815' stroke-width='2' stroke-linecap='round' d='M4 8h22M4 15h22M4 22h22'/%3E%3C/svg%3E") !important;
}
.navbar .navbar-nav {
align-items: center;
}
.navbar .nav-link {
display: inline-flex;
align-items: center;
font-size: 13px;
color: var(--ink-muted) !important;
padding: 6px 0 !important;
margin: 0 12px;
border-bottom: 1px solid transparent;
letter-spacing: -0.005em;
line-height: 1;
}
.navbar .nav-link:hover {
color: var(--color) !important;
}
.navbar .nav-link.active {
color: var(--color) !important;
border-bottom-color: var(--color);
}
.navbar .nav-link.nav-icon {
padding: 0 !important;
margin: 0 8px;
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
}
.navbar .nav-link .fa,
.navbar .nav-link .fab {
font-size: 15px;
line-height: 1;
}
.navbar #navbarSupportedContent {
align-items: center;
}
.navbar-brand {
font-family: var(--font-serif) !important;
font-size: 20px !important;
letter-spacing: -0.01em;
color: var(--color) !important;
padding-right: 18px;
margin-right: 12px;
border-right: 1px solid var(--border-color);
}
.navbar-brand em,
.navbar-brand i {
font-style: italic;
font-weight: 400;
}
.navbar-dark .navbar-toggler {
border-color: var(--border-color);
color: var(--color);
}
.navbar-dark .navbar-toggler-icon {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='%231A1815' stroke-width='2' stroke-linecap='round' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");
}
.navbar .btn-signin {
display: inline-flex;
align-items: center;
height: 32px;
padding: 0 14px !important;
margin-left: 6px;
border: 1px solid var(--color);
background: var(--color);
color: var(--canvas-bg-color) !important;
border-radius: 6px;
font-size: 13px;
font-weight: 500;
line-height: 1;
}
.navbar .btn-signin:hover {
background: var(--primary-hover-bg);
color: var(--canvas-bg-color) !important;
}
.navbar .user-chip {
display: inline-flex !important;
align-items: center;
gap: 8px;
padding: 4px 12px 4px 6px !important;
margin-left: 6px;
border: 1px solid var(--border-color);
border-radius: 999px;
background: var(--sidebar-bg-color);
font-size: 12.5px;
color: var(--color) !important;
}
.navbar .user-chip:hover {
background: var(--hover-bg-color);
}
.navbar .user-chip img {
width: 22px;
height: 22px;
}
.navbar .user-chip .user-chip-name {
color: var(--color);
font-weight: 500;
}
.navbar .user-chip::after {
color: var(--ink-muted);
}
#navbarSupportedContent {
padding-right: 0;
}
.generalMessage {
display: block;
text-align: center;
color: var(--header-color);
}
.rgba-gradient {
background: var(--canvas-bg-color);
color: var(--color);
}
/* ===== Paper landing — editorial hero ===== */
.paper-hero {
max-width: 1100px;
margin: 0 auto;
padding: 72px 32px 40px;
}
.paper-eyebrow {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
font-weight: 500;
}
.paper-hero h1.hero-title {
font-family: var(--font-serif);
font-weight: 400;
font-size: clamp(2.4rem, 6vw, 4.9rem);
line-height: 1.02;
letter-spacing: -0.025em;
margin: 18px 0 0;
color: var(--color);
text-wrap: balance;
}
.paper-hero h1 .accent {
color: var(--accent);
font-style: italic;
}
.hero-subtitle {
margin-top: 20px;
font-size: 17px;
line-height: 1.55;
color: var(--ink-soft);
max-width: 580px;
text-wrap: pretty;
opacity: 1;
}
.paper-cta-row {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
margin-top: 32px;
}
.paper-cta-row .meta {
margin-left: 6px;
font-size: 12.5px;
color: var(--ink-muted);
}
.btn-hero {
font-family: var(--font-sans);
border: 1px solid var(--color);
background: var(--color);
color: var(--canvas-bg-color);
padding: 12px 20px;
font-size: 14px;
font-weight: 500;
border-radius: 6px;
letter-spacing: -0.005em;
transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.btn-hero:hover {
background: var(--primary-hover-bg);
border-color: var(--primary-hover-bg);
color: var(--canvas-bg-color);
}
.btn-hero-ghost {
background: transparent;
border: 1px solid var(--border-color);
color: var(--color);
padding: 12px 20px;
font-size: 14px;
font-weight: 500;
border-radius: 6px;
}
.btn-hero-ghost:hover {
background: var(--hover-bg-color);
border-color: var(--color);
color: var(--color);
}
/* Before/after preview card */
.paper-preview {
margin-top: 48px;
display: grid;
grid-template-columns: 1fr 1fr;
border: 1px solid var(--border-color);
border-radius: 10px;
overflow: hidden;
background: var(--paper-card, #fff);
}
.paper-preview .pane {
padding: 0;
}
.paper-preview .pane + .pane {
border-left: 1px solid var(--border-color);
}
.paper-preview .pane-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 12px 18px;
border-bottom: 1px solid var(--border-color);
}
.paper-preview .pane-label {
font-family: var(--font-mono);
font-size: 10.5px;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--ink-muted);
}
.paper-preview .pane-url {
font-family: var(--font-mono);
font-size: 11.5px;
color: var(--ink-soft);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.paper-preview .pane-body {
padding: 22px;
font-family: var(--font-mono);
font-size: 13.5px;
line-height: 1.85;
color: var(--color);
}
.paper-preview .tok {
color: var(--ink-muted);
}
.paper-preview .redact {
background: var(--highlight, #FFF3C4);
padding: 0 4px;
border-radius: 3px;
color: var(--color);
position: relative;
}
.paper-preview .redact::after {
content: '';
position: absolute;
left: 4px;
right: 4px;
top: 50%;
border-top: 1.5px solid var(--color);
opacity: 0.55;
}
.dark-mode .paper-preview .redact {
background: rgba(255, 243, 196, 0.15);
}
@media (max-width: 767px) {
.paper-preview {
grid-template-columns: 1fr;
}
.paper-preview .pane + .pane {
border-left: none;
border-top: 1px solid var(--border-color);
}
}
/* Stats strip */
.paper-stats {
border-top: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
background: var(--paper-bg-alt, #F3F1EC);
}
.dark-mode .paper-stats {
background: #181715;
}
.paper-stats-inner {
max-width: 1100px;
margin: 0 auto;
padding: 28px 32px 32px;
}
.paper-stats-meta {
display: flex;
justify-content: space-between;
align-items: center;
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
font-size: 11px;
letter-spacing: 0.08em;
color: var(--ink-muted);
margin-bottom: 20px;
}
.paper-stats-meta-left {
text-transform: uppercase;
}
.paper-stats-meta-right {
text-transform: lowercase;
display: inline-flex;
align-items: center;
gap: 6px;
}
.paper-stats-dot {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
background: #1f9d55;
box-shadow: 0 0 0 3px rgba(31, 157, 85, 0.18);
}
.paper-stats-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 32px;
}
@media (max-width: 900px) {
.paper-stats-grid { grid-template-columns: repeat(2, 1fr); gap: 28px; }
}
.paper-stat-card {
display: flex;
flex-direction: column;
}
.paper-stat-value {
font-family: var(--font-serif);
font-size: 56px;
line-height: 1;
color: var(--color);
letter-spacing: -0.02em;
}
.paper-stat-label {
margin-top: 10px;
font-size: 13px;
color: var(--ink-muted);
}
.paper-stat-bars {
display: block;
width: 100%;
height: 36px;
margin-top: 16px;
overflow: visible;
}
.paper-stat-bars rect {
fill: var(--ink-muted);
opacity: 0.35;
}
.paper-stat-bars rect.is-latest {
fill: #2937e3;
opacity: 1;
}
.dark-mode .paper-stat-bars rect.is-latest {
fill: #6c7bff;
}
.paper-stat-delta {
margin-top: 12px;
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
font-size: 12px;
color: var(--ink-muted);
display: flex;
align-items: center;
gap: 8px;
}
.paper-stat-sep {
opacity: 0.5;
}
.paper-stat-pct.is-up {
color: #1f9d55;
}
.paper-stat-pct.is-down {
color: #b54137;
}
.paper-stat-arrow {
font-size: 10px;
margin-right: 2px;
}
/* How it works — editorial numbered steps */
.paper-how {
max-width: 1100px;
margin: 0 auto;
padding: 64px 32px;
display: grid;
grid-template-columns: 260px 1fr;
gap: 56px;
}
.paper-how-heading {
font-family: var(--font-serif);
font-weight: 400;
font-size: 32px;
line-height: 1.1;
margin-top: 12px;
letter-spacing: -0.02em;
}
.paper-step {
display: grid;
grid-template-columns: 64px 1fr;
gap: 20px;
padding: 22px 0;
border-bottom: 1px solid var(--border-color);
}
.paper-step:first-child {
border-top: 1px solid var(--border-color);
}
.paper-step .step-num {
font-family: var(--font-mono);
font-size: 12px;
color: var(--ink-muted);
padding-top: 6px;
}
.paper-step .step-title {
font-family: var(--font-serif);
font-size: 22px;
letter-spacing: -0.01em;
line-height: 1.2;
}
.paper-step .step-desc {
margin-top: 6px;
color: var(--ink-soft);
max-width: 560px;
text-wrap: pretty;
}
.paper-step .step-desc a {
color: var(--accent);
}
@media (max-width: 767px) {
.paper-how {
grid-template-columns: 1fr;
gap: 24px;
padding: 40px 20px;
}
}
/* Trust row — conferences */
.paper-trust {
max-width: 1100px;
margin: 0 auto 80px;
padding: 0 32px;
}
.paper-trust-inner {
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 24px 28px;
display: grid;
grid-template-columns: 1.3fr 1fr 1fr 1fr;
gap: 28px;
background: var(--paper-card, #fff);
}
.dark-mode .paper-trust-inner {
background: var(--admin-stat-bg);
}
.paper-trust-lede {
font-family: var(--font-serif);
font-size: 22px;
line-height: 1.25;
margin-top: 10px;
text-wrap: balance;
}
.paper-trust-item {
border-left: 1px solid var(--border-color);
padding-left: 20px;
}
.paper-trust-item .short {
font-family: var(--font-serif);
font-size: 26px;
letter-spacing: -0.01em;
}
.paper-trust-item .long {
font-size: 11.5px;
color: var(--ink-muted);
margin-top: 4px;
line-height: 1.4;
text-wrap: pretty;
}
@media (max-width: 767px) {
.paper-trust-inner {
grid-template-columns: 1fr;
gap: 16px;
padding: 20px;
}
.paper-trust-item {
border-left: none;
border-top: 1px solid var(--border-color);
padding-left: 0;
padding-top: 16px;
}
}
/* Legacy featurette / home-content left in place but restyled */
.home-content {
max-width: 900px;
}
.usage-steps {
font-size: 1.05rem;
line-height: 1.8;
padding-left: 1.2em;
}
.usage-example {
font-size: 0.9rem;
color: var(--ink-muted);
margin-top: 8px;
}
.featurette-lead {
font-size: 1.05rem;
line-height: 1.7;
color: var(--ink-soft);
}
/* Metrics grid */
.metrics-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
margin-bottom: 48px;
}
.metric-card {
text-align: center;
padding: 24px 16px;
border: 1px solid var(--border-color);
border-radius: 8px;
background: var(--admin-stat-bg);
}
.metric-value {
font-family: var(--font-serif);
font-size: 2.4rem;
font-weight: 400;
line-height: 1.1;
letter-spacing: -0.02em;
}
.metric-label {
font-family: var(--font-mono);
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--ink-muted);
margin-top: 6px;
}
.dropdown-menu {
background-color: var(--paper-card, var(--main-bg-color)) !important;
color: var(--color) !important;
border: 1px solid var(--border-color) !important;
border-radius: 8px !important;
box-shadow: 0 12px 28px rgba(26, 24, 21, 0.08), 0 2px 6px rgba(26, 24, 21, 0.05) !important;
padding: 6px !important;
font-family: var(--font-sans);
font-size: 13px;
min-width: 11rem;
}
.dropdown-menu .dropdown-item {
color: var(--color) !important;
padding: 7px 10px !important;
border-radius: 5px;
font-size: 13px;
}
.dropdown-menu .dropdown-item:hover,
.dropdown-menu .dropdown-item:focus {
background: var(--hover-bg-color) !important;
color: var(--color) !important;
}
.dropdown-menu .dropdown-divider {
border-top-color: var(--border-color) !important;
margin: 4px 2px;
}
.dropdown-menu .dropdown-header {
color: var(--ink-muted);
font-family: var(--font-mono);
font-size: 10.5px;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.body,
.file-content,
.markdown-body {
background-color: var(--main-bg-color) !important;
color: var(--color) !important;
}
.markdown-body table tr {
background-color: var(--main-bg-color);
border-top: 1px solid var(--border-color);
}
.markdown-body table tr:nth-child(2n) {
background-color: var(--paper-bg-alt);
}
.markdown-body table td,
.markdown-body table th {
border: 1px solid var(--border-color);
}
.file-content {
padding: 4px 7px;
text-align: left;
min-height: 100%;
}
.badge {
font-size: 75%;
font-weight: 500;
padding: 3px 8px;
border-radius: 10px;
vertical-align: middle;
}
.warning-feedback {
width: 100%;
margin-top: 0.25rem;
font-size: 80%;
color: #dc8e35;
}
.dropdown-item:focus,
.dropdown-item:hover {
background-color: var(--hover-bg-color);
}
.card-header .btn,
.card-header .btn:hover,
.card-header .btn:focus {
border: none !important;
background: transparent !important;
}
.btn {
color: var(--btn-color);
border: 1px solid var(--border-color);
background: transparent;
border-radius: 4px;
white-space: nowrap;
}
.btn:hover,
.btn:active {
color: var(--btn-color);
border: 1px solid var(--border-color);
background-color: var(--hover-bg-color);
box-shadow: none !important;
}
.btn.btn-primary {
color: var(--primary-color);
background-color: var(--primary-bg);
}
.btn.btn-primary:active,
.btn.btn-primary:hover {
color: var(--primary-active-color);
background-color: var(--primary-hover-bg) !important;
}
.btn::placeholder {
/* Chrome, Firefox, Opera, Safari 10.1+ */
color: var(--color);
opacity: 1;
/* Firefox */
}
.white_border {
border: 1px solid white;
color: white;
}
.leftCol {
display: flex;
position: relative;
flex: 0 0 auto;
width: 100%;
z-index: 9;
flex-direction: column;
}
.leftCol,
.sidePanel,
.card {
background-color: var(--sidebar-bg-color);
border: 1px solid var(--border-color);
}
@media (min-width: 768px) {
.leftCol {
flex: 0 0 310px;
width: 310px;
height: 100%;
}
}
/* ===== File tree search & header ===== */
.leftCol-search {
padding: 10px 12px 0;
}
.tree-search-box {
display: flex;
align-items: center;
gap: 8px;
background: var(--canvas-bg-color);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 7px 10px;
transition: border-color 0.15s;
}
.tree-search-box:focus-within {
border-color: var(--ink-muted);
}
.tree-search-icon {
font-size: 12px;
color: var(--ink-muted);
flex-shrink: 0;
}
.tree-search-input {
flex: 1;
border: none;
outline: none;
background: transparent;
font-family: var(--font-sans);
font-size: 13px;
color: var(--color);
min-width: 0;
}
.tree-search-input::placeholder {
color: var(--ink-muted);
}
.tree-search-kbd {
font-family: var(--font-sans);
font-size: 11px;
color: var(--ink-muted);
background: var(--paper-bg-alt);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 1px 6px;
line-height: 1.4;
flex-shrink: 0;
}
.tree-search-clear {
background: none;
border: none;
color: var(--ink-muted);
font-size: 16px;
cursor: pointer;
padding: 0 2px;
line-height: 1;
}
.tree-search-clear:hover { color: var(--color); }
.leftCol-project-header {
display: flex;
align-items: baseline;
justify-content: space-between;
padding: 12px 14px 4px;
gap: 8px;
}
.project-name {
font-family: var(--font-sans);
font-size: 13px;
font-weight: 600;
color: var(--color);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.project-file-count {
font-family: var(--font-sans);
font-size: 12px;
color: var(--ink-muted);
white-space: nowrap;
flex-shrink: 0;
}
/* ===== File tree ===== */
.files {
position: relative;
display: block;
overflow: auto;
height: 100%;
padding: 4px 6px;
}
.files ul {
list-style: none;
margin: 0;
padding: 0;
}
.files li ul {
padding-left: 8px;
margin-left: 7px;
border-left: 1px solid var(--border-color);
}
.files .folder > ul { display: none; }
.files .folder.open > ul { display: block; }
.files .file,
.files .folder {
position: relative;
color: var(--ink-soft);
cursor: pointer;
word-break: break-all;
}
.files a {
display: flex;
align-items: center;
gap: 4px;
padding: 1px 8px 1px 2px;
font-family: var(--font-sans);
font-size: 13px;
color: var(--ink-soft);
border-radius: 4px;
text-decoration: none;
line-height: 1.5;
position: relative;
}
.files a:hover {
background: var(--hover-bg-color);
color: var(--color);
text-decoration: none;
}
.files:focus { outline: none; }
.files a.tree-focused {
background: var(--hover-bg-color);
color: var(--color);
}
.files .file.active > a {
background: rgba(128, 128, 128, 0.15);
color: var(--color);
}
.files .file.active > a .tree-icon-file { background: #5B7BA5; }
.files .file.active > a .tree-count { color: var(--ink-muted); }
/* Tree icon shapes */
.tree-icon-folder,
.tree-icon-file {
display: inline-block;
flex-shrink: 0;
}
/* Collapsed folder: outlined square */
.tree-icon-folder {
width: 9px;
height: 9px;
border-radius: 2px;
background: transparent;
border: 1.2px solid var(--ink-muted);
opacity: 0.45;
}
/* Open folder: filled brown square */
.files .folder.open > a .tree-icon-folder {
background: #A07D2E;
border-color: #A07D2E;
opacity: 0.75;
}
.dark-mode .files .folder.open > a .tree-icon-folder {
background: #C9A03A;
border-color: #C9A03A;
}
.tree-icon-file {
width: 6px;
height: 6px;
background: #5B7BA5;
transform: rotate(45deg);
border-radius: 1px;
margin: 0 2px;
opacity: 0.7;
}
.dark-mode .tree-icon-file {
background: #7BA3D0;
}
/* Expand/collapse triangle */
.tree-toggle {
display: inline-flex;
align-items: center;
justify-content: center;
width: 10px;
height: 14px;
flex-shrink: 0;
opacity: 0.6;
}
.tree-toggle::after {
content: "";
display: block;
width: 0;
height: 0;
border-style: solid;
border-width: 3px 0 3px 4.5px;
border-color: transparent transparent transparent var(--ink-muted);
transition: transform 0.12s ease;
}
.files .folder.open > a .tree-toggle::after {
transform: rotate(90deg);
}
/* Spacer for nested files to align with folder contents (replaces the toggle arrow width) */
.tree-spacer {
display: inline-block;
width: 10px;
flex-shrink: 0;
}
/* File name and count */
.tree-name {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tree-count {
font-family: var(--font-sans);
font-size: 11px;
color: var(--ink-muted);
flex-shrink: 0;
margin-left: auto;
padding-left: 8px;
opacity: 0.7;
}
.files .folder > a {
color: var(--color);
}
/* Remove old Font Awesome icon pseudo-elements */
.files .file::before,
.files .folder::before {
display: none;
}
.files .folder > a::after {
display: none;
}
/* Search results */
.tree-search-path {
color: var(--ink-muted);
font-size: 11px;
}
.tree-search-empty {
padding: 16px 12px;
color: var(--ink-muted);
font-size: 12.5px;
font-family: var(--font-sans);
text-align: center;
}
/* ===== Explorer IDE chrome ===== */
.leftCol {
background: var(--paper-bg-alt, #F3F1EC);
border-right: 1px solid var(--border-color);
}
.dark-mode .leftCol { background: var(--sidebar-bg-color); }
.status-bar {
background: var(--canvas-bg-color);
border-bottom: 1px solid var(--border-color);
padding: 10px 14px;
}
.paths .breadcrumb-item,
.paths .breadcrumb-item a {
font-family: var(--font-mono);
font-size: 12px;
color: var(--ink-muted);
letter-spacing: 0.02em;
}
.paths .breadcrumb-item.active,
.paths .breadcrumb-item:last-child {
color: var(--color);
}
.paths .breadcrumb-item + .breadcrumb-item::before {
content: '/';
color: var(--ink-muted);
}
.last-update {
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--ink-muted);
padding: 8px 10px;
border-top: 1px solid var(--border-color);
letter-spacing: 0.02em;
}
.ace_editor {
height: 100%;
}
.ace_scroller {
cursor: default;
}
.status-bar {
display: flex;
align-items: center;
gap: 12px;
background-color: var(--canvas-bg-color);
padding: 10px 14px;
margin: 0;
border-bottom: 1px solid var(--border-color);
border-radius: 0;
flex-shrink: 0;
}
.status-bar-actions {
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
}
.status-bar-actions .btn {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--paper-card);
border: 1px solid var(--border-color);
color: var(--color);
border-radius: 6px;
padding: 4px 10px;
font-size: 12.5px;
min-height: 30px;
}
.status-bar-actions .btn:hover {
background: var(--hover-bg-color);
color: var(--color);
}
/* An action that is currently on, e.g. JS execution enabled for this file. */
.status-bar-actions .btn.btn-active {
border-color: currentColor;
font-weight: 600;
}
.paths {
flex: 1 1 auto;
min-width: 0;
padding: 0;
margin: 0;
background-color: initial;
border: none;
border-radius: 0;
align-items: center;
overflow-x: auto;
white-space: nowrap;
flex-wrap: nowrap;
}
.paths::-webkit-scrollbar { display: none; }
.paths a {
color: var(--color);
}
.paths .breadcrumb-item {
padding-left: 3px;
}
.paths .breadcrumb-item::before {
padding-right: 3px;
}
.content {
height: 100%;
overflow: scroll;
padding-top: 42px;
background-color: var(--main-bg-color);
text-align: center;
}
.image-content {
max-width: 100%;
max-height: 100%;
text-align: center;
padding: 4px;
}
/* Rendered PDF: a toolbar above a scrolling column of pages. */
.pdf-viewer {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
background-color: var(--main-bg-color);
}
.pdf-toolbar {
display: flex;
align-items: center;
gap: 4px;
flex: 0 0 auto;
padding: 4px 8px;
border-bottom: 1px solid var(--border-color, rgba(0, 0, 0, 0.12));
}
.pdf-toolbar-group {
display: inline-flex;
align-items: center;
gap: 4px;
}
.pdf-toolbar-right {
margin-left: auto;
}
.pdf-toolbar-btn {
border: 0;
background: none;
color: inherit;
padding: 4px 8px;
border-radius: 4px;
font-size: 13px;
line-height: 1.2;
cursor: pointer;
}
.pdf-toolbar-btn:hover:not(:disabled) {
background-color: rgba(128, 128, 128, 0.18);
}
.pdf-toolbar-btn:disabled {
opacity: 0.4;
cursor: default;
}
.pdf-toolbar-zoom {
min-width: 52px;
font-variant-numeric: tabular-nums;
}
.pdf-toolbar-page {
width: 3.5em;
text-align: right;
padding: 2px 4px;
font-size: 13px;
color: inherit;
background: none;
border: 1px solid var(--border-color, rgba(0, 0, 0, 0.2));
border-radius: 4px;
}
.pdf-toolbar-count {
font-size: 13px;
opacity: 0.75;
font-variant-numeric: tabular-nums;
}
.pdf-pages {
flex: 1 1 auto;
min-height: 0;
overflow: auto;
padding: 8px 0;
}
.pdf-viewer-page {
/* Sized to the page's aspect ratio while empty so the scrollbar is honest
and only on-screen pages get rasterised; the canvas takes over once the
page renders. */
margin: 0 auto 12px;
}
.pdf-viewer-page canvas {
display: block;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
.pdf-viewer-error {
padding: 24px;
text-align: center;
font-weight: bold;
}
/* Rendered HTML document. Always light: the document brings its own styling
and dark mode can't reach inside a cross-origin frame to adapt it. */
.html-doc {
display: block;
height: 100%;
}
.html-doc-frame {
display: block;
width: 100%;
height: 100%;
border: 0;
background-color: #fff;
}
.file-error {
font-weight: bold;
font-size: 50px;
text-align: center;
}
pdfviewer {
display: block;
padding: 15px;
}
pdfpageviewer {
display: block;
width: 100%;
margin-bottom: 10px;
}
notebook {
display: block;
text-align: left;
padding: 15px;
}
@media (min-width: 768px) {
notebook {
padding-left: 100px;
}
}
.nb-output th,
.nb-output td {
border: 1px solid var(--border-color) !important;
}
.floatingchat-container-wrap {
left: auto !important;
top: auto !important;
bottom: 3px !important;
height: 47px !important;
right: 3px !important;
}
.floating-chat-kofi-popup-iframe {
left: auto !important;
top: auto !important;
bottom: 55px !important;
right: 10px !important;
}
/* ===== Paper FAQ (two-col editorial) ===== */
.paper-faq {
max-width: 1180px;
margin: 0 auto;
padding: 48px 32px 80px;
font-family: var(--font-sans);
}
.paper-faq-hero {
padding-bottom: 40px;
border-bottom: 1px solid var(--border-color);
margin-bottom: 36px;
}
.paper-faq-eyebrow {
font-family: var(--font-mono);
font-size: 11px;
color: var(--ink-muted);
letter-spacing: 0.14em;
text-transform: uppercase;
margin-bottom: 32px;
}
.paper-faq-title {
font-family: var(--font-serif);
font-weight: 400;
font-size: clamp(2.6rem, 5.5vw, 4.6rem);
line-height: 1.03;
letter-spacing: -0.02em;
color: var(--color);
margin: 0 0 22px;
max-width: 14em;
}
.paper-faq-title em { font-style: italic; color: var(--color); }
.paper-faq-lede {
color: var(--ink-soft);
font-size: 17px;
line-height: 1.55;
max-width: 38em;
margin: 0;
}
.paper-faq-lede a { color: var(--color); border-bottom: 1px solid var(--color); }
.paper-faq-lede a:hover { color: var(--accent); border-bottom-color: var(--accent); }
.paper-faq-body {
display: grid;
grid-template-columns: 220px 1fr;
gap: 60px;
align-items: start;
}
.paper-faq-toc {
position: sticky;
top: 32px;
font-size: 13.5px;
}
.paper-faq-toc-head {
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--ink-muted);
letter-spacing: 0.14em;
text-transform: uppercase;
padding-bottom: 10px;
margin-bottom: 6px;
border-bottom: 1px solid var(--border-color);
}
.paper-faq-toc nav {
display: flex;
flex-direction: column;
}
.paper-faq-toc nav a {
color: var(--ink-soft);
padding: 8px 0 8px 14px;
border-left: 2px solid transparent;
text-decoration: none;
margin-left: -2px;
}
.paper-faq-toc nav a:hover,
.paper-faq-toc nav a.active {
color: var(--color);
border-left-color: var(--color);
}
.faq-section {
min-width: 0;
}
.faq-section > div {
width: 100%;
}
.faq-section h4.faq-cat {
font-family: var(--font-serif);
font-weight: 400;
font-size: clamp(1.7rem, 2.6vw, 2.2rem);
letter-spacing: -0.015em;
color: var(--color);
margin: 0 0 6px;
padding-bottom: 14px;
border-bottom: 1px solid var(--border-color);
}
.faq-section h4.faq-cat i { display: none; }
.faq-section .panel-group { margin-bottom: 56px; }
.faq-section .panel-default .panel-title a {
display: block;
position: relative;
padding: 22px 0 22px 42px;
font-family: var(--font-serif);
font-weight: 400;
font-size: 20px;
line-height: 1.35;
letter-spacing: -0.005em;
color: var(--color);
text-decoration: none;
cursor: pointer;
}
.faq-section .panel-default .panel-title a:hover {
color: var(--accent);
}
.faq-section .panel-heading {
background: transparent;
padding: 0 !important;
border: none;
}
.faq-section .panel-default {
background: transparent;
border: none;
border-bottom: 1px solid var(--border-soft);
border-radius: 0;
margin-bottom: 0 !important;
box-shadow: none;
}
.faq-section .panel-default .panel-title {
margin-bottom: 0;
}
.faq-section .panel-default .panel-title a:after {
content: "";
position: absolute;
left: 0;
right: auto;
top: 22px;
transform: none;
font-family: var(--font-mono);
font-size: 18px;
line-height: 1.35;
color: var(--ink-muted);
float: none;
margin: 0;
font-weight: 400;
}
.faq-section .panel-default .panel-title a.collapsed:after {
content: "+";
}
.faq-section .panel-default .panel-body {
padding: 0 0 22px 42px !important;
color: var(--ink-soft);
font-size: 15px;
line-height: 1.65;
border-top: none;
max-width: 42em;
}
.table {
color: var(--color);
}
.table td,
.table th,
hr,
.dropdown-divider {
border-color: var(--border-color);
}
.table.repositories td {
word-break: break-word;
}
loc {
display: block;
position: relative;
width: 100%;
height: 5px;
}
loc .lang {
float: left;
height: 100%;
}
.rounded-circle.fa {
display: inline-block;
font-size: 75px;
height: 140px;
width: 140px;
border: 4px solid;
line-height: 140px;
text-align: center;
}
.featurette-divider {
margin: 4.5rem 0;
border-color: var(--border-color);
}
/* Featurette headings */
.featurette-heading {
font-family: var(--font-serif);
font-weight: 400;
font-size: 2rem;
line-height: 1.15;
letter-spacing: -0.02em;
margin-bottom: 14px;
color: var(--color);
}
.dark-mode .shadow {
box-shadow: none;
}
.dark-mode .overflow-auto::-webkit-scrollbar {
width: 10px;
}
.dark-mode .overflow-auto::-webkit-scrollbar-track {
-webkit-box-shadow: none;
background: inherit;
border-radius: 0;
}
.dark-mode .overflow-auto::-webkit-scrollbar-thumb {
border-radius: 10px;
border: 1px solid var(--border-color);
background-color: var(--hover-bg-color);
}
.dark-mode .rgba-gradient {
background: linear-gradient(135deg, #2a2d4a, #151728);
}
.section-number {
padding-right: 10px;
font-weight: bold;
font-style: italic;
}
.org-subscript-child {
font-size: 85%;
}
.highlighted-line {
position: absolute;
background: rgba(100, 200, 100, 0.5);
z-index: 20
}
pre,
code {
font-family: "Fira Code", "Courier New", Courier, monospace;
line-height: 1.1;
color: var(--color)
}
.diff-lines,
.diff-file,
.diff-index {
background: rgba(172, 172, 172, 0.5);
}
.diff-add {
background: rgba(100, 200, 100, 0.5);
}
.diff-remove {
background: rgba(200, 100, 100, 0.5);
}
/* ===== Dashboard & List Styles ===== */
.dashboard-title {
font-size: 1.4rem;
font-weight: 600;
letter-spacing: -0.01em;
}
/* Quota bars */
.quota-row {
display: flex;
gap: 16px;
margin-bottom: 16px;
padding: 0;
}
.quota-item {
flex: 1;
min-width: 0;
}
.quota-header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 4px;
}
.quota-label {
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.3px;
opacity: 0.7;
}
.quota-value {
font-size: 0.8rem;
font-weight: 500;
font-variant-numeric: tabular-nums;
}
.quota-progress {
height: 6px;
border-radius: 3px;
background: var(--hover-bg-color);
}
.quota-progress .progress-bar {
border-radius: 3px;
}
/* Filter chips */
.filter-chip {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 10px;
font-size: 0.8rem;
font-weight: 500;
background: var(--primary-bg);
color: var(--primary-color);
border-radius: 12px;
line-height: 1.4;
}
.filter-chip-close {
display: inline-flex;
align-items: center;
justify-content: center;
background: none;
border: none;
color: inherit;
opacity: 0.7;
cursor: pointer;
padding: 0;
/* 24px tap target; negative margin keeps the chip visually compact */
min-width: 24px;
min-height: 24px;
margin: -6px -6px -6px 0;
font-size: 1rem;
line-height: 1;
border-radius: 999px;
}
.filter-chip-close:hover {
opacity: 1;
}
/* Repository/PR list */
.repo-list {
list-style: none;
padding: 0;
margin: 0;
}
.repo-list-item {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 16px 0;
border-bottom: 1px solid var(--border-color);
gap: 12px;
}
.repo-list-item:first-child {
border-top: 1px solid var(--border-color);
}
.repo-list-item.repo-inactive {
opacity: 0.6;
}
.repo-list-item-content {
flex: 1;
min-width: 0;
}
.repo-list-item-header {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
margin-bottom: 4px;
}
.repo-name {
font-family: var(--font-mono);
font-size: 14px;
font-weight: 500;
color: var(--color);
word-break: break-word;
}
.repo-name:hover {
color: var(--accent);
}
.repo-source {
font-size: 0.85rem;
opacity: 0.8;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
}
.repo-date {
opacity: 0.7;
}
.repo-meta {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 8px;
font-size: 0.8rem;
opacity: 0.7;
}
.repo-meta span {
display: inline-flex;
align-items: center;
gap: 4px;
white-space: nowrap;
}
.repo-list-item-actions {
flex-shrink: 0;
padding-top: 2px;
margin-left: 14px;
}
.repo-list-empty {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 48px 20px;
opacity: 0.5;
font-size: 0.95rem;
list-style: none;
border-bottom: 1px solid var(--border-color);
border-top: 1px solid var(--border-color);
}
.repo-list-empty i {
font-size: 1.8rem;
}
/* Type badges (Repo / PR) */
.type-badge {
display: inline-flex;
align-items: center;
gap: 3px;
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.3px;
padding: 2px 8px;
border-radius: 4px;
white-space: nowrap;
}
.type-badge {
font-family: var(--font-mono);
letter-spacing: 0.06em;
padding: 2px 8px;
border-radius: 999px;
border: 1px solid var(--border-color);
background: var(--paper-bg-alt, transparent);
}
.type-badge.type-repo,
.type-badge.type-pr {
background: var(--paper-bg-alt);
color: var(--ink-muted);
border-color: var(--border-color);
}
.dark-mode .type-badge.type-repo,
.dark-mode .type-badge.type-pr {
background: rgba(255, 255, 255, 0.06);
color: var(--ink-muted);
border-color: var(--border-color);
}
.type-badge.type-coauthor {
background: rgba(99, 102, 241, 0.12);
color: #4f46e5;
border-color: rgba(99, 102, 241, 0.35);
margin-left: 6px;
}
.dark-mode .type-badge.type-coauthor {
background: rgba(129, 140, 248, 0.18);
color: #a5b4fc;
border-color: rgba(165, 180, 252, 0.45);
}
/* Type filter button group */
.btn-group .btn:not(.btn-primary) {
background: var(--hover-bg-color);
}
/* ===== Anonymize Page Layout ===== */
/* Landing state: centered URL input */
.anonymize-landing {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
padding: 20px;
}
.anonymize-landing-inner {
width: 100%;
max-width: 600px;
}
.anonymize-landing-inner h2 {
font-weight: 700;
}
/* Anonymize workspace: topbar + split */
.anonymize-workspace {
display: flex;
flex-direction: column;
height: 100%;
background: var(--canvas-bg-color);
}
.anonymize-topbar {
background: var(--paper-card);
border-bottom: 1px solid var(--border-color);
padding: 18px 28px;
flex: 0 0 auto;
}
.anonymize-topbar-inner { max-width: 1400px; margin: 0 auto; }
.anonymize-topbar-head {
display: flex;
align-items: center;
gap: 14px;
flex-wrap: wrap;
}
.anonymize-topbar-title {
margin: 4px 0 0;
font-size: clamp(1.8rem, 3vw, 2.4rem);
}
.anonymize-split {
flex: 1 1 auto;
display: flex;
min-height: 0;
}
/* Form column (left) */
.anonymize-form-col {
flex: 0 0 auto;
width: 100%;
min-width: 0;
background: var(--canvas-bg-color);
border-right: 1px solid var(--border-color);
overflow-y: auto;
}
.anonymize-form-col .paper-settings-main {
max-width: 720px;
padding: 28px 32px 40px;
margin: 0;
}
.anonymize-form-col .paper-settings-section:first-child { padding-top: 0; }
.anonymize-form-col .anonymize-submit-bar {
position: sticky;
bottom: 0;
background: var(--canvas-bg-color);
padding: 14px 0 0;
border-top: 1px solid var(--border-color);
margin-top: 20px;
}
.anonymize-form-col .anonymize-submit-bar .btn { width: 100%; padding: 12px 16px; font-size: 15px; }
/* Preview column */
.anonymize-preview-col {
flex: 1 1 auto;
min-width: 0;
overflow: auto;
background: var(--paper-bg-alt);
padding: 28px 32px;
}
.anonymize-preview-head {
display: flex;
align-items: baseline;
gap: 12px;
padding-bottom: 12px;
border-bottom: 1px solid var(--border-color);
margin-bottom: 20px;
}
.anonymize-preview-head .paper-eyebrow {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
}
.anonymize-preview-sub { color: var(--ink-soft); font-size: 13px; }
.anonymize-preview-body {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 28px 32px;
}
/* Form grids for paired fields */
.form-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-grid-3 { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 16px; }
@media (max-width: 700px) {
.form-grid-2, .form-grid-3 { grid-template-columns: 1fr; }
}
.paper-optional {
font-family: var(--font-sans);
font-weight: 400;
color: var(--ink-muted);
text-transform: none;
letter-spacing: 0;
font-size: 11px;
margin-left: 6px;
}
/* Plan cards */
.paper-plan-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 14px;
}
.paper-plan-card {
position: relative;
display: block;
padding: 18px 20px;
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
cursor: pointer;
transition: border-color 0.15s ease, box-shadow 0.15s ease;
margin: 0;
}
.paper-plan-card input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.paper-plan-card.selected {
border-color: var(--color);
box-shadow: 0 0 0 2px var(--color) inset;
}
.paper-plan-head {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
}
.paper-plan-price {
font-family: var(--font-serif);
font-size: 2rem;
color: var(--color);
margin: 6px 0 4px;
}
.paper-plan-price .paper-plan-per { font-family: var(--font-sans); font-size: 12px; color: var(--ink-soft); }
.paper-plan-desc { font-size: 13px; color: var(--ink-soft); }
.paper-plan-desc ul { padding-left: 18px; margin: 0; }
.paper-settings-copy { color: var(--ink-soft); font-size: 13px; margin: 0 0 14px; }
.anonymize-section-title {
font-size: 0.85rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.3px;
margin: 18px 0 8px 0;
padding-bottom: 6px;
border-bottom: 1px solid var(--border-color);
opacity: 0.7;
}
.anonymize-section-title i {
margin-right: 4px;
}
.anonymize-submit-bar {
padding: 12px 0 4px 0;
}
.anonymize-submit-bar .btn {
font-size: 1rem;
padding: 10px 20px;
font-weight: 600;
}
.anonymize-page .form-check {
padding-top: 4px;
padding-bottom: 4px;
}
.anonymize-page .form-check-label {
font-weight: 500;
}
/* Preview column on desktop */
.anonymize-preview-col {
min-height: 0;
min-width: 0;
}
/* PR diff overflow */
.pr-diff pre {
overflow-x: auto;
max-width: 100%;
}
@media (min-width: 768px) {
.anonymize-form-col {
height: 100%;
width: 520px;
flex: 0 0 520px;
}
.anonymize-preview-col {
height: 100%;
flex: 1;
}
}
/* Mobile: stack form above preview, tighten paddings */
@media (max-width: 767px) {
.anonymize-workspace { height: auto; min-height: 100%; }
.anonymize-topbar { padding: 14px 16px; }
.anonymize-topbar-title { font-size: 1.6rem; margin-top: 2px; }
.anonymize-split {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-height: 0;
}
.anonymize-form-col {
width: 100% !important;
flex: 0 0 auto !important;
height: auto !important;
border-right: none;
border-bottom: 1px solid var(--border-color);
overflow: visible;
}
.anonymize-form-col .paper-settings-main {
padding: 18px 16px 24px;
max-width: none;
}
.anonymize-form-col .anonymize-submit-bar {
position: sticky;
bottom: 0;
margin: 20px -16px 0;
padding: 12px 16px;
background: var(--canvas-bg-color);
border-top: 1px solid var(--border-color);
z-index: 10;
}
.anonymize-form-col .anonymize-submit-bar .btn {
width: 100%;
padding: 12px 16px;
font-size: 15px;
}
.anonymize-preview-col {
width: 100%;
flex: 0 0 auto;
height: auto !important;
max-height: none;
padding: 18px 16px 24px;
overflow: visible;
}
.anonymize-preview-body {
padding: 16px;
border-radius: 8px;
}
.anonymize-preview-body pre,
.anonymize-preview-body .pr-diff pre {
overflow-x: auto;
max-width: 100%;
}
.anonymize-landing-inner { padding: 16px; }
}
@media (min-width: 1280px) {
.anonymize-form-col {
width: 620px;
flex: 0 0 620px;
}
}
/* ===== Mobile Responsive Improvements ===== */
/* Mobile-friendly touch targets */
@media (max-width: 767px) {
.btn {
min-height: 38px;
padding: 6px 14px;
font-size: 14px;
}
.btn-sm {
min-height: 34px;
padding: 5px 10px;
}
.navbar .nav-link {
padding: 8px 12px;
}
.navbar .nav-link .fa,
.navbar .nav-link .fab {
font-size: 24px;
line-height: 32px;
}
.container.page {
padding-left: 15px;
padding-right: 15px;
max-width: 100%;
}
h1 { font-size: 1.6rem; }
h2 { font-size: 1.35rem; }
h3 { font-size: 1.15rem; }
/* Dashboard list items */
.repo-list-item {
flex-direction: column;
}
.repo-list-item-actions {
align-self: flex-start;
}
/* Quota row stacks on mobile */
.quota-row {
flex-direction: column;
gap: 10px;
padding: 10px 12px;
}
/* Dropdown menus right-aligned on mobile */
.dropdown-menu {
position: absolute;
right: 0;
left: auto;
}
/* Form controls spacing */
.form-group {
margin-bottom: 12px;
}
.form-control {
font-size: 16px; /* Prevents iOS zoom */
}
/* Status bar wrapping */
.status-bar {
gap: 6px;
padding: 8px 10px;
}
.status-bar .btn {
font-size: 12px;
padding: 4px 10px;
min-height: 32px;
}
.status-bar .paths {
font-size: 11.5px;
overflow-x: auto;
flex-wrap: nowrap;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
}
.status-bar .paths::-webkit-scrollbar { display: none; }
.status-bar-actions {
flex-shrink: 0;
gap: 4px;
}
/* Home hero section */
#home .display-4 {
font-size: 1.8rem;
}
#home h4.subtext-header {
font-size: 1rem;
}
/* Progress bars on dashboard */
.progress:not(.quota-progress) {
min-width: 120px !important;
}
/* Badge readability */
.badge {
font-size: 70%;
}
/* Search & filter toolbar */
.col-2.input-group {
width: 100% !important;
max-width: 100%;
flex: 0 0 100%;
}
/* Metadata spans wrapping */
.color-text-secondary span {
display: inline-block;
margin-bottom: 2px;
}
/* Ko-fi widget hidden on mobile */
.floatingchat-container-wrap {
display: none !important;
}
/* Metrics cards on mobile */
.metrics-grid {
grid-template-columns: 1fr;
gap: 10px;
}
.metric-value {
font-size: 1.5rem;
}
.hero-title {
font-size: 1.8rem;
}
.hero-subtitle {
font-size: 0.95rem;
}
/* ---- Anonymize page mobile ---- */
.anonymize-landing {
align-items: flex-start;
padding-top: 60px;
}
.anonymize-page .container-fluid > .row {
height: auto !important;
min-height: 100%;
}
.anonymize-form-col {
width: 100% !important;
flex: 0 0 100% !important;
border-right: none;
border-top: 1px solid var(--border-color);
}
.anonymize-preview-col {
height: auto !important;
max-height: none;
}
.anonymize-section-title {
font-size: 0.8rem;
margin: 12px 0 8px 0;
}
.anonymize-submit-bar {
position: sticky;
bottom: 0;
background: var(--sidebar-bg-color);
padding: 10px 0;
margin: 0 -12px;
padding-left: 12px;
padding-right: 12px;
border-top: 1px solid var(--border-color);
z-index: 10;
}
.anonymize-submit-bar .btn {
font-size: 1rem;
padding: 12px 20px;
}
/* Compact checkboxes on mobile */
.anonymize-page .form-check {
padding-top: 6px;
padding-bottom: 6px;
min-height: 36px;
}
.anonymize-page .form-check-label {
font-size: 0.95rem;
}
.anonymize-page .card-body {
padding: 12px;
}
/* PR preview on mobile */
.pr-title {
font-size: 1.15rem;
}
.pr-diff pre {
font-size: 0.75rem;
}
.pr-comment .mb-1 h5 {
font-size: 1rem;
}
.nav-tabs .nav-link {
padding: 8px 12px;
font-size: 0.9rem;
}
}
/* Tablet tweaks */
@media (min-width: 768px) and (max-width: 991px) {
.container.page {
max-width: 100%;
padding-left: 15px;
padding-right: 15px;
}
.leftCol {
flex: 0 0 250px;
width: 250px;
}
}
/* ===== Explorer page (paper) ===== */
.explorer-page {
display: flex;
height: 100%;
width: 100%;
background: var(--canvas-bg-color);
position: relative;
}
.explorer-main {
flex: 1 1 auto;
min-width: 0;
display: flex;
flex-direction: column;
overflow: hidden;
background: var(--canvas-bg-color);
}
.explorer-content {
flex: 1 1 auto;
min-height: 0;
width: 100%;
overflow: auto;
}
.leftCol-head,
.leftCol-close {
display: none;
}
.leftCol-body {
flex: 1 1 auto;
min-height: 0;
overflow: auto;
}
.leftCol-foot {
padding: 8px 12px;
border-top: 1px solid var(--border-color);
background: var(--paper-bg-alt);
}
.leftCol-foot .last-update {
border-top: none;
padding: 0;
}
.leftCol-backdrop { display: none; }
.paper-inline-warning {
display: flex;
align-items: flex-start;
gap: 8px;
margin: 8px;
padding: 10px 12px;
background: rgba(138, 107, 30, 0.08);
border: 1px solid rgba(138, 107, 30, 0.35);
border-radius: 8px;
color: var(--color);
font-size: 12.5px;
line-height: 1.4;
}
.paper-inline-warning i { color: #8A6B1E; margin-top: 2px; flex-shrink: 0; }
.dark-mode .paper-inline-warning i { color: #FFD37A; }
@media (min-width: 768px) {
.leftCol-body { padding: 8px 4px; }
}
/* Mobile / tablet toggle */
.sidebar-toggle {
display: none;
align-items: center;
gap: 8px;
position: fixed;
bottom: 18px;
right: 18px;
z-index: 1100;
padding: 10px 14px;
background: var(--color);
color: var(--canvas-bg-color);
border: 1px solid var(--color);
border-radius: 999px;
font-family: var(--font-sans);
font-size: 13px;
font-weight: 500;
box-shadow: 0 6px 20px rgba(0,0,0,0.15);
cursor: pointer;
outline: none;
}
.sidebar-toggle:hover { background: var(--primary-hover-bg); }
.sidebar-toggle:focus,
.sidebar-toggle:focus-visible { outline: none; box-shadow: 0 6px 20px rgba(0,0,0,0.15); }
@media (max-width: 991px) {
.sidebar-toggle { display: inline-flex; }
/* Move Ko-fi widget to the left to avoid clashing with the Files button */
.floatingchat-container-wrap {
left: 3px !important;
right: auto !important;
}
.floating-chat-kofi-popup-iframe {
left: 10px !important;
right: auto !important;
}
/* Sidebar becomes a slide-in drawer */
.leftCol {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: min(86vw, 340px);
max-width: 340px;
z-index: 1200;
border: none;
border-right: 1px solid var(--border-color);
transform: translateX(0);
transition: transform 0.22s ease;
box-shadow: 4px 0 24px rgba(0,0,0,0.18);
background: var(--sidebar-bg-color);
}
.leftCol.collapsed {
transform: translateX(-105%);
box-shadow: none;
pointer-events: none;
}
.leftCol-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 14px;
border-bottom: 1px solid var(--border-color);
background: var(--paper-bg-alt);
}
.leftCol-eyebrow {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
}
.leftCol-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 0;
background: transparent;
border: 1px solid var(--border-color);
border-radius: 8px;
color: var(--ink-muted);
cursor: pointer;
}
.leftCol-close:hover { color: var(--color); border-color: var(--color); }
.leftCol-foot { display: block; }
.leftCol-body { padding: 4px 0; }
.leftCol-backdrop {
display: block;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.32);
z-index: 1150;
backdrop-filter: blur(2px);
}
.dark-mode .leftCol-backdrop { background: rgba(0,0,0,0.5); }
}
/* ===== Admin Interface (Paper style) ===== */
.admin-nav {
display: flex;
gap: 4px;
padding: 4px;
margin: 8px 0 20px;
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
flex-wrap: wrap;
}
.admin-nav a {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 14px;
border-radius: 7px;
color: var(--ink-muted);
text-decoration: none;
font-family: var(--font-mono);
font-size: 11.5px;
font-weight: 500;
letter-spacing: 0.06em;
text-transform: uppercase;
transition: background-color 0.15s, color 0.15s;
white-space: nowrap;
}
.admin-nav a:hover {
background: var(--paper-bg-alt);
color: var(--color);
}
.admin-nav a.active {
background: var(--color);
color: var(--paper-card);
}
.admin-nav a i {
font-size: 12px;
width: 14px;
text-align: center;
}
@media (max-width: 767px) {
.admin-nav {
flex-direction: column;
}
.admin-nav a {
justify-content: flex-start;
}
}
/* Admin stat cards — compact, denser packing for many KPIs */
.admin-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 8px;
margin-bottom: 16px;
}
.admin-stat-card {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 10px 12px;
}
.admin-stat-card .stat-value {
font-family: var(--font-serif);
font-size: 1.4rem;
font-weight: 400;
line-height: 1.1;
color: var(--color);
}
.admin-stat-card .stat-label {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--ink-muted);
text-transform: uppercase;
letter-spacing: 0.08em;
margin-top: 4px;
}
/* Admin toolbar — kept as alias to dashboard filter row */
.admin-toolbar {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
margin: 16px 0 12px;
}
.admin-toolbar .form-control {
max-width: 320px;
}
@media (max-width: 767px) {
.admin-toolbar .form-control {
max-width: 100%;
width: 100%;
}
}
.pagination-compact {
display: inline-flex;
align-items: center;
gap: 6px;
flex-wrap: nowrap;
font-family: var(--font-mono);
font-size: 12px;
color: var(--ink-muted);
}
.pagination-compact input {
width: 60px;
text-align: center;
flex-shrink: 0;
}
.pagination-compact .btn {
padding: 4px 10px;
min-height: 34px;
background: var(--paper-card);
border: 1px solid var(--border-color);
color: var(--color);
flex-shrink: 0;
}
.pagination-compact > span {
white-space: nowrap;
}
/* Admin list items */
.admin-list-item {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 12px 0;
border-bottom: 1px solid var(--border-color);
}
.admin-list-item:last-child {
border-bottom: none;
}
.admin-list-item .item-main {
flex: 1;
min-width: 0;
}
.admin-list-item .item-title {
font-size: 1rem;
font-weight: 600;
margin-bottom: 4px;
word-break: break-word;
}
.admin-list-item .item-meta {
font-size: 0.85rem;
opacity: 0.8;
}
.admin-list-item .item-meta span {
margin-right: 12px;
display: inline-block;
margin-bottom: 2px;
}
.admin-list-item .item-actions {
flex-shrink: 0;
}
@media (max-width: 767px) {
.admin-list-item {
flex-direction: column;
gap: 8px;
}
.admin-list-item .item-actions {
align-self: flex-start;
}
}
/* Status badge improvements */
.status-badge {
display: inline-block;
font-size: 11px;
font-weight: 600;
padding: 2px 8px;
border-radius: 10px;
text-transform: uppercase;
letter-spacing: 0.3px;
vertical-align: middle;
}
.status-badge {
font-family: var(--font-sans);
font-weight: 500;
letter-spacing: 0.02em;
border: 1px solid transparent;
text-transform: none;
font-size: 11.5px;
padding: 1px 9px 2px;
border-radius: 999px;
}
.status-badge.status-ready {
background: #E8F3EC;
color: #2F7A44;
border-color: #CFE6D6;
}
.status-badge.status-error {
background: #FBE7E7;
color: #B42318;
border-color: #F3C7C7;
}
.status-badge.status-preparing,
.status-badge.status-download {
background: #EEF0FF;
color: #3B4AD6;
border-color: #D4D8FA;
}
.status-badge.status-expired,
.status-badge.status-removed,
.status-badge.status-removing,
.status-badge.status-expiring {
background: var(--paper-bg-alt);
color: var(--ink-muted);
border-color: var(--border-color);
}
.status-badge.status-active {
background: #E8F3EC;
color: #2F7A44;
border-color: #CFE6D6;
}
/* Admin queue job cards */
.queue-job-card {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 16px 18px;
margin-bottom: 10px;
}
.queue-job-card .job-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
flex-wrap: wrap;
gap: 8px;
}
.queue-job-card .job-id {
font-family: var(--font-mono);
font-size: 0.95rem;
color: var(--color);
word-break: break-all;
display: flex;
align-items: center;
gap: 10px;
}
.queue-job-card .job-timestamps {
font-family: var(--font-mono);
font-size: 11.5px;
color: var(--ink-muted);
display: flex;
flex-wrap: wrap;
gap: 14px;
}
.queue-job-card .job-actions {
display: flex;
gap: 8px;
margin-top: 10px;
}
.queue-job-card .job-actions .btn {
font-size: 12px;
padding: 4px 12px;
background: var(--paper-card);
border: 1px solid var(--border-color);
color: var(--color);
}
/* Admin section headers */
.admin-section-header {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
margin: 24px 0 12px;
padding-bottom: 8px;
border-bottom: 1px solid var(--border-color);
}
.admin-section-header h2 {
margin: 0;
font-family: var(--font-mono);
font-size: 11px;
font-weight: 500;
color: var(--ink-muted);
text-transform: uppercase;
letter-spacing: 0.08em;
}
.admin-section-header h2 i {
margin-right: 6px;
color: var(--ink-muted);
}
.admin-section-header .section-count {
background: var(--paper-bg-alt);
color: var(--ink-muted);
border: 1px solid var(--border-color);
font-family: var(--font-mono);
font-size: 11px;
padding: 1px 10px;
border-radius: 999px;
}
/* User detail card */
.user-detail-card {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 22px;
margin-bottom: 24px;
}
.user-detail-card .user-header {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 18px;
padding-bottom: 16px;
border-bottom: 1px solid var(--border-color);
flex-wrap: wrap;
}
.user-detail-card .user-header img {
border-radius: 50%;
}
.user-detail-card .user-header h1 {
margin: 0;
font-family: var(--font-serif);
font-weight: 400;
font-size: 1.6rem;
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
.user-detail-grid {
display: grid;
grid-template-columns: 160px 1fr;
gap: 10px 20px;
font-size: 0.92rem;
}
.user-detail-grid .detail-label {
font-family: var(--font-mono);
font-size: 10.5px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--ink-muted);
white-space: nowrap;
padding-top: 2px;
}
.user-detail-grid .detail-value {
word-break: break-all;
color: var(--color);
}
@media (max-width: 767px) {
.user-detail-grid {
grid-template-columns: 1fr;
}
.user-detail-grid .detail-label {
margin-top: 8px;
border-top: 1px solid var(--border-color);
padding-top: 8px;
}
.user-detail-grid .detail-label:first-child {
border-top: none;
margin-top: 0;
padding-top: 0;
}
}
/* ===== Paper empty/error states ===== */
.paper-empty {
min-height: calc(100vh - 60px);
display: flex;
align-items: center;
justify-content: center;
padding: 40px 24px;
}
.paper-empty-inner {
max-width: 560px;
text-align: left;
}
.paper-empty-title {
font-family: var(--font-serif);
font-weight: 400;
font-size: clamp(2.4rem, 6vw, 4.4rem);
line-height: 1.02;
letter-spacing: -0.025em;
margin: 18px 0 20px;
color: var(--color);
}
.paper-empty-title em {
color: var(--accent);
font-style: italic;
}
.paper-empty-lede {
font-size: 17px;
line-height: 1.55;
color: var(--ink-soft);
text-wrap: pretty;
}
.paper-empty-cta {
display: flex;
gap: 10px;
margin-top: 28px;
flex-wrap: wrap;
}
/* ===== Paper page chrome ===== */
.paper-page {
max-width: 1100px;
margin: 0 auto;
padding: 32px 32px 80px;
}
@media (max-width: 991px) {
.paper-page,
.paper-page.container,
.paper-page.container-fluid { padding: 20px 18px 60px !important; }
.paper-page .row { margin-left: 0; margin-right: 0; }
.paper-page .row > [class*='col'],
.paper-page .row > .w-100 { padding-left: 0; padding-right: 0; }
/* Navbar drawer (mobile + tablet — navbar-expand-lg collapses <992px) */
.navbar.navbar-expand-lg {
padding: 10px 18px !important;
}
.navbar .navbar-collapse {
margin: 10px -18px 0;
padding: 12px 18px 16px;
border-top: 1px solid var(--border-color);
background: var(--header-bg-color);
}
.navbar .navbar-nav {
align-items: stretch !important;
gap: 2px;
}
.navbar .navbar-nav .nav-item,
.navbar .navbar-nav .nav-link {
width: 100%;
}
.navbar .nav-link {
display: flex !important;
align-items: center;
justify-content: flex-start;
margin: 0 !important;
padding: 12px 4px !important;
border-bottom: 1px solid var(--border-color) !important;
border-radius: 0;
font-size: 14px;
line-height: 1.2;
gap: 0;
min-height: 44px;
box-sizing: border-box;
}
.navbar .nav-link:not(.btn-signin):not(.user-chip) {
color: var(--color) !important;
}
.navbar .nav-link .fas,
.navbar .nav-link .fab,
.navbar .nav-link .fa,
.navbar .nav-link i {
display: inline-flex !important;
align-items: center;
justify-content: center;
width: 28px;
flex-shrink: 0;
font-size: 16px;
line-height: 1;
margin: 0 10px 0 0 !important;
}
.navbar .navbar-nav .nav-item:last-child .nav-link,
.navbar .navbar-nav > .nav-link:last-child { border-bottom-color: transparent !important; }
.navbar .nav-link.active {
color: var(--color) !important;
border-bottom-color: var(--border-color) !important;
}
/* Items without leading icon: reserve the same 28px icon column so text aligns */
.navbar .nav-item > .nav-link:not(.btn-signin):not(.user-chip)::before {
content: '';
display: inline-block;
width: 28px;
margin-right: 10px;
flex-shrink: 0;
}
.navbar .nav-link:has(> i)::before,
.navbar .nav-link.nav-icon::before { display: none !important; }
.navbar .nav-link.nav-icon {
width: 100% !important;
height: auto !important;
justify-content: flex-start !important;
padding: 12px 4px !important;
}
.navbar .nav-link.nav-icon::after {
content: attr(title);
font-family: var(--font-sans);
font-size: 14px;
color: var(--color);
}
.navbar .btn-signin {
display: inline-flex !important;
width: auto !important;
align-self: flex-start;
justify-content: center;
height: 40px;
padding: 0 18px !important;
margin: 14px 0 0 !important;
border-radius: 8px;
border-bottom: none !important;
}
.navbar .btn-signin i { margin: 0 8px 0 0 !important; width: auto !important; }
/* User chip — integrate into drawer as a normal row */
.navbar .user-chip-wrap { width: 100%; }
.navbar .user-chip {
display: flex !important;
width: 100%;
margin: 0 !important;
padding: 10px 4px !important;
background: transparent !important;
border: none !important;
border-bottom: 1px solid var(--border-color) !important;
border-radius: 0 !important;
justify-content: flex-start;
gap: 0;
min-height: 44px;
}
.navbar .user-chip::before { display: none !important; }
.navbar .user-chip img {
width: 28px !important;
height: 28px !important;
margin-right: 10px !important;
flex-shrink: 0;
}
.navbar .user-chip .user-chip-name {
font-size: 14px;
font-weight: 500;
color: var(--color) !important;
}
.navbar .user-chip.dropdown-toggle::after {
margin-left: auto;
color: var(--ink-muted);
}
/* Dropdown menu items render inline, not floating */
.navbar .user-chip-wrap .dropdown-menu {
position: static !important;
float: none;
width: 100%;
margin: 0 !important;
padding: 0 !important;
background: transparent !important;
border: none !important;
box-shadow: none !important;
transform: none !important;
}
.navbar .user-chip-wrap .dropdown-menu .dropdown-item {
padding: 10px 4px 10px 42px !important;
font-size: 13.5px;
color: var(--ink-muted) !important;
background: transparent !important;
border-bottom: 1px solid var(--border-color);
text-align: left !important;
}
.navbar .user-chip-wrap .dropdown-menu .dropdown-item:last-child { border-bottom: none; }
.navbar .user-chip-wrap .dropdown-divider { display: none; }
.navbar-brand { border-right: none !important; padding-right: 0 !important; margin-right: 0 !important; }
.dark-mode .navbar .navbar-collapse { background: var(--header-bg-color); border-top-color: var(--border-color); }
.dark-mode .navbar .nav-link { border-bottom-color: var(--border-color) !important; }
.dark-mode .navbar-toggler .navbar-toggler-icon {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='%23f5f5f5' stroke-width='2' stroke-linecap='round' d='M4 8h22M4 15h22M4 22h22'/%3E%3C/svg%3E") !important;
}
}
/* Status pill — page header indicator */
.status-pill {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
border-radius: 999px;
background: var(--paper-bg-alt);
border: 1px solid var(--border-color);
color: var(--ink-soft);
font-family: var(--font-mono);
font-size: 11.5px;
letter-spacing: 0.08em;
text-transform: uppercase;
}
/* Paper progress bar */
/* The track is a pseudo-element so the label below it lives in normal flow
instead of overflowing an 8px-high box into the next section. */
.paper-progress {
position: relative;
height: auto;
background: none;
margin: 18px 0 8px;
}
.paper-progress::before {
content: "";
display: block;
height: 8px;
background: var(--paper-bg-alt);
border-radius: 999px;
}
.paper-progress .paper-progress-bar {
position: absolute;
top: 0;
left: 0;
height: 8px;
background: var(--color);
border-radius: 999px;
transition: width 0.4s ease;
min-width: 4px;
}
.paper-progress .paper-progress-label {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
font-family: var(--font-mono);
font-size: 11.5px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--ink-muted);
}
.paper-progress .paper-progress-pct { color: var(--color); }
.paper-progress.paper-progress-ready .paper-progress-bar { background: var(--color); }
/* Status error card */
.paper-error-card {
margin-top: 18px;
padding: 20px 22px;
background: var(--paper-bg-alt);
border: 1px solid var(--border-color);
border-left: 3px solid #C53030;
border-radius: 10px;
color: var(--color);
}
.dark-mode .paper-error-card { border-left-color: #FF8B7B; }
.paper-ratelimit-card {
margin-top: 18px;
padding: 20px 22px;
background: var(--paper-bg-alt);
border: 1px solid var(--border-color);
border-left: 3px solid #D69E2E;
border-radius: 10px;
color: var(--color);
}
.dark-mode .paper-ratelimit-card { border-left-color: #F6E05E; }
.paper-ratelimit-head {
display: flex;
align-items: flex-start;
gap: 14px;
}
.paper-ratelimit-head > i {
font-size: 18px;
color: #D69E2E;
margin-top: 4px;
flex-shrink: 0;
}
.dark-mode .paper-ratelimit-head > i { color: #F6E05E; }
.paper-ratelimit-card strong { color: var(--color); }
.status-pill-ratelimit { border-color: #D69E2E; color: #D69E2E; }
.dark-mode .status-pill-ratelimit { border-color: #F6E05E; color: #F6E05E; }
.status-ratelimit { background: #D69E2E; }
.dark-mode .status-ratelimit { background: #F6E05E; }
.paper-error-head {
display: flex;
align-items: flex-start;
gap: 14px;
}
.paper-error-head > i {
font-size: 18px;
color: #C53030;
margin-top: 4px;
flex-shrink: 0;
}
.dark-mode .paper-error-head > i { color: #FF8B7B; }
.paper-error-eyebrow {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
}
.paper-error-title {
font-family: var(--font-serif);
font-size: 1.4rem;
line-height: 1.2;
margin-top: 2px;
color: var(--color);
}
.paper-error-msg {
margin: 12px 0 0;
font-size: 14px;
line-height: 1.55;
color: var(--ink-soft);
font-family: var(--font-mono);
word-break: break-word;
white-space: pre-wrap;
}
.paper-error-hints {
margin: 14px 0 0;
padding-left: 18px;
color: var(--ink-soft);
font-size: 13.5px;
line-height: 1.6;
}
.paper-error-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 18px;
}
/* Detail grid (status page, generic) */
.paper-detail-grid {
display: grid;
grid-template-columns: 160px 1fr;
gap: 10px 20px;
margin-top: 18px;
font-size: 0.92rem;
}
.paper-detail-grid .detail-label {
font-family: var(--font-mono);
font-size: 10.5px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--ink-muted);
white-space: nowrap;
padding-top: 2px;
}
.paper-detail-grid .detail-value { word-break: break-all; color: var(--color); }
.paper-detail-grid .detail-value a { color: var(--color); border-bottom: 1px solid var(--border-color); }
.paper-detail-grid .detail-value a:hover { border-bottom-color: var(--color); }
@media (max-width: 700px) {
.paper-detail-grid { grid-template-columns: 1fr; gap: 4px 0; }
.paper-detail-grid .detail-label { padding-top: 8px; }
}
/* Support cards (Contribute / Feedback / Sponsor) */
.paper-support-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 14px;
margin: 18px 0 28px;
}
.paper-support-card {
display: flex;
flex-direction: column;
gap: 10px;
padding: 20px;
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
color: var(--color);
text-decoration: none;
transition: border-color 0.15s ease, transform 0.15s ease;
}
.paper-support-card:hover {
border-color: var(--color);
text-decoration: none;
color: var(--color);
}
.paper-support-card .paper-support-eyebrow {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
display: flex;
align-items: center;
gap: 8px;
}
.paper-support-card p {
margin: 0;
font-size: 14px;
line-height: 1.55;
color: var(--ink-soft);
}
.paper-support-card .paper-support-cta {
margin-top: auto;
font-size: 13px;
font-weight: 500;
color: var(--color);
display: inline-flex;
align-items: center;
gap: 6px;
}
.paper-support-card:hover .paper-support-cta i { transform: translateX(2px); }
.paper-support-card .paper-support-cta i { transition: transform 0.15s ease; }
/* Ko-fi embed wrapper */
.paper-kofi-wrap {
border: 1px solid var(--border-color);
border-radius: 10px;
overflow: hidden;
background: var(--paper-card);
}
.paper-kofi-wrap iframe {
border: 0;
width: 100%;
height: 650px;
display: block;
}
.dark-mode .paper-kofi-wrap iframe {
filter: invert(0.88) hue-rotate(180deg) sepia(0.15) saturate(1.2) brightness(1.1) contrast(0.85);
}
@media (max-width: 700px) {
.paper-kofi-wrap iframe { height: 720px; }
}
/* ===== Pull request page (paper) ===== */
.pr-page {
min-height: 100%;
background: var(--canvas-bg-color);
}
.pr-page-inner { padding-top: 24px; padding-bottom: 60px; }
.pr-header {
margin: 6px 0 18px;
}
.pr-title {
margin: 4px 0 10px;
font-size: clamp(1.6rem, 3vw, 2.4rem);
line-height: 1.15;
word-break: break-word;
}
.pr-header-meta {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px 14px;
font-family: var(--font-mono);
font-size: 12px;
color: var(--ink-muted);
}
.pr-header-meta .pr-meta-item {
display: inline-flex;
align-items: center;
gap: 6px;
}
.pr-header-meta .pr-meta-item i { color: var(--ink-muted); }
.pr-body-card {
margin: 18px 0 24px;
padding: 20px 22px;
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
}
.pr-body-card .paper-section-eyebrow { margin-bottom: 12px; }
/* Paper-style tabs */
.paper-tabs {
display: flex;
flex-wrap: wrap;
gap: 0;
border-bottom: 1px solid var(--border-color);
margin: 18px 0 0;
}
.paper-tabs .paper-tab {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 16px;
background: transparent;
border: 0;
border-bottom: 2px solid transparent;
font-family: var(--font-sans);
font-size: 13.5px;
font-weight: 500;
color: var(--ink-muted);
cursor: pointer;
transition: color 0.15s ease, border-color 0.15s ease;
margin-bottom: -1px;
}
.paper-tabs .paper-tab:hover { color: var(--color); }
.paper-tabs .paper-tab.active {
color: var(--color);
border-bottom-color: var(--color);
}
.paper-tabs .paper-tab i { color: inherit; opacity: 0.85; }
.paper-tabs .paper-tab:focus,
.paper-tabs .paper-tab:focus-visible,
.paper-tabs .paper-tab:active {
outline: none;
box-shadow: none;
}
.paper-tabs .paper-tab:focus-visible {
color: var(--color);
background: var(--hover-bg-color);
border-radius: 6px 6px 0 0;
}
/* ===== Diff (file-grouped, gutter line numbers) ===== */
.pr-diff {
margin: 16px 0 28px;
display: flex;
flex-direction: column;
gap: 16px;
}
.diff-file-block {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
overflow: hidden;
}
.diff-file-header {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 14px;
background: var(--paper-bg-alt);
border-bottom: 1px solid var(--border-color);
font-family: var(--font-mono);
font-size: 12.5px;
color: var(--color);
}
.diff-file-icon { color: var(--ink-muted); flex-shrink: 0; }
.diff-file-name {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
}
.diff-file-status {
flex-shrink: 0;
padding: 2px 8px;
border-radius: 999px;
font-size: 10px;
letter-spacing: 0.12em;
text-transform: uppercase;
border: 1px solid var(--border-color);
color: var(--ink-muted);
background: var(--paper-card);
}
.diff-file-status-added { color: #2F6B3E; border-color: rgba(47,107,62,0.35); background: rgba(47,107,62,0.08); }
.diff-file-status-deleted { color: #A13A2E; border-color: rgba(161,58,46,0.35); background: rgba(161,58,46,0.08); }
.diff-file-status-renamed { color: #8A6B1E; border-color: rgba(138,107,30,0.35); background: rgba(138,107,30,0.08); }
.dark-mode .diff-file-status-added { color: #A7E2A7; border-color: rgba(167,226,167,0.35); background: rgba(167,226,167,0.08); }
.dark-mode .diff-file-status-deleted { color: #FF8B7B; border-color: rgba(255,139,123,0.35); background: rgba(255,139,123,0.08); }
.dark-mode .diff-file-status-renamed { color: #FFD37A; border-color: rgba(255,211,122,0.35); background: rgba(255,211,122,0.08); }
.diff-file-table {
width: 100%;
border-collapse: collapse;
font-family: var(--font-mono);
font-size: 12.5px;
line-height: 1.55;
table-layout: fixed;
}
.diff-file-table tr.diff-row { vertical-align: top; }
.diff-file-table .diff-gutter {
width: 48px;
padding: 0 10px;
text-align: right;
color: var(--ink-muted);
background: var(--paper-bg-alt);
border-right: 1px solid var(--border-color);
user-select: none;
font-variant-numeric: tabular-nums;
vertical-align: top;
white-space: nowrap;
}
.diff-file-table .diff-gutter-new { border-right: 1px solid var(--border-color); }
.diff-file-table .diff-sign {
width: 18px;
padding: 0 6px;
text-align: center;
color: var(--ink-muted);
background: var(--paper-bg-alt);
user-select: none;
vertical-align: top;
}
.diff-file-table .diff-code {
padding: 1px 12px;
white-space: pre-wrap;
word-break: break-word;
color: var(--color);
}
/* Hunk header row */
.diff-row-hunk td {
background: var(--paper-bg-alt) !important;
color: var(--ink-muted);
border-top: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
font-size: 12px;
letter-spacing: 0.02em;
padding-top: 6px;
padding-bottom: 6px;
}
.diff-row-hunk .diff-code { color: var(--ink-muted); }
/* Add / remove rows */
.diff-row-add .diff-code {
background: rgba(47,107,62,0.10);
color: #1F4A2A;
}
.diff-row-add .diff-sign,
.diff-row-add .diff-gutter {
background: rgba(47,107,62,0.06);
color: #2F6B3E;
}
.diff-row-remove .diff-code {
background: rgba(161,58,46,0.10);
color: #6E1F1A;
}
.diff-row-remove .diff-sign,
.diff-row-remove .diff-gutter {
background: rgba(161,58,46,0.06);
color: #A13A2E;
}
.dark-mode .diff-row-add .diff-code { background: rgba(167,226,167,0.10); color: #C9F0C9; }
.dark-mode .diff-row-add .diff-sign,
.dark-mode .diff-row-add .diff-gutter { background: rgba(167,226,167,0.06); color: #A7E2A7; }
.dark-mode .diff-row-remove .diff-code { background: rgba(255,139,123,0.10); color: #FFC9C0; }
.dark-mode .diff-row-remove .diff-sign,
.dark-mode .diff-row-remove .diff-gutter { background: rgba(255,139,123,0.06); color: #FF8B7B; }
@media (max-width: 700px) {
.diff-file-table { font-size: 11.5px; }
.diff-file-table .diff-gutter { width: 36px; padding: 0 6px; }
.diff-file-table .diff-sign { width: 14px; padding: 0 4px; }
.diff-file-table .diff-code { padding: 1px 8px; }
}
/* Comments */
.pr-comments {
list-style: none;
margin: 16px 0 28px;
padding: 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.pr-comment {
padding: 16px 18px;
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
}
.pr-comment-head {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 12px;
flex-wrap: wrap;
padding-bottom: 8px;
margin-bottom: 8px;
border-bottom: 1px solid var(--border-color);
}
.pr-comment-author {
font-weight: 600;
color: var(--color);
font-size: 14px;
display: inline-flex;
align-items: center;
gap: 6px;
}
.pr-comment-author i { color: var(--ink-muted); font-size: 12px; }
.pr-comment-date {
font-family: var(--font-mono);
font-size: 11.5px;
color: var(--ink-muted);
letter-spacing: 0.02em;
}
.pr-comment-body { color: var(--color); font-size: 14px; line-height: 1.6; }
.pr-comment-body :last-child { margin-bottom: 0; }
@media (max-width: 700px) {
.pr-page-inner { padding-top: 14px; padding-bottom: 40px; }
.pr-body-card { padding: 14px 14px; border-radius: 8px; }
.pr-comment { padding: 12px 14px; }
.paper-tabs .paper-tab { padding: 10px 12px; font-size: 13px; }
.pr-diff pre { font-size: 11.5px; padding: 12px; }
}
/* Toasts — paper style, dark-mode aware */
.toast {
background-color: var(--paper-card) !important;
color: var(--color) !important;
border: 1px solid var(--border-color) !important;
border-radius: 10px !important;
box-shadow: 0 8px 24px rgba(0,0,0,0.08);
backdrop-filter: none;
min-width: 280px;
max-width: calc(100vw - 24px);
}
.toast .toast-header {
background: transparent !important;
color: var(--color) !important;
border-bottom: 1px solid var(--border-color) !important;
font-family: var(--font-sans);
padding: 10px 12px;
}
.toast .toast-header strong {
font-weight: 600;
color: var(--color);
letter-spacing: 0.01em;
}
.toast .toast-header .close {
color: var(--ink-muted) !important;
text-shadow: none;
opacity: 0.9;
font-size: 1.2rem;
}
.toast .toast-header .close:hover { color: var(--color) !important; opacity: 1; }
.toast .toast-body {
color: var(--color) !important;
padding: 12px;
font-size: 14px;
line-height: 1.45;
}
.dark-mode .toast { box-shadow: 0 8px 24px rgba(0,0,0,0.5); }
.paper-crumbs {
font-family: var(--font-mono);
font-size: 11px;
color: var(--ink-muted);
letter-spacing: 0.02em;
}
.paper-crumbs a, .paper-crumbs .here {
color: var(--color);
text-decoration: none;
}
.paper-page-title {
font-family: var(--font-serif);
font-weight: 400;
font-size: clamp(2rem, 4.5vw, 3.2rem);
line-height: 1.05;
letter-spacing: -0.02em;
margin: 10px 0 6px;
color: var(--color);
}
.paper-page-title em { color: var(--accent); font-style: italic; }
.paper-page-lede {
color: var(--ink-soft);
font-size: 16px;
max-width: 640px;
line-height: 1.55;
}
.paper-meta-rule {
display: flex;
flex-wrap: wrap;
gap: 16px 24px;
align-items: center;
margin: 22px 0 18px;
padding: 12px 0;
border-top: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
font-family: var(--font-mono);
font-size: 11.5px;
color: var(--ink-muted);
letter-spacing: 0.02em;
}
.paper-meta-rule b { color: var(--color); font-weight: 500; }
.paper-card {
background: var(--paper-card, #fff);
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 20px 22px;
}
.dark-mode .paper-card { background: var(--admin-stat-bg); }
.paper-section-eyebrow {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
font-weight: 500;
margin-bottom: 10px;
display: block;
}
.paper-section-title {
font-family: var(--font-serif);
font-weight: 400;
font-size: 22px;
letter-spacing: -0.01em;
margin: 0 0 8px;
}
.paper-kbd {
display: inline-block;
font-family: var(--font-mono);
font-size: 10.5px;
padding: 1px 6px;
border: 1px solid var(--border-color);
border-bottom-width: 2px;
border-radius: 3px;
background: var(--paper-card, #fff);
color: var(--color);
}
/* Pill for status / meta */
.paper-pill {
display: inline-flex;
align-items: center;
gap: 6px;
font-family: var(--font-mono);
font-size: 10.5px;
padding: 2px 8px;
border: 1px solid var(--border-color);
border-radius: 999px;
color: var(--ink-soft);
background: var(--paper-card, #fff);
letter-spacing: 0.04em;
}
.paper-pill.accent { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.paper-pill.good { border-color: #2F6B3E; color: #2F6B3E; }
.paper-pill.warn { border-color: #8A6B1E; color: #8A6B1E; }
.paper-pill.bad { border-color: #A13A2E; color: #A13A2E; }
/* Editorial list row */
.paper-row {
display: grid;
grid-template-columns: 1fr auto;
gap: 16px;
align-items: start;
padding: 18px 0;
border-bottom: 1px solid var(--border-color);
}
.paper-row:first-child { border-top: 1px solid var(--border-color); }
.paper-row .row-title {
font-family: var(--font-serif);
font-size: 20px;
letter-spacing: -0.01em;
line-height: 1.2;
}
.paper-row .row-title a { color: var(--color); }
.paper-row .row-meta {
font-family: var(--font-mono);
font-size: 11px;
color: var(--ink-muted);
letter-spacing: 0.03em;
margin-top: 6px;
display: flex;
flex-wrap: wrap;
gap: 14px;
}
.paper-row .row-actions { display: flex; gap: 6px; flex-shrink: 0; }
/* Paper form building blocks */
.paper-form-step {
display: grid;
grid-template-columns: 48px 1fr;
gap: 20px;
padding: 22px 0;
border-bottom: 1px solid var(--border-color);
}
.paper-form-step:first-child { border-top: 1px solid var(--border-color); }
.paper-form-step .step-num {
font-family: var(--font-mono);
font-size: 11.5px;
color: var(--ink-muted);
padding-top: 4px;
letter-spacing: 0.02em;
}
.paper-form-step .step-title {
font-family: var(--font-serif);
font-size: 22px;
letter-spacing: -0.01em;
line-height: 1.2;
margin-bottom: 4px;
}
.paper-form-step .step-sub {
color: var(--ink-soft);
font-size: 13.5px;
margin-bottom: 14px;
text-wrap: pretty;
}
.paper-field-label {
display: block;
font-family: var(--font-mono);
font-size: 10.5px;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--ink-muted);
font-weight: 500;
margin-bottom: 6px;
}
.paper-switch-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
gap: 16px;
}
.paper-switch-row + .paper-switch-row {
border-top: 1px dashed var(--border-soft);
}
.paper-switch-row .sw-label { font-weight: 500; }
.paper-switch-row .sw-sub {
display: block;
font-size: 12.5px;
color: var(--ink-muted);
margin-top: 2px;
}
/* Paper-style form controls reuse Bootstrap classes */
.paper-page .form-control,
.paper-page .custom-select {
border-radius: 6px;
border-color: var(--border-color);
font-size: 14px;
padding: 8px 12px;
height: auto;
background: var(--input-bg);
color: var(--input-color);
}
.paper-page .form-control:focus,
.paper-page .custom-select:focus {
color: var(--input-color);
background: var(--input-bg);
border-color: var(--accent);
box-shadow: 0 0 0 2px var(--accent-soft);
}
.form-control:focus,
.custom-select:focus,
input:focus,
textarea:focus,
select:focus {
color: var(--input-color) !important;
background-color: var(--input-bg) !important;
}
.form-control::selection,
input::selection,
textarea::selection {
background: var(--accent-soft);
color: var(--input-color);
}
.dark-mode .form-control::selection,
.dark-mode input::selection,
.dark-mode textarea::selection {
background: rgba(167, 178, 255, 0.30);
color: var(--input-color);
}
/* Primary/accent button variants */
.btn.btn-ink {
background: var(--color);
color: var(--canvas-bg-color);
border: 1px solid var(--color);
font-weight: 500;
border-radius: 6px;
padding: 8px 14px;
}
.btn.btn-ink:hover {
background: var(--primary-hover-bg);
color: var(--canvas-bg-color);
border-color: var(--primary-hover-bg);
}
.btn.btn-accent {
background: var(--accent);
color: #fff;
border: 1px solid var(--accent);
font-weight: 500;
border-radius: 6px;
}
.btn.btn-accent:hover { background: #2E3BB8; border-color: #2E3BB8; color: #fff; }
/* Paper-style filter row buttons (Sort / Status / type filter) */
.paper-page .dashboard-filter-row {
display: flex;
align-items: center;
gap: 10px;
padding: 14px 0;
border-top: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
margin: 18px 0 0;
flex-wrap: wrap;
}
.paper-page .dashboard-filter-row .form-control {
height: 38px;
background: var(--paper-card);
}
.paper-page .dashboard-filter-controls {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.paper-page .dashboard-filter-row .dropdown-toggle,
.paper-page .dashboard-filter-row .btn-group .btn {
background: var(--paper-card);
border: 1px solid var(--border-color);
color: var(--color);
height: 38px;
padding: 0 14px;
font-size: 14px;
font-weight: 500;
border-radius: var(--radius-control, 6px);
display: inline-flex;
align-items: center;
gap: 6px;
line-height: 1;
}
/* "Sort · Name ↓" style toggles: the label is muted, the value is ink so the
current state reads at a glance. */
.paper-page .dashboard-filter-row .dropdown-toggle .filter-btn-label {
color: var(--ink-muted);
font-weight: 500;
}
.paper-page .dashboard-filter-row .dropdown-toggle .filter-btn-label::after {
content: "·";
margin-left: 6px;
color: var(--ink-faint);
}
.paper-page .dashboard-filter-row .dropdown-toggle .filter-btn-value {
font-weight: 500;
}
.paper-page .dashboard-filter-row .dropdown-toggle .fas {
font-size: 11px;
color: var(--ink-muted);
}
.paper-page .dashboard-filter-row .dropdown-toggle:hover,
.paper-page .dashboard-filter-row .btn-group .btn:hover {
background: var(--hover-bg-color);
border-color: var(--border-color);
color: var(--color);
}
.paper-page .dashboard-filter-row .btn-group {
gap: 0;
}
.paper-page .dashboard-filter-row .btn-group .btn {
border-radius: 0;
border-right-width: 0;
}
.paper-page .dashboard-filter-row .btn-group .btn:first-child { border-top-left-radius: 6px; border-bottom-left-radius: 6px; }
.paper-page .dashboard-filter-row .btn-group .btn:last-child { border-top-right-radius: 6px; border-bottom-right-radius: 6px; border-right-width: 1px; }
.paper-page .dashboard-filter-row .btn-group .btn.btn-primary {
background: var(--color);
color: var(--canvas-bg-color);
border-color: var(--color);
}
.paper-page .dashboard-filter-row .search-wrap {
flex: 1 1 280px;
min-width: 220px;
}
/* Quota row refinements */
.paper-page .quota-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 40px;
margin: 24px 0 0;
padding: 0;
background: transparent;
border: none;
border-radius: 0;
}
.paper-page .quota-label {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
opacity: 1;
}
.paper-page .quota-value {
font-family: var(--font-mono);
font-size: 13px;
font-variant-numeric: tabular-nums;
color: var(--color);
}
.paper-page .quota-value .quota-unlimited-tag {
font-family: var(--font-sans);
font-size: 12px;
color: var(--ink-muted);
margin-left: 4px;
}
/* Quota bars: ink by default, colour only when a limit is nearly reached.
Unlimited quotas render an empty track (no fill), never a full green bar. */
.paper-page .quota-track {
height: 6px;
background: var(--paper-bg-alt);
border: 1px solid var(--border-color);
border-radius: 999px;
overflow: hidden;
width: 100%;
min-width: 0;
}
.paper-page .quota-track .quota-fill {
height: 100%;
min-width: 2px;
border-radius: 999px;
background: var(--color);
transition: width 0.3s ease;
}
.paper-page .quota-track.quota-warn .quota-fill { background: var(--status-progress); }
.paper-page .quota-track.quota-danger .quota-fill { background: var(--status-error); }
.paper-page .quota-track.quota-unlimited {
background: repeating-linear-gradient(
-45deg,
var(--paper-bg-alt) 0 4px,
var(--border-soft, var(--border-color)) 4px 6px
);
}
/* Dashboard repo/PR list refinements */
.paper-page .repo-list { margin-top: 8px; }
.paper-page .repo-list-item {
padding: 20px 0;
gap: 16px;
border-bottom: 1px solid var(--border-soft, var(--border-color));
}
.paper-page .repo-list-item:first-child { border-top: none; }
.paper-page .repo-list-item-header { gap: 10px; margin-bottom: 6px; }
.paper-page .repo-name {
font-family: var(--font-mono);
font-size: 15px;
color: var(--color);
}
.paper-page .repo-source {
font-size: 13px;
color: var(--ink-soft);
opacity: 1;
gap: 10px;
}
.paper-page .repo-source a { color: var(--ink-soft); border-bottom: 1px dotted var(--border-color); }
.paper-page .repo-source a:hover { color: var(--color); }
.paper-page .repo-meta {
font-family: var(--font-mono);
font-size: 12px;
color: var(--ink-muted);
opacity: 1;
gap: 16px;
margin-top: 10px;
}
.paper-page .type-badge {
font-family: var(--font-mono);
font-size: 11px;
padding: 3px 8px;
letter-spacing: 0.1em;
}
.paper-page .repo-list-item-actions .dropdown-toggle {
background: var(--paper-card);
border: 1px solid var(--border-color);
color: var(--color);
border-radius: 6px;
font-size: 13px;
padding: 6px 12px;
height: auto;
}
/* Paper settings (editorial 2-col) */
.paper-settings { max-width: 1180px; margin: 0 auto; padding: 48px 32px 80px; }
.paper-settings .paper-page-title { max-width: 14em; }
.paper-settings-body {
display: grid;
grid-template-columns: 220px 1fr;
gap: 60px;
margin-top: 32px;
border-top: 1px solid var(--border-color);
padding-top: 28px;
}
.paper-settings-toc { position: sticky; top: 32px; align-self: start; }
.paper-settings-toc-head {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
margin-bottom: 12px;
}
.paper-settings-toc nav { display: flex; flex-direction: column; gap: 2px; }
.paper-settings-toc nav a {
padding: 8px 0 8px 14px;
border-left: 2px solid transparent;
color: var(--ink-soft);
font-size: 14px;
text-decoration: none;
}
.paper-settings-toc nav a:hover,
.paper-settings-toc nav a.active {
color: var(--color);
border-left-color: var(--color);
}
.paper-settings-main { min-width: 0; max-width: 720px; }
.paper-settings-section { padding: 28px 0; border-bottom: 1px solid var(--border-soft, var(--border-color)); }
.paper-settings-section:first-child { padding-top: 0; }
.paper-settings-section:last-of-type { border-bottom: none; }
.paper-settings-section .form-group { margin-bottom: 18px; }
.paper-settings-section .form-check { padding: 10px 0 10px 28px; border-bottom: 1px solid var(--border-soft, var(--border-color)); }
.paper-settings-section .form-check:last-child { border-bottom: none; }
/* Checkbox labels are UI text, so they use the sans face like the rest of
the forms; the serif stays reserved for display headings. */
.paper-settings-section .form-check-label { font-family: var(--font-sans); font-size: 14px; font-weight: 500; color: var(--color); cursor: pointer; }
.paper-settings-section .form-check-input { cursor: pointer; width: 16px; height: 16px; margin-top: 3px; margin-left: -28px; accent-color: var(--color); }
.paper-settings-section .form-text { color: var(--ink-soft); font-size: 13px; margin-top: 4px; max-width: 48em; }
.paper-settings-section .paper-section-copy { margin: -4px 0 14px; }
.paper-settings-footer { padding-top: 24px; display: flex; flex-direction: column; gap: 14px; }
.paper-settings-footer .btn-ink { align-self: flex-start; }
.paper-settings-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; }
.paper-settings-hint { font-size: 13px; color: var(--ink-muted); }
/* Inline alerts in the paper palette (Bootstrap's .alert colours clash) */
.paper-inline-alert {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 10px 12px;
border-radius: var(--radius-control, 6px);
border: 1px solid var(--border-color);
background: var(--paper-bg-alt);
font-size: 13px;
color: var(--color);
}
.paper-inline-alert i { margin-top: 2px; color: var(--ink-muted); }
.paper-inline-alert-error { border-color: var(--status-error); background: var(--status-error-soft); }
.paper-inline-alert-error i { color: var(--status-error); }
/* Account card and danger zone on the settings page */
.paper-account-card {
display: flex;
align-items: center;
gap: 14px;
padding: 14px 16px;
border: 1px solid var(--border-color);
border-radius: var(--radius-surface, 10px);
background: var(--paper-card);
margin-bottom: 20px;
}
.paper-account-card img { flex-shrink: 0; }
.paper-account-identity { flex: 1 1 auto; min-width: 0; }
.paper-account-name { font-family: var(--font-mono); font-size: 14px; font-weight: 500; color: var(--color); }
.paper-account-meta { font-size: 13px; color: var(--ink-muted); margin-top: 2px; }
.paper-danger-zone {
padding: 16px;
border: 1px solid var(--status-error);
border-radius: var(--radius-surface, 10px);
background: var(--status-error-soft);
}
.paper-danger-head { font-weight: 600; font-size: 14px; color: var(--status-error); margin-bottom: 6px; }
.paper-danger-copy { font-size: 13px; color: var(--ink-soft); max-width: 52em; margin-bottom: 12px; }
.paper-danger-zone .paper-inline-alert { margin-bottom: 12px; }
.btn.btn-outline-danger {
background: transparent;
color: var(--status-error);
border: 1px solid var(--status-error);
font-weight: 500;
border-radius: var(--radius-control, 6px);
padding: 8px 14px;
}
.btn.btn-outline-danger:hover { background: var(--status-error); color: #fff; border-color: var(--status-error); }
/* Navbar user menu: two-line items (label + hint) */
.navbar .user-menu { min-width: 260px; }
.navbar .user-menu .dropdown-item { display: flex; align-items: flex-start; gap: 10px; padding: 8px 10px !important; }
.navbar .user-menu .dropdown-item i { width: 16px; margin-top: 3px; font-size: 13px; color: var(--ink-muted); text-align: center; }
.navbar .user-menu .dropdown-item span { display: flex; flex-direction: column; line-height: 1.3; }
.navbar .user-menu .dropdown-item small { font-size: 12px; color: var(--ink-muted); }
.navbar .user-menu .dropdown-header {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--ink-muted);
padding: 8px 10px 6px;
}
.paper-field-label {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
margin-bottom: 6px;
display: block;
}
@media (max-width: 900px) {
.paper-settings-body { grid-template-columns: 1fr; gap: 24px; }
.paper-settings-toc { position: static; }
.paper-settings-toc nav { flex-direction: row; flex-wrap: wrap; gap: 8px; }
.paper-settings-toc nav a { border-left: none; border-bottom: 2px solid transparent; padding: 4px 0; }
.paper-settings-toc nav a.active, .paper-settings-toc nav a:hover { border-bottom-color: var(--color); border-left: none; }
}
/* Paper table (reference grid) */
.paper-table {
display: block;
margin-top: 20px;
background: transparent;
border: none;
border-top: 1px solid var(--border-color);
border-radius: 0;
overflow: visible;
}
.paper-table .paper-table-head,
.paper-table .paper-table-row {
display: grid;
grid-template-columns: minmax(280px, 2.4fr) minmax(140px, 1fr) 140px 90px 140px 52px;
align-items: center;
gap: 18px;
padding: 12px 4px;
}
.paper-table.paper-table-conferences .paper-table-head,
.paper-table.paper-table-conferences .paper-table-row {
grid-template-columns: minmax(280px, 2.4fr) 140px 90px 220px 52px;
}
.paper-table.paper-table-repos .paper-table-head,
.paper-table.paper-table-repos .paper-table-row {
grid-template-columns: minmax(280px, 2.4fr) minmax(140px, 1fr) 90px 140px 52px;
}
.paper-table.paper-table-repos.has-bulk .paper-table-head,
.paper-table.paper-table-repos.has-bulk .paper-table-row {
grid-template-columns: 28px minmax(280px, 2.4fr) minmax(140px, 1fr) 90px 140px 52px;
gap: 12px;
}
.paper-table .admin-users-row {
grid-template-columns: 28px minmax(280px, 2.4fr) 90px 120px 100px 52px !important;
gap: 12px !important;
}
/* Dashboard: conference folded into the name cell, numbers right-aligned. */
.paper-table.paper-table-dashboard .paper-table-head,
.paper-table.paper-table-dashboard .paper-table-row {
grid-template-columns: minmax(320px, 3fr) 190px 90px 170px 52px;
gap: 20px;
/* Two-line rows land at ~60px, close to Carbon's "large" density. */
padding: 8px 4px;
}
.paper-table.paper-table-dashboard .cell-anon .anon-text { gap: 2px; }
.paper-table.paper-table-dashboard .cell-anon .repo-name { padding: 0; }
.paper-table .paper-table-head {
background: transparent;
border-bottom: 1px solid var(--border-color);
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--ink-muted);
padding-top: 8px;
padding-bottom: 8px;
}
.paper-table .paper-table-head .sortable {
cursor: pointer;
user-select: none;
display: inline-flex;
align-items: center;
gap: 6px;
/* Sortable headers are real <button>s for keyboard users. */
background: none;
border: none;
padding: 2px 0;
margin: 0;
font: inherit;
letter-spacing: inherit;
text-transform: inherit;
color: inherit;
border-radius: 4px;
}
.paper-table .paper-table-head .sortable:hover { color: var(--color); }
.paper-table .paper-table-head .sortable.active { color: var(--color); }
.paper-table .paper-table-head .sortable i { font-size: 10px; }
/* Quantitative columns are right-aligned so digits line up. */
.paper-table .paper-table-head .num,
.paper-table .paper-table-row .num { text-align: right; }
.paper-table .paper-table-head .num .sortable { flex-direction: row-reverse; }
.paper-table .paper-table-row {
border-top: 1px solid var(--border-soft, var(--border-color));
font-size: 14px;
transition: background-color 0.12s ease;
}
.paper-table .paper-table-row:hover {
background: var(--hover-bg-color);
}
/* Rows that open a view on click get a pointer so hover means something. */
.paper-table .paper-table-row.row-clickable { cursor: pointer; }
/* Dim inactive rows through their cells rather than the row itself. Applying
opacity to the row creates a stacking context that traps the actions
dropdown menu (z-index) beneath the rows rendered after it, making its
items unclickable. Leave the actions column at full opacity so it stays
interactive. */
.paper-table .paper-table-row.repo-inactive > *:not(.cell-actions) { opacity: 0.55; }
.paper-table .paper-table-row.repo-error {
background: var(--status-error-soft);
border-left: 2px solid var(--status-error);
padding-left: 6px;
}
.paper-table .paper-table-row.repo-error:hover { background: var(--status-error-soft-hover); }
.paper-table .cell-status .status-sub-error,
.cell-status .status-sub.status-sub-error {
color: var(--status-error);
}
.paper-table .cell-status .status-sub-warn { color: var(--status-progress); }
.paper-table .cell-anon {
display: flex;
align-items: center;
gap: 12px;
min-width: 0;
}
.paper-table .cell-anon .type-badge {
flex-shrink: 0;
min-width: 52px;
justify-content: center;
}
.paper-table .cell-anon .anon-text { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.paper-table .cell-anon .anon-title {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.paper-table .cell-anon .anon-title .type-badge { margin-left: 0; }
.paper-table .cell-anon .repo-name {
/* Identifiers stay mono; everything human-readable below is sans. */
font-family: var(--font-mono);
font-size: 14px;
color: var(--color);
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
max-width: 100%;
padding: 2px 0;
}
.paper-table .cell-anon .repo-name-static { color: var(--ink-muted); font-style: italic; }
.paper-table .cell-anon .anon-sub {
font-family: var(--font-sans);
font-size: 13px;
color: var(--ink-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
align-items: center;
gap: 10px;
min-width: 0;
}
.paper-table .cell-anon .anon-sub .anon-source {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* The conference tag keeps a readable share of the line; the source
truncates first since it is repeated in the name and in the tooltip. */
.paper-table .cell-anon .anon-sub .conf-tag {
flex: 0 1 auto;
min-width: 72px;
max-width: 50%;
}
.paper-table .cell-anon .anon-sub a {
color: var(--ink-muted);
border-bottom: 1px dotted var(--border-color);
/* Taller hit area without changing the line box */
padding: 4px 0;
margin: -4px 0;
}
.paper-table .cell-anon .anon-sub a:hover { color: var(--color); }
.paper-table .cell-anon .anon-sub .commit-hash { font-family: var(--font-mono); font-size: 12px; }
/* Conference shown as a small tag inside the name cell. `.cell-conf` keeps
the clipping rules so a long conference string never bleeds. */
.paper-table .cell-conf {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--ink-muted);
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.paper-table .cell-conf span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.paper-table .cell-status { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; font-size: 14px; color: var(--color); min-width: 0; }
.paper-table .cell-status .status-line { display: inline-flex; align-items: center; gap: 8px; }
.paper-table .cell-status .status-sub {
flex-basis: 100%;
font-family: var(--font-sans);
font-size: 13px;
line-height: 1.3;
color: var(--ink-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.paper-table .cell-views { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--color); }
.paper-table .cell-expires { font-family: var(--font-sans); font-size: 13px; color: var(--ink-soft); }
.paper-table .cell-expires .expires-never { color: var(--ink-muted); }
.paper-table .cell-expires .expires-past { color: var(--ink-muted); }
.paper-table .empty-dash { color: var(--ink-faint); }
.paper-table .cell-actions { display: flex; justify-content: flex-end; }
/* Status dots use the semantic tokens so they stay legible in both themes.
Old status-* class names are kept as aliases for other templates. */
.status-dot {
width: 8px;
height: 8px;
border-radius: 999px;
display: inline-block;
flex-shrink: 0;
background: var(--status-inactive);
}
.status-dot.status-ready { background: var(--status-ready); }
.status-dot.status-error { background: var(--status-error); }
.status-dot.status-progress,
.status-dot.status-preparing { background: var(--status-progress); }
.status-dot.status-expired,
.status-dot.status-removed { background: var(--status-inactive); }
/* ---- Dashboard extras ---------------------------------------------- */
/* Room for the fixed Ko-fi pill so it never covers the last row's actions. */
.dashboard-page { padding-bottom: 96px; }
.dashboard-meta {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px 10px;
margin-top: 12px;
font-size: 13px;
color: var(--ink-muted);
}
.dashboard-meta .dashboard-count { font-variant-numeric: tabular-nums; }
.btn-link-inline {
background: none;
border: none;
padding: 2px 4px;
margin: -2px 0;
font: inherit;
color: var(--link-color);
cursor: pointer;
border-radius: 4px;
}
.btn-link-inline:hover { color: var(--link-hover-color); text-decoration: underline; }
.btn.btn-outline-ink {
background: transparent;
color: var(--color);
border: 1px solid var(--border-color);
font-weight: 500;
border-radius: var(--radius-control, 6px);
padding: 8px 14px;
}
.btn.btn-outline-ink:hover { background: var(--hover-bg-color); color: var(--color); border-color: var(--color); }
.paper-page .dropdown-menu .dropdown-item-danger,
.paper-page .dropdown-menu .dropdown-item-danger i { color: var(--status-error); }
.paper-page .dropdown-menu .dropdown-item-danger:hover,
.paper-page .dropdown-menu .dropdown-item-danger:focus { background: var(--status-error-soft-hover); color: var(--status-error); }
.paper-page .dropdown-menu button.dropdown-item { width: 100%; text-align: left; background: none; border: none; }
.paper-page .dropdown-menu .dropdown-divider { border-top-color: var(--border-soft, var(--border-color)); margin: 4px 0; }
/* Loading skeleton */
.paper-table .paper-table-skeleton { pointer-events: none; }
.skeleton {
display: block;
background: var(--paper-bg-alt);
border-radius: 4px;
position: relative;
overflow: hidden;
}
.skeleton::after {
content: "";
position: absolute;
inset: 0;
transform: translateX(-100%);
background: linear-gradient(90deg, transparent, var(--hover-bg-color), transparent);
animation: skeleton-shimmer 1.4s infinite;
}
.skeleton-line { height: 12px; }
.skeleton-line + .skeleton-line { margin-top: 8px; }
.skeleton-line-sm { height: 10px; }
.skeleton-badge { width: 52px; height: 22px; border-radius: 999px; flex-shrink: 0; }
@keyframes skeleton-shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .skeleton::after { animation: none; } }
/* Empty state with a way out */
.paper-table .paper-table-empty {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 56px 20px;
color: var(--ink-muted);
text-align: center;
border-top: 1px solid var(--border-soft, var(--border-color));
}
.paper-table .paper-table-empty i { font-size: 1.6rem; color: var(--ink-faint); }
.paper-table .paper-table-empty-actions { display: flex; gap: 8px; margin-top: 8px; }
.bulk-bar {
display: flex;
align-items: center;
gap: 8px;
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 8px 12px;
margin: 8px 0;
}
/* Tighter admin page header — admin is power-user UI, no need for huge title + lede */
.paper-page.admin-page .paper-page-title { font-size: 1.6rem; margin: 4px 0; }
.paper-page.admin-page .paper-page-lede { display: none; }
.paper-page.admin-page .paper-crumbs { margin-bottom: 4px; }
.paper-page.admin-page .admin-nav { margin: 6px 0 12px; }
/* Admin filter toolbar — single compact line, inline labels (no boxed groups) */
.admin-filter-toolbar {
display: flex;
flex-direction: column;
gap: 6px;
margin: 8px 0 12px;
position: sticky;
top: 0;
z-index: 4;
background: var(--canvas-bg-color);
padding: 6px 0;
border-bottom: 1px solid var(--border-soft, var(--border-color));
box-shadow: 0 1px 0 var(--canvas-bg-color);
}
@media (max-width: 900px) {
.admin-filter-toolbar { position: static; box-shadow: none; }
}
.admin-filter-row {
display: flex;
flex-wrap: wrap;
gap: 6px;
align-items: center;
}
.admin-filter-row .search-wrap { flex: 1; min-width: 220px; }
.admin-filter-row .search-wrap .form-control { height: 34px; }
.admin-filter-inline {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
color: var(--ink-muted);
}
.admin-filter-inline > label {
font-family: var(--font-mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--ink-muted);
margin: 0;
white-space: nowrap;
}
.admin-filter-inline .form-control-sm {
height: 28px;
padding: 2px 8px;
font-size: 12px;
}
.admin-filter-inline input[type="text"].form-control-sm,
.admin-filter-inline input[type="search"].form-control-sm { width: 130px; }
.admin-filter-inline input[type="date"].form-control-sm { width: 130px; }
.admin-filter-inline select.form-control-sm { width: auto; min-width: 88px; }
.admin-filter-inline .arrow { color: var(--ink-muted); font-size: 11px; }
.admin-filter-spacer { flex: 1; }
/* Active-filter chips — visually surface what's currently constraining the view */
.admin-active-chips {
display: flex;
flex-wrap: wrap;
gap: 6px;
align-items: center;
font-size: 12px;
color: var(--ink-muted);
}
.admin-active-chip {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 4px 2px 10px;
border: 1px solid var(--border-color);
border-radius: 999px;
background: var(--hover-bg-color);
font-size: 12px;
color: var(--color);
}
.admin-active-chip .key { color: var(--ink-muted); font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; }
.admin-active-chip button {
background: none;
border: none;
cursor: pointer;
padding: 0 4px;
color: var(--ink-muted);
font-size: 12px;
border-radius: 50%;
}
.admin-active-chip button:hover { color: #B42318; }
.admin-search-hint {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
font-family: var(--font-mono);
font-size: 11px;
color: var(--ink-muted);
pointer-events: none;
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 1px 5px;
background: var(--paper-card);
}
.admin-filter-row .search-wrap { position: relative; }
.admin-filter-row .search-wrap .form-control { padding-right: 40px; }
.paper-table-row.row-selected {
background: rgba(47, 122, 68, 0.06);
}
.queue-state-pills { display: inline-flex; gap: 6px; margin-left: 8px; flex-wrap: wrap; }
.queue-state-pills .pill {
font-size: 11px;
padding: 2px 8px;
border-radius: 999px;
border: 1px solid var(--border-color);
background: var(--paper-card);
color: var(--ink-muted);
}
.queue-state-pills .pill-active { color: #C48A2E; border-color: rgba(196,138,46,0.4); }
.queue-state-pills .pill-failed { color: #B42318; border-color: rgba(180,35,24,0.4); }
.queue-state-pills .pill-completed { color: #2F7A44; border-color: rgba(47,122,68,0.3); }
.queue-state-pills .pill-waiting { color: var(--ink-soft); }
.queue-state-pills .pill-delayed { color: var(--ink-muted); }
/* Compact summary bar — replaces stat cards. Each pill is also a filter shortcut. */
.admin-summary {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
margin: 8px 0 12px;
font-size: 13px;
}
.admin-summary .summary-total {
font-family: var(--font-serif);
font-size: 1.05rem;
color: var(--color);
margin-right: 8px;
}
.admin-summary .summary-meta {
color: var(--ink-muted);
font-size: 12px;
margin-right: 8px;
}
.admin-summary .summary-pill {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 3px 10px;
border-radius: 999px;
border: 1px solid var(--border-color);
background: var(--paper-card);
color: var(--ink-muted);
cursor: pointer;
font-size: 12px;
user-select: none;
transition: background-color 0.1s, border-color 0.1s;
}
.admin-summary .summary-pill:hover { background: var(--hover-bg-color); }
.admin-summary .summary-pill .count {
font-family: var(--font-mono);
font-variant-numeric: tabular-nums;
color: var(--color);
}
.admin-summary .summary-pill.active {
background: var(--primary-bg);
color: var(--primary-color);
border-color: var(--primary-bg);
}
.admin-summary .summary-pill.active .count { color: inherit; }
.admin-summary .summary-pill.error .count { color: #B42318; }
.admin-summary .summary-pill.warn .count { color: #C48A2E; }
.admin-summary .summary-pill.ok .count { color: #2F7A44; }
.dark-mode .admin-summary .summary-pill.error .count { color: #F08A82; }
.dark-mode .admin-summary .summary-pill.warn .count { color: #E8B970; }
.dark-mode .admin-summary .summary-pill.ok .count { color: #7DC894; }
.dark-mode .queue-state-pills .pill-active { color: #E8B970; border-color: rgba(232,185,112,0.4); }
.dark-mode .queue-state-pills .pill-failed { color: #F08A82; border-color: rgba(240,138,130,0.4); }
.dark-mode .queue-state-pills .pill-completed { color: #7DC894; border-color: rgba(125,200,148,0.3); }
.job-progress {
flex: 1;
height: 6px;
background: var(--border-soft, var(--border-color));
border-radius: 999px;
overflow: hidden;
margin-left: 12px;
max-width: 200px;
}
.job-progress-bar { height: 100%; background: #2F7A44; transition: width 0.3s; }
.paper-table-empty {
padding: 48px 4px;
text-align: center;
color: var(--ink-muted);
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
border-top: 1px solid var(--border-soft, var(--border-color));
}
.paper-table-empty i { font-size: 1.6rem; }
/* ===== Queue dashboard (redesigned) ===== */
.q-header {
display: flex;
align-items: baseline;
justify-content: space-between;
flex-wrap: wrap;
gap: 12px;
margin-bottom: 4px;
}
.q-header-actions {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.q-range-btns {
display: inline-flex;
border: 1px solid var(--border-color);
border-radius: 8px;
overflow: hidden;
}
.q-range-btns .btn {
border: none;
border-radius: 0;
padding: 5px 14px;
font-family: var(--font-mono);
font-size: 11px;
color: var(--ink-muted);
background: var(--paper-card);
}
.q-range-btns .btn + .btn { border-left: 1px solid var(--border-color); }
.q-range-btns .btn.active {
background: var(--color);
color: var(--paper-card);
}
.btn-dark {
background: var(--color) !important;
color: var(--paper-card) !important;
border-color: var(--color) !important;
border-radius: 999px;
padding: 5px 18px;
font-family: var(--font-mono);
font-size: 11px;
font-weight: 500;
letter-spacing: 0.04em;
}
/* Queue overview cards */
.q-cards {
display: flex;
gap: 10px;
margin: 16px 0;
flex-wrap: wrap;
}
.q-card {
flex: 1;
min-width: 140px;
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 14px 16px;
cursor: pointer;
transition: border-color 0.15s, box-shadow 0.15s;
}
.q-card:hover { border-color: var(--ink-muted); }
.q-card.selected {
border-color: var(--color);
box-shadow: 0 0 0 1px var(--color);
}
.q-card-head {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
}
.q-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: #2F7A44;
flex-shrink: 0;
}
.q-dot-red { background: #B42318; }
.dark-mode .q-dot { background: #7DC894; }
.dark-mode .q-dot-red { background: #F08A82; }
.q-card-name {
font-family: var(--font-mono);
font-size: 11.5px;
font-weight: 500;
color: var(--ink-muted);
letter-spacing: 0.04em;
}
.q-card-count {
font-family: var(--font-serif);
font-size: 2rem;
font-weight: 400;
line-height: 1.1;
color: var(--color);
margin-bottom: 6px;
}
.q-card-sub {
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--ink-muted);
letter-spacing: 0.04em;
}
.q-card-bar {
height: 4px;
background: var(--border-color);
border-radius: 2px;
overflow: hidden;
margin-top: 6px;
}
.q-card-bar-fill {
height: 100%;
background: #3B4AD6;
border-radius: 2px;
transition: width 0.3s;
}
.dark-mode .q-card-bar-fill { background: #A7B2FF; }
/* Detail: throughput + stats */
.q-detail {
display: grid;
grid-template-columns: 1fr 320px;
gap: 16px;
margin-bottom: 20px;
}
.q-throughput {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 16px 20px;
}
.q-chart-wrap {
position: relative;
}
.q-throughput canvas {
width: 100%;
display: block;
}
.q-chart-tooltip {
position: absolute;
pointer-events: none;
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 6px;
padding: 6px 10px;
font-family: var(--font-mono);
font-size: 11px;
line-height: 1.6;
white-space: nowrap;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
z-index: 10;
}
.q-chart-tooltip .q-tip-time {
color: var(--ink-muted);
margin-bottom: 2px;
}
.q-chart-tooltip .q-tip-completed { color: #3B4AD6; }
.q-chart-tooltip .q-tip-failed { color: #B42318; }
.dark-mode .q-chart-tooltip .q-tip-completed { color: #A7B2FF; }
.dark-mode .q-chart-tooltip .q-tip-failed { color: #F08A82; }
.q-chart-crosshair {
position: absolute;
top: 0;
width: 1px;
height: 100%;
background: var(--ink-muted);
opacity: 0.3;
pointer-events: none;
z-index: 9;
}
.q-stats-panel {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 16px 20px;
display: flex;
flex-direction: column;
}
.q-section-label {
font-family: var(--font-mono);
font-size: 11px;
font-weight: 500;
color: var(--ink-muted);
text-transform: lowercase;
letter-spacing: 0.04em;
margin-bottom: 14px;
}
.q-section-right {
float: right;
text-transform: uppercase;
font-size: 10px;
letter-spacing: 0.08em;
}
.q-legend-completed { color: #3B4AD6; }
.q-legend-failed { color: #B42318; margin-left: 8px; }
.q-legend-exec { color: #B8860B; margin-left: 8px; letter-spacing: 2px; }
.dark-mode .q-legend-completed { color: #A7B2FF; }
.dark-mode .q-legend-failed { color: #F08A82; }
.dark-mode .q-legend-exec { color: #F5C842; }
.q-chart-tooltip .q-tip-exec { color: #B8860B; }
.dark-mode .q-chart-tooltip .q-tip-exec { color: #F5C842; }
.q-stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px 20px;
flex: 1;
}
.q-stat-label {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--ink-muted);
text-transform: uppercase;
letter-spacing: 0.08em;
margin-bottom: 2px;
}
.q-stat-value {
font-family: var(--font-serif);
font-size: 1.3rem;
font-weight: 400;
color: var(--color);
line-height: 1.2;
}
.q-stats-actions {
display: flex;
gap: 8px;
margin-top: 16px;
padding-top: 14px;
border-top: 1px solid var(--border-color);
}
.q-stats-actions .btn {
font-family: var(--font-mono);
font-size: 11px;
padding: 6px 14px;
border-radius: 8px;
background: var(--paper-card);
border: 1px solid var(--border-color);
color: var(--color);
}
/* Jobs section */
.q-jobs {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 16px 20px;
}
.q-jobs-header {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 12px;
}
/* State filter toggles */
.q-state-filters {
display: inline-flex;
gap: 6px;
flex-wrap: wrap;
}
.q-state-toggle {
cursor: pointer;
display: inline-flex;
align-items: center;
}
.q-state-toggle input { display: none; }
.q-state-chip {
font-family: var(--font-mono);
font-size: 11px;
padding: 3px 10px;
border-radius: 10px;
border: 1px solid var(--border-color);
background: var(--paper-card);
color: var(--ink-muted);
transition: opacity 0.15s, background 0.15s;
text-transform: capitalize;
}
.q-state-toggle input:checked + .q-state-chip {
opacity: 1;
}
.q-state-toggle input:not(:checked) + .q-state-chip {
opacity: 0.4;
text-decoration: line-through;
}
/* State badge colors */
.q-state-badge, .q-state-chip {
font-family: var(--font-mono);
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.3px;
}
.q-state-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 8px;
}
.q-state-active { background: #dbeafe; color: #1d4ed8; }
.q-state-waiting { background: #fef3c7; color: #92400e; }
.q-state-delayed { background: #e0e7ff; color: #4338ca; }
.q-state-failed { background: #fee2e2; color: #b91c1c; }
.q-state-completed { background: #dcfce7; color: #166534; }
.dark-mode .q-state-active { background: rgba(59,130,246,0.2); color: #93bbfd; }
.dark-mode .q-state-waiting { background: rgba(251,191,36,0.15); color: #fbbf24; }
.dark-mode .q-state-delayed { background: rgba(99,102,241,0.2); color: #a5b4fc; }
.dark-mode .q-state-failed { background: rgba(239,68,68,0.2); color: #fca5a5; }
.dark-mode .q-state-completed { background: rgba(34,197,94,0.15); color: #86efac; }
.q-cell-state { width: 120px; }
.q-delay-hint {
display: block;
font-size: 10px;
color: var(--ink-muted);
margin-top: 2px;
font-family: var(--font-mono);
}
.q-search-row {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 12px;
}
.q-search-row .form-control {
max-width: 320px;
height: 34px;
}
.q-auto-refresh {
font-family: var(--font-mono);
font-size: 11px;
color: var(--ink-muted);
display: inline-flex;
align-items: center;
gap: 6px;
cursor: pointer;
white-space: nowrap;
}
/* Jobs table */
.q-table {
width: 100%;
border-collapse: collapse;
}
.q-table thead th {
font-family: var(--font-mono);
font-size: 9.5px;
font-weight: 500;
color: var(--ink-muted);
text-transform: uppercase;
letter-spacing: 0.08em;
padding: 8px 10px;
border-bottom: 1px solid var(--border-color);
text-align: left;
white-space: nowrap;
}
.q-table tbody tr {
border-bottom: 1px solid var(--border-color);
transition: background 0.1s;
}
.q-table tbody tr:hover { background: var(--paper-bg-alt); }
.q-table tbody tr:last-child { border-bottom: none; }
.q-table tbody td {
padding: 10px 10px;
font-size: 0.88rem;
vertical-align: middle;
}
.q-cell-id {
font-family: var(--font-mono);
font-size: 12px;
white-space: nowrap;
}
.q-cell-id {
display: flex;
align-items: center;
gap: 8px;
}
.q-chevron {
font-size: 9px;
color: var(--ink-muted);
transition: transform 0.15s;
flex-shrink: 0;
}
.q-chevron-open {
transform: rotate(90deg);
}
.q-cell-id a { color: var(--color); }
.q-cell-payload {
font-family: var(--font-mono);
font-size: 12px;
color: var(--color);
}
.q-payload-detail {
color: var(--ink-muted);
}
.q-cell-num {
font-family: var(--font-mono);
font-size: 12px;
text-align: center;
white-space: nowrap;
}
.q-cell-progress {
min-width: 120px;
}
.q-progress-wrap {
display: flex;
align-items: center;
gap: 8px;
}
.q-progress-bar {
flex: 1;
height: 6px;
border-radius: 3px;
overflow: hidden;
background-image: linear-gradient(to right, #3B4AD6 var(--pct, 0%), var(--border-color) var(--pct, 0%));
}
.dark-mode .q-progress-bar {
background-image: linear-gradient(to right, #A7B2FF var(--pct, 0%), var(--border-color) var(--pct, 0%));
}
.q-progress-label {
font-family: var(--font-mono);
font-size: 11px;
color: var(--ink-muted);
white-space: nowrap;
min-width: 32px;
text-align: right;
}
.q-cell-actions {
text-align: right;
white-space: nowrap;
}
.q-cell-actions .btn {
padding: 3px 8px;
font-size: 11px;
background: transparent;
border: 1px solid var(--border-color);
color: var(--ink-muted);
}
.q-cell-actions .btn:hover { color: var(--color); }
.q-row-failed { background: rgba(180,35,24,0.04); }
.dark-mode .q-row-failed { background: rgba(240,138,130,0.06); }
.q-error-detail {
padding: 4px 10px 12px;
font-size: 12px;
}
.q-error-reason {
color: #B42318;
font-size: 0.82rem;
margin-bottom: 4px;
}
.dark-mode .q-error-reason { color: #F08A82; }
/* Error toast */
.q-toast-error {
background: #FBE7E7;
color: #B42318;
border: 1px solid #F3C7C7;
border-radius: 8px;
padding: 10px 16px;
margin-bottom: 12px;
font-family: var(--font-mono);
font-size: 12px;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
}
.dark-mode .q-toast-error {
background: rgba(240,138,130,0.1);
color: #F08A82;
border-color: rgba(240,138,130,0.25);
}
.q-error-stack {
font-size: 0.78rem;
max-height: 120px;
overflow: auto;
margin: 4px 0 0;
background: var(--paper-bg-alt);
border: 1px solid var(--border-color);
border-radius: 6px;
padding: 8px 10px;
}
/* Expanded job detail row */
.q-row-expanded > td { border-bottom-color: transparent; }
.q-detail-row > td {
padding: 0 10px 14px !important;
border-bottom: 1px solid var(--border-color);
}
.q-job-detail {
background: var(--paper-bg-alt);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 14px 16px;
}
.q-job-detail-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: 10px 20px;
margin-bottom: 10px;
}
.q-job-detail-item {
display: flex;
flex-direction: column;
gap: 2px;
}
.q-job-detail-label {
font-family: var(--font-mono);
font-size: 9px;
font-weight: 500;
color: var(--ink-muted);
text-transform: uppercase;
letter-spacing: 0.08em;
}
.q-job-detail-value {
font-family: var(--font-mono);
font-size: 12px;
color: var(--color);
word-break: break-all;
}
.q-job-detail-value a { color: var(--color); }
.q-job-detail-error {
margin: 8px 0;
}
.q-job-detail-actions {
display: flex;
gap: 8px;
margin-top: 12px;
padding-top: 10px;
border-top: 1px solid var(--border-color);
}
.q-job-detail-actions .btn {
font-family: var(--font-mono);
font-size: 11px;
padding: 5px 12px;
border-radius: 6px;
background: var(--paper-card);
border: 1px solid var(--border-color);
color: var(--color);
}
@media (max-width: 900px) {
.q-detail { grid-template-columns: 1fr; }
.q-cards { flex-direction: column; }
.q-card { min-width: 100%; }
.q-jobs-header { flex-direction: column; align-items: flex-start; }
.q-tabs { flex-wrap: wrap; }
.q-search-row { flex-wrap: wrap; }
.q-search-row .form-control { max-width: 100%; flex: 1; }
.q-table { font-size: 12px; }
.q-header { flex-direction: column; }
.q-job-detail-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 900px) {
.paper-table .paper-table-head { display: none; }
.paper-table .paper-table-row,
.paper-table.paper-table-conferences .paper-table-row,
.paper-table.paper-table-repos .paper-table-row,
.paper-table .admin-users-row {
display: flex !important;
flex-wrap: wrap;
align-items: center;
gap: 6px 12px;
padding: 14px 0;
grid-template-columns: none !important;
}
.paper-table .cell-anon {
flex: 1 1 calc(100% - 52px);
min-width: 0;
order: 1;
}
.paper-table .cell-actions {
flex: 0 0 auto;
order: 2;
align-self: center;
}
.paper-table .cell-status,
.paper-table .cell-views,
.paper-table .cell-conf,
.paper-table .cell-expires {
order: 3;
font-size: 13px;
color: var(--ink-muted);
display: inline-flex;
align-items: center;
gap: 6px;
text-align: left;
}
/* Status, date, views and expiry sit on one meta line with a common
baseline; the sub-text is inline instead of wrapping under the word. */
.paper-table .cell-status { flex-wrap: nowrap; gap: 6px; min-width: 0; }
.paper-table .cell-status .status-sub { flex-basis: auto; font-size: 13px; line-height: inherit; }
.paper-table .cell-status .status-sub::before { content: "·"; margin-right: 6px; color: var(--ink-faint); }
.paper-table .cell-conf {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.paper-table .cell-views.num { text-align: left; }
.paper-table .paper-table-skeleton .cell-status,
.paper-table .paper-table-skeleton .cell-views,
.paper-table .paper-table-skeleton .cell-expires { flex: 1 1 30%; }
.paper-table .cell-views::before {
content: '\f06e';
font-family: 'Font Awesome 5 Free';
font-weight: 900;
font-size: 10px;
color: var(--ink-muted);
}
.paper-table .cell-expires::before {
content: '\f017';
font-family: 'Font Awesome 5 Free';
font-weight: 400;
font-size: 10px;
color: var(--ink-muted);
}
.paper-table .cell-conf::before {
content: '\f51c';
font-family: 'Font Awesome 5 Free';
font-weight: 900;
font-size: 10px;
color: var(--ink-muted);
}
/* The dashboard renders its own icon inside the conference tag. */
.paper-table-dashboard .cell-conf::before { content: none; }
.paper-table .cell-conf:has(.empty-dash),
.paper-table .cell-expires:has(.empty-dash) { display: none; }
.paper-table .cell-views::before,
.paper-table .cell-expires::before { color: var(--ink-faint); }
}
/* Paper-themed dropdown menus (Sort / Status / Actions) */
.paper-page .dropdown-menu {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: var(--radius-surface, 10px);
box-shadow: 0 12px 28px rgba(26, 24, 21, 0.08);
padding: 6px;
min-width: 220px;
font-family: var(--font-sans);
font-size: 14px;
color: var(--color);
margin-top: 6px;
}
.paper-page .dropdown-menu .dropdown-header {
font-family: var(--font-mono);
font-size: 10px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
padding: 8px 10px 6px;
font-weight: 500;
}
.paper-page .dropdown-menu .dropdown-item {
border-radius: 6px;
padding: 8px 10px;
color: var(--color);
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.paper-page .dropdown-menu .dropdown-item:hover,
.paper-page .dropdown-menu .dropdown-item:focus {
background: var(--hover-bg-color);
color: var(--color);
}
.paper-page .dropdown-menu .dropdown-item i {
width: 16px;
font-size: 13px;
color: var(--ink-muted);
}
.paper-page .dropdown-menu .form-check.dropdown-item {
padding: 8px 10px 8px 36px !important;
position: relative;
}
.paper-page .dropdown-menu .form-check.dropdown-item .form-check-input {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
margin: 0;
width: 16px;
height: 16px;
accent-color: var(--color);
cursor: pointer;
}
.paper-page .dropdown-menu .form-check.dropdown-item .form-check-label {
font-family: var(--font-sans);
font-size: 14px;
color: var(--color);
font-weight: 400;
margin: 0;
cursor: pointer;
}
/* Three-dots icon action button */
.btn.btn-icon-dots {
width: 32px;
height: 32px;
padding: 0;
border: 1px solid transparent;
background: transparent;
color: var(--ink-muted);
border-radius: 6px;
display: inline-flex;
align-items: center;
justify-content: center;
line-height: 1;
}
.btn.btn-icon-dots:hover,
.btn.btn-icon-dots:focus,
.btn.btn-icon-dots[aria-expanded="true"] {
background: var(--hover-bg-color);
border-color: var(--border-color);
color: var(--color);
}
.btn.btn-icon-dots::after { display: none; }
.btn.btn-icon-dots i { font-size: 15px; }
.paper-page .repo-list-empty {
border-top: none;
padding: 56px 20px;
color: var(--ink-muted);
}
/* Filter chips */
.paper-page .filter-chip {
background: var(--paper-bg-alt);
color: var(--color);
border: 1px solid var(--border-color);
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 4px 10px;
border-radius: 999px;
}
@media (max-width: 768px) {
.paper-page .paper-page-title { font-size: clamp(1.4rem, 6vw, 1.9rem); margin: 4px 0 2px; }
.paper-page .paper-page-lede { font-size: 13px; line-height: 1.4; margin-bottom: 0; }
.paper-page .btn-ink { padding: 6px 12px; font-size: 13px; }
/* Quotas stack in one column on phones so labels and values keep the
same 11px / 13px sizes as desktop instead of shrinking to 9px. */
.paper-page .quota-row {
grid-template-columns: 1fr;
gap: 12px;
padding: 0;
margin: 16px 0 0;
}
.paper-page .dashboard-filter-row {
padding: 10px 0;
margin-top: 12px;
gap: 8px;
}
.paper-page .quota-header {
flex-direction: row;
align-items: baseline;
gap: 8px;
}
.paper-page .quota-value { white-space: nowrap; }
/* Filter controls: type group fills the row, Sort and Status share one. */
.paper-page .dashboard-filter-controls { width: 100%; }
.paper-page .dashboard-filter-controls .btn-group { flex: 1 1 100%; display: flex; }
.paper-page .dashboard-filter-controls .btn-group .btn { flex: 1; justify-content: center; }
.paper-page .dashboard-filter-controls .dropdown { flex: 1 1 0; min-width: 0; }
.paper-page .dashboard-filter-controls .dropdown .dropdown-toggle { width: 100%; justify-content: space-between; }
.paper-page .dashboard-filter-controls .dropdown .filter-btn-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
@media (max-width: 480px) {
.paper-page .paper-page-lede {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
/* Empty state */
.empty-state {
text-align: center;
padding: 40px 20px;
opacity: 0.6;
}
.empty-state i {
font-size: 2rem;
margin-bottom: 10px;
display: block;
}
/* ===== Paper profile / settings ===== */
.paper-page .progress {
height: 10px;
background: var(--paper-bg-alt);
border: 1px solid var(--border-color);
border-radius: 999px;
overflow: hidden;
margin-bottom: 20px;
}
.paper-page .progress .progress-bar {
background: var(--color);
color: var(--canvas-bg-color);
font-family: var(--font-mono);
font-size: 10px;
line-height: 10px;
}
/* Bootstrap's .bg-* utilities are !important, so the paper palette must be
too, otherwise the bright Bootstrap green/yellow/red leak through. */
.paper-page .progress .progress-bar.bg-success { background: var(--status-ready) !important; }
.paper-page .progress .progress-bar.bg-warning { background: var(--status-progress) !important; color: #fff; }
.paper-page .progress .progress-bar.bg-danger { background: var(--status-error) !important; }
.paper-page .progress .progress-bar.bg-dark { background: var(--ink-faint) !important; }
.paper-page > h5,
.paper-page form > h5,
.paper-page .form > h5 {
font-family: var(--font-mono);
font-size: 11px;
font-weight: 500;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--ink-muted);
margin: 24px 0 8px;
}
.paper-page .accordion .card {
background: var(--paper-card, var(--sidebar-bg-color));
border: 1px solid var(--border-color);
border-radius: 8px !important;
margin-bottom: 8px;
overflow: hidden;
}
.paper-page .accordion .card + .card { border-top: 1px solid var(--border-color); }
.paper-page .accordion .card-header {
background: transparent;
border: none;
padding: 0;
}
.paper-page .accordion .card-header .btn {
color: var(--color) !important;
font-family: var(--font-sans);
font-weight: 500;
font-size: 14px;
padding: 14px 18px !important;
background: transparent !important;
border: none !important;
position: relative;
}
.paper-page .accordion .card-header .btn::after {
content: "+";
position: absolute;
right: 18px;
font-family: var(--font-serif);
font-size: 20px;
color: var(--ink-muted);
}
.paper-page .accordion .card-header .btn:not(.collapsed)::after { content: ""; }
.paper-page .accordion .card-body {
padding: 6px 18px 18px !important;
border-top: 1px solid var(--border-soft);
}
.paper-page .accordion .form-check-label {
color: var(--color);
font-weight: 500;
font-size: 13.5px;
}
.paper-page .accordion .form-text {
color: var(--ink-muted);
font-size: 12px;
margin-top: 2px;
}
.faq-section .panel-body code {
font-family: var(--font-mono);
font-size: 13px;
padding: 1px 6px;
background: var(--paper-bg-alt);
border: 1px solid var(--border-color);
border-radius: 3px;
color: var(--color);
}
.faq-section .panel-body a {
color: var(--accent);
}
@media (max-width: 820px) {
.paper-faq-body {
grid-template-columns: 1fr;
gap: 24px;
}
.paper-faq-toc {
position: static;
}
}
/* ===== Paper footer ===== */
.paper-footer {
margin-top: 80px;
padding: 56px max(20px, calc((100vw - 1200px) / 2)) 28px;
border-top: 1px solid var(--border-color);
background: var(--canvas-bg-color);
font-family: var(--font-sans);
}
.paper-footer-inner {
display: grid;
grid-template-columns: 1.6fr 1fr 1fr 1fr;
gap: 40px;
}
.paper-footer-brand .paper-footer-mark {
font-family: var(--font-serif);
font-size: 22px;
letter-spacing: -0.01em;
color: var(--color);
}
.paper-footer-brand .paper-footer-mark em {
font-style: italic;
font-weight: 400;
}
.paper-footer-tag {
margin-top: 10px;
color: var(--ink-soft);
font-size: 13.5px;
line-height: 1.55;
max-width: 340px;
}
.paper-footer-head {
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--ink-muted);
letter-spacing: 0.1em;
text-transform: uppercase;
margin-bottom: 14px;
}
.paper-footer-col a {
display: block;
color: var(--color);
font-size: 13.5px;
padding: 4px 0;
text-decoration: none;
}
.paper-footer-col a:hover {
color: var(--accent);
}
.paper-footer-rule {
height: 1px;
background: var(--border-color);
margin: 40px 0 16px;
}
.paper-footer-foot {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 12px;
font-size: 12px;
color: var(--ink-muted);
font-family: var(--font-mono);
letter-spacing: 0.02em;
}
.paper-footer-foot .paper-footer-meta {
font-family: var(--font-serif);
font-style: italic;
font-size: 13.5px;
letter-spacing: 0;
color: var(--ink-soft);
}
@media (max-width: 768px) {
.paper-footer-inner {
grid-template-columns: 1fr 1fr;
}
}
.file.folder.truncated .truncated-warning {
color: #d39e00;
margin-left: 4px;
font-size: 0.85em;
flex-shrink: 0;
}
.file.folder.truncated > a {
color: #d39e00;
}
/* ===== Errors admin page =====
Uses the existing design tokens (--paper-card, --border-color, --ink-muted,
--primary-bg, etc.) so light + dark themes are picked up automatically.
Bucket colors are exposed as their own tokens with light/dark overrides
below so status pills stay legible against the dark canvas. */
body {
--bucket-error-bg: #FCEDED;
--bucket-error-fg: #8A1F1F;
--bucket-error-bd: #F0C4C4;
--bucket-error-dot: #B53737;
--bucket-warn-bg: #FFF3DF;
--bucket-warn-fg: #7A4D00;
--bucket-warn-bd: #F0D8A0;
--bucket-warn-dot: #B07A2F;
--bucket-info-bg: #EAF2EC;
--bucket-info-fg: #2C5D3A;
--bucket-info-bd: #C5DCCD;
--bucket-info-dot: #5B8D6B;
/* Subtle elevation tokens — gives cards weight without losing the paper
palette. Single soft shadow + a 1px hairline to keep the editorial feel. */
--card-shadow: 0 1px 2px rgba(26, 24, 21, 0.04), 0 4px 14px rgba(26, 24, 21, 0.05);
--card-shadow-hover: 0 1px 2px rgba(26, 24, 21, 0.06), 0 8px 24px rgba(26, 24, 21, 0.08);
}
.dark-mode {
--bucket-error-bg: rgba(255, 139, 123, 0.10);
--bucket-error-fg: #FF8B7B;
--bucket-error-bd: rgba(255, 139, 123, 0.28);
--bucket-error-dot: #FF8B7B;
--bucket-warn-bg: rgba(255, 211, 122, 0.10);
--bucket-warn-fg: #FFD37A;
--bucket-warn-bd: rgba(255, 211, 122, 0.28);
--bucket-warn-dot: #FFD37A;
--bucket-info-bg: rgba(152, 200, 168, 0.10);
--bucket-info-fg: #98C8A8;
--bucket-info-bd: rgba(152, 200, 168, 0.28);
--bucket-info-dot: #98C8A8;
--card-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 6px 18px rgba(0, 0, 0, 0.30);
--card-shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.45), 0 12px 28px rgba(0, 0, 0, 0.40);
}
.errors-page .errors-header { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin: 4px 0 8px; }
.errors-page .errors-actions { display: flex; gap: 6px; }
.errors-page .kpi-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
margin: 14px 0 18px;
}
.errors-page .kpi-card {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 18px 20px;
display: flex;
flex-direction: column;
gap: 4px;
box-shadow: var(--card-shadow);
transition: box-shadow 160ms ease, transform 160ms ease;
}
.errors-page .kpi-card:hover { box-shadow: var(--card-shadow-hover); }
.errors-page .kpi-label {
font-family: var(--font-mono);
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--ink-muted);
}
.errors-page .kpi-value {
font-family: var(--font-serif);
font-size: 2.6rem;
font-weight: 400;
line-height: 1;
margin-top: 2px;
color: var(--color);
}
.errors-page .kpi-card.kpi-error .kpi-value { color: var(--bucket-error-fg); }
.errors-page .kpi-card.kpi-warn .kpi-value { color: var(--bucket-warn-fg); }
.errors-page .kpi-card.kpi-info .kpi-value { color: var(--bucket-info-fg); }
.errors-page .kpi-sub { font-size: 0.78rem; color: var(--ink-muted); font-style: italic; }
.errors-page .kpi-sub.up { color: var(--bucket-error-fg); font-style: normal; }
.errors-page .kpi-sub.down { color: var(--bucket-info-fg); font-style: normal; }
.errors-page .dropped-warn { color: var(--bucket-error-fg); font-weight: 600; font-style: normal; }
.errors-page .volume-chart {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 18px 22px;
margin-bottom: 18px;
box-shadow: var(--card-shadow);
}
.errors-page .volume-head {
display: flex; justify-content: space-between; align-items: center;
font-family: var(--font-mono);
font-size: 0.7rem; color: var(--ink-muted);
text-transform: uppercase; letter-spacing: 0.08em;
margin-bottom: 10px;
}
.errors-page .volume-legend { display: flex; gap: 14px; align-items: center; text-transform: none; letter-spacing: 0; font-family: var(--font-sans); }
.errors-page .volume-legend .dot { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 5px; vertical-align: middle; }
.errors-page .dot.dot-error { background: var(--bucket-error-dot); }
.errors-page .dot.dot-warn { background: var(--bucket-warn-dot); }
.errors-page .dot.dot-info { background: var(--bucket-info-dot); }
.errors-page .volume-bars { display: flex; align-items: flex-end; gap: 4px; height: 80px; }
.errors-page .volume-bar { display: flex; flex-direction: column-reverse; flex: 1 1 0; min-width: 6px; height: 100%; }
.errors-page .volume-bar .seg { display: block; width: 100%; }
.errors-page .seg.seg-error { background: var(--bucket-error-dot); }
.errors-page .seg.seg-warn { background: var(--bucket-warn-dot); }
.errors-page .seg.seg-info { background: var(--bucket-info-dot); opacity: 0.7; }
.errors-page .errors-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
.errors-page .seg-tabs {
display: inline-flex;
border: 1px solid var(--border-color);
border-radius: 8px;
overflow: hidden;
background: var(--paper-card);
}
.errors-page .seg-tabs button {
background: transparent; border: none;
padding: 6px 14px; font-size: 0.85rem; cursor: pointer;
color: var(--color); font-family: var(--font-sans);
}
.errors-page .seg-tabs button + button { border-left: 1px solid var(--border-color); }
.errors-page .seg-tabs button.active { background: var(--primary-bg); color: var(--primary-color); }
.errors-page .errors-toolbar .search-wrap { position: relative; flex: 1 1 320px; min-width: 220px; }
.errors-page .errors-toolbar .search-wrap input {
width: 100%;
padding: 6px 10px 6px 32px;
border: 1px solid var(--border-color);
border-radius: 8px;
font-family: var(--font-mono); font-size: 0.82rem;
background: var(--input-bg);
color: var(--input-color);
}
.errors-page .errors-toolbar .search-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--ink-muted); font-size: 0.85rem; }
.errors-page .errors-toolbar .filter-count { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); font-size: 0.72rem; color: var(--ink-muted); }
.errors-page .errors-toolbar .select-wrap { display: inline-flex; align-items: center; gap: 6px; }
.errors-page .errors-toolbar .select-wrap label {
font-family: var(--font-mono);
font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em;
color: var(--ink-muted); margin: 0;
}
.errors-page .errors-toolbar .select-wrap select {
background: var(--input-bg); color: var(--input-color);
border: 1px solid var(--border-color); border-radius: 8px;
}
.errors-page .errors-toolbar .autoref { display: inline-flex; gap: 6px; align-items: center; font-size: 0.82rem; color: var(--color); cursor: pointer; margin: 0; }
.errors-page .btn-icon { width: 32px; padding: 4px 0; }
.errors-page .errors-list {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 12px;
overflow: hidden;
box-shadow: var(--card-shadow);
}
.errors-page .errors-list-head,
.errors-page .errors-row-main {
display: grid;
grid-template-columns: 110px 100px 100px 1fr 60px 70px;
gap: 16px;
padding: 18px 20px;
align-items: start;
}
.errors-page .errors-list-head { padding: 12px 20px; align-items: center; }
.errors-page .errors-list-head {
font-family: var(--font-mono);
font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em;
color: var(--ink-muted);
border-bottom: 1px solid var(--border-color);
background: var(--paper-bg-alt);
}
.errors-page .errors-row { border-bottom: 1px solid var(--border-soft); }
.errors-page .errors-row:last-child { border-bottom: none; }
.errors-page .errors-row.open { background: var(--paper-bg-alt); }
.errors-page .errors-row-main { cursor: pointer; }
.errors-page .errors-row-main:hover { background: var(--hover-bg-color); }
.errors-page .col-when .when-rel { font-size: 0.95rem; color: var(--color); font-variant-numeric: tabular-nums; }
.errors-page .col-when .when-abs { font-family: var(--font-mono); font-size: 0.78rem; color: var(--ink-muted); font-variant-numeric: tabular-nums; margin-top: 2px; }
.errors-page .col-sev { display: flex; align-items: center; gap: 8px; }
.errors-page .sev-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.errors-page .sev-dot.sev-error { background: var(--bucket-error-dot); }
.errors-page .sev-dot.sev-warn { background: var(--bucket-warn-dot); }
.errors-page .sev-dot.sev-info { background: var(--bucket-info-dot); }
.errors-page .sev-label { font-family: var(--font-mono); font-size: 0.74rem; letter-spacing: 0.08em; color: var(--color); }
.errors-page .pill-module {
display: inline-block;
font-family: var(--font-mono); font-size: 0.78rem;
background: var(--paper-bg-alt); color: var(--ink-soft);
border: 1px solid var(--border-color);
padding: 3px 10px; border-radius: 6px;
}
.errors-page .col-msg .msg-code {
font-family: var(--font-mono);
font-size: 1rem;
color: var(--color);
font-weight: 600;
}
.errors-page .col-msg .msg-context { color: var(--ink-muted); font-style: italic; font-size: 0.88rem; margin-left: 10px; }
.errors-page .col-msg .msg-detail {
color: var(--ink-soft);
font-family: var(--font-mono);
font-size: 0.82rem;
margin-left: 10px;
}
.errors-page .col-msg .msg-url {
color: var(--ink-muted);
font-family: var(--font-mono);
font-size: 0.8rem;
margin-top: 6px;
word-break: break-all;
}
.errors-page .count-pill {
display: inline-block;
padding: 2px 8px; border-radius: 4px;
background: var(--primary-bg); color: var(--primary-color);
font-family: var(--font-mono); font-size: 0.78rem; font-variant-numeric: tabular-nums;
}
.errors-page .count-pill.count-pill-muted {
background: transparent; color: var(--ink-muted);
border: 1px solid var(--border-color);
}
.errors-page .status-pill {
display: inline-block;
padding: 2px 10px; border-radius: 4px;
font-family: var(--font-mono); font-size: 0.8rem; font-variant-numeric: tabular-nums;
border: 1px solid transparent;
}
.errors-page .status-pill.status-error { background: var(--bucket-error-bg); color: var(--bucket-error-fg); border-color: var(--bucket-error-bd); }
.errors-page .status-pill.status-warn { background: var(--bucket-warn-bg); color: var(--bucket-warn-fg); border-color: var(--bucket-warn-bd); }
.errors-page .status-pill.status-info { background: var(--bucket-info-bg); color: var(--bucket-info-fg); border-color: var(--bucket-info-bd); }
.errors-page .errors-row-detail { padding: 0 16px 16px; }
.errors-page .detail-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border-color); margin-bottom: 12px; }
.errors-page .detail-tabs button {
background: transparent; border: 0;
border-bottom: 2px solid transparent;
padding: 8px 12px; font-size: 0.85rem; cursor: pointer;
color: var(--ink-muted); font-family: var(--font-sans);
}
.errors-page .detail-tabs button.active { color: var(--color); border-bottom-color: var(--color); }
.errors-page .detail-body { display: grid; grid-template-columns: 1fr 260px; gap: 20px; }
.errors-page .detail-main pre {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 18px 22px;
font-family: var(--font-mono);
font-size: 0.85rem;
line-height: 1.7;
color: var(--color);
max-height: 26em;
overflow: auto;
/* pre-wrap honors leading-space indentation (so aligned columns survive)
while still wrapping long string values; overflow-wrap forces the break
mid-word for unbroken URLs / encoded JSON detail strings. */
white-space: pre-wrap;
overflow-wrap: anywhere;
margin: 0;
box-shadow: var(--card-shadow);
}
.errors-page .related-list {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 12px;
max-height: 22em; overflow: auto;
box-shadow: var(--card-shadow);
}
.errors-page .stack-pre {
/* Stack frames look better with a tighter line-height than the curated
JSON view, since each frame is a single readable line. */
line-height: 1.45;
white-space: pre;
overflow-x: auto;
}
.errors-page .related-row {
display: flex; gap: 10px; padding: 6px 12px; align-items: center;
border-bottom: 1px solid var(--border-soft);
font-size: 0.8rem;
}
.errors-page .related-row:last-child { border-bottom: none; }
.errors-page .detail-actions { display: flex; gap: 6px; align-items: center; margin-top: 10px; }
.errors-page .copy-hint { font-size: 0.78rem; color: var(--bucket-info-fg); }
.errors-page .detail-aside {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 18px;
box-shadow: var(--card-shadow);
}
.errors-page .aside-block + .aside-block { margin-top: 16px; }
.errors-page .aside-label {
font-family: var(--font-mono);
font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em;
color: var(--ink-muted); margin-bottom: 4px;
}
.errors-page .aside-value {
font-family: var(--font-serif);
font-size: 1.05rem;
color: var(--color);
word-break: break-word;
line-height: 1.3;
}
.errors-page .aside-value.mono { font-family: var(--font-mono); font-size: 0.82rem; }
.errors-page .aside-sub { color: var(--ink-muted); font-style: italic; font-size: 0.8rem; font-family: var(--font-sans); }
.errors-page .errors-pager { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; color: var(--ink-muted); font-size: 0.85rem; }
@media (max-width: 720px) {
.errors-page .errors-list-head,
.errors-page .errors-row-main { grid-template-columns: 80px 80px 1fr 60px; }
.errors-page .errors-list-head .col-mod,
.errors-page .errors-row-main .col-mod,
.errors-page .errors-list-head .col-sev,
.errors-page .errors-row-main .col-sev { display: none; }
.errors-page .detail-body { grid-template-columns: 1fr; }
}
/* ── Overview page ──────────────────────────────────────────────── */
/* Header with title + range buttons (matches reference top bar) */
.overview-page .ov-header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 16px;
margin-bottom: 2px;
}
/* Status dot */
.overview-page .ov-dot {
display: inline-block;
width: 8px; height: 8px;
border-radius: 50%;
margin-left: 6px;
vertical-align: middle;
}
.overview-page .ov-dot-ok { background: #2F7A44; }
.overview-page .ov-dot-warn { background: #C48A2E; }
.overview-page .ov-dot-idle { background: var(--ink-muted); }
.dark-mode .overview-page .ov-dot-ok { background: #7DC894; }
.dark-mode .overview-page .ov-dot-warn { background: #E8B970; }
/* ── Top KPI row (5 cards) ────────────────────────────────────── */
.overview-page .ov-kpi-row {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 16px;
margin: 16px 0 22px;
}
.overview-page .ov-kpi-card {
background: var(--paper-card, #fff);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 18px 22px;
display: flex;
flex-direction: column;
gap: 4px;
box-shadow: var(--card-shadow);
transition: box-shadow 160ms ease;
}
.overview-page .ov-kpi-card:hover { box-shadow: var(--card-shadow-hover); }
.overview-page .ov-kpi-label {
font-family: var(--font-mono);
font-size: 0.68rem;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--ink-muted);
}
.overview-page .ov-kpi-value {
font-family: var(--font-serif);
font-size: 2.6rem;
font-weight: 400;
line-height: 1;
margin-top: 2px;
color: var(--color);
}
.overview-page .ov-kpi-value.ov-val-warn { color: #B42318; }
.dark-mode .overview-page .ov-kpi-value.ov-val-warn { color: #F08A82; }
.overview-page .ov-kpi-sub {
font-size: 0.76rem;
color: var(--ink-muted);
margin-top: 2px;
}
/* ── Daily highlights ─────────────────────────────────────────── */
.overview-page .ov-daily-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
margin: -4px 0 22px;
}
.overview-page .ov-daily-card {
background: var(--primary-bg);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 16px 20px;
box-shadow: var(--card-shadow);
}
.overview-page .ov-daily-label {
font-family: var(--font-mono);
font-size: 0.68rem;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--ink-muted);
}
.overview-page .ov-daily-value {
font-family: var(--font-serif);
font-size: 2.35rem;
font-weight: 400;
line-height: 1;
color: var(--accent, #3B4AD6);
margin-top: 6px;
}
.overview-page .ov-daily-sub {
font-size: 0.76rem;
color: var(--ink-muted);
margin-top: 5px;
}
.dark-mode .overview-page .ov-daily-card {
background: var(--paper-card);
}
.dark-mode .overview-page .ov-daily-value {
color: #A7B2FF;
}
/* ── Chart cards ─────────────────────────────────────────────── */
.overview-page .ov-chart-row {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16px;
margin-bottom: 18px;
}
.overview-page .ov-chart-card {
background: var(--paper-card, #fff);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 18px 22px 14px;
box-shadow: var(--card-shadow);
}
.overview-page .ov-chart-head {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 14px;
}
.overview-page .ov-chart-title {
font-family: var(--font-serif);
font-size: 1.05rem;
}
.overview-page .ov-chart-legend {
font-family: var(--font-mono);
font-size: 0.7rem;
color: var(--ink-muted);
display: flex;
align-items: center;
gap: 5px;
}
.overview-page .ov-dot-legend {
display: inline-block;
width: 8px; height: 8px;
border-radius: 50%;
}
.overview-page .ov-dot-accent { background: var(--accent, #3B4AD6); }
.overview-page .ov-dot-ok-fill { background: #2F7A44; }
.overview-page .ov-dot-user-fill { background: #8B5E2E; }
.overview-page .ov-dot-new-user-fill { background: #C48A2E; }
.dark-mode .overview-page .ov-dot-ok-fill { background: #7DC894; }
.dark-mode .overview-page .ov-dot-user-fill { background: #D0A15F; }
.dark-mode .overview-page .ov-dot-new-user-fill { background: #E8B970; }
/* Spark bar chart */
.overview-page .ov-spark-bars {
display: flex;
align-items: flex-end;
gap: 3px;
height: 140px;
}
.overview-page .ov-spark-col {
flex: 1;
display: flex;
align-items: flex-end;
height: 100%;
position: relative;
}
.overview-page .ov-spark-fill {
width: 100%;
background: var(--accent, #3B4AD6);
border-radius: 2px 2px 0 0;
transition: height 300ms ease;
opacity: 0.55;
}
.overview-page .ov-spark-fill-alt { background: #2F7A44; }
.overview-page .ov-spark-fill-user { background: #8B5E2E; }
.overview-page .ov-spark-fill-new-user { background: #C48A2E; }
.dark-mode .overview-page .ov-spark-fill-alt { background: #7DC894; }
.dark-mode .overview-page .ov-spark-fill-user { background: #D0A15F; }
.dark-mode .overview-page .ov-spark-fill-new-user { background: #E8B970; }
.overview-page .ov-spark-col:hover .ov-spark-fill { opacity: 1; }
.overview-page .ov-spark-col.has-tip::after {
content: attr(data-tip);
position: absolute;
left: 50%;
bottom: calc(100% + 10px);
transform: translateX(-50%) translateY(4px);
z-index: 10;
padding: 6px 8px;
border-radius: 6px;
background: var(--color);
color: var(--canvas-bg-color);
font-family: var(--font-mono);
font-size: 0.68rem;
line-height: 1;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 120ms ease, transform 120ms ease;
}
.overview-page .ov-spark-col.has-tip::before {
content: "";
position: absolute;
left: 50%;
bottom: calc(100% + 4px);
transform: translateX(-50%) translateY(4px);
z-index: 10;
border: 5px solid transparent;
border-top-color: var(--color);
opacity: 0;
pointer-events: none;
transition: opacity 120ms ease, transform 120ms ease;
}
.overview-page .ov-spark-col.has-tip:hover::after,
.overview-page .ov-spark-col.has-tip:hover::before {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
.overview-page .ov-spark-x {
display: flex;
justify-content: space-between;
font-family: var(--font-mono);
font-size: 0.66rem;
color: var(--ink-muted);
margin-top: 6px;
}
/* ── Three-panel row ──────────────────────────────────────────── */
.overview-page .ov-triple-row {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
margin-bottom: 18px;
}
.overview-page .ov-panel-card {
background: var(--paper-card, #fff);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 18px 20px;
box-shadow: var(--card-shadow);
}
.overview-page .ov-panel-head {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 14px;
}
.overview-page .ov-panel-title {
font-family: var(--font-serif);
font-size: 1.05rem;
}
.overview-page .ov-panel-meta {
font-family: var(--font-mono);
font-size: 0.68rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--ink-muted);
}
.overview-page .ov-panel-foot {
margin-top: 12px;
padding-top: 10px;
border-top: 1px solid var(--border-color);
font-size: 0.82rem;
}
.overview-page .ov-panel-foot a { color: var(--link-color); text-decoration: none; }
.overview-page .ov-panel-foot a:hover { text-decoration: underline; }
/* Stacked horizontal bar (repo status) */
.overview-page .ov-stacked-bar {
display: flex;
height: 18px;
border-radius: 6px;
overflow: hidden;
margin-bottom: 14px;
}
.overview-page .ov-bar-seg { min-width: 2px; transition: width 400ms ease; }
.overview-page .ov-bar-ready { background: #2F7A44; }
.overview-page .ov-bar-preparing { background: #C48A2E; }
.overview-page .ov-bar-error { background: #B42318; }
.overview-page .ov-bar-expired { background: #8A857C; }
.overview-page .ov-bar-removed { background: #B5AFA2; }
.dark-mode .overview-page .ov-bar-ready { background: #7DC894; }
.dark-mode .overview-page .ov-bar-preparing { background: #E8B970; }
.dark-mode .overview-page .ov-bar-error { background: #F08A82; }
.dark-mode .overview-page .ov-bar-expired { background: #6B665E; }
.dark-mode .overview-page .ov-bar-removed { background: #4A453E; }
.overview-page .ov-bar-legend { display: flex; flex-direction: column; gap: 6px; }
.overview-page .ov-legend-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.82rem;
text-decoration: none;
color: inherit;
}
.overview-page .ov-legend-item:hover { text-decoration: none; color: inherit; }
.overview-page .ov-swatch {
display: inline-block;
width: 12px; height: 12px;
border-radius: 3px;
flex-shrink: 0;
}
.overview-page .ov-legend-n {
margin-left: auto;
font-family: var(--font-mono);
font-size: 0.8rem;
font-weight: 600;
}
/* Error horizontal bars */
.overview-page .ov-error-bars { display: flex; flex-direction: column; gap: 12px; }
.overview-page .ov-ebar-row { display: flex; align-items: center; gap: 10px; }
.overview-page .ov-ebar-label {
width: 30px;
flex-shrink: 0;
font-family: var(--font-mono);
font-size: 0.72rem;
text-transform: uppercase;
color: var(--ink-muted);
}
.overview-page .ov-ebar-track {
flex: 1;
height: 10px;
background: var(--hover-bg-color);
border-radius: 5px;
overflow: hidden;
}
.overview-page .ov-ebar-fill {
height: 100%;
border-radius: 5px;
transition: width 400ms ease;
}
.overview-page .ov-ebar-error { background: #B42318; }
.overview-page .ov-ebar-warn { background: #C48A2E; }
.overview-page .ov-ebar-info { background: var(--accent, #3B4AD6); }
.dark-mode .overview-page .ov-ebar-error { background: #F08A82; }
.dark-mode .overview-page .ov-ebar-warn { background: #E8B970; }
.overview-page .ov-ebar-n {
width: 36px;
text-align: right;
font-family: var(--font-mono);
font-size: 0.82rem;
font-weight: 600;
flex-shrink: 0;
}
/* Routes / queue table */
.overview-page .ov-routes-table { display: flex; flex-direction: column; }
.overview-page .ov-route-row {
display: grid;
grid-template-columns: 1fr 60px 60px 60px;
padding: 8px 0;
border-bottom: 1px solid var(--border-soft, var(--border-color));
text-decoration: none;
color: inherit;
font-size: 0.85rem;
align-items: center;
}
.overview-page .ov-route-row:last-child { border-bottom: none; }
.overview-page .ov-route-row:hover { background: var(--hover-bg-color); text-decoration: none; color: inherit; }
.overview-page .ov-route-head {
font-family: var(--font-mono);
font-size: 0.68rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--ink-muted);
border-bottom: 1px solid var(--border-color);
}
.overview-page .ov-route-head:hover { background: transparent; }
.overview-page .ov-route-name {
font-family: var(--font-mono);
font-size: 0.84rem;
}
.overview-page .ov-route-n {
text-align: right;
font-family: var(--font-mono);
font-size: 0.84rem;
}
.overview-page .ov-route-lat { color: var(--ink-muted); }
.overview-page .ov-n-bad { color: #B42318; font-weight: 600; }
.dark-mode .overview-page .ov-n-bad { color: #F08A82; }
/* ── Services bar ─────────────────────────────────────────────── */
.overview-page .ov-services-card {
background: var(--paper-card, #fff);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 18px 22px;
box-shadow: var(--card-shadow);
margin-bottom: 18px;
}
.overview-page .ov-services-head {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 16px;
}
.overview-page .ov-services-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 14px;
}
.overview-page .ov-svc {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 12px 14px;
border: 1px solid var(--border-soft, var(--border-color));
border-radius: 10px;
}
.overview-page .ov-svc-dot {
width: 10px; height: 10px;
border-radius: 50%;
margin-top: 3px;
flex-shrink: 0;
}
.overview-page .ov-svc-info { display: flex; flex-direction: column; gap: 1px; flex: 1; }
.overview-page .ov-svc-name {
font-family: var(--font-mono);
font-size: 0.88rem;
font-weight: 600;
}
.overview-page .ov-svc-meta {
font-size: 0.76rem;
color: var(--ink-muted);
}
.overview-page .ov-svc-detail {
font-size: 0.74rem;
color: var(--ink-muted);
white-space: nowrap;
}
/* ── Responsive ───────────────────────────────────────────────── */
@media (max-width: 900px) {
.overview-page .ov-kpi-row { grid-template-columns: repeat(3, 1fr); }
.overview-page .ov-daily-row { grid-template-columns: repeat(3, 1fr); }
.overview-page .ov-triple-row { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
.overview-page .ov-kpi-row { grid-template-columns: repeat(2, 1fr); }
.overview-page .ov-daily-row { grid-template-columns: 1fr; }
.overview-page .ov-chart-row { grid-template-columns: 1fr; }
.overview-page .ov-header { flex-direction: column; gap: 8px; }
}
@media (max-width: 480px) {
.overview-page .ov-kpi-row { grid-template-columns: 1fr 1fr; }
.overview-page .ov-services-grid { grid-template-columns: 1fr 1fr; }
}