Files
anonymous_github/public/css/style.css
T
tdurieuxandClaude Fable 5.1 88d8225f00 feat: rebuild the landing page around the product
The home page led with a text hero, a boxed stats strip, a numbered
how-it-works list, a trust card and three Bootstrap featurettes with
postage-stamp screenshots. It now shows the product first and stays
flat:

- Hero: copy on the left, the anonymize form in a browser frame on the
  right, one primary CTA plus a link to a real anonymized repository,
  and three reassurance points (free, read-only, expires).
- Proof and live stats collapse into hairline strips with no cards;
  the stat bars keep their daily-delta charts and the "+N today" line.
- Before/after example gets a section head and shows the actual XXXX-n
  masks, each labelled for screen readers.
- "What you get" is one large screenshot with three vertical tabs
  (Anonymize, Review, Manage) instead of three columns. Tabs are real
  buttons with tablist/tab/tabpanel roles, roving tabindex and arrow-key
  navigation; the description and link sit outside the button. Signed-out
  visitors are sent to sign in rather than to a dashboard that redirects.
- FAQ teaser with the three questions that come up most, linking into
  the FAQ anchors.
- Phone layout: tabs become a strip above the screenshot with the
  selected description below it, stats go two-up, panes stack, the CTA
  fills the width, and horizontal overflow is clipped so the hero bleed
  can never cause sideways scrolling.

Removes the dead how-it-works, trust, featurette and metrics styles and
the legacy mobile hero font overrides that fought the new sizes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 12:21:02 +02:00

7026 lines
171 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 =====
Copy-first hero with the product on the right, a flat proof and stats
strip, the before/after example, one screenshot with three tabs, and a
FAQ teaser. Everything sits in .paper-wrap (1140px) and uses the theme
tokens, so dark mode is free. */
.paper-landing {
overflow-x: clip;
}
.paper-wrap {
max-width: 1140px;
margin-left: auto;
margin-right: auto;
padding-left: 32px;
padding-right: 32px;
}
.paper-eyebrow {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-muted);
font-weight: 500;
}
/* Hero */
.paper-hero {
max-width: 1140px;
margin: 0 auto;
padding: 64px 32px 0;
display: grid;
grid-template-columns: 0.95fr 1.05fr;
gap: 48px;
align-items: center;
}
.paper-hero h1.hero-title {
font-family: var(--font-serif);
font-weight: 400;
font-size: clamp(2.6rem, 5.4vw, 4.4rem);
line-height: 1.02;
letter-spacing: -0.025em;
margin: 14px 0 0;
color: var(--color);
text-wrap: balance;
}
.paper-hero h1 .accent {
color: var(--accent);
font-style: italic;
}
.hero-subtitle {
margin-top: 18px;
font-size: 17px;
line-height: 1.55;
color: var(--ink-soft);
max-width: 30em;
text-wrap: pretty;
}
.paper-cta-row {
display: flex;
flex-wrap: wrap;
gap: 18px;
align-items: center;
margin-top: 26px;
}
.btn-hero {
display: inline-flex;
align-items: center;
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: var(--radius-control);
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);
text-decoration: none;
transform: translateY(-1px);
}
.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: var(--radius-control);
}
.btn-hero-ghost:hover {
background: var(--hover-bg-color);
border-color: var(--color);
color: var(--color);
}
.paper-link-arrow {
font-size: 14px;
color: var(--ink-soft);
text-decoration: underline;
text-underline-offset: 4px;
text-decoration-color: var(--border-color);
}
.paper-link-arrow:hover {
color: var(--color);
text-decoration-color: var(--color);
}
.paper-reassure {
list-style: none;
margin: 16px 0 0;
padding: 0;
display: flex;
flex-wrap: wrap;
gap: 6px 16px;
font-size: 12.5px;
color: var(--ink-muted);
}
.paper-reassure li::before {
content: "\2713";
color: var(--status-ready);
margin-right: 6px;
font-size: 11px;
}
/* Browser frame around screenshots */
.paper-frame {
border-radius: var(--radius-surface);
background: var(--paper-card);
border: 1px solid var(--border-color);
box-shadow: 0 24px 60px rgba(26, 24, 21, 0.10), 0 2px 6px rgba(26, 24, 21, 0.04);
overflow: hidden;
}
.dark-mode .paper-frame {
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
}
.paper-frame-bar {
display: flex;
align-items: center;
gap: 8px;
height: 34px;
padding: 0 12px;
border-bottom: 1px solid var(--border-soft);
background: var(--paper-bg-alt);
font-family: var(--font-mono);
font-size: 11px;
color: var(--ink-muted);
}
.paper-frame-bar .dots {
display: flex;
gap: 5px;
}
.paper-frame-bar .dots i {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--border-color);
}
.paper-frame-bar .url {
flex: 1;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.paper-frame img {
display: block;
width: 100%;
height: auto;
}
.paper-hero-shot .paper-frame {
width: 112%;
}
/* Proof strip */
.paper-proof {
margin-top: 64px;
padding-top: 18px;
padding-bottom: 18px;
border-top: 1px solid var(--border-color);
display: flex;
flex-wrap: wrap;
gap: 12px 30px;
align-items: center;
}
.paper-proof-venues {
display: flex;
gap: 22px;
align-items: center;
font-family: var(--font-serif);
font-size: 22px;
letter-spacing: -0.01em;
color: var(--ink-soft);
}
.paper-proof-venues i {
font-style: normal;
font-family: var(--font-sans);
font-size: 14px;
color: var(--ink-faint);
}
/* Stats: one hairline strip, no cards */
.paper-stats {
margin-top: 12px;
padding-top: 22px;
border-top: 1px solid var(--border-color);
}
.paper-stats-meta {
display: flex;
justify-content: space-between;
align-items: center;
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--ink-muted);
margin-bottom: 14px;
}
.paper-stats-meta-right {
display: inline-flex;
align-items: center;
gap: 6px;
}
.paper-stats-dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--status-ready);
}
.paper-stats-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
border-top: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
}
.paper-stat-card {
display: flex;
flex-direction: column;
padding: 22px 26px 20px 0;
margin-right: 26px;
border-right: 1px solid var(--border-color);
min-width: 0;
}
.paper-stat-card:last-child {
border-right: 0;
margin-right: 0;
padding-right: 0;
}
.paper-stat-value {
font-size: 44px;
font-weight: 500;
letter-spacing: -0.04em;
line-height: 1;
color: var(--color);
font-variant-numeric: tabular-nums;
}
.paper-stat-label {
margin-top: 6px;
font-size: 13px;
color: var(--ink-soft);
}
.paper-stat-bars {
display: block;
width: 100%;
height: 34px;
margin-top: 18px;
overflow: visible;
}
.paper-stat-bars rect {
fill: var(--border-color);
}
.paper-stat-bars rect.is-latest {
fill: var(--accent);
}
.paper-stat-delta {
margin-top: 10px;
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--status-ready);
}
/* Section heads */
.paper-section-head {
margin-top: 110px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 40px;
align-items: end;
}
.paper-section-head h2,
.paper-qa h2 {
font-family: var(--font-serif);
font-weight: 400;
font-size: clamp(2rem, 4.2vw, 3.25rem);
line-height: 1.05;
letter-spacing: -0.02em;
margin: 10px 0 0;
color: var(--color);
text-wrap: balance;
}
.paper-section-head h2 em,
.paper-qa h2 em,
.paper-feature-title em {
font-style: italic;
color: var(--accent);
}
.paper-section-head p {
font-size: 15px;
color: var(--ink-soft);
max-width: 32em;
margin: 0;
line-height: 1.6;
}
/* Before / after example */
.paper-preview {
margin-top: 28px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px;
}
.paper-preview .pane {
background: var(--paper-card);
border: 1px solid var(--border-color);
border-radius: var(--radius-surface);
overflow: hidden;
min-width: 0;
}
.paper-preview .pane-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 14px;
border-bottom: 1px solid var(--border-soft);
}
.paper-preview .pane-label {
font-family: var(--font-mono);
font-size: 11px;
color: var(--ink-muted);
white-space: nowrap;
}
.paper-preview .pane-url {
font-family: var(--font-mono);
font-size: 11px;
color: var(--ink-soft);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.paper-preview .pane-body {
padding: 16px 18px;
font-family: var(--font-mono);
font-size: 12.5px;
line-height: 1.9;
color: var(--ink-soft);
}
.paper-preview .pane-body strong {
color: var(--color);
font-weight: 600;
}
.paper-preview .tok {
color: var(--ink-faint);
}
.paper-preview .redact {
background: var(--accent-soft);
color: var(--accent);
border-radius: 4px;
padding: 0 5px;
}
/* Features: vertical tabs on the left, one screenshot on the right */
.paper-features {
margin-top: 28px;
padding-top: 28px;
border-top: 1px solid var(--border-color);
display: grid;
grid-template-columns: 5fr 7fr;
gap: 48px;
align-items: start;
}
.paper-features-list {
display: flex;
flex-direction: column;
}
.paper-feature {
border-left: 2px solid var(--border-soft);
padding: 16px 0 16px 20px;
transition: border-color 0.2s;
}
.paper-feature.is-on {
border-left-color: var(--color);
}
.paper-feature-tab {
all: unset;
display: block;
width: 100%;
cursor: pointer;
color: inherit;
border-radius: 4px;
}
.paper-feature-tab:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 4px;
}
.paper-feature-tab .paper-eyebrow {
display: block;
margin-bottom: 6px;
}
.paper-feature-title {
display: block;
font-family: var(--font-serif);
font-size: 24px;
line-height: 1.15;
letter-spacing: -0.015em;
color: var(--ink-muted);
transition: color 0.2s;
}
.paper-feature-title em {
color: inherit;
}
.paper-feature-tab:hover .paper-feature-title,
.paper-feature.is-on .paper-feature-title {
color: var(--color);
}
.paper-feature.is-on .paper-feature-title em {
color: var(--accent);
}
.paper-feature-more {
display: none;
}
.paper-feature.is-on .paper-feature-more {
display: block;
}
.paper-feature-more .paper-feature-title-m {
display: none;
}
.paper-feature-more p {
font-size: 14.5px;
color: var(--ink-soft);
line-height: 1.55;
margin: 10px 0 12px;
max-width: 30em;
}
.paper-features-stage {
min-width: 0;
}
.paper-feature-panel {
animation: paper-feature-in 0.25s ease-out;
}
@keyframes paper-feature-in {
from { opacity: 0; transform: translateY(4px); }
to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
.paper-feature-panel { animation: none; }
}
/* Each crop zooms on the part of the screenshot that carries the message.
Source screenshots are 2880x1800. */
.paper-crop {
position: relative;
height: 380px;
overflow: hidden;
background: var(--paper-card);
}
.paper-crop img {
position: absolute;
left: 0;
top: 0;
max-width: none;
height: auto;
display: block;
}
.paper-crop-anonymize img { width: 150%; transform: translate(-1.5%, -8%); }
.paper-crop-review img { width: 160%; transform: translate(-1%, -8%); }
.paper-crop-manage img { width: 150%; transform: translate(-6%, -9%); }
/* FAQ teaser */
.paper-qa {
margin-top: 110px;
display: grid;
grid-template-columns: 1fr 1.4fr;
gap: 40px;
align-items: start;
}
.paper-qa h2 {
margin-bottom: 12px;
}
.paper-qa .q {
border-top: 1px solid var(--border-color);
padding: 18px 0;
}
.paper-qa .q:last-child {
border-bottom: 1px solid var(--border-color);
}
.paper-qa .q a {
display: block;
font-weight: 500;
font-size: 15px;
color: var(--color);
margin-bottom: 6px;
}
.paper-qa .q a:hover {
color: var(--accent);
text-decoration: none;
}
.paper-qa .q p {
margin: 0;
font-size: 14px;
color: var(--ink-soft);
line-height: 1.6;
}
/* Tablet */
@media (max-width: 1100px) {
.paper-hero-shot .paper-frame { width: 100%; }
}
@media (max-width: 991px) {
.paper-hero {
grid-template-columns: 1fr;
gap: 36px;
padding-top: 40px;
}
.paper-section-head,
.paper-qa {
grid-template-columns: 1fr;
gap: 16px;
}
.paper-stats-grid {
grid-template-columns: 1fr 1fr;
}
.paper-stat-card:nth-child(2n) {
border-right: 0;
margin-right: 0;
padding-right: 0;
}
.paper-stat-card:nth-child(-n + 2) {
border-bottom: 1px solid var(--border-color);
}
}
/* Phone */
@media (max-width: 767px) {
.paper-wrap,
.paper-hero {
padding-left: 20px;
padding-right: 20px;
}
.paper-hero h1.hero-title {
font-size: clamp(2.4rem, 11vw, 3.25rem);
}
.hero-subtitle {
font-size: 16px;
}
.paper-cta-row .btn-hero {
width: 100%;
justify-content: center;
}
.paper-proof {
margin-top: 48px;
}
.paper-stat-card {
padding: 18px 16px 16px 0;
margin-right: 16px;
}
.paper-stat-value {
font-size: 36px;
}
.paper-section-head,
.paper-qa {
margin-top: 72px;
}
.paper-preview {
grid-template-columns: 1fr;
}
.paper-preview .pane-body {
font-size: 11.5px;
line-height: 1.8;
}
/* Tabs become a strip above the screenshot; the selected description
moves below it. display:contents lets the tab, the panel and the
description reorder as direct children of the section. */
.paper-features {
display: flex;
flex-wrap: wrap;
gap: 0;
padding-top: 0;
border-top: 0;
margin-top: 24px;
}
.paper-features-list,
.paper-feature,
.paper-features-stage {
display: contents;
}
.paper-feature-tab {
order: 1;
flex: 1 1 0;
width: auto;
padding: 12px 0 10px;
border-bottom: 2px solid var(--border-color);
border-radius: 0;
text-align: left;
}
.paper-feature.is-on .paper-feature-tab {
border-bottom-color: var(--color);
}
.paper-feature-tab .paper-eyebrow {
margin: 0;
font-size: 10.5px;
letter-spacing: 0.08em;
}
.paper-feature-tab .paper-feature-title {
display: none;
}
.paper-feature-panel {
order: 2;
width: 100%;
margin-top: 20px;
animation: none;
}
.paper-crop {
height: 240px;
}
.paper-crop-anonymize img { width: 230%; transform: translate(-1.5%, -8%); }
.paper-crop-review img { width: 240%; transform: translate(-1%, -8%); }
.paper-crop-manage img { width: 220%; transform: translate(-3%, -9%); }
.paper-feature-more {
order: 3;
width: 100%;
}
.paper-feature.is-on .paper-feature-more {
margin-top: 18px;
}
.paper-feature-more .paper-feature-title-m {
display: block;
font-size: 26px;
line-height: 1.1;
}
.paper-feature-more p {
max-width: none;
}
.paper-footer-inner > .paper-footer-brand {
grid-column: 1 / -1;
}
.paper-footer-foot {
flex-direction: column;
gap: 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;
}
/* ---- 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; }
}