mirror of
https://github.com/t5k6/obsidian-koreader-highlights.git
synced 2026-07-22 11:30:24 +00:00
775 lines
21 KiB
CSS
775 lines
21 KiB
CSS
/* 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);
|
||
}
|