t5k6_obsidian-koreader-high.../styles.css

775 lines
21 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.

/* Ensure the modal itself cannot horizontally overflow viewport */
.duplicate-modal,
.duplicate-modal .modal-content {
max-width: 100vw;
overflow-x: hidden;
}
/* ─────────────────────────────────────────────────────────────────── */
/* 0 ▸ KOReader RAW (do NOT override used as reference only) */
/* ─────────────────────────────────────────────────────────────────── */
:root {
/* Raw KOReader colors */
--khl-red-raw: #ff3300;
--khl-orange-raw: #ff8800;
--khl-yellow-raw: #ffff33;
--khl-green-raw: #00aa66;
--khl-olive-raw: #88ff77;
--khl-cyan-raw: #00ffee;
--khl-blue-raw: #0066ff;
--khl-purple-raw: #ee00ff;
--khl-gray-raw: #808080;
/* Display palette (theme-overridable) */
--khl-red: var(--khl-red-raw);
--khl-orange: var(--khl-orange-raw);
--khl-yellow: var(--khl-yellow-raw);
--khl-green: #28c828;
/* softened green for light mode */
--khl-olive: var(--khl-olive-raw);
--khl-cyan: var(--khl-cyan-raw);
--khl-blue: var(--khl-blue-raw);
--khl-purple: var(--khl-purple-raw);
--khl-gray: var(--khl-gray-raw);
/* Foreground helpers (contrast colors) */
--on-khl-red: #ffffff;
--on-khl-orange: #000000;
--on-khl-yellow: #000000;
--on-khl-green: #ffffff;
/* light & dark share the same by default */
--on-khl-olive: #000000;
--on-khl-cyan: #000000;
--on-khl-blue: #ffffff;
--on-khl-purple: #ffffff;
--on-khl-gray: #000000;
/* Layout tokens */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 12px;
--spacing-lg: 20px;
--radius-sm: 4px;
--radius-md: 6px;
--radius-lg: var(--radius-m, 8px);
--transition: 0.15s ease;
--max-modal-w: clamp(300px, 90vw, 600px);
--max-modal-h: 80vh;
--max-preview-h: 40vh;
}
/* 1 ▸ Display palette is now part of the single :root token block above */
body.theme-dark {
--khl-green: #19b219;
/* bit darker & more saturated */
}
/* 2 ▸ Foreground helpers are part of the token block; dark theme can override selectively */
body.theme-dark {
--on-khl-green: #e8ffe8;
/* softer mint on OLED black */
}
/* Optional: neutralise legacy neon lime pasted from elsewhere */
mark[style*="#00ff00"] {
background-color: var(--khl-green) !important;
color: var(--on-khl-green) !important;
}
/* ─────────────────────────────────────────────────────────────────── */
/* Helpers: scrollable panel, badges, buttons, focus & motion */
/* ─────────────────────────────────────────────────────────────────── */
/* [removed] .scrollable-panel (unused) */
/* Badge component (color via specific class or data-attr) */
.badge {
font-size: 0.75rem;
font-weight: 500;
padding: var(--spacing-xs) var(--spacing-sm);
border-radius: var(--radius-sm);
display: inline-block;
}
.badge[data-type="exact"] {
background: var(--khl-green);
color: var(--on-khl-green);
}
.badge[data-type="updated"] {
background: var(--khl-yellow);
color: var(--on-khl-yellow);
}
.badge[data-type="divergent"] {
background: var(--khl-orange);
color: var(--on-khl-orange);
}
/* Button base */
.btn {
padding: var(--spacing-sm);
border-radius: var(--radius-md);
display: flex;
flex-direction: column;
align-items: center;
gap: var(--spacing-xs);
width: 100%;
transition:
transform var(--transition),
filter var(--transition);
box-sizing: border-box;
}
.btn:hover:not(.disabled) {
transform: translateY(-1px);
filter: brightness(1.1);
}
.btn.cta {
background: var(--color-accent);
color: var(--color-base-100);
}
.btn.warn {
background: var(--khl-red);
color: var(--on-khl-red);
}
.btn.disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* Focus only for keyboard navigation */
:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 2px;
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
.btn,
.badge,
.duplicate-modal-container {
transition: none !important;
}
}
/* ─────────────────────────────────────────────────────────────────── */
/* Duplicate-Finder modal */
/* ─────────────────────────────────────────────────────────────────── */
.duplicate-modal-container {
width: 100%;
/* occupy available space from modal-content */
max-width: 100%;
/* do not exceed modal-content */
max-height: var(--max-modal-h);
margin: 0;
/* avoid extra horizontal margins */
padding: var(--spacing-lg);
position: relative;
/* allows sidebar positioning */
overflow: hidden;
/* prevent any scrollbars in container; inner panes can scroll */
box-sizing: border-box;
/* include padding in width */
}
/* Ensure children don't exceed container width */
.duplicate-modal-container > * {
max-width: 100%;
box-sizing: border-box;
}
/* Ensure no child forces horizontal overflow */
.duplicate-modal-container * {
min-width: 0;
}
.duplicate-modal-header {
display: flex;
align-items: center;
gap: var(--spacing-md);
margin-bottom: var(--spacing-md);
}
.duplicate-modal-header h2 {
margin: 0;
flex-grow: 1;
}
/* [removed] legacy duplicate-badge classes (use .badge[data-type]) */
/* buttons */
.duplicate-modal .duplicate-buttons {
display: grid;
/* Use CSS Grid for robust columns */
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
/* Allow shrink to container width */
gap: var(--spacing-md);
/* Consistent spacing between all buttons */
margin-top: var(--spacing-lg);
width: 100%;
box-sizing: border-box;
min-width: 0;
justify-items: stretch;
}
.duplicate-modal .duplicate-buttons .btn {
/* Ensure buttons fill their grid cell and lay out content horizontally */
flex-direction: row !important;
/* beat generic .btn rules */
justify-content: center;
align-items: center;
gap: var(--spacing-sm);
width: 100%;
padding: var(--spacing-sm) var(--spacing-md);
min-width: 0;
/* allow content to shrink to avoid overflow */
max-width: 100%;
}
/*
* Override Obsidian's "icon-only" button style.
* When a button has our custom `.mod-both` class, we ensure
* the text is visible and properly aligned with the icon.
*/
.duplicate-modal .modal-button-container .button.mod-both {
/* Restore the font-size that Obsidian's icon-only style removes. */
font-size: var(--font-ui-medium);
}
/*
* Force the text part of the button (which is in a span) to be visible.
* This is a defense against themes that might use `display: none` on it.
*/
.duplicate-modal .modal-button-container .button.mod-both > span {
display: inline !important;
}
.duplicate-modal .koreader-modal-action-button {
display: flex;
/* make sure it's flex even if theme overrides .btn */
flex-direction: row !important;
/* ensure text appears next to icon */
justify-content: center;
align-items: center;
gap: var(--spacing-sm);
width: 100%;
padding: var(--spacing-sm) var(--spacing-md);
min-width: 0;
/* allow content to shrink to avoid overflow */
}
/* Ensure icon/text layout inside the button is stable */
.duplicate-modal .koreader-modal-action-button svg,
.duplicate-modal .koreader-modal-action-button .button-icon {
flex: 0 0 auto;
}
.duplicate-modal .koreader-modal-action-button .button-text {
display: inline-block !important;
white-space: normal;
/* allow wrapping to avoid overflow */
color: inherit;
/* inherit color so warn/cta are readable */
flex: 1 1 auto;
min-width: 0;
text-align: center;
}
/* On very narrow widths, allow wrapping of the button label to avoid overflow */
@media (max-width: 420px) {
.duplicate-modal .koreader-modal-action-button .button-text {
white-space: normal;
}
}
/* Slightly reduce lateral padding on very small viewports to prevent overflow */
@media (max-width: 420px) {
.duplicate-modal-container {
padding-left: var(--spacing-md);
padding-right: var(--spacing-md);
width: min(96vw, 100vw - 16px);
max-width: min(var(--max-modal-w), 100vw - 16px);
}
}
/* [removed] global .koreader-modal-action-button .button-text (conflicts with modal-scoped rule) */
/* Make sure the CTA stands out and warning is clear but secondary */
.duplicate-buttons .btn.cta {
background: var(--color-accent);
color: var(--text-on-accent);
border: 1px solid var(--color-accent);
}
.duplicate-buttons .btn.warn {
background: var(--khl-red);
/* strong, consistent red */
color: var(--on-khl-red);
/* readable on red */
border: 1px solid var(--khl-red);
}
.duplicate-buttons .btn.warn:hover {
background: var(--background-modifier-error-hover);
}
/* [removed] legacy .mod-* button styles (unused) */
/* Message and File Path */
.duplicate-message {
margin-bottom: var(--spacing-lg);
}
.duplicate-file-path {
display: flex;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-xs) var(--spacing-sm);
background-color: var(--color-base-20);
border-radius: var(--radius-sm);
font-family: var(--font-monospace);
font-size: 0.9em;
overflow-wrap: break-word;
/* Wrap long paths */
word-break: break-all;
/* Aggressive breaking if needed */
}
/* Ensure the path text span can shrink and wrap within the container */
.duplicate-file-path span:last-child {
min-width: 0;
flex: 1 1 auto;
word-break: break-all;
overflow-wrap: anywhere;
}
/* Keep the leading icon from shrinking/growing */
.duplicate-file-path span:first-child {
flex: 0 0 auto;
}
/* Statistics Section */
.duplicate-stats {
display: block;
/* simple flow for consistent alignment */
background: var(--color-base-20);
padding: var(--spacing-md);
border-radius: var(--radius-md);
margin: var(--spacing-lg) 0;
}
.stat-item {
display: flex;
align-items: center;
gap: var(--spacing-xs);
}
.stat-icon {
color: var(--color-accent);
}
.stat-value {
font-weight: bold;
margin-left: auto;
}
/* Prominent stats section styling */
.duplicate-stats h4 {
margin-top: 0;
margin-bottom: var(--spacing-sm);
border-bottom: 1px solid var(--background-modifier-border);
padding-bottom: var(--spacing-sm);
}
.duplicate-stats ul {
margin: 0;
padding-inline-start: 20px;
}
.duplicate-stats li {
margin-bottom: var(--spacing-xs);
}
/* Settings Section */
.duplicate-settings {
margin: var(--spacing-lg) 0;
padding: var(--spacing-sm);
background: var(--color-base-20);
border-radius: var(--radius-md);
}
.button-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
}
.button-container button:focus {
box-shadow: 0 0 0 2px var(--color-accent);
}
.button-icon {
display: flex;
align-items: center;
justify-content: center;
}
/* Keyboard Shortcuts */
.duplicate-shortcuts {
margin-top: var(--spacing-lg);
text-align: center;
font-size: 0.9em;
color: var(--color-base-70);
}
.duplicate-shortcuts kbd {
background: var(--background-modifier-hover);
padding: var(--spacing-xs) var(--spacing-sm);
border-radius: var(--radius-sm);
font-size: 0.9em;
}
/* Sidebar indicating match type */
.duplicate-modal-sidebar {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 6px;
border-top-left-radius: var(--radius-lg);
border-bottom-left-radius: var(--radius-lg);
}
.duplicate-modal-sidebar[data-type="exact"] {
background: var(--khl-green);
}
.duplicate-modal-sidebar[data-type="updated"] {
background: var(--khl-yellow);
}
.duplicate-modal-sidebar[data-type="divergent"] {
background: var(--khl-orange);
}
/* Helper actions row */
.duplicate-modal-helpers {
display: flex;
gap: var(--spacing-sm);
margin: var(--spacing-sm) 0 var(--spacing-md);
}
/* ─────────────────────────────────────────────────────────────────── */
/* Template Preview modal */
/* ─────────────────────────────────────────────────────────────────── */
/* Style for the rendered output */
.koreader-template-preview-modal .template-preview-rendered {
max-height: var(--max-preview-h);
overflow-y: auto;
overflow-x: hidden;
width: 100%;
padding: var(--spacing-sm) var(--spacing-md);
background-color: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-md);
margin-top: var(--spacing-sm);
}
/* Style for the code block container rendered by MarkdownRenderer */
.koreader-template-preview-modal .template-preview-code-block
.markdown-rendered
pre {
max-height: var(--max-preview-h);
overflow: auto;
margin-top: var(--spacing-sm);
/* Padding and other styles are usually handled by the theme's pre/code styling */
}
/* ─────────────────────────────────────────────────────────────────── */
/* Settings Panel UI */
/* ─────────────────────────────────────────────────────────────────── */
/* Style section headings as H2 */
.koreader-importer-settings summary {
color: var(--h2-color);
font-family: var(--h2-font);
font-style: var(--h2-style);
font-variant: var(--h2-variant);
line-height: var(--h2-line-height);
font-size: var(--font-ui-medium);
font-weight: var(--font-semibold);
margin-block-end: var(--p-spacing);
margin-block-start: var(--p-spacing);
}
/* Validation list under custom filename template row */
.koreader-setting-validation {
margin-top: var(--spacing-xs);
}
.koreader-setting-validation ul {
margin: var(--spacing-xs) 0 0;
padding-left: 1.2em;
}
.koreader-setting-validation li {
margin-bottom: 2px;
}
/* Make all text inputs and textareas in our settings panel have a responsive consistent width */
.koreader-importer-settings .setting-item-control,
.koreader-importer-settings .search-input-container {
max-width: clamp(260px, 90vw, 450px);
width: 100%;
flex: 1 1 auto;
justify-content: flex-end;
}
/* Make the input/textarea itself fill its now-constrained container */
.koreader-importer-settings .setting-item-control input[type="text"],
.koreader-importer-settings .setting-item-control textarea {
width: 100%;
}
/* Special handling for the template selector to align dropdown and buttons */
.koreader-template-selector .setting-item-control {
display: flex;
justify-content: flex-end;
/* Align to the right side */
align-items: center;
gap: var(--spacing-sm);
width: 100%;
max-width: clamp(260px, 90vw, 450px);
}
.koreader-template-selector .setting-item-control .dropdown {
flex-grow: 1;
/* Allow dropdown to take up available space */
}
/* ─────────────────────────────────────────────────────────────────── */
/* Suggestion highlight (FolderSuggester) */
/* ─────────────────────────────────────────────────────────────────── */
.suggestion-highlight {
color: var(--text-accent);
font-weight: 600;
}
.suggestion-score {
opacity: 0.6;
font-size: 0.9em;
margin-left: 0.5em;
}
/* Hide KOReader Importer's internal UID in the Properties UI */
.metadata-property[data-property-key="kohl-uid"] {
display: none !important;
}
/*
KOReader Highlights Callout Styling
- Add this to an enabled CSS snippet in Obsidian.
- This colors the callout title bar with your KOReader highlight colors.
*/
/*
* --- MASTER RULE ---
* Set a consistent icon for all KOReader callouts.
*/
.callout[data-callout="yellow"],
.callout[data-callout="orange"],
.callout[data-callout="red"],
.callout[data-callout="purple"],
.callout[data-callout="blue"],
.callout[data-callout="green"],
.callout[data-callout="cyan"],
.callout[data-callout="olive"],
.callout[data-callout="gray"],
.callout[data-callout="highlight"] {
--callout-icon: lucide-highlighter;
}
/*
* This flattened selector list correctly targets the content area of
* ALL our custom callouts and forces its background to be transparent.
*/
.callout[data-callout="yellow"] .callout-content,
.callout[data-callout="orange"] .callout-content,
.callout[data-callout="red"] .callout-content,
.callout[data-callout="purple"] .callout-content,
.callout[data-callout="blue"] .callout-content,
.callout[data-callout="green"] .callout-content,
.callout[data-callout="cyan"] .callout-content,
.callout[data-callout="olive"] .callout-content,
.callout[data-callout="gray"] .callout-content,
.callout[data-callout="highlight"] .callout-content {
background: transparent !important;
}
/*
* --- PER-COLOR TITLE STYLING ---
* These rules apply the KOReader palette colors ONLY to the title bar.
*/
.callout[data-callout="yellow"] .callout-title {
background-color: var(--khl-yellow);
color: var(--on-khl-yellow);
}
.callout[data-callout="orange"] .callout-title {
background-color: var(--khl-orange);
color: var(--on-khl-orange);
}
.callout[data-callout="red"] .callout-title {
background-color: var(--khl-red);
color: var(--on-khl-red);
}
.callout[data-callout="purple"] .callout-title {
background-color: var(--khl-purple);
color: var(--on-khl-purple);
}
.callout[data-callout="blue"] .callout-title {
background-color: var(--khl-blue);
color: var(--on-khl-blue);
}
.callout[data-callout="green"] .callout-title {
background-color: var(--khl-green);
color: var(--on-khl-green);
}
.callout[data-callout="cyan"] .callout-title {
background-color: var(--khl-cyan);
color: var(--on-khl-cyan);
}
.callout[data-callout="olive"] .callout-title {
background-color: var(--khl-olive);
color: var(--on-khl-olive);
}
.callout[data-callout="gray"] .callout-title {
background-color: var(--khl-gray);
color: var(--on-khl-gray);
}
.callout[data-callout="highlight"] .callout-title {
background-color: var(--khl-gray);
color: var(--on-khl-gray);
}
/* Spinner for indeterminate progress modal */
.koreader-spinner {
width: 40px;
height: 40px;
border: 4px solid var(--background-modifier-border);
border-top-color: var(--interactive-accent);
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 1em auto;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* ─────────────────────────────────────────────────────────────────── */
/* WYSIWYG Template Editor Modal (Single-Column Layout) */
/* ─────────────────────────────────────────────────────────────────── */
/* Adjust modal width for a vertical layout. */
.koreader-template-editor-modal .modal-content {
width: 80vw;
max-width: 800px;
}
/* Main container: stack panes vertically */
.koreader-editor-container {
display: flex;
flex-direction: column;
gap: var(--spacing-lg);
height: 70vh;
margin-bottom: var(--spacing-lg);
}
/* Individual panes */
.koreader-editor-pane,
.koreader-preview-pane {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
min-height: 0;
}
.koreader-editor-pane {
flex-basis: 40%;
}
.koreader-preview-pane {
flex-basis: 60%;
}
/* Remove default styling from the Setting component wrapper */
.koreader-template-editor-setting {
padding: 0;
border: none;
flex-grow: 1;
display: flex;
}
/* Hide the empty info block that creates the left margin */
.koreader-template-editor-setting .setting-item-info {
display: none;
}
/*
* Make the control block a column-oriented flex container.
* This is necessary for its child (the textarea) to grow vertically.
*/
.koreader-template-editor-setting .setting-item-control {
min-height: 0; /* important in flex layouts */
}
/*
* Style the textarea to grow and fill the available vertical space.
*/
.koreader-template-editor-textarea {
flex: 1 1 auto;
height: 100%; /* fill the pane height */
min-height: 18rem; /* or 300px; pick what you like */
box-sizing: border-box;
resize: vertical; /* vertical only is usually nicer */
}
/* Style for the rendered preview area */
.koreader-template-editor-modal .template-preview-rendered {
flex-grow: 1;
max-height: none;
overflow-y: auto;
border: 1px solid var(--background-modifier-border);
padding: var(--spacing-md);
border-radius: var(--radius-md);
background-color: var(--background-secondary);
}
/* Style for displaying template compilation errors */
.koreader-template-editor-modal .template-preview-rendered.template-error {
color: var(--text-error);
white-space: pre-wrap;
font-family: var(--font-monospace);
font-size: var(--font-ui-smaller);
}