shynkro_watchlog-obsidian-p.../styles.css
2026-07-06 01:12:48 +01:00

7176 lines
159 KiB
CSS
Raw Permalink 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.

/* ════════════════════════════════════════════════════════
WatchLog Plugin Styles
Uses Obsidian CSS variables throughout.
════════════════════════════════════════════════════════ */
/* ── View shell ─────────────────────────────────────────── */
.wl-view {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
font-size: var(--font-ui-small);
color: var(--text-normal);
/* Default theme: plugin-specific accent vars (themed variants override below) */
--wl-accent: hsl(258deg 6.48% 13.98%);
--wl-rating-color: #BA7517;
--wl-watched-color: #1D9E75;
--wl-group-border-overlay: rgb(0 0 0 / 20%);
}
/* ── Tab bar ────────────────────────────────────────────── */
.wl-tab-bar {
display: flex;
gap: 2px;
padding: 8px 10px 0;
border-bottom: 0.5px solid var(--background-modifier-border);
flex-shrink: 0;
/* Clip the button row so it can never extend past the panel and let the whole
view be dragged sideways ("loose sheet" pan). On mobile the tabs go icon-only
(below) so nothing is actually clipped. */
overflow-x: hidden;
}
/* ── Mobile: icon-only tabs ─────────────────────────────────
Seven text labels overflow a phone-width panel; render Lucide icons instead
and let them share the row equally so all seven fit with no horizontal scroll. */
.wl-view.wl-mobile .wl-tab-bar {
gap: 0;
padding: 6px 4px 0;
}
.wl-tab-btn-icon {
flex: 1 1 0;
min-width: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 7px 0;
position: relative;
}
.wl-tab-btn-icon .svg-icon {
width: 20px;
height: 20px;
}
/* Count badge in icon mode: a small purple dot on the icon (vs. "(N)" on desktop). */
.wl-tab-btn-icon.wl-tab-has-badge::after {
content: '';
position: absolute;
top: 3px;
right: calc(50% - 13px);
width: 7px;
height: 7px;
border-radius: 50%;
background-color: #7F77DD;
}
.wl-tab-btn {
padding: 5px 14px;
background: none;
border: none;
border-bottom: 2px solid transparent;
color: var(--text-muted);
cursor: pointer;
font-size: var(--font-ui-small);
font-weight: 500;
margin-bottom: -0.5px;
transition: color 0.15s, border-color 0.15s;
}
.wl-tab-btn:hover {
color: var(--text-normal);
}
.wl-tab-btn.is-active {
color: var(--text-accent);
border-bottom-color: var(--text-accent);
}
/* ── Tab content ────────────────────────────────────────── */
.wl-tab-content {
flex: 1 1 0%;
min-height: 0;
overflow-y: auto;
/* Clip horizontal overflow so the view can't be panned sideways like a loose
sheet. Without this, overflow-y:auto + the default overflow-x:visible forces
overflow-x to compute to `auto` (per the CSS overflow spec), turning the
scroller into a horizontal scroll container on mobile. */
overflow-x: hidden;
padding: 12px 10px;
}
/* Mobile keyboard fix: WatchLogView pins the tab content to an explicit px
height (passed via --wl-pinned-tab-height) while an editor is focused.
The two-class selector outranks the flex base rule above. */
.wl-tab-content.wl-tab-content-pinned {
flex: none;
height: var(--wl-pinned-tab-height);
}
/* ════════════════════════════════════════════════════════
DASHBOARD TAB
════════════════════════════════════════════════════════ */
/* ── Dashboard container ────────────────────────────────── */
.wl-dashboard {
display: flex;
flex-direction: column;
gap: 0;
}
/* ── Rings grid ─────────────────────────────────────────── */
.wl-rings-grid {
display: grid;
/* Desktop: fixed 3-column layout (original look). Mobile overrides this with a
container-responsive auto-fit grid below. */
grid-template-columns: repeat(3, 1fr);
gap: 12px;
margin-bottom: 16px;
}
/* Mobile: reflow on the actual panel width (not the viewport). Wide enough panels
show up to 3 columns at full ring size and degrade to 2 then 1 as it narrows.
min(110px, 100%) caps the track at the container width so a panel narrower than
one card can never force horizontal overflow. */
.wl-view.wl-mobile .wl-rings-grid {
grid-template-columns: repeat(auto-fit, minmax(min(110px, 100%), 1fr));
}
/* ── Unified Total / Time card ──────────────────────────── */
/* The two vertical dividers are rendered as 1px grid gaps that reveal the
card's background colour. A 1px child border-left did not paint reliably at the
exact column boundary, so the gap-reveal technique is used instead: the gaps
always span the full row height and are guaranteed to paint. */
.wl-dash-unified {
grid-column: 1 / -1;
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: stretch;
gap: 0 1px;
background-color: var(--background-modifier-border); /* shows through the gaps */
border-radius: 8px;
overflow: hidden;
}
.wl-dash-unified-bordered {
border: 2px solid var(--wl-accent);
}
.wl-dash-seg {
display: flex;
flex-direction: column;
justify-content: center;
padding: 10px 12px;
min-width: 0;
background-color: var(--background-secondary-alt); /* covers card bg except gaps */
}
.wl-dash-seg .wl-rect-top {
justify-content: space-between;
align-items: baseline;
gap: 8px;
}
.wl-dash-seg-center {
align-items: center;
text-align: center;
}
.wl-dash-seg-label {
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
margin-bottom: 6px;
}
.wl-dash-seg-value {
font-size: 18px;
font-weight: 700;
color: var(--text-normal);
line-height: 1.1;
}
.wl-ring-item {
/* Single source of truth for the gauge circle size; the SVG and the accent
ring (::before) both derive from it so they stay locked together. */
--wl-ring-size: 110px;
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
position: relative;
/* Let the grid track shrink below the card's intrinsic content width. */
min-width: 0;
}
/* Accent ring: anchored to the SVG circle rather than the whole card.
The SVG is the first child (so its centre is one half-size down from the
item top) and its viewBox is 120 with the arc's outer edge at radius 50,
i.e. 100/120 of the box. Sizing the ring just outside that keeps it flush
against the arc at any gauge size. */
.wl-ring-item::before {
content: '';
position: absolute;
width: calc(var(--wl-ring-size) * 0.855);
height: calc(var(--wl-ring-size) * 0.855);
border-radius: 50%;
border: 2px solid var(--wl-accent);
opacity: 0.9;
top: calc(var(--wl-ring-size) / 2);
left: 50%;
transform: translate(-50%, -50%);
}
.wl-ring-svg {
width: var(--wl-ring-size);
/* Scale down (keeping the square aspect) if the cell is narrower than the
gauge, so a column can drop below 110px without overflowing. */
max-width: 100%;
height: auto;
aspect-ratio: 1 / 1;
overflow: visible;
}
.wl-ring-track {
stroke: var(--background-modifier-border);
}
.wl-ring-arc {
transition: stroke-dashoffset 0.4s ease;
}
.wl-ring-percent-text {
font-size: 18px;
font-weight: 700;
fill: var(--text-normal);
}
.wl-ring-sub-text {
font-size: 11px;
fill: var(--text-muted);
}
.wl-ring-label {
font-size: var(--font-ui-small);
font-weight: 600;
color: var(--text-normal);
}
.wl-ring-subtitle {
font-size: 13px;
color: var(--text-muted);
}
/* Single-line reading subline under a ring card (reserved on type cards too,
so every ring card stays the same height). */
.wl-ring-subline {
font-size: 11px;
min-height: 1.3em;
line-height: 1.3;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* ── Summary metrics ────────────────────────────────────── */
.wl-summary-metrics {
margin-bottom: 16px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
overflow: hidden;
}
.wl-metric-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 12px;
border-bottom: 0.5px solid var(--background-modifier-border);
}
.wl-metric-row:last-child {
border-bottom: none;
}
.wl-metric-label {
color: var(--text-muted);
}
.wl-metric-value {
font-weight: 600;
color: var(--text-normal);
}
/* ── Time ring text ─────────────────────────────────────── */
.wl-ring-time-text {
font-size: 13px;
font-weight: 700;
fill: var(--text-normal);
}
/* ── Recently watched ───────────────────────────────────── */
.wl-section-title {
font-size: var(--font-ui-small);
font-weight: 600;
color: var(--text-normal);
text-transform: uppercase;
letter-spacing: 0.04em;
margin-bottom: 8px;
}
.wl-recently-watched {
margin-bottom: 8px;
}
.wl-rw-item {
display: flex;
align-items: center;
gap: 8px;
padding: 7px 10px;
border-radius: 5px;
margin-bottom: 4px;
background: var(--background-secondary);
}
.wl-rw-title {
flex: 1;
min-width: 0;
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Fixed 3-column right side: badge | ep | pct */
.wl-rw-col-badge {
flex-shrink: 0;
}
.wl-rw-col-ep {
width: 38px;
flex-shrink: 0;
font-size: 11px;
font-weight: 500;
color: var(--text-muted);
white-space: nowrap;
}
.wl-rw-col-pct {
width: 32px;
flex-shrink: 0;
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
text-align: right;
white-space: nowrap;
}
/* ── Empty state ────────────────────────────────────────── */
.wl-empty-state {
color: var(--text-muted);
font-style: italic;
padding: 12px 0;
text-align: center;
}
/* ════════════════════════════════════════════════════════
LIST TAB
════════════════════════════════════════════════════════ */
.wl-list {
display: flex;
flex-direction: column;
gap: 6px;
}
/* ── Header ─────────────────────────────────────────────── */
.wl-list-header {
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: 4px;
}
.wl-list-title {
font-size: 15px;
font-weight: 700;
}
.wl-add-btn {
/* color via .wl-btn-success */
padding: 4px 10px;
border-radius: 4px;
cursor: pointer;
font-size: var(--font-ui-small);
font-weight: 500;
}
/* ── Search ─────────────────────────────────────────────── */
.wl-search-wrap {
width: 100%;
}
.wl-search-input {
width: 100%;
padding: 6px 10px;
border-radius: 5px;
border: 0.5px solid var(--background-modifier-border);
background: var(--background-primary);
color: var(--text-normal);
font-size: var(--font-ui-small);
box-sizing: border-box;
}
.wl-search-input:focus {
outline: none;
border-color: var(--interactive-accent);
}
.wl-select {
padding: 4px 6px;
border-radius: 4px;
border: 0.5px solid var(--background-modifier-border);
background: var(--background-secondary);
color: var(--text-normal);
font-size: 11px;
cursor: pointer;
flex: 1;
min-width: 0;
}
.wl-select-sm {
flex: unset;
width: auto;
}
.wl-select:focus {
outline: none;
border-color: var(--interactive-accent);
}
/* ── Divider ────────────────────────────────────────────── */
.wl-divider {
height: 0.5px;
background: var(--background-modifier-border);
margin: 2px 0;
}
/* ── Results count ──────────────────────────────────────── */
.wl-results-count {
font-size: 14px;
font-weight: 700;
color: var(--text-normal);
padding: 2px 0;
}
/* ── Table ──────────────────────────────────────────────── */
.wl-table-section {
display: flex;
flex-direction: column;
gap: 4px;
}
.wl-table {
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
overflow: hidden;
}
/* Virtual-scroll: fixed-height container; children are absolutely positioned */
.wl-virt-container {
position: relative;
}
/* Virtual-scroll: each rendered item; top is set inline from the offset table */
.wl-virt-item {
position: absolute;
left: 0;
right: 0;
}
.wl-table-header-row {
display: grid;
/* Title | Priority | Started | Rating | Status | Pin */
grid-template-columns: 1fr 56px 72px 56px 90px 20px;
padding: 5px 8px;
background: #626262;
font-size: 12px;
font-weight: 600;
color: #ffffff;
border-bottom: 0.5px solid var(--background-modifier-border);
}
.wl-col-priority-h,
.wl-col-started-h,
.wl-col-rating-h,
.wl-col-status-h {
text-align: center;
}
/* ── Row ────────────────────────────────────────────────── */
.wl-row {
display: grid;
grid-template-columns: 1fr 56px 72px 56px 90px 20px;
padding: 7px 8px;
align-items: center;
cursor: pointer;
border-bottom: 2px solid var(--wl-group-border-overlay);
transition: background 0.1s;
border-top: 2px solid var(--wl-group-border-overlay);
border-left: 2px solid rgb(255 255 255 / 20%);
border-right: 2px solid rgb(255 255 255 / 20%);
}
/* Visible gap between top-level rows and after accordions */
.wl-row + .wl-row:not(.wl-row-indented),
.wl-accordion + .wl-row:not(.wl-row-indented) {
margin-top: 8px;
}
.wl-row:hover {
background: var(--background-modifier-hover);
}
.wl-row.is-expanded {
background: var(--background-secondary);
}
.wl-col-title {
min-width: 0;
display: flex;
flex-direction: column;
gap: 3px;
/* Fix #2: prevent badge from stretching to full column width */
align-items: flex-start;
}
.wl-row-title-text {
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.wl-col-started {
font-size: 11px;
color: var(--text-muted);
text-align: center;
}
/* ── Rating column ──────────────────────────────────────── */
.wl-col-rating {
display: flex;
align-items: center;
justify-content: center;
}
.wl-row-rating {
font-size: 11px;
color: var(--wl-rating-color);
font-weight: 600;
white-space: nowrap;
}
.wl-row-rating-empty {
color: var(--text-faint);
font-weight: 400;
}
.wl-col-status {
display: flex;
align-items: center;
justify-content: center;
}
/* wl-chevron kept for season headers only */
.wl-chevron {
font-size: 18px;
color: var(--text-muted);
display: inline-block;
transition: transform 0.2s;
}
.wl-chevron.is-open {
transform: rotate(90deg);
}
/* ── Progress bar ───────────────────────────────────────── */
.wl-progress-wrap {
height: 3px;
background: var(--background-modifier-border);
border-radius: 2px;
overflow: hidden;
width: 100%;
}
.wl-progress-bar {
height: 100%;
background: var(--wl-accent);
border-radius: 2px;
transition: width 0.3s ease;
min-width: 0;
}
/* ── Badges ─────────────────────────────────────────────── */
.wl-badge {
display: inline-block;
padding: 2px 7px;
border-radius: 20px;
font-size: 11px;
font-weight: 500;
color: #ffffff;
white-space: nowrap;
line-height: 1.4;
}
.wl-badge-sm {
padding: 1px 6px;
font-size: 10px;
}
.wl-badge-plain {
display: inline-block;
font-size: 11px;
font-weight: bold;
color: var(--text-normal);
white-space: nowrap;
}
/* ════════════════════════════════════════════════════════
ACCORDION
════════════════════════════════════════════════════════ */
.wl-accordion {
padding: 12px 10px;
background: var(--background-primary-alt);
border-bottom: 0.5px solid var(--background-modifier-border);
}
/* ── Accordion header ───────────────────────────────────── */
.wl-accordion-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 12px;
gap: 10px;
}
.wl-acc-header-left {
flex: 1;
min-width: 0;
}
.wl-acc-subtitle {
font-size: 14px;
font-weight: 600;
color: var(--text-normal);
display: flex;
align-items: center;
gap: 5px;
}
.wl-acc-header-right {
flex-shrink: 0;
text-align: right;
min-width: 70px;
}
.wl-acc-percent {
font-size: 15px;
font-weight: 700;
line-height: 1;
}
.wl-acc-progress-label {
font-size: 11px;
color: var(--text-muted);
margin-bottom: 4px;
}
.wl-acc-progress-wrap {
height: 3px;
background: var(--background-modifier-border);
border-radius: 2px;
overflow: hidden;
width: 70px;
}
/* ── Accordion body ─────────────────────────────────────── */
.wl-accordion-body {
margin-bottom: 12px;
}
/* ── Season ─────────────────────────────────────────────── */
.wl-season-wrap {
margin-bottom: 10px;
}
.wl-season-header {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
padding: 4px 0;
user-select: none;
}
.wl-season-header:hover {
opacity: 0.85;
}
.wl-season-badge {
display: inline-block;
padding: 2px 10px;
border-radius: 20px;
font-size: 11px;
font-weight: 600;
color: #ffffff;
}
.wl-season-ep-count {
font-size: 11px;
color: var(--text-muted);
flex: 1;
}
/* ── Episode grid ───────────────────────────────────────── */
.wl-episode-grid {
display: flex;
flex-wrap: wrap;
gap: 4px;
padding: 6px 0;
}
.wl-episode-box {
width: 28px;
height: 28px;
border-radius: 4px;
border: 0.5px solid var(--background-modifier-border);
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
font-weight: 500;
cursor: pointer;
background: var(--background-primary);
color: var(--text-muted);
transition: background 0.15s, color 0.15s, border-color 0.15s;
user-select: none;
}
.wl-episode-box:hover {
border-color: var(--interactive-accent);
color: var(--text-normal);
}
.wl-episode-box.is-watched {
background: var(--wl-watched-color);
border-color: var(--wl-watched-color);
color: #ffffff;
font-size: 14px;
}
.wl-episode-box.is-skipped {
border-color: #6b2972;
color: #6b2972;
font-size: 14px;
}
/* Watched + skipped: keep watched background, override border to purple */
.wl-episode-box.is-watched.is-skipped {
border-color: #6b2972;
}
/* ── Season fill/clear button ───────────────────────────── */
.wl-season-fill-btn {
width: 20px;
height: 28px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
font-weight: 700;
cursor: pointer;
user-select: none;
transition: opacity 0.15s;
flex-shrink: 0;
}
.wl-season-fill-btn.is-fill {
background: #1D9E75;
border: 0.5px solid #1D9E75;
color: #ffffff;
}
.wl-season-fill-btn.is-clear {
background: #E24B4A;
border: 0.5px solid #E24B4A;
color: #ffffff;
}
.wl-season-fill-btn:hover {
opacity: 0.75;
}
/* ── Movie row ──────────────────────────────────────────── */
.wl-movie-row {
display: flex;
align-items: center;
gap: 10px;
padding: 6px 0;
}
.wl-movie-checkbox {
width: 16px;
height: 16px;
cursor: pointer;
}
.wl-movie-label {
font-weight: 500;
}
/* ── Accordion footer ───────────────────────────────────── */
.wl-accordion-footer {
border-top: 0.5px solid var(--background-modifier-border);
padding-top: 10px;
display: flex;
flex-direction: column;
gap: 8px;
}
.wl-stars-row {
display: flex;
align-items: center;
gap: 8px;
}
.wl-stars-label {
font-size: 11px;
color: var(--text-muted);
width: 48px;
flex-shrink: 0;
}
.wl-stars {
display: flex;
gap: 3px;
}
.wl-star {
font-size: 18px;
color: var(--text-faint);
cursor: pointer;
transition: color 0.12s;
line-height: 1;
}
.wl-star:hover,
.wl-star.is-active {
color: var(--wl-rating-color);
}
.wl-footer-row {
display: flex;
align-items: center;
gap: 8px;
}
.wl-footer-label {
font-size: 11px;
color: var(--text-muted);
width: 80px;
flex-shrink: 0;
}
.wl-notes-input {
flex: 1;
padding: 4px 8px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
font-size: var(--font-ui-small);
}
.wl-footer-date {
padding: 3px 6px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
font-size: var(--font-ui-small);
}
.wl-footer-today-btn {
font-size: 11px;
padding: 2px 8px;
line-height: 1.4;
}
.wl-footer-today-btn.is-dimmed {
opacity: 0.4;
cursor: default;
}
.wl-footer-action-row {
margin-top: 4px;
gap: 6px;
justify-content: space-between;
}
.wl-edit-btn {
padding: 3px 10px;
background: transparent;
border: 0.5px solid var(--background-modifier-border);
color: var(--text-normal);
border-radius: 4px;
cursor: pointer;
font-size: 11px;
}
.wl-edit-btn:hover {
background: var(--background-modifier-hover);
}
.wl-delete-btn {
/* color via .wl-btn-danger */
padding: 3px 10px;
border-radius: 4px;
cursor: pointer;
font-size: 11px;
}
/* ════════════════════════════════════════════════════════
INLINE WIDGET
════════════════════════════════════════════════════════ */
.wl-widget {
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
padding: 8px 10px;
background: var(--background-secondary);
margin: 4px 0;
}
.wl-widget-main-row {
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.wl-widget-cb,
.wl-widget-next-cb {
width: 14px;
height: 14px;
cursor: pointer;
flex-shrink: 0;
}
.wl-widget-title {
font-weight: 600;
font-size: var(--font-ui-small);
}
.wl-widget-sep {
color: var(--text-faint);
font-size: 10px;
padding: 0 1px;
}
.wl-widget-bar-wrap {
flex: 1;
min-width: 40px;
height: 3px;
background: var(--background-modifier-border);
border-radius: 2px;
overflow: hidden;
}
.wl-widget-percent {
font-size: 11px;
color: var(--text-muted);
font-weight: 600;
}
.wl-widget-date {
font-size: 11px;
color: var(--text-faint);
}
.wl-widget-next-row {
display: flex;
align-items: center;
gap: 6px;
margin-top: 5px;
padding-top: 5px;
border-top: 0.5px solid var(--background-modifier-border);
}
.wl-widget-next-label {
font-size: 11px;
color: var(--text-muted);
}
.wl-widget-error {
color: var(--text-error);
font-size: var(--font-ui-small);
font-style: italic;
padding: 4px 8px;
}
/* ════════════════════════════════════════════════════════
MODALS
════════════════════════════════════════════════════════ */
.wl-add-modal {
display: flex;
flex-direction: column;
gap: 8px;
padding: 4px 0;
}
.wl-modal-row {
display: flex;
align-items: center;
gap: 8px;
}
.wl-modal-label {
font-size: 12px;
color: var(--text-muted);
width: 110px;
flex-shrink: 0;
}
/* Two labelled fields sharing one row, with fixed-width inputs anchored into
two columns (rather than stretched to 50%) to save vertical space. */
.wl-modal-pair-cell {
display: flex;
align-items: center;
gap: 8px;
}
/* Right group anchors to the row's right edge, leaving empty space in the
middle, so its input's right edge meets the full-width fields' right edge. */
.wl-modal-pair-cell-right {
margin-left: auto;
}
/* Left cell keeps the standard 110px label so its input's left edge lines up
with the full-width (Title) input; the right cell's label is natural width. */
.wl-modal-pair-cell-right .wl-modal-label {
width: auto;
}
/* All four paired fields (two number inputs + two selects) share one fixed,
narrow width — only their left/right edges align with the full-width fields;
they intentionally do not span the row. */
.wl-modal-pair-cell .wl-modal-input,
.wl-modal-pair-cell .wl-select {
flex: 0 0 auto;
width: 110px;
min-width: 0;
}
.wl-modal-input {
flex: 1;
padding: 5px 8px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
font-size: var(--font-ui-small);
}
.wl-modal-input-sm {
max-width: 80px;
flex: unset;
}
.wl-modal-input:focus {
outline: none;
border-color: var(--interactive-accent);
}
.wl-modal-info {
font-size: 11px;
color: var(--text-muted);
font-style: italic;
}
.wl-modal-error {
font-size: 11px;
color: var(--text-error);
font-style: italic;
}
/* Doubled class (+ :focus variant) outranks Obsidian's `input[type=…]` /
`input[type=…]:focus` border rules and `.wl-modal-input:focus` above. */
.wl-input-error.wl-input-error,
.wl-input-error.wl-input-error:focus {
border-color: var(--text-error);
}
/* Full-width text input (group rename prompt). */
.wl-input {
width: 100%;
}
.wl-modal-textarea {
flex: 1;
width: 100%;
padding: 5px 8px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
font-size: var(--font-ui-small);
resize: vertical;
font-family: inherit;
box-sizing: border-box;
}
.wl-modal-textarea:focus {
outline: none;
border-color: var(--interactive-accent);
}
.wl-modal-input-stack {
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
}
.wl-modal-results {
/* Grown by ~2 reclaimed form rows (Episodes/duration + Status/priority now
pair onto single rows) so the results list fills the freed vertical space
while the overall modal height stays the same. */
max-height: 272px;
overflow-y: auto;
border: 0.5px solid var(--background-modifier-border);
border-radius: 5px;
margin-top: 2px;
}
.wl-result-item {
padding: 7px 10px;
cursor: pointer;
border-bottom: 0.5px solid var(--background-modifier-border);
transition: background 0.1s;
}
/* Rows that carry a cover thumbnail lay out as a flex row (thumb · text). */
.wl-result-item.wl-has-thumb {
display: flex;
align-items: center;
gap: 10px;
}
.wl-result-item:last-child {
border-bottom: none;
}
.wl-result-text {
min-width: 0;
flex: 1 1 auto;
}
/* Shared cover thumbnail for add-flow search-result rows (poster 2:3). */
.wl-result-thumb {
position: relative;
flex: 0 0 auto;
width: 40px;
height: 60px;
border-radius: 3px;
overflow: hidden;
background: var(--background-modifier-border);
display: flex;
align-items: center;
justify-content: center;
}
.wl-result-thumb-icon {
font-size: 18px;
opacity: 0.6;
line-height: 1;
}
.wl-result-thumb-img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.wl-result-item:hover,
.wl-result-item.is-selected,
.wl-result-item.wl-result-item-focused {
background: var(--background-modifier-hover);
}
.wl-result-title {
font-weight: 500;
font-size: var(--font-ui-small);
}
.wl-result-meta {
font-size: 11px;
color: var(--text-muted);
}
.wl-modal-loading {
padding: 10px;
text-align: center;
color: var(--text-muted);
font-style: italic;
font-size: var(--font-ui-small);
}
.wl-modal-form {
display: flex;
flex-direction: column;
gap: 7px;
margin-top: 4px;
padding-top: 10px;
border-top: 0.5px solid var(--background-modifier-border);
}
.wl-modal-btn-row {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
margin-top: 4px;
gap: 8px;
}
.wl-duplicate-warning {
display: flex;
align-items: center;
gap: 8px;
background: color-mix(in srgb, var(--background-modifier-error) 60%, transparent 40%);
border: 0.5px solid color-mix(in srgb, var(--background-modifier-border) 50%, #E24B4A 50%);
border-radius: 4px;
padding: 6px 10px;
font-size: var(--font-ui-small);
color: var(--text-normal);
width: 100%;
box-sizing: border-box;
}
.wl-btn {
padding: 5px 12px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-secondary);
color: var(--text-normal);
cursor: pointer;
font-size: var(--font-ui-small);
}
.wl-btn:hover {
background: var(--background-modifier-hover);
}
.wl-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.wl-btn:disabled:hover {
background: var(--background-secondary);
}
/* ── Custom Lists import modal ─────────────────────────── */
.wl-import-textarea {
min-height: 140px;
margin: 8px 0;
font-family: var(--font-monospace);
}
.wl-import-header-toggle {
display: flex;
align-items: center;
gap: 6px;
margin: 4px 0 10px;
}
.wl-import-header-toggle label {
font-size: var(--font-ui-small);
color: var(--text-muted);
cursor: pointer;
}
.wl-import-header-checkbox {
cursor: pointer;
}
.wl-import-preview {
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 8px;
}
.wl-import-counts {
font-size: var(--font-ui-small);
color: var(--text-muted);
}
.wl-import-banner {
padding: 6px 10px;
border-radius: 4px;
background: color-mix(in srgb, var(--background-secondary) 80%, #BA7517 20%);
border: 0.5px solid color-mix(in srgb, var(--background-modifier-border) 60%, #BA7517 40%);
font-size: 11px;
color: var(--text-muted);
line-height: 1.5;
}
.wl-import-banner-error {
padding: 6px 10px;
border-radius: 4px;
background: color-mix(in srgb, var(--background-modifier-error) 50%, transparent 50%);
border: 0.5px solid color-mix(in srgb, var(--background-modifier-border) 50%, #E24B4A 50%);
font-size: 11px;
color: var(--text-normal);
line-height: 1.5;
}
.wl-btn-primary {
/* green color scheme — matches .wl-btn-success */
background: transparent;
color: var(--color-green);
border-color: var(--color-green);
}
.wl-btn-primary:hover {
background: var(--color-green);
color: var(--text-on-accent);
border-color: var(--color-green);
}
/* ════════════════════════════════════════════════════════
SETTINGS
════════════════════════════════════════════════════════ */
.wl-settings-nav {
display: flex;
gap: 2px;
margin-bottom: 16px;
border-bottom: 0.5px solid var(--background-modifier-border);
padding-bottom: 0;
}
.wl-settings-nav-btn {
padding: 6px 16px;
background: none;
border: none;
border-bottom: 2px solid transparent;
color: var(--text-muted);
cursor: pointer;
font-size: var(--font-ui-small);
font-weight: 500;
margin-bottom: -0.5px;
transition: color 0.15s, border-color 0.15s;
}
.wl-settings-nav-btn:hover {
color: var(--text-normal);
}
.wl-settings-nav-btn.is-active {
color: var(--text-accent);
border-bottom-color: var(--text-accent);
}
.wl-settings-section-title {
font-size: 12px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
margin: 14px 0 8px;
}
.wl-settings-info {
font-size: var(--font-ui-small);
color: var(--text-muted);
background: var(--background-secondary);
border-radius: 5px;
padding: 8px 12px;
margin-bottom: 10px;
border-left: 3px solid var(--interactive-accent);
}
.wl-status-indicator {
font-size: 12px;
color: var(--text-muted);
margin: 4px 0 8px;
}
.wl-status-ok {
color: #1D9E75;
font-weight: 600;
}
.wl-status-error {
color: #E24B4A;
font-weight: 600;
}
/* ── API settings callouts ──────────────────────────────── */
.wl-api-callout {
border: 1px solid var(--background-modifier-border);
border-left-width: 3px;
border-radius: 8px;
padding: 10px 14px 14px;
margin: 14px 0;
background: var(--background-secondary);
}
.wl-api-callout-title {
font-size: 13px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
margin-bottom: 4px;
}
/* Muted, theme-aware tints — discreet rather than loud. */
.wl-api-callout--movies {
border-left-color: rgba(74, 137, 220, 0.55);
background: rgba(74, 137, 220, 0.06);
}
.wl-api-callout--movies .wl-api-callout-title { color: rgba(74, 137, 220, 0.95); }
.wl-api-callout--anime {
border-left-color: rgba(45, 168, 115, 0.55);
background: rgba(45, 168, 115, 0.06);
}
.wl-api-callout--anime .wl-api-callout-title { color: rgba(45, 168, 115, 0.95); }
.wl-api-callout--books {
border-left-color: rgba(214, 158, 46, 0.6);
background: rgba(214, 158, 46, 0.07);
}
.wl-api-callout--books .wl-api-callout-title { color: rgba(214, 158, 46, 0.95); }
/* ── Tag sections ───────────────────────────────────────── */
.wl-tag-section {
margin-bottom: 16px;
padding: 10px 12px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
}
.wl-tags-list {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 8px;
min-height: 24px;
}
.wl-tag-pill {
display: flex;
align-items: center;
gap: 5px;
padding: 3px 8px;
border-radius: 20px;
background: var(--background-secondary);
border: 0.5px solid var(--background-modifier-border);
font-size: 12px;
}
.wl-tag-dot-wrap {
position: relative;
display: inline-flex;
cursor: pointer;
}
.wl-tag-dot-wrap:hover .wl-tag-dot {
outline: 2px solid var(--interactive-accent);
outline-offset: 1px;
}
.wl-tag-dot {
width: 8px;
height: 8px;
border-radius: 50%;
display: inline-block;
flex-shrink: 0;
}
.wl-tag-color-picker {
position: absolute;
width: 0;
height: 0;
opacity: 0;
pointer-events: none;
}
/* Season color palette */
.wl-season-colors-list {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 8px;
}
.wl-season-color-pill {
display: flex;
align-items: center;
gap: 5px;
background: var(--background-secondary);
border-radius: 4px;
padding: 3px 6px;
font-size: 12px;
}
.wl-season-color-label {
color: var(--text-muted);
font-size: 11px;
}
.wl-tag-name {
color: var(--text-normal);
}
.wl-tag-del {
color: var(--text-faint);
cursor: pointer;
font-size: 14px;
line-height: 1;
margin-left: 2px;
}
.wl-tag-del:hover {
color: var(--text-error);
}
.wl-tag-add-row {
display: flex;
gap: 6px;
align-items: center;
}
.wl-color-input {
width: 36px;
height: 28px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 4px;
padding: 2px;
cursor: pointer;
background: none;
}
/* ── Folders ────────────────────────────────────────────── */
.wl-folder-list {
margin: 8px 0;
}
.wl-folder-row {
display: flex;
gap: 10px;
padding: 5px 0;
border-bottom: 0.5px solid var(--background-modifier-border);
font-size: var(--font-ui-small);
}
.wl-folder-type {
font-weight: 500;
width: 100px;
flex-shrink: 0;
}
.wl-folder-path {
color: var(--text-muted);
font-family: var(--font-monospace);
font-size: 11px;
}
/* ════════════════════════════════════════════════════════
MOBILE RESPONSIVE
════════════════════════════════════════════════════════ */
@media (max-width: 600px) {
/* FEATURE 2 — hide Priority, Started, Rating columns */
.wl-col-priority,
.wl-col-priority-h,
.wl-col-started,
.wl-col-started-h,
.wl-col-rating,
.wl-col-rating-h {
display: none;
}
.wl-table-header-row,
.wl-row {
grid-template-columns: 1fr 90px 20px;
}
/* FEATURE 3 — smaller toolbar buttons */
.wl-header-controls .wl-btn,
.wl-header-controls .wl-add-btn {
font-size: 10px;
padding: 3px 6px;
}
}
@media (max-width: 400px) {
/* Tighten the rings-grid gap on very small screens; column count and ring
size are now handled by the auto-fit grid + scaling SVG above. */
.wl-rings-grid {
gap: 8px;
}
.wl-table-header-row,
.wl-row {
grid-template-columns: 1fr 56px 20px;
}
.wl-col-started,
.wl-col-rating,
.wl-col-started-h,
.wl-col-rating-h,
.wl-col-priority,
.wl-col-priority-h {
display: none;
}
.wl-episode-grid {
gap: 3px;
}
.wl-episode-box {
width: 30px;
height: 30px;
font-size: 10px;
}
}
@media (max-width: 600px) {
.wl-accordion-header {
flex-wrap: wrap;
}
.wl-acc-header-left {
width: 100%;
margin-bottom: 6px;
}
.wl-acc-right-group {
width: 100%;
}
}
/* ════════════════════════════════════════════════════════
NEW IN 0.3.0
════════════════════════════════════════════════════════ */
/* ── +Add / Edit button dropdown ────────────────────────── */
.wl-add-btn-wrap {
position: relative;
}
.wl-dropdown {
position: absolute;
top: calc(100% + 4px);
right: 0;
z-index: 200;
background: var(--background-primary);
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
min-width: 168px;
padding: 4px 0;
}
/* Popovers anchored to a button via dynamic top/left (ReadingTab) instead of
the default right-aligned drop placement. */
.wl-dropdown.wl-popover-anchored {
right: auto;
}
/* ── Group header row ────────────────────────────────────── */
.wl-table .wl-group-row {
background: transparent;
border: 2px solid var(--wl-group-border-overlay);
border-left: 4px solid var(--wl-accent);
border-right: 4px solid var(--wl-accent);
}
.wl-group-name {
font-weight: 600;
}
.wl-group-stats {
font-size: 11px;
color: var(--text-muted);
margin-top: 2px;
}
/* ── Indented member rows (inside expanded group) ────────── */
.wl-row-indented {
padding-left: 24px;
background: var(--background-primary-alt);
border-left: 2px solid var(--background-modifier-border);
}
/* ── Per-title stats: right-side group (3 stat blocks + progress) ── */
.wl-acc-right-group {
display: flex;
flex-direction: row;
gap: 20px;
flex-shrink: 0;
align-items: flex-start;
background: rgb(0 0 0 / 5%);
border: 1px solid rgb(255 255 255 / 15%);
border-radius: 6px;
padding: 6px 6px;
font-size: 5px;
}
/* Each stat block (left / watched / episodes) — centered under their numbers */
.wl-acc-stat-block {
flex-shrink: 0;
text-align: center;
min-width: 50px;
}
/* ════════════════════════════════════════════════════════
MINIMAL WIDGET
════════════════════════════════════════════════════════ */
.wl-widget-minimal {
display: inline-flex;
margin: 2px 0;
}
.wl-widget-minimal-row {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 3px 8px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 20px;
background: var(--background-secondary);
white-space: nowrap;
}
/* ════════════════════════════════════════════════════════
GROUP ACTION BUTTONS (rename / delete)
════════════════════════════════════════════════════════ */
.wl-group-name-row {
display: flex;
align-items: center;
gap: 5px;
min-width: 0;
}
.wl-group-action-btn {
flex-shrink: 0;
width: 20px;
height: 20px;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: 0.5px solid var(--background-modifier-border);
border-radius: 3px;
color: var(--text-muted);
cursor: pointer;
font-size: 11px;
line-height: 1;
transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.wl-group-action-btn:hover {
background: var(--background-modifier-hover);
color: var(--text-normal);
border-color: var(--interactive-accent);
}
/* .wl-group-action-btn-delete — color via .wl-btn-danger */
.wl-group-rename-input {
flex: 1;
min-width: 0;
padding: 2px 6px;
border: 0.5px solid var(--interactive-accent);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
font-size: var(--font-ui-small);
font-weight: 600;
}
.wl-group-rename-input:focus {
outline: none;
}
/* ════════════════════════════════════════════════════════
AIRTIME TAB
════════════════════════════════════════════════════════ */
.wl-airtime {
display: flex;
flex-direction: column;
gap: 6px;
}
/* ── Cards container ─────────────────────────────────── */
.wl-airtime-cards {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 4px;
}
/* ── Single card ─────────────────────────────────────── */
.wl-airtime-card {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 10px;
padding: 4px 6px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
background: var(--background-secondary);
transition: background 0.1s;
}
.wl-airtime-card:hover {
background: var(--background-modifier-hover);
}
/* ── Left section ────────────────────────────────────── */
.wl-airtime-card-left {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 4px;
}
.wl-airtime-card-title {
font-weight: 600;
font-size: var(--font-ui-small);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.wl-airtime-card-meta {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 6px;
}
.wl-airtime-schedule {
font-size: 11px;
color: var(--text-muted);
}
/* ── Right section ───────────────────────────────────── */
.wl-airtime-card-right {
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 6px;
}
/* ── Countdown pill ──────────────────────────────────── */
.wl-airtime-pill {
padding: 2px 10px;
border-radius: 20px;
font-size: 11px;
font-weight: 600;
white-space: nowrap;
}
.wl-airtime-pill-today {
background: #7F77DD;
color: #ffffff;
}
.wl-airtime-pill-tomorrow {
background: #1D9E75;
color: #ffffff;
}
.wl-airtime-pill-days {
background: var(--background-primary);
color: var(--text-muted);
border: 0.5px solid var(--background-modifier-border);
}
.wl-airtime-pill-today-series {
background: #EEEDFE;
color: #3C3489;
border: 0.5px solid #AFA9EC;
}
.wl-airtime-pill-aired {
background: #FAEEDA;
color: #633806;
border: 0.5px solid #FAC775;
}
.wl-airtime-pill-due {
background: #FCEBEB;
color: #791F1F;
border: 0.5px solid #F7C1C1;
}
/* ── Episode badge ───────────────────────────────────── */
.wl-ep-badge {
display: inline-flex;
align-items: center;
align-self: flex-start;
width: fit-content;
padding: 2px 8px;
border-radius: 20px;
font-size: 11px;
font-weight: 600;
white-space: nowrap;
background: #EEEDFE;
color: #3C3489;
border: 0.5px solid #AFA9EC;
}
.wl-ep-badge-final {
display: inline-flex;
align-items: center;
align-self: flex-start;
width: fit-content;
padding: 2px 8px;
border-radius: 20px;
font-size: 11px;
font-weight: 600;
white-space: nowrap;
background: #FCEBEB;
color: #791F1F;
border: 0.5px solid #F7C1C1;
}
/* ── Schedule hint text ──────────────────────────────── */
.wl-schedule-hint {
font-size: 11px;
color: var(--text-muted);
margin-top: 2px;
}
/* ── Action buttons ──────────────────────────────────── */
.wl-airtime-actions {
display: flex;
gap: 4px;
}
.wl-airtime-action-btn {
width: 24px;
height: 24px;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: 0.5px solid var(--background-modifier-border);
border-radius: 4px;
cursor: pointer;
font-size: 13px;
line-height: 1;
color: var(--text-muted);
transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.wl-airtime-action-btn:hover {
background: var(--background-modifier-hover);
color: var(--text-normal);
border-color: var(--interactive-accent);
}
/* .wl-airtime-action-btn-delete — color via .wl-btn-danger */
/* ── Tick (complete) button ───────────────────────────────── */
.wl-airtime-action-btn-tick {
color: #1D9E75;
border-color: #1D9E75;
font-size: 14px;
}
.wl-airtime-action-btn-tick:hover {
background: #1D9E75;
color: #ffffff;
border-color: #1D9E75;
}
/* ── Time input — wide enough for HH:MM ──────────────────── */
.wl-time-input {
min-width: 110px;
max-width: 130px;
flex: unset;
}
/* ── JST clock display ───────────────────────────────────── */
.wl-jst-clock {
font-size: 11px;
color: var(--text-muted);
white-space: nowrap;
flex-shrink: 0;
padding-left: 4px;
}
/* ── Upcoming title count badge ──────────────────────────── */
.wl-list-title-wrap {
display: flex;
align-items: center;
gap: 6px;
}
.wl-list-count {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 20px;
height: 18px;
padding: 0 5px;
border-radius: 20px;
background: var(--background-modifier-border);
color: var(--text-muted);
font-size: 11px;
font-weight: 600;
}
/* ════════════════════════════════════════════════════════
RECTANGLE DASHBOARD CARDS
════════════════════════════════════════════════════════ */
.wl-rect-item {
display: flex;
flex-direction: column;
gap: 6px;
padding: 10px 12px;
background: var(--background-secondary-alt);
border: 2px solid var(--wl-accent);
border-radius: 8px;
}
.wl-rect-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 4px;
}
.wl-rect-label {
font-size: 11px;
font-weight: 600;
color: var(--text-normal);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.wl-rect-unwatched {
font-size: 10px;
color: var(--text-muted);
white-space: nowrap;
flex-shrink: 0;
}
.wl-rect-value {
font-size: 22px;
font-weight: 700;
color: var(--text-normal);
line-height: 1;
}
.wl-rect-bar-wrap {
height: 3px;
background: var(--background-modifier-border);
border-radius: 2px;
overflow: hidden;
width: 100%;
}
.wl-rect-bar {
height: 100%;
border-radius: 2px;
transition: width 0.3s ease;
}
/* Single-line caption under a rect card's bar (e.g. "X / Y pages").
min-height reserves the line so cards without a sublabel stay the same height. */
.wl-rect-subline {
font-size: 10px;
color: var(--text-muted);
min-height: 1.3em;
line-height: 1.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* ════════════════════════════════════════════════════════
SELECTION MODE
════════════════════════════════════════════════════════ */
/* Header controls area (right side of header) */
.wl-header-controls {
display: flex;
align-items: center;
gap: 6px;
flex: 1;
min-width: 0;
}
/* Toolbar action-button wrapper — a nested flex row that fills the space left
by the (max-width-capped) search input, mirroring the controls row's gap so
the buttons lay out exactly as if they were direct flex items. ListTab can
rebuild the wrapper in isolation (selection-mode toggles) without touching
the search input; margin-left:auto children (wl-header-controls-right) still
pin to the row's right edge because the wrapper spans the remaining width. */
.wl-toolbar-actions {
display: flex;
align-items: center;
gap: 6px;
flex: 1 1 auto;
min-width: 0;
}
/* Add buttons pinned to the far right of the toolbar row */
.wl-header-controls-right {
display: flex;
align-items: center;
gap: 6px;
margin-left: auto;
flex-shrink: 0;
}
/* Small button variant */
.wl-btn-sm {
padding: 3px 8px;
font-size: 11px;
}
/* Cancel button inside the persistent rewrite-frontmatter progress notice */
.wl-notice-cancel-btn {
margin-left: 8px;
}
/* Overflow guard (WatchLogView.guardOverflow): re-enables scrolling when an
outside mutation forces the tab content to overflow: hidden. The two-class
selector outranks single-class rules; inline overrides are stripped by the
guard itself (style.removeProperty) so no !important is needed. */
.wl-tab-content.wl-force-overflow-auto {
overflow: auto;
}
/* ── Mobile toolbar crossfade slot ──────────────────────────
On mobile the search input and the action buttons overlap inside a single
fixed-height slot and crossfade between each other (toggled by the chevron
button). Both panes are absolutely positioned so swapping them causes no
reflow — only opacity is animated (mobile WebView layout transitions are
unreliable). */
.wl-toolbar-slot {
position: relative;
flex: 1;
min-width: 0;
height: 30px;
}
.wl-toolbar-slot-pane {
position: absolute;
inset: 0;
display: flex;
align-items: center;
gap: 6px;
}
/* Search input fills the full slot width on mobile (overriding the desktop
max-width cap). */
.wl-toolbar-slot-pane .wl-reading-search-wrap {
max-width: none;
}
/* Animate opacity only — never width/flex/layout. */
.wl-toolbar-fade {
transition: opacity 180ms ease;
}
.wl-toolbar-pane-hidden {
opacity: 0;
pointer-events: none;
}
/* Square chevron toggle button at the right end of the toolbar row. */
.wl-toolbar-toggle-btn {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
padding: 0;
}
/* Active (selected) state for the selection mode toggle button */
.wl-btn.is-active {
background: var(--interactive-accent);
color: var(--text-on-accent);
border-color: var(--interactive-accent);
}
/* Saved filter preset button — active state (green tint) */
.wl-btn.wl-btn-preset-active {
background: rgba(29, 158, 117, 0.15);
border-color: #1D9E75;
color: #1D9E75;
}
/* Action bar container */
.wl-action-bar {
display: flex;
align-items: center;
gap: 5px;
}
/* Selected row highlight — scoped to .wl-row and given a :hover variant so it
outranks .wl-row:hover / .wl-row.is-expanded / .wl-table .wl-group-row. */
.wl-row.wl-row-selected,
.wl-row.wl-row-selected:hover {
background: color-mix(in srgb, var(--background-secondary) 80%, var(--interactive-accent) 20%);
}
/* Selection checkbox column */
.wl-col-select-h,
.wl-col-select {
width: 24px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
}
/* Extend grid template when selection mode is active — see v0.5.5 override below */
/* Airtime card selection checkbox */
.wl-airtime-select-cb {
width: 14px;
height: 14px;
flex-shrink: 0;
cursor: pointer;
margin-right: 6px;
}
/* Make selected airtime cards have a subtle highlight */
.wl-airtime-card.wl-row-selected {
background: color-mix(in srgb, var(--background-secondary) 80%, var(--interactive-accent) 20%);
border-color: var(--interactive-accent);
}
/* Due / Aired highlight borders — per theme */
.wl-view:not([data-theme]) .wl-airtime-card.is-due,
.wl-view:not([data-theme]) .wl-airtime-card.is-aired {
border: 2px solid #207119;
}
.wl-view[data-theme="nightfall"] .wl-airtime-card.is-due,
.wl-view[data-theme="nightfall"] .wl-airtime-card.is-aired {
border: 2px solid #7B2CBF;
}
.wl-view[data-theme="bluez"] .wl-airtime-card.is-due,
.wl-view[data-theme="bluez"] .wl-airtime-card.is-aired {
border: 2px solid #2C7DA0;
}
/* ════════════════════════════════════════════════════════
v0.5.5 NEW STYLES
════════════════════════════════════════════════════════ */
.wl-dashboard > * {
flex-shrink: 0;
}
/* ── Priority column ────────────────────────────────────── */
.wl-col-priority-h,
.wl-col-priority {
font-size: 12px;
color: #ffffff;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: center;
justify-content: center;
}
.wl-priority-badge {
font-size: 10px;
font-weight: 600;
}
/* Selection mode — add checkbox column */
.wl-table.wl-selection-mode .wl-table-header-row,
.wl-table.wl-selection-mode .wl-row {
grid-template-columns: 24px 1fr 56px 72px 56px 90px 20px;
}
/* ── Row spacing ────────────────────────────────────────── */
.wl-row:not(.wl-row-indented) {
margin-bottom: 3px;
}
/* ── Pin icon ───────────────────────────────────────────── */
.wl-col-pin {
display: flex;
align-items: center;
justify-content: center;
width: 20px;
flex-shrink: 0;
}
.wl-pin-icon {
font-size: 12px;
opacity: 0.2;
cursor: pointer;
transition: opacity 0.15s;
user-select: none;
line-height: 1;
}
.wl-pin-icon:hover,
.wl-pin-icon.is-pinned {
opacity: 1;
}
/* ── Link icon in accordion ─────────────────────────────── */
.wl-acc-link-icon {
font-size: 13px;
--icon-size: 13px;
text-decoration: none;
opacity: 0.6;
transition: opacity 0.15s;
cursor: pointer;
flex-shrink: 0;
/* Center the glyph/SVG in a fixed box so the emoji globe and the file-text
icon align identically, instead of the SVG sitting on the text baseline. */
display: inline-flex;
align-items: center;
justify-content: center;
}
/* Block-center the Lucide SVG at the same size as the globe glyph (13px). */
.wl-acc-link-icon svg {
display: block;
width: 13px;
height: 13px;
}
.wl-acc-link-icon:hover {
opacity: 1;
}
/* ── wl-stat widget ─────────────────────────────────────── */
.wl-wstat {
display: inline-block;
margin: 2px 0;
}
.wl-stat-card {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 20px;
background: var(--background-secondary);
white-space: nowrap;
}
.wl-stat-icon {
font-size: 13px;
}
.wl-stat-value {
font-weight: 700;
font-size: var(--font-ui-small);
color: var(--text-normal);
}
.wl-stat-label {
font-size: 11px;
color: var(--text-muted);
}
.wl-stat-sep {
color: var(--text-faint);
margin: 0 2px;
}
/* ── Full cards (140×55px base) ─────────────────────────── */
.wl-full-card {
display: flex;
flex-direction: column;
width: 160px;
height: 70px;
padding: 6px 10px;
border-radius: 6px;
background: var(--background-secondary);
border: 0.5px solid var(--background-modifier-border);
box-sizing: border-box;
overflow: hidden;
}
.wl-full-card-header {
font-size: 10px;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 2px;
}
.wl-full-card-value {
font-size: 18px;
font-weight: 700;
color: var(--text-normal);
line-height: 1.1;
white-space: nowrap;
}
.wl-full-card-title {
font-size: 14px;
font-weight: 600;
color: var(--text-normal);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 2px;
}
.wl-full-card-sub {
font-size: 12px;
color: var(--text-muted);
margin-top: 1px;
white-space: nowrap;
}
.wl-full-card-meta {
display: flex;
align-items: center;
gap: 4px;
font-size: 9px;
color: var(--text-muted);
margin-top: auto;
}
.wl-full-card-bar-wrap {
height: 3px;
background: var(--background-modifier-border);
border-radius: 2px;
margin-top: 4px;
overflow: hidden;
}
.wl-full-card-bar {
height: 100%;
background: var(--interactive-accent);
border-radius: 2px;
}
/* ── Time full card (280×55px, two-column) ──────────────── */
.wl-full-card-time {
width: 320px;
}
.wl-full-card-time-cols {
display: flex;
gap: 10px;
flex: 1;
}
.wl-full-card-time-col {
flex: 1;
min-width: 0;
}
.wl-full-card-days {
font-size: 15px;
color: var(--text-muted);
white-space: nowrap;
}
/* ── wl-upcoming widget ─────────────────────────────────── */
.wl-wupcoming {
display: inline-block;
margin: 2px 0;
}
.wl-upcoming-card {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 5px 12px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 8px;
background: var(--background-secondary);
white-space: nowrap;
flex-wrap: wrap;
}
.wl-upcoming-empty {
color: var(--text-muted);
font-style: italic;
font-size: var(--font-ui-small);
}
.wl-upcoming-title {
font-weight: 600;
font-size: var(--font-ui-small);
}
.wl-upcoming-date {
font-size: 11px;
color: var(--text-muted);
}
.wl-upcoming-countdown {
font-size: 11px;
font-weight: 600;
color: var(--interactive-accent);
}
/* ── wl-nowwatching widget ──────────────────────────────── */
.wl-wnowwatching {
display: inline-block;
margin: 2px 0;
}
.wl-nowwatching-card {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 5px 12px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 8px;
background: var(--background-secondary);
white-space: nowrap;
flex-wrap: wrap;
}
.wl-nowwatching-empty {
color: var(--text-muted);
font-style: italic;
font-size: var(--font-ui-small);
}
.wl-nowwatching-title {
font-weight: 600;
font-size: var(--font-ui-small);
}
.wl-nowwatching-ep {
font-size: 11px;
color: var(--text-muted);
}
.wl-nowwatching-bar-wrap {
width: 60px;
height: 4px;
background: var(--background-modifier-border);
border-radius: 2px;
overflow: hidden;
}
.wl-nowwatching-bar {
height: 100%;
background: var(--interactive-accent);
border-radius: 2px;
transition: width 0.3s ease;
}
.wl-nowwatching-pct {
font-size: 11px;
color: var(--text-muted);
font-weight: 600;
}
/* ── wl-nowwatching full layout ─────────────────────────── */
.wl-full-card-nw {
height: auto;
width: 200px;
}
.wl-nw-bottom-row {
display: flex;
align-items: center;
gap: 6px;
margin-top: 4px;
}
.wl-nw-bar-col {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 2px;
min-width: 0;
}
.wl-nw-pct {
font-size: 9px;
color: var(--text-muted);
font-weight: 600;
}
/* ── Shared vertical separator ──────────────────────────── */
.wl-vert-sep {
width: 1px;
background: var(--background-modifier-border);
align-self: stretch;
flex-shrink: 0;
margin: 0 4px;
}
/* ── wl-stat: time completed full (triple card) ─────────── */
.wl-wstat.wl-wstat-triple {
display: block;
}
.wl-full-card-triple {
width: 100%;
height: auto;
padding: 8px 10px;
}
.wl-triple-cols {
display: flex;
align-items: stretch;
gap: 0;
}
.wl-triple-col {
flex: 1;
min-width: 0;
padding: 0 8px;
}
.wl-triple-col:first-child {
padding-left: 0;
}
/* ── wl-now-next (combined now watching + up next) ──────── */
.wl-wnownext {
display: block;
margin: 2px 0;
}
.wl-full-card-now-next {
width: 100%;
height: auto;
padding: 8px 10px;
}
.wl-double-cols {
display: flex;
align-items: stretch;
gap: 0;
}
.wl-double-col {
flex: 1;
min-width: 0;
padding: 0 8px;
}
.wl-double-col:first-child {
padding-left: 0;
}
/* ── Widgets settings tab ───────────────────────────────── */
.wl-widget-info-section {
margin-bottom: 16px;
padding: 10px 12px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
}
.wl-widget-info-name {
font-size: 13px;
font-weight: 700;
font-family: var(--font-monospace);
color: var(--text-normal);
margin-bottom: 4px;
}
.wl-widget-info-desc {
font-size: var(--font-ui-small);
color: var(--text-muted);
margin-bottom: 8px;
}
.wl-widget-info-code-row {
display: flex;
align-items: flex-start;
gap: 8px;
}
.wl-widget-info-code {
flex: 1;
font-size: 11px;
background: var(--background-primary-alt);
padding: 4px 8px;
border-radius: 4px;
white-space: pre;
color: var(--text-muted);
font-family: var(--font-monospace);
}
/* ════════════════════════════════════════════════════════
THEME SYSTEM — CSS VARIABLES
════════════════════════════════════════════════════════ */
/* Nightfall theme — accent colors only, no background/text overrides */
.wl-view[data-theme="nightfall"] {
--wl-accent: #4b246c;
--wl-rating-color: #C77DFF;
--wl-watched-color: #7B2CBF;
--wl-group-border-overlay: rgba(92, 31, 154, 0.25);
}
/* Bluez theme — accent colors only, no background/text overrides */
.wl-view[data-theme="bluez"] {
--wl-accent: #144a62;
--wl-rating-color: #61A5C2;
--wl-watched-color: #2C7DA0;
--wl-group-border-overlay: rgba(1, 73, 124, 0.3);
}
/* ════════════════════════════════════════════════════════
THEME PICKER (Settings → Customize)
════════════════════════════════════════════════════════ */
.wl-theme-cards {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-top: 6px;
}
.wl-theme-card {
flex: 1;
min-width: 90px;
border: 1.5px solid var(--background-modifier-border);
border-radius: 8px;
padding: 8px 10px;
cursor: pointer;
background: var(--background-secondary);
transition: border-color 0.15s, background 0.15s;
}
.wl-theme-card:hover {
border-color: var(--interactive-accent);
background: var(--background-modifier-hover);
}
.wl-theme-card.is-selected {
border-color: var(--interactive-accent);
background: color-mix(in srgb, var(--background-secondary) 80%, var(--interactive-accent) 20%);
}
.wl-theme-card-name {
font-size: 12px;
font-weight: 600;
color: var(--text-normal);
margin-bottom: 6px;
}
.wl-theme-strip {
display: flex;
gap: 2px;
border-radius: 4px;
overflow: hidden;
}
.wl-theme-swatch {
flex: 1;
height: 12px;
}
/* ════════════════════════════════════════════════════════
FILTERS DROPDOWN PANEL
════════════════════════════════════════════════════════ */
.wl-filters-panel {
min-width: 240px;
padding: 8px 0;
}
.wl-filter-global-btns {
display: flex;
gap: 6px;
padding: 4px 12px 8px;
border-bottom: 0.5px solid var(--background-modifier-border);
margin-bottom: 4px;
}
.wl-filter-section {
padding: 0;
}
/* QoL 3 — Collapsible section header */
.wl-filter-section-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 12px 4px;
cursor: pointer;
user-select: none;
}
.wl-filter-section-header:hover {
background: var(--background-modifier-hover);
}
.wl-filter-section-header .wl-filter-label {
margin-bottom: 0;
width: auto;
}
.wl-filter-chevron {
font-size: 10px;
color: var(--text-muted);
}
.wl-filter-section-content {
display: block;
padding: 2px 12px 6px;
}
/* Wrapper around the Apply button at the bottom of the filter popover. */
.wl-filter-apply-wrap {
padding: 6px 12px 2px;
}
.wl-filter-section .wl-filter-label {
display: block;
margin-bottom: 4px;
width: auto;
}
.wl-filter-checkbox-row {
display: flex;
align-items: center;
gap: 6px;
padding: 2px 0;
font-size: 12px;
cursor: pointer;
}
.wl-filter-checkbox-row input[type="checkbox"] {
margin: 0;
cursor: pointer;
}
.wl-sorting-panel {
min-width: 200px;
padding: 8px 0;
}
.wl-filter-row {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 12px;
}
.wl-filter-label {
font-size: 11px;
color: var(--text-muted);
width: 54px;
flex-shrink: 0;
}
.wl-filter-row .wl-select {
flex: 1;
min-width: 0;
}
/* ════════════════════════════════════════════════════════
SUGGESTIONS SECTION (Dashboard)
════════════════════════════════════════════════════════ */
.wl-suggestions {
margin-bottom: 16px;
}
.wl-suggestions-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.wl-suggestion-card {
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
padding: 10px 12px;
background: var(--background-secondary);
}
.wl-suggestion-label {
font-size: 10px;
color: var(--text-faint);
text-transform: uppercase;
letter-spacing: 0.04em;
margin-bottom: 4px;
}
.wl-suggestion-title {
font-size: 13px;
color: var(--text-normal);
font-weight: 500;
word-break: break-word;
}
.wl-suggestion-empty {
color: var(--text-faint);
font-style: italic;
}
.wl-suggestion-random-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 4px;
}
.wl-suggestion-shuffle {
background: transparent;
border: none;
cursor: pointer;
font-size: 14px;
padding: 0 2px;
opacity: 0.7;
transition: opacity 0.15s;
}
.wl-suggestion-shuffle:hover {
opacity: 1;
}
/* ════════════════════════════════════════════════════════
CSV IMPORT / EXPORT MODAL
════════════════════════════════════════════════════════ */
.wl-csv-modal {
min-width: 420px;
}
.wl-csv-ctrl-row {
display: flex;
align-items: center;
gap: 6px;
margin-bottom: 8px;
flex-wrap: wrap;
}
.wl-csv-count {
margin-left: auto;
font-size: 12px;
color: var(--text-muted);
}
.wl-csv-list {
max-height: 300px;
overflow-y: auto;
border: 0.5px solid var(--background-modifier-border);
border-radius: 4px;
margin-bottom: 12px;
}
.wl-csv-row {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
border-bottom: 0.5px solid var(--background-modifier-border);
}
.wl-csv-row:last-child {
border-bottom: none;
}
.wl-csv-row:hover {
background: var(--background-modifier-hover);
}
.wl-csv-row-dupe {
background: color-mix(in srgb, var(--background-modifier-error) 40%, transparent 60%);
}
.wl-csv-row-dupe:hover {
background: color-mix(in srgb, var(--background-modifier-error) 55%, transparent 45%);
}
.wl-csv-row-title {
flex: 1;
font-size: 13px;
color: var(--text-normal);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.wl-csv-row-meta {
font-size: 11px;
color: var(--text-faint);
flex-shrink: 0;
}
.wl-csv-dupe-badge {
font-size: 10px;
padding: 1px 5px;
border-radius: 3px;
background: color-mix(in srgb, #E24B4A 20%, transparent 80%);
color: #E24B4A;
flex-shrink: 0;
}
.wl-csv-dupe-warning {
font-size: 12px;
color: var(--text-muted);
background: color-mix(in srgb, var(--background-modifier-error) 30%, transparent 70%);
border-radius: 4px;
padding: 6px 10px;
margin-bottom: 8px;
}
.wl-csv-drop-zone {
border: 1.5px dashed var(--background-modifier-border);
border-radius: 6px;
padding: 20px;
text-align: center;
margin-bottom: 12px;
}
.wl-csv-drop-label {
font-size: 13px;
color: var(--text-muted);
margin-bottom: 10px;
}
.wl-csv-file-input {
display: block;
margin: 0 auto;
font-size: 12px;
}
.wl-csv-preview {
margin-bottom: 8px;
}
.wl-csv-step {
margin-bottom: 8px;
}
.wl-csv-step-title {
font-size: 14px;
font-weight: 600;
color: var(--text-normal);
margin-bottom: 4px;
}
.wl-csv-step-desc {
font-size: 12px;
color: var(--text-muted);
margin-bottom: 8px;
}
.wl-csv-info-note {
font-size: 11px;
color: var(--text-faint);
background: var(--background-primary-alt);
border-left: 2px solid var(--background-modifier-border);
padding: 5px 8px;
border-radius: 3px;
margin-bottom: 12px;
}
.wl-csv-map-grid {
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 14px;
}
.wl-csv-map-row {
display: flex;
align-items: center;
gap: 10px;
}
.wl-csv-map-label {
font-size: 12px;
color: var(--text-muted);
width: 70px;
flex-shrink: 0;
}
.wl-csv-map-select {
flex: 1;
}
.wl-csv-preview-btn {
display: block;
margin-left: auto;
}
.wl-csv-btn-row {
flex-direction: row;
justify-content: flex-end;
}
/* ── Value mapping step ──────────────────────────────────── */
.wl-csv-valmap-section-title {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-faint);
margin: 12px 0 6px;
}
.wl-csv-valmap-section-title:first-of-type {
margin-top: 4px;
}
.wl-csv-valmap-row {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 6px;
}
.wl-csv-valmap-orig {
font-size: 12px;
font-weight: 600;
color: var(--text-normal);
min-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.wl-csv-valmap-arrow {
font-size: 12px;
color: var(--text-faint);
flex-shrink: 0;
}
.wl-csv-valmap-select {
flex: 1;
}
.wl-csv-valmap-btn-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 14px;
gap: 8px;
}
/* ── Import progress bar ─────────────────────────────────── */
.wl-csv-bg-note {
font-size: 11px;
color: var(--text-muted);
font-style: italic;
display: block;
margin-bottom: 6px;
flex-basis: 100%;
}
.wl-csv-progress-wrap {
display: flex;
align-items: center;
gap: 8px;
flex: 1;
min-width: 0;
flex-wrap: wrap;
}
.wl-csv-progress-track {
flex: 1;
height: 6px;
background: var(--background-modifier-border);
border-radius: 3px;
overflow: hidden;
min-width: 0;
}
.wl-csv-progress-fill {
height: 100%;
background: var(--interactive-accent);
border-radius: 3px;
width: 0%;
transition: width 0.1s ease;
}
.wl-csv-progress-text {
font-size: 11px;
color: var(--text-muted);
white-space: nowrap;
min-width: 80px;
text-align: right;
}
/* ── Settings regenerate progress bar ───────────────────── */
.wl-regen-progress-wrap {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
margin: 0 0 8px 0;
padding: 0 2px;
}
/* ── Header import progress bar ─────────────────────────── */
.wl-header-import-progress {
display: flex;
align-items: center;
gap: 6px;
flex: 1;
margin: 0 10px;
max-width: 240px;
}
.wl-header-import-track {
flex: 1;
height: 4px;
background: var(--background-modifier-border);
border-radius: 2px;
overflow: hidden;
min-width: 40px;
}
.wl-header-import-fill {
height: 100%;
background: var(--interactive-accent);
border-radius: 2px;
transition: width 0.15s ease;
width: 0%;
}
.wl-header-import-text {
font-size: 11px;
color: var(--text-muted);
white-space: nowrap;
}
/* ════════════════════════════════════════════════════════
CUSTOM LISTS TAB (v0.8.0)
════════════════════════════════════════════════════════ */
.wl-custom-lists {
display: flex;
flex-direction: column;
gap: 0;
min-height: 0;
flex: 1;
}
/* ── Empty state ──────────────────────────────────────────── */
.wl-cl-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 14px;
padding: 40px 20px;
}
.wl-cl-empty-text {
font-size: 14px;
color: var(--text-muted);
}
/* ── Sub-tab bar ──────────────────────────────────────────── */
.wl-cl-sub-tabs {
display: flex;
align-items: center;
gap: 2px;
padding: 8px 2px 0;
border-bottom: 0.5px solid var(--background-modifier-border);
flex-shrink: 0;
flex-wrap: wrap;
}
.wl-cl-sub-tab {
display: flex;
align-items: center;
gap: 4px;
padding: 4px 10px;
border-radius: 4px 4px 0 0;
cursor: pointer;
background: var(--background-secondary);
border: 0.5px solid var(--background-modifier-border);
border-bottom: none;
font-size: var(--font-ui-small);
color: var(--text-muted);
transition: background 0.12s, color 0.12s;
position: relative;
margin-bottom: -0.5px;
}
.wl-cl-sub-tab:hover {
background: var(--background-modifier-hover);
color: var(--text-normal);
}
.wl-cl-sub-tab.is-active {
background: var(--background-primary);
color: var(--text-normal);
font-weight: 600;
border-bottom: 0.5px solid var(--background-primary);
}
.wl-cl-sub-tab-name {
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.wl-cl-sub-tab-del {
font-size: 13px;
line-height: 1;
color: var(--text-faint);
cursor: pointer;
opacity: 0;
transition: opacity 0.12s, color 0.12s;
flex-shrink: 0;
}
.wl-cl-sub-tab:hover .wl-cl-sub-tab-del {
opacity: 1;
}
.wl-cl-sub-tab-del:hover {
color: var(--text-error);
}
.wl-cl-sub-tab-add {
padding: 3px 10px;
border-radius: 4px;
border: 0.5px dashed var(--background-modifier-border);
background: none;
color: var(--text-muted);
cursor: pointer;
font-size: 15px;
line-height: 1;
transition: color 0.12s, border-color 0.12s;
}
.wl-cl-sub-tab-add:hover {
color: var(--text-normal);
border-color: var(--interactive-accent);
}
.wl-cl-sub-tab-rename {
max-width: 100px;
padding: 1px 4px;
border: 0.5px solid var(--interactive-accent);
border-radius: 3px;
background: var(--background-primary);
color: var(--text-normal);
font-size: var(--font-ui-small);
font-weight: 600;
}
.wl-cl-sub-tab-rename:focus {
outline: none;
}
/* ── List view ────────────────────────────────────────────── */
.wl-cl-list-view {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
padding-top: 8px;
}
/* ── Header ───────────────────────────────────────────────── */
.wl-cl-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 6px;
gap: 8px;
}
.wl-cl-count {
font-size: 14px;
font-weight: 700;
color: var(--text-muted);
}
.wl-cl-toolbar {
display: flex;
gap: 4px;
align-items: center;
position: relative;
}
/* ── Draft banner ─────────────────────────────────────────── */
.wl-cl-draft-banner {
margin: 6px 0;
padding: 6px 10px;
border-radius: 4px;
background: color-mix(in srgb, var(--background-secondary) 80%, #BA7517 20%);
border: 0.5px solid color-mix(in srgb, var(--background-modifier-border) 60%, #BA7517 40%);
font-size: 11px;
color: var(--text-muted);
flex-shrink: 0;
}
/* ── Table ────────────────────────────────────────────────── */
.wl-cl-table-wrap {
flex: 1;
overflow-x: auto;
overflow-y: auto;
min-height: 0;
}
.wl-cl-table {
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
overflow: hidden;
width: 100%;
}
.wl-cl-thead {
background: var(--background-secondary);
border-bottom: 0.5px solid var(--background-modifier-border);
}
/* ── Column resize (Excel-style) ──────────────────────────── */
/* Resizable mode: explicit column widths, no flex redistribution, horizontal scroll. */
.wl-cl-table-resizable {
width: max-content;
min-width: 100%;
/* Let the scroll container (.wl-cl-table-wrap) own the horizontal scroll so
the sticky actions cell clamps to the viewport edge, not the table edge. */
overflow: visible;
}
.wl-cl-table-resizable .wl-cl-tr {
min-width: 100%;
}
.wl-cl-table-resizable .wl-cl-th.wl-cl-col-fixed,
.wl-cl-table-resizable .wl-cl-td.wl-cl-col-fixed {
flex: 0 0 var(--wl-cl-cw);
}
/* ── Sticky row actions (resizable mode only) ─────────────── */
/* Keep the actions cell pinned to the visible right edge while the table
scrolls horizontally. Opaque backgrounds (base colour + translucent state
overlay) match the row so scrolled cell content does not show through. */
.wl-cl-table-resizable .wl-cl-td-actions {
/* margin-left:auto pushes the cell flush to the right edge when the table fits
(free space to the right); it resolves to 0 when the table overflows, letting
sticky pin it to the visible right edge. The opaque background (matched to the
row state below) means revealed controls never let cell content bleed through —
the reveal animates only the inner controls' opacity, not this cell. */
margin-left: auto;
position: sticky;
right: 0;
z-index: 1;
background-color: var(--background-primary);
}
.wl-cl-table-resizable .wl-cl-th-actions {
margin-left: auto;
position: sticky;
right: 0;
z-index: 3;
background-color: var(--background-secondary);
}
.wl-cl-table-resizable .wl-cl-tr-body:hover .wl-cl-td-actions {
background-image: linear-gradient(var(--background-modifier-hover), var(--background-modifier-hover));
}
.wl-cl-table-resizable .wl-cl-tr-body.wl-cl-tr-checked .wl-cl-td-actions,
.wl-cl-table-resizable .wl-cl-tr-body.wl-cl-tr-checked:hover .wl-cl-td-actions {
background-image: linear-gradient(
color-mix(in srgb, var(--color-green) 5%, transparent),
color-mix(in srgb, var(--color-green) 5%, transparent)
);
}
.wl-cl-th-resizable {
position: relative;
}
.wl-cl-col-resize {
position: absolute;
top: 0;
right: 0;
width: 8px;
height: 100%;
cursor: col-resize;
z-index: 2;
}
/* Always-visible quiet separator; brighter + thicker on hover to signal resize. */
.wl-cl-col-resize::after {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 6px;
width: 1px;
background: var(--background-modifier-border);
transition: background 0.12s, width 0.12s;
}
.wl-cl-col-resize:hover::after {
width: 2px;
background: var(--interactive-accent);
}
body.wl-cl-col-resizing {
cursor: col-resize;
user-select: none;
}
.wl-cl-tr {
display: flex;
align-items: stretch;
}
.wl-cl-tr-header {
padding: 4px 6px;
}
.wl-cl-tr-body {
padding: 3px 6px;
border-bottom: 0.5px solid var(--background-modifier-border);
transition: background 0.1s;
min-height: 28px;
align-items: center;
}
.wl-cl-tr-body:last-child {
border-bottom: none;
}
.wl-cl-tr-body:hover {
background: var(--background-modifier-hover);
}
.wl-cl-tr-body:hover .wl-cl-row-action {
opacity: 1;
}
.wl-cl-th {
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
padding: 2px 6px;
flex: 1;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.wl-cl-autotime-refresh {
cursor: pointer;
margin-left: 4px;
font-size: 13px;
opacity: 0.6;
transition: opacity 0.15s;
}
.wl-cl-autotime-refresh:hover {
opacity: 1;
}
.wl-cl-th-num {
flex: 0 0 28px;
text-align: center;
}
.wl-cl-th-actions {
flex: 0 0 64px;
}
.wl-cl-td {
font-size: var(--font-ui-small);
padding: 2px 6px;
flex: 1;
min-width: 0;
display: flex;
align-items: center;
cursor: pointer;
overflow: hidden;
}
.wl-cl-td-num {
flex: 0 0 28px;
font-size: 11px;
color: var(--text-faint);
text-align: center;
justify-content: center;
cursor: default;
}
.wl-cl-td-name {
font-weight: 500;
}
.wl-cl-td-actions {
flex: 0 0 64px;
display: flex;
align-items: center;
gap: 2px;
justify-content: flex-end;
cursor: default;
overflow: visible;
}
/* ── Row actions ──────────────────────────────────────────── */
.wl-cl-row-action {
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 3px;
cursor: pointer;
font-size: 12px;
color: var(--text-muted);
opacity: 0;
transition: opacity 0.12s, background 0.12s, color 0.12s;
flex-shrink: 0;
user-select: none;
}
.wl-cl-drag-handle {
cursor: grab;
font-size: 14px;
}
.wl-cl-drag-handle:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
}
.wl-cl-dup-btn:hover {
color: var(--interactive-accent);
background: var(--background-modifier-hover);
}
.wl-cl-row-del:hover {
color: var(--text-on-accent);
background: #E24B4A;
}
/* ── Drag state ───────────────────────────────────────────── */
.wl-cl-dragging {
opacity: 0.4;
}
/* Element+state selectors per drop target outrank each target's own border
rules (e.g. the .wl-cl-sub-tab border shorthand). */
.wl-cl-sub-tab.wl-cl-drag-over,
.wl-cl-tr-body.wl-cl-drag-over,
.wl-editcol-card.wl-cl-drag-over,
.wl-reading-col-card.wl-cl-drag-over {
border-top: 2px solid var(--interactive-accent);
}
/* ── Cell content ─────────────────────────────────────────── */
.wl-cl-cell-text {
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.wl-cl-cell-empty {
color: var(--text-faint);
font-style: italic;
}
.wl-cl-dup-name {
color: #E24B4A;
}
/* ── Editing state ────────────────────────────────────────── */
.wl-cl-editing {
overflow: visible;
z-index: 10;
position: relative;
}
/* Cell scope outranks the .wl-cl-td base padding. */
.wl-cl-td.wl-cl-editing {
padding: 0 4px;
}
.wl-cl-cell-input {
width: 100%;
padding: 2px 5px;
border: 0.5px solid var(--interactive-accent);
border-radius: 3px;
background: var(--background-primary);
color: var(--text-normal);
font-size: var(--font-ui-small);
outline: none;
box-sizing: border-box;
}
.wl-cl-cell-select {
width: 100%;
padding: 2px 4px;
font-size: var(--font-ui-small);
}
/* ── Autofill dropdown ────────────────────────────────────── */
.wl-cl-autofill-wrap {
position: relative;
width: 100%;
}
.wl-cl-autofill-wrap .wl-cl-cell-input {
width: 100%;
}
.wl-cl-autofill-dropdown {
/* position/top/left/width are set inline via JS (fixed, body-level) */
max-height: 180px;
overflow-y: auto;
background: var(--background-primary);
border: 0.5px solid var(--background-modifier-border);
border-radius: 5px;
box-shadow: 0 4px 12px rgba(0,0,0,0.18);
z-index: 9999;
}
/* ── Select badge (neutral, no color) ────────────────────── */
.wl-cl-select-badge {
display: inline-block;
padding: 1px 8px;
border-radius: 20px;
font-size: 11px;
font-weight: 500;
background: var(--background-secondary);
border: 0.5px solid var(--background-modifier-border);
color: var(--text-normal);
white-space: nowrap;
}
/* ── Add row footer ───────────────────────────────────────── */
.wl-cl-add-row {
padding: 6px 2px;
border-top: 0.5px solid var(--background-modifier-border);
}
/* ── Sort panel ───────────────────────────────────────────── */
.wl-cl-sort-panel {
position: absolute;
top: calc(100% + 4px);
right: 0;
z-index: 200;
background: var(--background-primary);
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0,0,0,0.18);
min-width: 200px;
padding: 6px 0;
}
/* ════════════════════════════════════════════════════════
EDIT COLUMNS MODAL (v0.8.0)
════════════════════════════════════════════════════════ */
.wl-editcol-modal {
--dialog-width: 820px;
}
.wl-editcols-modal {
min-width: 90%;
width: calc(100% - 40px);
max-width: calc(100% - 40px);
}
.wl-editcols-list {
margin-bottom: 10px;
max-height: 460px;
overflow-x: auto;
overflow-y: auto;
}
/* ── Horizontal card layout for Edit Columns ─────────────────────── */
.wl-editcol-card-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
gap: 8px;
padding: 4px;
}
.wl-editcol-card {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
width: 130px;
flex: 0 0 130px;
padding: 6px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 5px;
background: var(--background-secondary);
box-sizing: border-box;
}
.wl-editcol-card.wl-cl-dragging {
opacity: 0.5;
}
.wl-editcol-card.wl-cl-drag-over {
border-left: 2px solid var(--interactive-accent);
}
.wl-editcol-card-handle {
cursor: grab;
color: var(--text-faint);
font-size: 11px;
text-align: center;
user-select: none;
line-height: 1;
}
.wl-editcol-card-handle:hover {
color: var(--text-muted);
}
.wl-editcol-card-name {
width: 100%;
box-sizing: border-box;
font-size: 12px;
height: 26px;
padding: 2px 6px;
}
.wl-editcol-card-name-wrap {
width: 100%;
}
.wl-editcol-card-name-label {
width: 100%;
padding: 2px 6px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary-alt);
color: var(--text-muted);
font-size: 12px;
text-align: left;
box-sizing: border-box;
}
.wl-editcol-card-type {
width: 100%;
box-sizing: border-box;
font-size: 12px;
height: 26px;
padding: 2px 6px;
}
.wl-editcol-card-type-locked {
width: 100%;
padding: 3px 6px;
border: 0.5px dashed var(--background-modifier-border);
border-radius: 4px;
color: var(--text-muted);
font-size: 11px;
font-style: italic;
text-align: center;
box-sizing: border-box;
}
.wl-editcol-card-toggles {
display: flex;
gap: 4px;
justify-content: center;
}
.wl-editcol-card-toggle {
flex: 0 0 22px;
width: 22px;
height: 22px;
font-size: 11px;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
}
.wl-editcol-card-del {
align-self: center;
width: 22px;
height: 22px;
padding: 0;
font-size: 11px;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
}
.wl-editcol-card-del:hover {
color: var(--text-error);
}
.wl-editcol-card-spacer {
flex: 1;
min-height: 4px;
}
.wl-editcol-card-opts {
display: flex;
flex-direction: column;
gap: 4px;
border-top: 0.5px dashed var(--background-modifier-border);
padding-top: 6px;
margin-top: 2px;
}
.wl-editcol-card-opt-row {
display: flex;
gap: 4px;
align-items: center;
}
.wl-editcol-card-opt-input {
flex: 1;
min-width: 0;
font-size: 11px;
padding: 1px 4px;
height: 22px;
}
.wl-editcol-card-opt-del {
flex: 0 0 auto;
width: 18px;
height: 18px;
padding: 0;
font-size: 10px;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
}
.wl-editcol-card-opt-del:hover {
color: var(--text-error);
}
.wl-editcol-card-opt-add {
font-size: 11px;
padding: 1px 4px;
height: 22px;
}
/* Auto card (# and Name) — sized individually via data-auto attr */
.wl-editcol-card.wl-editcol-card-auto {
opacity: 0.5;
pointer-events: none;
background: var(--background-modifier-hover);
}
.wl-editcol-card.wl-editcol-card-auto[data-auto="#"] {
width: 40px;
flex: 0 0 40px;
padding: 4px;
}
.wl-editcol-card.wl-editcol-card-auto[data-auto="Name"] {
width: 70px;
flex: 0 0 70px;
padding: 4px 6px;
}
/* Add-column card */
.wl-editcol-card.wl-editcol-card-add {
width: 80px;
flex: 0 0 80px;
border: 1px dashed var(--background-modifier-border);
background: transparent;
align-items: center;
justify-content: center;
min-height: unset;
cursor: pointer;
color: var(--text-muted);
padding: 6px;
}
.wl-editcol-card.wl-editcol-card-add:hover {
border-color: var(--interactive-accent);
color: var(--text-normal);
}
.wl-editcol-card-add-label {
font-size: 12px;
text-align: center;
}
.wl-cl-name-error {
font-size: 12px;
color: var(--text-error);
margin: -4px 0 6px;
}
/* ── Notes modal ─────────────────────────────────────────── */
.wl-notes-modal {
display: flex;
flex-direction: column;
}
.wl-notes-mode-bar {
display: flex;
gap: 6px;
margin-bottom: 10px;
}
.wl-notes-edit-area {
display: flex;
flex-direction: column;
}
.wl-modal-textarea.wl-notes-textarea {
width: 100%;
min-height: 220px;
resize: vertical;
font-family: var(--font-monospace);
font-size: 13px;
padding: 8px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
box-sizing: border-box;
margin-bottom: 12px;
}
.wl-notes-preview-area {
min-height: 160px;
max-height: 420px;
overflow-y: auto;
padding: 10px 12px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
margin-bottom: 12px;
font-size: 14px;
line-height: 1.6;
}
/* ── Edit Columns modal — mobile responsive ──────────────── */
@media (max-width: 720px) {
.wl-editcols-modal {
min-width: unset;
width: calc(100% - 16px);
max-width: calc(100% - 16px);
}
.wl-editcols-list {
max-height: 260px;
}
}
/* ── Clear filters button ────────────────────────────────── */
.wl-btn-clear-filters {
color: var(--text-muted);
}
.wl-btn-clear-filters:hover {
color: var(--text-normal);
}
/* ── Filter active dot ───────────────────────────────────── */
.wl-filter-dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--interactive-accent);
vertical-align: middle;
margin-left: 3px;
margin-bottom: 1px;
}
/* ════════════════════════════════════════════════════════
DRAFTS TAB
════════════════════════════════════════════════════════ */
/* ── Notice banner (matches Custom Lists draft banner) ── */
.wl-drafts-notice {
margin: 4px 0 10px;
padding: 6px 10px;
border-radius: 4px;
background: color-mix(in srgb, var(--background-secondary) 80%, #BA7517 20%);
border: 0.5px solid color-mix(in srgb, var(--background-modifier-border) 60%, #BA7517 40%);
font-size: 11px;
color: var(--text-muted);
line-height: 1.5;
}
/* ── Count label ─────────────────────────────────────── */
.wl-drafts-count-label {
color: var(--text-muted);
font-size: var(--font-ui-smaller);
margin-left: 4px;
}
/* ── Empty state ─────────────────────────────────────── */
.wl-drafts-empty {
text-align: center;
padding: 32px 16px;
color: var(--text-muted);
font-style: italic;
}
/* ── Cards list (mirrors .wl-airtime-cards) ──────────── */
.wl-drafts-cards {
display: flex;
flex-direction: column;
gap: 4px;
margin-top: 6px;
}
/* ── Single card (mirrors .wl-airtime-card) ──────────── */
.wl-drafts-card {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
background: var(--background-secondary);
transition: background 0.1s;
}
.wl-drafts-card:hover {
background: var(--background-modifier-hover);
}
/* ── Title ───────────────────────────────────────────── */
.wl-drafts-card-title {
font-weight: 600;
font-size: var(--font-ui-small);
flex: 1;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* ── Source note link ────────────────────────────────── */
.wl-drafts-card-source {
flex-shrink: 0;
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.wl-drafts-source-link {
color: var(--text-accent);
cursor: pointer;
font-family: var(--font-monospace);
font-size: var(--font-ui-smaller);
}
.wl-drafts-source-link:hover {
text-decoration: underline;
}
.wl-drafts-source-count {
color: var(--text-muted);
font-size: var(--font-ui-smaller);
cursor: help;
}
/* ── "In Watchlist" indicator ────────────────────────── */
.wl-drafts-card-dup {
flex-shrink: 0;
font-size: var(--font-ui-smaller);
font-weight: 500;
color: var(--color-red, #e24b4a);
min-width: 0;
}
/* ── Action buttons ──────────────────────────────────── */
.wl-drafts-card-actions {
flex-shrink: 0;
display: flex;
align-items: center;
gap: 4px;
}
.wl-drafts-added-label {
font-size: var(--font-ui-smaller);
color: var(--text-muted);
font-style: italic;
padding: 2px 6px;
background: var(--background-modifier-border);
border-radius: 4px;
white-space: nowrap;
}
.wl-drafts-dismiss {
color: var(--text-muted);
}
.wl-drafts-dismiss:hover {
color: var(--color-red, #e24b4a);
}
/* ── "In Watchlist" state — italic + dimmed (Fix 4) ──── */
.wl-drafts-card-watchlist {
opacity: 0.55;
font-style: italic;
}
/* ── "Added" state ───────────────────────────────────── */
.wl-drafts-card-added .wl-drafts-card-title {
font-style: italic;
color: var(--text-muted);
}
/* ── Season total preview (Edit modal) ───────────────── */
.wl-modal-season-total {
font-size: 11px;
color: var(--text-muted);
margin-top: 4px;
font-style: italic;
}
/* ── Skip count inline labels next to Total Episodes input ── */
.wl-modal-skip-inline {
font-size: var(--font-ui-small);
color: var(--text-muted);
white-space: nowrap;
}
/* ── Quick Info tab ──────────────────────────────────── */
.wl-qi-section {
margin-bottom: 6px;
}
.wl-qi-section-header {
display: flex;
align-items: center;
gap: 6px;
padding: 6px 8px;
border-radius: 4px;
cursor: pointer;
font-weight: 600;
font-size: var(--font-ui-small);
background: var(--background-secondary);
border: 0.5px solid var(--background-modifier-border);
user-select: none;
}
.wl-qi-section-header:hover {
background: var(--background-modifier-hover);
}
.wl-qi-chevron {
font-size: 10px;
color: var(--text-muted);
flex-shrink: 0;
}
.wl-qi-section-label {
color: var(--text-normal);
}
.wl-qi-section-body {
margin-top: 4px;
display: flex;
flex-direction: column;
gap: 4px;
}
.wl-qi-banner {
padding: 8px 12px;
border-radius: 4px;
background: color-mix(in srgb, var(--background-secondary) 80%, #1D9E75 20%);
border: 0.5px solid color-mix(in srgb, var(--background-modifier-border) 60%, #1D9E75 40%);
font-size: 13px;
color: var(--text-muted);
line-height: 1.5;
}
.wl-qi-banner-heading {
font-weight: 600;
color: var(--text-normal);
margin-bottom: 3px;
font-size: 13px;
}
.wl-qi-banner-body {
white-space: pre-line;
}
/* ════════════════════════════════════════════════════════
LINT-REFACTORED UTILITY CLASSES
(Replaced inline style= assignments)
════════════════════════════════════════════════════════ */
/* AirtimeTab — time row top spacing */
.wl-modal-row-mt {
margin-top: 10px;
}
/* AirtimeTab — cancel button right spacing */
.wl-btn-mr {
margin-right: 6px;
}
/* DashboardTab — time rect bar full width */
.wl-rect-bar-full {
width: 100%;
}
/* CustomListsTab — bold toggle button preview */
.wl-editcols-bold-btn {
font-weight: bold;
}
/* CustomListsTab — italic toggle button preview */
.wl-editcols-italic-btn {
font-style: italic;
}
/* CustomListsTab — bold cell text */
.wl-cell-bold {
font-weight: 700;
}
/* CustomListsTab — italic cell text */
.wl-cell-italic {
font-style: italic;
}
/* CustomListsTab — fixed-position autofill dropdown */
.wl-pos-fixed {
position: fixed;
}
/* ListTab — inline group name input */
.wl-group-name-input {
width: 110px;
font-size: 11px;
padding: 2px 6px;
flex: unset;
}
/* ListTab — filters panel popup (fixed, body-level) */
.wl-filters-panel-popup {
position: fixed;
z-index: 9999;
max-height: 70vh;
overflow-y: auto;
background-color: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
padding: 8px;
min-width: 230px;
width: 230px;
}
/* ListTab — mobile sorting panel */
.wl-sorting-panel-mobile {
position: fixed;
left: 8px;
right: 8px;
max-height: 70vh;
overflow-y: auto;
}
/* SettingsTab — hidden quick-info section body */
.wl-qi-section-body-hidden {
display: none;
}
/* ── Inner sub-tab bar (Watchlist List/History, Upcoming Tracker/History/Maybe) ─ */
.wl-inner-tab-bar {
display: flex;
gap: 2px;
padding: 6px 10px 0;
border-bottom: 1px solid var(--background-modifier-border);
flex-shrink: 0;
}
.wl-inner-tab-btn {
padding: 4px 12px;
background: none;
border: none;
border-bottom: 2px solid transparent;
color: var(--text-muted);
cursor: pointer;
font-size: var(--font-ui-small);
font-weight: 500;
margin-bottom: -1px;
}
.wl-inner-tab-btn:hover { color: var(--text-normal); }
.wl-inner-tab-btn.is-active {
color: var(--text-accent);
border-bottom-color: var(--text-accent);
}
/* ── Feature 1: Recently arrived label ──────────────────────────────────────── */
.wl-badge-row {
display: flex;
align-items: center;
gap: 4px;
flex-wrap: wrap;
}
.wl-recently-arrived {
font-size: 10px;
color: var(--color-green);
font-style: italic;
opacity: 0.85;
}
.wl-recently-arrived-filter {
color: var(--color-green);
font-size: 11px;
}
/* ── Feature 3: Watchlist History sub-tab ────────────────────────────────────── */
.wl-history-list {
padding: 8px 12px;
display: flex;
flex-direction: column;
gap: 0;
}
.wl-history-entry {
font-size: 13px;
font-style: italic;
color: var(--text-muted);
padding: 3px 0;
line-height: 1.4;
border-bottom: none;
font-weight: 600;
}
.wl-history-empty {
padding: 16px 12px;
font-size: 12px;
color: var(--text-muted);
font-style: italic;
}
/* ── Log Tab (timeline) ───────────────────────────────────────────────────── */
.wl-log-tab {
padding: 12px 0 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
.wl-log-filter-bar {
display: flex;
gap: 6px;
padding: 10px 12px 6px;
border-bottom: 1px solid var(--background-modifier-border);
flex-shrink: 0;
}
.wl-log-filter-btn {
font-size: 12px;
font-weight: 500;
padding: 4px 12px;
border-radius: 14px;
border: 1px solid var(--background-modifier-border);
background: transparent;
color: var(--text-muted);
cursor: pointer;
transition: background 0.15s, color 0.15s;
}
.wl-log-filter-btn:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
}
.wl-log-filter-btn.is-active {
background: var(--interactive-accent);
color: var(--text-on-accent);
border-color: var(--interactive-accent);
}
.wl-log-empty {
padding: 24px 16px;
font-size: 13px;
color: var(--text-muted);
font-style: italic;
text-align: center;
}
.wl-log-timeline {
padding: 8px 12px 16px;
flex: 1;
overflow-y: auto;
min-height: 0;
}
.wl-log-virtual-scroll {
overflow-y: auto;
}
.wl-log-spacer {
width: 100%;
position: relative;
}
.wl-log-viewport {
width: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
}
/* Virtual-scroll rows are absolutely positioned inside the viewport; the
per-row `top` offset is set dynamically by LogTab. */
.wl-log-viewport .wl-log-day-header,
.wl-log-viewport .wl-log-entry {
position: absolute;
left: 0;
right: 0;
}
.wl-log-day {
margin-bottom: 4px;
}
.wl-log-day-header {
font-size: 12px;
font-weight: 600;
color: var(--text-normal);
padding: 10px 0 6px;
border-bottom: 1px solid var(--background-modifier-border);
margin-bottom: 4px;
}
.wl-log-entries {
padding-left: 4px;
}
.wl-log-entry {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 4px 0;
min-height: 24px;
}
.wl-log-dot-col {
display: flex;
flex-direction: column;
align-items: center;
width: 10px;
flex-shrink: 0;
padding-top: 6px;
}
.wl-log-dot {
width: 10px;
height: 10px;
border-radius: 50%;
flex-shrink: 0;
}
.wl-log-connector {
width: 2px;
flex: 1;
min-height: 12px;
background: var(--background-modifier-border);
}
.wl-log-content {
flex: 1;
min-width: 0;
line-height: 1.4;
padding-top: 2px;
}
.wl-log-source {
font-size: 12px;
color: var(--text-muted);
}
.wl-log-sep {
font-size: 12px;
color: var(--text-faint);
}
.wl-log-title {
font-size: 14px;
font-weight: 500;
color: var(--text-normal);
}
.wl-log-action {
font-size: 13px;
font-weight: 500;
}
.wl-log-time {
font-size: 12px;
color: var(--text-faint);
flex-shrink: 0;
padding-top: 3px;
}
/* ── Feature 2: Upcoming History sub-tab ────────────────────────────────────── */
.wl-airtime-history-card {
opacity: 0.92;
}
.wl-airtime-history-right {
flex-direction: row;
align-items: center;
gap: 4px;
}
/* ── Feature 2c: Maybe cards ─────────────────────────────────────────────────── */
.wl-maybe-card {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 8px 12px;
background: var(--background-secondary);
border-radius: 6px;
margin-bottom: 6px;
border: 1px solid var(--background-modifier-border);
min-height: 0;
}
.wl-maybe-card.wl-airtime-card-aired {
border-color: var(--color-orange);
background: color-mix(in srgb, var(--color-orange) 6%, var(--background-secondary));
}
.wl-maybe-card-left {
display: flex;
align-items: center;
gap: 8px;
flex: 1;
min-width: 0;
overflow: hidden;
}
.wl-maybe-card-title {
font-size: 12px;
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.wl-maybe-card-right {
display: flex;
align-items: center;
gap: 4px;
flex-shrink: 0;
}
/* ── Feature 4: Sort direction toggle ───────────────────────────────────────── */
.wl-sort-dir-btn {
min-width: 28px;
padding: 3px 6px;
font-size: 13px;
}
/* ── Feature 5: Custom Lists tick button ─────────────────────────────────────── */
.wl-cl-th-tick {
width: 28px;
max-width: 28px;
flex-shrink: 0;
padding: 0 4px;
display: flex;
align-items: center;
justify-content: center;
}
.wl-cl-td-tick {
width: 28px;
max-width: 28px;
flex-shrink: 0;
padding: 0 4px;
display: flex;
align-items: center;
justify-content: center;
}
.wl-cl-tick-btn {
cursor: pointer;
font-size: 14px;
color: var(--text-muted);
line-height: 1;
user-select: none;
transition: color 0.1s;
}
.wl-cl-tick-btn:hover { color: var(--color-green); }
.wl-cl-tick-btn.is-checked {
color: var(--color-green);
font-weight: bold;
}
/* Row scope + :hover variant outrank .wl-cl-tr-body:hover. */
.wl-cl-tr-body.wl-cl-tr-checked,
.wl-cl-tr-body.wl-cl-tr-checked:hover {
border-left: 3px solid var(--color-green);
background: color-mix(in srgb, var(--color-green) 5%, transparent);
}
/* Generic hide utility — doubled class outranks single-class display rules
(e.g. .wl-filter-section-content). */
.wl-hidden.wl-hidden { display: none; }
/* ── Cards view ─────────────────────────────────────────────────────────── */
.wl-cards-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 12px;
padding: 8px;
}
.wl-cards-scroll-container {
position: relative;
width: 100%;
overflow-y: auto;
/* Reserve the scrollbar gutter so clientWidth (which the virtual-scroll math
reads to size cards) doesn't change when the scrollbar appears — otherwise
the cards would re-layout to a new width/height the first time content
overflows, a one-off layout shift. */
scrollbar-gutter: stable;
/* Fill remaining vertical space inside the watchlist container. */
flex: 1 1 auto;
min-height: 0;
}
.wl-cards-scroll-spacer {
position: relative;
width: 100%;
}
.wl-cards-grid.wl-cards-grid-virtual {
position: absolute;
top: 0;
left: 0;
right: 0;
display: grid;
grid-template-columns: repeat(var(--wl-cards-cols, 1), 1fr);
/* Pin every row to the exact height the virtual-scroll math uses for the
spacer/padding offset. Without this, auto rows size to content and a card
whose intrinsic height exceeds --wl-card-height would stretch the whole
row, desyncing rendered height from reserved height (the CLS source). */
grid-auto-rows: var(--wl-card-height, auto);
align-content: start;
gap: 12px;
/* The virtual-scroll row offset is an inline padding-top set by ListTab —
deliberately NOT transform: translateY, which made Chromium's layout-shift
tracker report a row of stationary cards as shifted on every row advance. */
padding: 0;
box-sizing: border-box;
}
.wl-cards-grid.wl-cards-grid-virtual .wl-card {
width: 100%;
height: var(--wl-card-height, auto);
/* --wl-card-height is the single source of truth for card height. Explicitly
cancel the base .wl-card aspect-ratio:2/3 here: in the grid it would give the
card an intrinsic height of trackWidth*1.5, which (when the real 1fr track is
wider than the computed cardWidth) overflows the reserved row and stretches
the card after layout — shifting the absolute poster (the logged CLS). */
aspect-ratio: auto;
}
.wl-detail-modal {
display: flex;
flex-direction: column;
gap: 16px;
max-height: calc(85vh - 40px);
overflow-y: auto;
}
.wl-detail-header {
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 16px;
flex-wrap: wrap;
}
.wl-detail-header-left {
display: flex;
flex-direction: column;
gap: 6px;
flex: 1;
min-width: 0;
}
/* Cover box: in-flow aspect-ratio slot (reserves its space from first paint,
same as ReadingTab's cover). Placeholder + poster are stacked absolutely and
swapped by opacity via .has-poster so revealing the image causes no shift. */
.wl-detail-cover {
position: relative;
width: 96px;
aspect-ratio: 2 / 3;
flex-shrink: 0;
border-radius: 6px;
overflow: hidden;
background: var(--background-secondary);
}
.wl-detail-cover-placeholder {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 2.6rem;
font-weight: 700;
color: rgba(255, 255, 255, 0.85);
}
.wl-detail-cover-placeholder.is-loading {
animation: wl-poster-pulse 1.5s ease-in-out infinite;
}
.wl-detail-cover-placeholder span {
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.wl-detail-cover-img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
display: block;
opacity: 0;
transition: opacity 0.2s ease;
}
.wl-detail-cover.has-poster .wl-detail-cover-img {
opacity: 1;
}
.wl-detail-title {
margin: 0;
font-size: 1.3rem;
font-weight: 700;
}
.wl-detail-badge-row {
display: flex;
align-items: center;
gap: 8px;
}
.wl-detail-group-meta {
font-size: 0.85rem;
opacity: 0.7;
}
.wl-detail-stats-box {
display: flex;
flex-direction: row;
align-items: center;
gap: 16px;
padding: 8px 12px;
border: 1px solid var(--background-modifier-border, rgba(255,255,255,0.1));
border-radius: 6px;
}
/* Narrow widths: same font, tighter item gap + container padding so the
4-block bar (left / watched / episodes / progress) fits without clipping. */
@media (max-width: 600px) {
.wl-detail-stats-box {
gap: 7px;
padding: 8px 7px;
}
}
/* ── Credits (director / cast) rows — detail modal + List expanded row ────── */
.wl-detail-credits {
display: flex;
flex-direction: column;
gap: 2px;
margin-top: 6px;
}
.wl-acc-credits {
display: flex;
flex-direction: column;
gap: 1px;
margin-top: 2px;
}
.wl-credits-row {
font-size: 12px;
color: var(--text-muted);
line-height: 1.5;
min-width: 0;
}
.wl-credits-label {
font-weight: 600;
margin-right: 6px;
}
.wl-credits-label::after {
content: ':';
}
.wl-credits-name.is-clickable {
cursor: pointer;
color: var(--text-normal);
}
.wl-credits-name.is-clickable:hover {
color: var(--text-accent, var(--interactive-accent));
text-decoration: underline;
}
.wl-detail-episodes {
display: flex;
flex-direction: column;
gap: 8px;
}
.wl-detail-rating,
.wl-detail-notes,
.wl-detail-date {
display: flex;
flex-direction: column;
gap: 6px;
}
.wl-detail-rating {
flex-direction: row;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.wl-detail-date {
flex-direction: row;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
.wl-detail-status {
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
.wl-detail-notes-input {
width: 100%;
min-height: 60px;
resize: vertical;
font-family: inherit;
font-size: 0.9rem;
}
.wl-detail-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 12px;
gap: 12px;
}
.wl-detail-group-grid {
/* Scrolls inside the parent .wl-detail-modal, no own scroll container. */
}
.wl-card {
position: relative;
aspect-ratio: 2 / 3;
border-radius: 8px;
overflow: hidden;
cursor: pointer;
transition: transform 0.15s ease, box-shadow 0.15s ease;
border: 1px solid rgba(255, 255, 255, 0.05);
}
.wl-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
/* Selected card in selection mode — border only (no background tint), in the
theme accent used by the Watched checkbox. Drawn as an inset outline rather
than a border: outlines paint above the absolutely-positioned poster, follow
the border-radius, and never change the card's layout box. */
/* Drawn as an ::after overlay, not an outline/border on the card itself: the
absolutely-positioned poster paints above a negative-offset outline, leaving
only the ~1px sliver outside the padding box visible. The overlay is the
card's last paint-order child, so the full border width shows over the poster
without affecting layout or intercepting clicks. */
.wl-card.wl-card-selected::after {
content: '';
position: absolute;
inset: 0;
border: 3px solid var(--wl-watched-color);
border-radius: inherit;
pointer-events: none;
}
.wl-card-poster-placeholder {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 3rem;
font-weight: 700;
color: rgba(255, 255, 255, 0.85);
}
.wl-card-poster-placeholder.is-loading {
animation: wl-poster-pulse 1.5s ease-in-out infinite;
}
@keyframes wl-poster-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
.wl-card-poster-placeholder span {
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
/* Group-card collage: equal vertical strips of member covers, separated by
thin background-color lines (the flex gap reveals the card background). */
.wl-card-collage {
position: absolute;
inset: 0;
display: flex;
gap: 2px;
background-color: var(--background-primary);
}
.wl-card-collage-strip {
flex: 1;
min-width: 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.wl-card-progress-bar {
margin-top: 6px;
width: 100%;
height: 3px;
border-radius: 2px;
background: rgba(255, 255, 255, 0.2);
overflow: hidden;
}
.wl-card-progress-fill {
height: 100%;
border-radius: 2px;
background: rgba(255, 255, 255, 0.8);
transition: width 0.2s ease;
}
.wl-cards-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 48px 16px;
gap: 8px;
color: var(--text-muted, rgba(255, 255, 255, 0.55));
}
.wl-cards-empty-icon {
font-size: 2.5rem;
opacity: 0.6;
}
.wl-cards-empty-msg {
margin: 0;
font-size: 0.95rem;
}
.wl-card-context-menu {
position: absolute;
top: 36px;
right: 8px;
z-index: 20;
min-width: 150px;
padding: 4px;
border-radius: 6px;
background: var(--background-secondary, #2a2a2a);
border: 1px solid var(--background-modifier-border, rgba(255, 255, 255, 0.1));
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
display: flex;
flex-direction: column;
}
.wl-card-context-menu.is-right-aligned {
right: 8px;
left: auto;
}
.wl-card-context-item {
padding: 6px 10px;
cursor: pointer;
border-radius: 4px;
font-size: 0.9rem;
color: var(--text-normal);
}
.wl-card-context-item:hover {
background: var(--background-modifier-hover, rgba(255, 255, 255, 0.08));
}
.is-mobile .wl-card:hover {
transform: none;
box-shadow: none;
}
.is-mobile .wl-card:active {
transform: scale(0.97);
}
.wl-card:focus-visible {
outline: 2px solid var(--interactive-accent);
outline-offset: 2px;
}
.wl-detail-episodes .wl-episode-grid {
flex-wrap: wrap;
}
.wl-card-poster {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
/* display:block from first paint so the absolute inset:0 box is reserved
before the image data arrives; the unloaded poster is hidden with opacity
(which keeps the box) and fades in on load over the letter placeholder.
Note: the scroll-CLS logged against this img was NOT the reveal — it was
the grid's translateY offset (see .wl-cards-grid-virtual / ListTab). */
display: block;
opacity: 0;
transition: opacity 0.2s ease;
}
/* Poster loaded: fade the image in on top of the letter placeholder (which
stays behind it). Opacity — not display — so the swap causes zero layout shift. */
.wl-card.has-poster .wl-card-poster {
opacity: 1;
}
.wl-card-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 8px;
padding-top: 40px;
background: linear-gradient(transparent, rgba(0, 0, 0, 0.85));
display: flex;
flex-direction: column;
gap: 4px;
}
.wl-card-title {
color: #fff;
font-size: 0.8rem;
font-weight: 600;
line-height: 1.2;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.wl-card-type-badge {
font-size: 0.65rem;
padding: 1px 6px;
border-radius: 3px;
color: #fff;
width: fit-content;
}
.wl-card-status-badge {
position: absolute;
top: 6px;
left: 6px;
font-size: 0.6rem;
padding: 2px 6px;
border-radius: 3px;
color: #fff;
}
.wl-card-menu-btn {
position: absolute;
top: 4px;
right: 4px;
background: rgba(0, 0, 0, 0.5);
border: none;
color: #fff;
border-radius: 50%;
width: 24px;
height: 24px;
cursor: pointer;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.15s;
padding: 0;
}
.wl-card:hover .wl-card-menu-btn {
opacity: 1;
}
.is-mobile .wl-card-menu-btn {
opacity: 1;
}
/* ── Community rating ────────────────────────────────────────────────── */
.wl-rating-divider {
display: inline-block;
width: 1px;
height: 18px;
background-color: var(--background-modifier-border);
margin: 0 8px;
vertical-align: middle;
}
.wl-community-badge {
display: inline-flex;
align-items: center;
gap: 6px;
}
.wl-community-source {
font-size: 11px;
font-weight: 500;
padding: 2px 6px;
border-radius: 4px;
line-height: 1.2;
}
.wl-community-source--imdb { background-color: #F5C518; color: #000000; }
.wl-community-source--mal { background-color: #2E51A2; color: #FFFFFF; }
.wl-community-source--anilist { background-color: #3DB4F2; color: #FFFFFF; }
.wl-community-source--tmdb { background-color: #01B4E4; color: #FFFFFF; }
.wl-community-score {
font-size: 15px;
font-weight: 500;
color: var(--text-normal);
}
.wl-community-votes {
font-size: 12px;
color: var(--text-faint);
}
.wl-community-empty {
font-size: 12px;
color: var(--text-faint);
opacity: 0.6;
font-style: italic;
}
.wl-community-refresh {
background: transparent;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
width: 22px;
height: 22px;
padding: 0;
cursor: pointer;
font-size: 13px;
line-height: 1;
color: var(--text-muted);
display: inline-flex;
align-items: center;
justify-content: center;
}
.wl-community-refresh:hover {
color: var(--text-normal);
background-color: var(--background-modifier-hover);
}
.wl-community-refresh.is-loading {
animation: wl-spin 0.9s linear infinite;
pointer-events: none;
}
/* Trailer control at the tail of the rating row (rating badge → refresh → YouTube). */
.wl-trailer-control {
display: inline-flex;
align-items: center;
vertical-align: middle;
}
.wl-trailer-btn {
/* Wide clickable frame (~3× the icon) with the YouTube glyph centred at its
natural proportions — only the frame widens, never the icon. */
min-width: 66px;
padding: 2px 20px;
margin-left: 8px;
background: transparent;
border: none;
border-radius: 6px;
cursor: pointer;
color: #FF0000; /* Permanent red, not hover-only. */
display: inline-flex;
align-items: center;
justify-content: center;
vertical-align: middle;
box-shadow: none;
}
.wl-trailer-btn:hover {
color: #CC0000; /* Discreet darker-red + subtle wash so it still reads as clickable. */
background: var(--background-modifier-hover);
}
.wl-trailer-btn .svg-icon {
width: 22px;
height: 22px;
}
.wl-trailer-refresh {
margin-left: 8px;
}
.wl-trailer-refresh .svg-icon {
width: 14px;
height: 14px;
}
@keyframes wl-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* ── API routing card ────────────────────────────────────────────────── */
.wl-settings-card {
margin-top: 24px;
padding: 14px 16px;
border: 1px solid var(--background-modifier-border);
border-radius: 8px;
background-color: var(--background-secondary);
}
.wl-settings-card-title {
font-size: 14px;
font-weight: 600;
margin-bottom: 4px;
color: var(--text-normal);
}
.wl-settings-card-desc {
font-size: 12px;
color: var(--text-muted);
margin-bottom: 12px;
}
.wl-type-api-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.wl-type-api-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 6px 0;
border-bottom: 1px solid var(--background-modifier-border);
}
.wl-type-api-row:last-child {
border-bottom: none;
}
.wl-type-api-name {
font-size: 13px;
color: var(--text-normal);
}
.wl-type-api-locked {
font-size: 12px;
color: var(--text-muted);
opacity: 0.55;
font-style: italic;
}
.wl-type-api-select {
max-width: 240px;
}
/* AddTitleModal: "no API configured" message */
.wl-modal-no-api {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 14px 12px;
color: var(--text-muted);
font-size: 13px;
text-align: center;
}
.wl-modal-no-api-icon {
font-size: 16px;
opacity: 0.7;
}
/* ── Filter panel: per-section "All" toggle + Groups-only divider ─────── */
.wl-filter-all-toggle {
color: var(--interactive-accent);
font-weight: 500;
}
.wl-filter-section-divider {
height: 1px;
background-color: var(--background-modifier-border);
margin: 6px 0;
}
/* ════════════════════════════════════════════════════════
READING TAB
════════════════════════════════════════════════════════ */
.wl-reading-tab {
display: flex;
flex-direction: column;
gap: 10px;
position: relative;
height: 100%;
min-height: 0;
overflow: hidden;
}
.wl-reading-popover {
z-index: 50;
min-width: 200px;
background: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
padding: 8px;
display: flex;
flex-direction: column;
gap: 4px;
}
.wl-reading-popover-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
margin-top: 4px;
}
.wl-reading-popover-label:first-child {
margin-top: 0;
}
.wl-reading-popover-checks {
display: flex;
flex-direction: column;
gap: 2px;
}
.wl-reading-popover-check {
display: flex;
align-items: center;
gap: 6px;
padding: 3px 4px;
border-radius: 4px;
cursor: pointer;
font-size: 13px;
}
.wl-reading-popover-check:hover {
background: var(--background-modifier-hover);
}
.wl-reading-popover-dot {
width: 8px;
height: 8px;
border-radius: 50%;
margin-left: auto;
}
.wl-reading-popover-footer {
margin-top: 6px;
display: flex;
justify-content: flex-end;
}
.wl-reading-filter-badge {
display: inline-block;
margin-left: 4px;
padding: 0 5px;
border-radius: 8px;
background: var(--interactive-accent);
color: var(--text-on-accent);
font-size: 10px;
font-weight: 600;
min-width: 14px;
text-align: center;
}
/* ── Sub-tab bar ───────────────────────────────────────── */
.wl-reading-subtabs {
display: flex;
gap: 2px;
border-bottom: 0.5px solid var(--background-modifier-border);
margin: 8px -2px 0;
}
.wl-reading-subtab {
display: flex;
align-items: center;
gap: 6px;
padding: 6px 14px;
background: none;
border: none;
border-bottom: 2px solid transparent;
color: var(--text-muted);
cursor: pointer;
font-size: var(--font-ui-small);
font-weight: 500;
margin-bottom: -0.5px;
transition: color 0.15s, border-color 0.15s;
}
.wl-reading-subtab:hover {
color: var(--text-normal);
}
.wl-reading-subtab.is-active {
color: #1D9E75;
border-bottom-color: #1D9E75;
}
.wl-reading-subtab-icon {
font-size: 1rem;
line-height: 1;
}
.wl-reading-subtab-label {
line-height: 1;
}
/* ── Toolbar ──────────────────────────────────────────── */
.wl-reading-toolbar {
display: flex;
align-items: center;
gap: 8px;
}
/* Gear + Add group — pushed to the far right of the toolbar row (was driven by
the toolbar's space-between before search/actions were flattened into one
flex row). */
.wl-reading-toolbar-right {
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
margin-left: auto;
}
.wl-reading-search-wrap {
flex: 1;
min-width: 0;
max-width: 240px;
}
.wl-reading-search-input {
width: 100%;
padding: 6px 10px;
border-radius: 5px;
border: 0.5px solid var(--background-modifier-border);
background: var(--background-primary);
color: var(--text-normal);
font-size: var(--font-ui-small);
box-sizing: border-box;
}
.wl-reading-search-input:focus {
outline: none;
border-color: var(--interactive-accent);
}
.wl-reading-add-btn {
/* color via .wl-btn-success */
padding: 4px 12px;
border-radius: 4px;
cursor: pointer;
font-size: var(--font-ui-small);
font-weight: 500;
}
.wl-reading-manage-btn {
padding: 4px 8px;
font-size: 14px;
}
/* ── Card grid (placeholder for Phase 2 cards) ───────── */
.wl-reading-content {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.wl-reading-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 12px;
}
/* ── Empty state ─────────────────────────────────────── */
.wl-reading-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 48px 16px;
gap: 8px;
color: var(--text-muted);
}
.wl-reading-empty-icon {
font-size: 2.5rem;
opacity: 0.6;
}
.wl-reading-empty-msg {
margin: 0;
font-size: 0.95rem;
}
.wl-reading-empty-link {
color: var(--interactive-accent);
cursor: pointer;
text-decoration: underline;
}
.wl-reading-empty-link:hover {
filter: brightness(1.15);
}
.wl-reading-empty-search {
padding: 24px 16px;
text-align: center;
color: var(--text-muted);
font-size: var(--font-ui-small);
}
/* ── Reading cards ───────────────────────────────────── */
.wl-reading-card {
position: relative;
display: flex;
flex-direction: column;
gap: 4px;
cursor: pointer;
border-radius: 6px;
padding: 4px;
transition: background 0.15s;
}
.wl-reading-card:hover {
background: var(--background-modifier-hover);
}
.wl-reading-card-cover {
position: relative;
width: 100%;
aspect-ratio: 2 / 3;
border-radius: 5px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
background: var(--background-secondary);
}
.wl-reading-card-cover.is-loading {
animation: wl-poster-pulse 1.5s ease-in-out infinite;
}
.wl-reading-card-cover-img {
/* Absolutely fill the 2:3 cover box so a lazily-loaded cover image causes ZERO
layout shift — the box size is fixed by .wl-reading-card-cover's aspect-ratio
before the image arrives, and the in-flow icon fallback stays centred. */
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.wl-reading-card-cover-icon {
font-size: 2.5rem;
opacity: 0.75;
}
.wl-reading-card-status-badge {
position: absolute;
top: 6px;
left: 6px;
font-size: 0.6rem;
font-weight: 500;
padding: 2px 6px;
border-radius: 3px;
color: #fff;
}
.wl-reading-card-title {
margin-top: 4px;
font-weight: 600;
font-size: var(--font-ui-small);
color: var(--text-normal);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.wl-reading-card-author {
font-size: 11px;
color: var(--text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.wl-reading-card-progress-bar {
margin-top: 4px;
width: 100%;
height: 3px;
background: var(--background-modifier-border);
border-radius: 2px;
overflow: hidden;
}
.wl-reading-card-progress-fill {
height: 100%;
border-radius: 2px;
transition: width 0.2s ease;
}
.wl-reading-card-progress-text {
display: flex;
gap: 8px;
font-size: 10.5px;
color: var(--text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.wl-reading-card-progress-piece {
white-space: nowrap;
}
/* ── Reading virtual scroll ─────────────────────────── */
.wl-reading-scroll-container {
position: relative;
width: 100%;
overflow-y: auto;
flex: 1 1 auto;
min-height: 0;
}
.wl-reading-scroll-spacer {
position: relative;
width: 100%;
}
.wl-reading-grid.wl-reading-grid-virtual {
position: absolute;
top: 0;
left: 0;
right: 0;
display: grid;
grid-template-columns: repeat(var(--wl-reading-cols, 1), 1fr);
gap: 12px;
padding: 0;
box-sizing: border-box;
will-change: transform;
}
.wl-reading-grid.wl-reading-grid-virtual .wl-reading-card {
width: 100%;
height: var(--wl-reading-card-height, auto);
overflow: hidden;
}
.wl-reading-grid.wl-reading-grid-virtual .wl-reading-card-cover {
flex-shrink: 1;
min-height: 0;
}
/* ── Reading card context menu ──────────────────────── */
.wl-reading-card-menu-btn {
position: absolute;
top: 4px;
right: 4px;
background: rgba(0, 0, 0, 0.5);
border: none;
color: #fff;
border-radius: 50%;
width: 24px;
height: 24px;
cursor: pointer;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.15s;
padding: 0;
z-index: 5;
}
.wl-reading-card:hover .wl-reading-card-menu-btn {
opacity: 1;
}
.is-mobile .wl-reading-card-menu-btn {
opacity: 1;
}
.wl-reading-card-context-menu {
position: absolute;
top: 36px;
right: 8px;
z-index: 20;
min-width: 150px;
padding: 4px;
border-radius: 6px;
background: var(--background-secondary, #2a2a2a);
border: 1px solid var(--background-modifier-border, rgba(255, 255, 255, 0.1));
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
display: flex;
flex-direction: column;
}
.wl-reading-card-context-menu.is-right-aligned {
right: 8px;
left: auto;
}
.wl-reading-card-context-item {
padding: 6px 10px;
cursor: pointer;
border-radius: 4px;
font-size: 0.9rem;
color: var(--text-normal);
}
.wl-reading-card-context-item:hover {
background: var(--background-modifier-hover, rgba(255, 255, 255, 0.08));
}
/* ── Reading selection mode ─────────────────────────── */
.wl-reading-card.is-selected {
outline: 2px solid var(--interactive-accent);
outline-offset: -2px;
border-radius: 6px;
}
.wl-reading-action-bar {
display: flex;
align-items: center;
gap: 6px;
}
/* ── Reading filter presets ─────────────────────────── */
.wl-reading-popover-presets {
display: flex;
flex-direction: column;
gap: 2px;
margin-bottom: 4px;
}
.wl-reading-preset-row {
display: flex;
align-items: center;
gap: 4px;
}
.wl-reading-preset-load {
flex: 1;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.wl-reading-preset-del {
flex-shrink: 0;
padding: 2px 6px;
font-size: 11px;
opacity: 0.6;
}
.wl-reading-preset-del:hover {
opacity: 1;
}
.wl-reading-preset-save-row {
display: flex;
align-items: center;
gap: 4px;
margin-bottom: 6px;
}
.wl-reading-preset-name-input {
flex: 1;
min-width: 0;
}
/* ════════════════════════════════════════════════════════
READING MODALS
════════════════════════════════════════════════════════ */
.wl-reading-modal {
display: flex;
flex-direction: column;
gap: 10px;
max-height: calc(85vh - 40px);
overflow-y: auto;
padding: 4px 2px;
}
.wl-reading-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
font-size: 1.05rem;
font-weight: 600;
color: var(--text-normal);
padding: 0 2px 4px;
}
.wl-reading-modal-header-left {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.wl-reading-modal-header-actions {
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
}
.wl-reading-modal-header-actions .wl-btn.is-hidden {
display: none;
}
.wl-reading-modal-header-icon {
font-size: 1.2rem;
line-height: 1;
}
.wl-reading-lookup {
display: flex;
align-items: center;
gap: 6px;
}
.wl-reading-lookup-input {
flex: 1;
min-width: 0;
}
.wl-reading-lookup-btn {
flex-shrink: 0;
}
.wl-reading-lookup-results {
display: flex;
flex-direction: column;
gap: 2px;
min-height: 260px;
max-height: 380px;
overflow-y: auto;
margin-top: 6px;
padding: 4px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 5px;
background: var(--background-secondary);
}
.wl-reading-lookup-results:empty {
display: none;
}
.wl-reading-lookup-loading,
.wl-reading-lookup-empty {
padding: 8px;
color: var(--text-muted);
font-size: 12px;
font-style: italic;
}
.wl-reading-lookup-item {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
border-radius: 4px;
cursor: pointer;
border: 1px solid transparent;
}
.wl-reading-lookup-item-text {
min-width: 0;
flex: 1 1 auto;
}
.wl-reading-status-rating-row {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
gap: 16px;
}
.wl-reading-inline-group {
display: flex;
align-items: center;
gap: 8px;
}
.wl-reading-status-select {
width: auto;
min-width: 0;
flex: 0 0 auto;
padding-right: 24px;
}
.wl-reading-form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
align-items: start;
}
.wl-reading-form-grid-col {
display: flex;
flex-direction: column;
gap: 8px;
min-width: 0;
}
.wl-reading-form-grid-col .wl-reading-section-label {
margin-top: 0;
}
.wl-reading-lookup-item:hover {
background: var(--background-modifier-hover);
border-color: var(--background-modifier-border);
}
.wl-reading-lookup-item-title-row {
display: flex;
align-items: center;
gap: 6px;
}
.wl-reading-lookup-item-title {
font-weight: 500;
font-size: 13px;
}
.wl-reading-lookup-item-meta {
font-size: 11px;
color: var(--text-muted);
margin-top: 2px;
}
.wl-reading-modal-divider {
height: 1px;
background: var(--background-modifier-border);
margin: 4px 0;
}
.wl-reading-form {
display: flex;
flex-direction: column;
gap: 8px;
}
.wl-reading-section-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
margin-top: 8px;
padding-bottom: 2px;
border-bottom: 0.5px solid var(--background-modifier-border);
}
.wl-reading-row {
display: flex;
flex-direction: column;
gap: 4px;
}
.wl-reading-row-split {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.wl-reading-col {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
.wl-reading-label {
font-size: 12px;
font-weight: 500;
color: var(--text-muted);
}
.wl-reading-stars {
display: flex;
gap: 2px;
}
.wl-reading-vault-wrap {
display: flex;
align-items: center;
gap: 8px;
}
.wl-reading-vault-display {
flex: 1;
min-width: 0;
font-size: var(--font-ui-small);
}
.wl-reading-vault-path {
color: var(--text-normal);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
max-width: 100%;
vertical-align: bottom;
}
.wl-reading-vault-empty {
color: var(--text-muted);
font-style: italic;
}
.wl-reading-modal-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
padding-top: 8px;
border-top: 0.5px solid var(--background-modifier-border);
}
.wl-reading-modal-save {
/* uses .wl-reading-add-btn — color via .wl-btn-success */
}
/* ── Reading detail modal ────────────────────────────── */
.wl-reading-detail {
display: flex;
flex-direction: column;
gap: 14px;
}
.wl-reading-detail-header {
display: flex;
gap: 14px;
align-items: flex-start;
}
.wl-reading-detail-cover {
position: relative;
width: 90px;
aspect-ratio: 2 / 3;
flex-shrink: 0;
border-radius: 5px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
background: var(--background-secondary);
}
.wl-reading-detail-cover-img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.wl-reading-detail-cover-icon {
font-size: 2.2rem;
opacity: 0.75;
}
.wl-reading-detail-info {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 4px;
}
.wl-reading-detail-title {
margin: 0;
font-size: 16px;
font-weight: 700;
color: var(--text-normal);
}
.wl-reading-detail-author {
font-size: 13px;
color: var(--text-muted);
}
.wl-reading-detail-meta-row {
display: flex;
align-items: center;
gap: 10px;
margin-top: 2px;
}
.wl-reading-detail-status {
padding: 2px 8px;
border-radius: 999px;
color: #fff;
font-size: 11px;
font-weight: 500;
cursor: pointer;
}
.wl-reading-detail-stars {
display: flex;
gap: 2px;
}
.wl-reading-detail-actions {
display: flex;
align-items: center;
gap: 6px;
margin-top: 4px;
}
.wl-reading-external-link-wrap {
display: flex;
align-items: center;
gap: 4px;
}
.wl-reading-external-link-input {
flex: 1;
min-width: 160px;
font-size: 12px;
}
.wl-reading-detail-vault-row {
display: flex;
align-items: center;
gap: 6px;
margin-top: 2px;
font-size: 12px;
color: var(--text-muted);
}
.wl-reading-detail-vault-label {
flex-shrink: 0;
}
.wl-reading-detail-vault-path {
color: var(--text-normal);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100%;
}
.wl-reading-detail-vault-empty {
font-style: italic;
}
/* ── Detail progress ─────────────────────────────────── */
.wl-reading-detail-progress {
display: flex;
flex-direction: column;
gap: 6px;
}
.wl-reading-arc-row {
display: flex;
justify-content: center;
gap: 24px;
flex-wrap: wrap;
}
.wl-reading-arc-col {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
min-width: 110px;
}
.wl-reading-arc-svg-wrap {
width: 100px;
height: 56px;
overflow: hidden;
}
.wl-reading-arc-svg {
width: 100px;
height: 100px;
display: block;
}
.wl-reading-arc-pct {
font-size: 14px;
font-weight: 600;
fill: var(--text-normal);
}
.wl-reading-arc-controls {
display: flex;
align-items: center;
gap: 4px;
}
.wl-reading-step-btn {
min-width: 32px;
padding: 2px 8px;
}
.wl-reading-arc-input {
width: 52px;
text-align: center;
}
.wl-reading-arc-label {
font-size: 13px;
color: var(--text-muted);
text-align: center;
}
.wl-reading-arc-total-input {
width: 48px;
text-align: center;
}
/* ── Detail details grid ─────────────────────────────── */
.wl-reading-detail-details {
display: flex;
flex-direction: column;
gap: 6px;
}
.wl-reading-detail-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px 16px;
}
.wl-reading-detail-cell {
display: flex;
flex-direction: column;
gap: 2px;
}
/* ADDED + RELEASE share one grid cell so the modal keeps its height. */
.wl-reading-detail-cell-pair {
flex-direction: row;
gap: 16px;
}
.wl-reading-detail-pair-col {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
flex: 1;
}
.wl-reading-detail-cell-label {
font-size: 10.5px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--text-muted);
}
.wl-reading-detail-cell-value {
font-size: 13px;
color: var(--text-normal);
}
.wl-reading-detail-link {
color: var(--interactive-accent);
text-decoration: underline;
}
.wl-reading-detail-id-value {
display: flex;
align-items: center;
gap: 6px;
}
.wl-reading-detail-id-edit {
flex: 0 0 auto;
padding: 0 6px;
min-width: 0;
line-height: 1.6;
}
/* ── Inline-editable title / author ─────────────────── */
.wl-reading-detail-title-wrap {
line-height: 1;
}
.wl-reading-detail-author-wrap {
line-height: 1;
}
/* Dotted "editable" hint on hover — a transparent border-bottom that gains
colour avoids the partially-supported `text-decoration` shorthand while
keeping the layout stable. */
.wl-reading-detail-editable-text {
cursor: text;
border-bottom: 1px dotted transparent;
}
.wl-reading-detail-editable-text:hover {
border-bottom-color: var(--text-faint);
}
.wl-reading-detail-title-input {
width: 100%;
box-sizing: border-box;
font-size: 16px;
font-weight: 700;
background: transparent;
border: none;
border-bottom: 1.5px solid var(--interactive-accent);
border-radius: 0;
padding: 0;
color: var(--text-normal);
outline: none;
box-shadow: none;
height: auto;
line-height: 1.2;
}
.wl-reading-detail-author-input {
width: 100%;
box-sizing: border-box;
font-size: 13px;
background: transparent;
border: none;
border-bottom: 1px solid var(--background-modifier-border);
border-radius: 0;
padding: 0;
color: var(--text-muted);
outline: none;
box-shadow: none;
height: auto;
}
/* ── Inline status badge & dropdown ─────────────────── */
.wl-reading-detail-status-wrap {
display: inline-block;
}
.wl-reading-status-dropdown {
position: fixed;
background: var(--background-primary);
border: 0.5px solid var(--background-modifier-border);
border-radius: 6px;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
overflow: hidden;
min-width: 148px;
z-index: 1000;
}
.wl-reading-status-option {
display: flex;
align-items: center;
gap: 8px;
padding: 7px 12px;
font-size: 12px;
cursor: pointer;
color: var(--text-normal);
}
.wl-reading-status-option:hover {
background: var(--background-modifier-hover);
}
.wl-reading-status-option-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
/* Default (neutral) dot for options without an assigned colour. Status
options always set an inline background-color, which overrides this. */
background: var(--background-modifier-border);
}
/* ── Editable date cells ─────────────────────────────── */
.wl-reading-detail-cell-date {
display: flex;
align-items: center;
gap: 5px;
margin-top: 2px;
}
.wl-reading-detail-today-btn {
font-size: 10px;
padding: 1px 6px;
line-height: 1.4;
}
.wl-reading-detail-today-btn.is-dimmed {
opacity: 0.4;
cursor: default;
}
.wl-reading-detail-date-input {
font-size: 12px;
width: 88px;
padding: 1px 5px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 3px;
background: var(--background-primary);
color: var(--text-normal);
box-sizing: border-box;
}
/* ── Detail footer ───────────────────────────────────── */
.wl-reading-detail-footer {
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
padding-top: 10px;
border-top: 0.5px solid var(--background-modifier-border);
}
.wl-reading-detail-footer-left,
.wl-reading-detail-footer-right {
display: flex;
gap: 8px;
}
.wl-reading-detail-delete {
/* uses .wl-delete-btn — color via .wl-btn-danger */
}
/* ── Reading custom fields ──────────────────────────────────── */
.wl-reading-detail-custom-heading,
.wl-reading-detail-quotes-heading {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 6px;
}
.wl-reading-detail-custom-manage {
font-size: 12px;
color: var(--interactive-accent);
cursor: pointer;
text-decoration: underline;
}
.wl-reading-detail-custom-empty {
font-size: 12px;
color: var(--text-muted);
padding: 4px 0;
}
.wl-reading-custom-table {
display: flex;
flex-direction: column;
border: 0.5px solid var(--background-modifier-border);
border-radius: 4px;
overflow: hidden;
}
.wl-reading-custom-row {
display: grid;
grid-template-columns: 140px 1fr;
align-items: center;
min-height: 32px;
border-top: 0.5px solid var(--background-modifier-border);
}
.wl-reading-custom-row:first-child {
border-top: none;
}
.wl-reading-custom-table.is-border-mode .wl-reading-custom-row {
border-top: none;
}
.wl-reading-custom-label {
background: var(--background-secondary);
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
padding: 6px 10px;
font-size: 12px;
color: var(--text-muted);
font-weight: 500;
}
.wl-reading-custom-value {
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
padding: 4px 10px;
font-size: 13px;
color: var(--text-normal);
}
/* Fill mode: pastel label background (--wl-field-bg set per column by
ReadingDetailModal) with dark text for contrast. */
.wl-reading-custom-table:not(.is-border-mode) .wl-reading-custom-label {
background: var(--wl-field-bg, var(--background-secondary));
color: #1e1e1e;
}
/* Border mode: coloured label outline (--wl-field-border set per column). */
.wl-reading-custom-table.is-border-mode .wl-reading-custom-label {
border: 1.5px solid var(--wl-field-border, var(--background-modifier-border));
box-sizing: border-box;
}
.wl-reading-custom-table.is-border-mode .wl-reading-custom-value {
border: 0.5px solid var(--background-modifier-border);
box-sizing: border-box;
}
.wl-reading-custom-display {
display: inline-block;
min-height: 22px;
padding: 2px 4px;
cursor: text;
border-radius: 3px;
}
.wl-reading-custom-display:hover {
background: var(--background-modifier-hover);
}
.wl-reading-custom-display.is-placeholder {
color: var(--text-faint);
}
.wl-reading-custom-input {
width: 100%;
font-size: 13px;
}
/* ── Reading favorite quotes ────────────────────────────────── */
.wl-reading-detail-quotes {
display: flex;
flex-direction: column;
gap: 8px;
}
.wl-reading-detail-quotes-add {
font-size: 12px;
}
.wl-reading-quote-empty {
font-size: 12px;
color: var(--text-muted);
padding: 6px 0;
}
.wl-reading-quote-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.wl-reading-quote-card {
background: var(--background-secondary);
border-left: 3px solid var(--interactive-accent);
border-radius: 0 4px 4px 0;
padding: 8px 12px;
}
.wl-reading-quote-text {
font-size: 13px;
line-height: 1.5;
color: var(--text-normal);
white-space: pre-wrap;
}
.wl-reading-quote-ref {
font-size: 11px;
color: var(--text-muted);
margin-top: 4px;
font-style: italic;
}
.wl-reading-quote-form-host {
margin-top: 4px;
}
.wl-reading-quote-form {
display: flex;
flex-direction: column;
gap: 6px;
padding: 10px;
background: var(--background-secondary);
border-radius: 4px;
border: 0.5px solid var(--background-modifier-border);
}
.wl-reading-quote-textarea {
width: 100%;
resize: vertical;
min-height: 60px;
font-family: inherit;
}
.wl-reading-quote-ref-input {
width: 100%;
max-width: 240px;
}
.wl-reading-quote-form-actions {
display: flex;
justify-content: flex-end;
gap: 6px;
}
/* ── Manage columns — style toggle ────────────────────────── */
.wl-reading-cols-style-row {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 10px;
font-size: 12px;
}
.wl-reading-cols-style-label {
color: var(--text-muted);
flex-shrink: 0;
}
.wl-reading-cols-style-group {
display: flex;
gap: 4px;
}
.wl-reading-cols-style-btn {
font-size: 11px;
padding: 2px 12px;
height: 24px;
border-radius: 4px;
border: 0.5px solid var(--background-modifier-border);
background: transparent;
color: var(--text-muted);
cursor: pointer;
line-height: 1;
}
.wl-reading-cols-style-btn.is-active {
background: var(--interactive-accent);
color: var(--text-on-accent);
border-color: var(--interactive-accent);
}
/* ── Manage columns — color dot & palette ──────────────────── */
.wl-reading-col-color-dot {
flex: 0 0 18px;
width: 18px;
height: 18px;
border-radius: 50%;
border: 2px solid rgba(0, 0, 0, 0.15);
cursor: pointer;
padding: 0;
transition: transform 0.1s, border-color 0.1s;
}
.wl-reading-col-color-dot:hover {
transform: scale(1.2);
border-color: rgba(0, 0, 0, 0.35);
}
/* Per-list tab colour row in the Table settings modal. */
.wl-editcols-tabcolor-row {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 12px;
}
.wl-editcols-tabcolor-label {
font-size: 13px;
font-weight: 600;
color: var(--text-normal);
}
/* Chosen colour flows through CSS vars set by CustomListsTab; the .is-unset
class swaps in the checkerboard below instead. */
.wl-editcols-tabcolor-dot:not(.is-unset) {
background-color: var(--wl-dot-fill);
}
.wl-editcol-opt-color-dot:not(.is-unset) {
background-color: var(--wl-dot-fill);
border-color: var(--wl-dot-border);
}
.wl-editcols-tabcolor-dot.is-unset,
.wl-editcol-opt-color-dot.is-unset {
background: repeating-conic-gradient(
var(--background-modifier-border) 0% 25%,
var(--background-primary) 0% 50%
) 0 / 8px 8px;
}
.wl-editcol-opt-color-dot {
flex: 0 0 16px;
width: 16px;
height: 16px;
}
.wl-reading-col-palette {
position: fixed;
display: grid;
grid-template-columns: repeat(4, 24px);
gap: 5px;
padding: 8px;
background: var(--background-primary);
border: 0.5px solid var(--background-modifier-border);
border-radius: 7px;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
z-index: 1000;
}
.wl-reading-col-palette-swatch {
width: 24px;
height: 24px;
border-radius: 50%;
border: 2px solid;
cursor: pointer;
padding: 0;
transition: transform 0.1s;
}
.wl-reading-col-palette-swatch:hover {
transform: scale(1.18);
}
.wl-reading-col-palette-swatch.is-active {
outline: 2px solid var(--text-normal);
outline-offset: 1px;
}
/* Custom full-spectrum swatch in the shared colour picker. */
.wl-color-custom-swatch {
position: relative;
overflow: hidden;
}
.wl-color-custom-swatch.wl-color-custom-rainbow {
background: conic-gradient(
from 90deg,
#f43f5e, #f59e0b, #facc15, #22c55e, #06b6d4, #3b82f6, #8b5cf6, #f43f5e
);
border-color: var(--background-modifier-border);
}
.wl-color-custom-input {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
border: none;
opacity: 0;
cursor: pointer;
}
/* Clear / "no colour" swatch — checkerboard with a diagonal slash. */
.wl-color-clear-swatch {
border-color: var(--background-modifier-border);
background:
linear-gradient(
to top left,
transparent 0%,
transparent calc(50% - 1px),
var(--text-error, #e5484d) 50%,
transparent calc(50% + 1px),
transparent 100%
),
repeating-conic-gradient(
var(--background-modifier-border) 0% 25%,
var(--background-primary) 0% 50%
) 0 / 10px 10px;
}
/* ── Manage columns modal ──────────────────────────────────── */
.wl-reading-manage-cols-desc {
font-size: 12px;
color: var(--text-muted);
margin-bottom: 12px;
}
.wl-reading-manage-cols-list {
display: flex;
flex-direction: column;
gap: 0;
border: 0.5px solid var(--background-modifier-border);
border-radius: 5px;
overflow: hidden;
margin-bottom: 4px;
}
.wl-reading-manage-cols-empty {
font-size: 12px;
color: var(--text-muted);
padding: 10px 8px;
text-align: center;
}
/* Row layout — overrides the vertical card from .wl-editcol-card */
.wl-reading-col-card {
flex-direction: row;
align-items: center;
width: 100%;
box-sizing: border-box;
flex: none;
border: none;
border-bottom: 0.5px solid var(--background-modifier-border);
border-radius: 0;
background: transparent;
padding: 5px 6px;
gap: 8px;
}
.wl-reading-col-card:last-child {
border-bottom: none;
}
.wl-reading-col-card.wl-cl-dragging {
opacity: 0.5;
}
.wl-reading-col-card.wl-cl-drag-over {
border-left: 2px solid var(--interactive-accent);
}
.wl-reading-col-card .wl-editcol-card-handle {
flex: 0 0 16px;
width: 16px;
}
.wl-reading-col-card .wl-editcol-card-name {
flex: 1 1 130px;
min-width: 0;
width: auto;
height: 26px;
}
.wl-reading-col-card .wl-editcol-card-type {
flex: 0 0 90px;
width: 90px;
height: 26px;
}
.wl-reading-col-card .wl-reading-col-color-dot {
flex: 0 0 18px;
width: 18px;
height: 18px;
}
.wl-reading-col-opts-input {
flex: 1 1 130px;
min-width: 0;
font-size: 12px;
height: 26px;
box-sizing: border-box;
}
.wl-reading-col-card .wl-editcol-card-del {
flex: 0 0 26px;
width: 26px;
margin-left: 0;
}
.wl-reading-add-col {
margin-top: 12px;
}
.wl-reading-add-col-row {
display: flex;
gap: 6px;
align-items: center;
}
.wl-reading-add-col-name {
flex: 1 1 140px;
min-width: 0;
}
.wl-reading-add-col-type {
flex: 0 0 95px;
}
.wl-reading-add-col-opts {
flex: 1 1 130px;
min-width: 0;
}
.wl-reading-add-col-btn {
flex: 0 0 auto;
}
/* ── Drafts: Add choice modal ─────────────────────────────────────────────── */
.wl-draft-choice-subtitle {
margin-bottom: 14px;
font-size: 0.9em;
color: var(--text-muted);
text-align: center;
word-break: break-word;
}
.wl-draft-choice-grid {
display: flex;
flex-direction: row;
gap: 10px;
justify-content: center;
}
.wl-draft-choice-btn {
flex: 1 1 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-width: 0;
min-height: 65px;
padding: 12px 8px;
border: 0.5px solid var(--background-modifier-border);
border-radius: 10px;
background: var(--background-secondary);
color: var(--text-normal);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease;
}
.wl-draft-choice-btn:hover {
background: var(--background-modifier-hover);
border-color: var(--interactive-accent);
}
.wl-draft-choice-label {
font-size: 1.05em;
font-weight: 600;
text-align: center;
}
/* ════════════════════════════════════════════════════════
SHARED BUTTON COLOR UTILITIES
Color-only — layer on top of any geometry/button class.
Resting state is border-only; hover fills with the color.
════════════════════════════════════════════════════════ */
.wl-btn-danger {
background: transparent;
border: 0.5px solid rgba(var(--color-red-rgb), 0.65);
color: var(--text-error);
}
.wl-btn-danger:hover {
background: var(--text-error);
border-color: var(--text-error);
color: var(--text-on-accent);
}
.wl-btn-success {
background: transparent;
border: 0.5px solid rgba(var(--color-green-rgb), 0.65);
color: var(--color-green);
}
.wl-btn-success:hover {
background: var(--color-green);
border-color: var(--color-green);
color: var(--text-on-accent);
}
/* ── Status bar: Upcoming "due" counter ─────────────────── */
.wl-statusbar-upcoming {
cursor: pointer;
color: var(--color-orange);
}