Files
HelixNotes/src/app.css
T

528 lines
13 KiB
CSS

@import "tailwindcss";
@font-face {
font-family: "Inter";
src: local("Inter");
}
/* JetBrains Mono - self-hosted (see static/fonts/jetbrains-mono/, OFL-1.1).
Used for code blocks, inline code, the raw source editor, and the "Mono" font option. */
@font-face {
font-family: "JetBrains Mono";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2") format("woff2");
}
@font-face {
font-family: "JetBrains Mono";
font-style: italic;
font-weight: 400;
font-display: swap;
src: url("/fonts/jetbrains-mono/JetBrainsMono-Italic.woff2") format("woff2");
}
@font-face {
font-family: "JetBrains Mono";
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("/fonts/jetbrains-mono/JetBrainsMono-Bold.woff2") format("woff2");
}
@font-face {
font-family: "JetBrains Mono";
font-style: italic;
font-weight: 700;
font-display: swap;
src: url("/fonts/jetbrains-mono/JetBrainsMono-BoldItalic.woff2") format("woff2");
}
:root {
/* Light theme */
--bg-primary: #ffffff;
--bg-secondary: #f8f9fa;
--bg-tertiary: #f0f1f3;
--bg-hover: #e9ecef;
--bg-active: #dde1e6;
--bg-editor: #ffffff;
--text-primary: #1a1a2e;
--text-secondary: #495057;
--text-tertiary: #868e96;
--text-accent: #5b6abf;
--border-color: #e2e5e9;
--border-light: #f0f1f3;
--accent: #5b6abf;
--accent-hover: #4a59b0;
--accent-light: #eef0f9;
--danger: #e55353;
--danger-hover: #d43d3d;
--success: #40c057;
--warning: #fab005;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);
--sidebar-width: 220px;
--notelist-width: 280px;
--panel-resize-handle: 3px;
/* Monospace / code font (self-hosted JetBrains Mono, see @font-face above) */
--font-mono: "JetBrains Mono", "Fira Code", "Cascadia Code", ui-monospace,
monospace;
}
:root.dark {
--bg-primary: #1a1b26;
--bg-secondary: #1f2029;
--bg-tertiary: #24253a;
--bg-hover: #2a2b3d;
--bg-active: #33354a;
--bg-editor: #1a1b26;
--text-primary: #cdd6f4;
--text-secondary: #a6adc8;
--text-tertiary: #6c7086;
--text-accent: #89b4fa;
--border-color: #2a2b3d;
--border-light: #24253a;
--accent: #89b4fa;
--accent-hover: #74a8f7;
--accent-light: #1e2640;
--danger: #f38ba8;
--danger-hover: #eba0ac;
--success: #a6e3a1;
--warning: #f9e2af;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.3);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.4);
}
/* ── Named Themes ── */
:root[data-theme="solarized-light"] {
--bg-primary: #fdf6e3;
--bg-secondary: #eee8d5;
--bg-tertiary: #e5dfc9;
--bg-hover: #d8d0b8;
--bg-active: #ccc4aa;
--bg-editor: #fdf6e3;
--text-primary: #657b83;
--text-secondary: #839496;
--text-tertiary: #93a1a1;
--text-accent: #268bd2;
--border-color: #ddd5be;
--border-light: #eee8d5;
--accent: #268bd2;
--accent-hover: #1a7abf;
--accent-light: color-mix(in srgb, #268bd2 10%, transparent);
--danger: #dc322f;
--danger-hover: #c82929;
--success: #859900;
--warning: #b58900;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);
}
:root[data-theme="solarized-dark"] {
--bg-primary: #002b36;
--bg-secondary: #073642;
--bg-tertiary: #0a3f4e;
--bg-hover: #094350;
--bg-active: #0e4d5c;
--bg-editor: #002b36;
--text-primary: #839496;
--text-secondary: #657b83;
--text-tertiary: #586e75;
--text-accent: #268bd2;
--border-color: #073642;
--border-light: #0a3f4e;
--accent: #268bd2;
--accent-hover: #1a7abf;
--accent-light: color-mix(in srgb, #268bd2 15%, transparent);
--danger: #dc322f;
--danger-hover: #c82929;
--success: #859900;
--warning: #b58900;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);
}
:root[data-theme="catppuccin"] {
--bg-primary: #1e1e2e;
--bg-secondary: #181825;
--bg-tertiary: #11111b;
--bg-hover: #313244;
--bg-active: #45475a;
--bg-editor: #1e1e2e;
--text-primary: #cdd6f4;
--text-secondary: #bac2de;
--text-tertiary: #a6adc8;
--text-accent: #89b4fa;
--border-color: #313244;
--border-light: #181825;
--accent: #89b4fa;
--accent-hover: #74a8f7;
--accent-light: color-mix(in srgb, #89b4fa 12%, transparent);
--danger: #f38ba8;
--danger-hover: #eba0ac;
--success: #a6e3a1;
--warning: #f9e2af;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);
}
:root[data-theme="nord"] {
--bg-primary: #2e3440;
--bg-secondary: #3b4252;
--bg-tertiary: #434c5e;
--bg-hover: #4c566a;
--bg-active: #5a6578;
--bg-editor: #2e3440;
--text-primary: #eceff4;
--text-secondary: #e5e9f0;
--text-tertiary: #d8dee9;
--text-accent: #81a1c1;
--border-color: #3b4252;
--border-light: #434c5e;
--accent: #81a1c1;
--accent-hover: #6d8fa9;
--accent-light: color-mix(in srgb, #81a1c1 12%, transparent);
--danger: #bf616a;
--danger-hover: #a85060;
--success: #a3be8c;
--warning: #ebcb8b;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);
}
:root[data-theme="tokyo-night"] {
--bg-primary: #1a1b26;
--bg-secondary: #16161e;
--bg-tertiary: #1f2335;
--bg-hover: #292e42;
--bg-active: #3b4261;
--bg-editor: #1a1b26;
--text-primary: #c0caf5;
--text-secondary: #a9b1d6;
--text-tertiary: #565f89;
--text-accent: #7aa2f7;
--border-color: #292e42;
--border-light: #1f2335;
--accent: #7aa2f7;
--accent-hover: #6492e7;
--accent-light: color-mix(in srgb, #7aa2f7 12%, transparent);
--danger: #f7768e;
--danger-hover: #e56474;
--success: #9ece6a;
--warning: #e0af68;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);
}
:root[data-theme="github-light"] {
--bg-primary: #ffffff;
--bg-secondary: #f6f8fa;
--bg-tertiary: #eaeef2;
--bg-hover: #d0d7de;
--bg-active: #c6cdd5;
--bg-editor: #ffffff;
--text-primary: #1f2328;
--text-secondary: #656d76;
--text-tertiary: #8c959f;
--text-accent: #0969da;
--border-color: #d0d7de;
--border-light: #eaeef2;
--accent: #0969da;
--accent-hover: #0860c9;
--accent-light: color-mix(in srgb, #0969da 8%, transparent);
--danger: #d1242f;
--danger-hover: #c01020;
--success: #1a7f37;
--warning: #9a6700;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);
}
:root[data-theme="github-dark"] {
--bg-primary: #0d1117;
--bg-secondary: #161b22;
--bg-tertiary: #21262d;
--bg-hover: #30363d;
--bg-active: #3c444d;
--bg-editor: #0d1117;
--text-primary: #e6edf3;
--text-secondary: #8d96a0;
--text-tertiary: #6e7681;
--text-accent: #58a6ff;
--border-color: #30363d;
--border-light: #21262d;
--accent: #58a6ff;
--accent-hover: #4493f8;
--accent-light: color-mix(in srgb, #58a6ff 10%, transparent);
--danger: #f85149;
--danger-hover: #e03d3d;
--success: #3fb950;
--warning: #d29922;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);
}
:root[data-theme="dracula"] {
--bg-primary: #282a36;
--bg-secondary: #21222c;
--bg-tertiary: #191a21;
--bg-hover: #44475a;
--bg-active: #6272a4;
--bg-editor: #282a36;
--text-primary: #f8f8f2;
--text-secondary: #6272a4;
--text-tertiary: #44475a;
--text-accent: #bd93f9;
--border-color: #44475a;
--border-light: #2d2f3f;
--accent: #bd93f9;
--accent-hover: #a87ef5;
--accent-light: color-mix(in srgb, #bd93f9 12%, transparent);
--danger: #ff5555;
--danger-hover: #e54545;
--success: #50fa7b;
--warning: #f1fa8c;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);
}
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-user-select: none !important;
user-select: none !important;
}
html,
body {
height: 100%;
overflow: hidden;
font-family: var(
--editor-font-family,
"Inter",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
sans-serif
);
background: var(--bg-primary);
color: var(--text-primary);
font-size: var(--editor-font-size, 14px);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
user-select: none;
}
/* Scrollbar styling */
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: var(--text-tertiary);
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--text-secondary);
}
/* Selection */
::selection {
background: var(--accent);
color: white;
}
/* Focus ring */
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: -2px;
}
/* Allow text selection in editor and source view */
.editor-content,
.editor-content *,
.source-editor {
-webkit-user-select: text !important;
user-select: text !important;
}
/* Transitions */
.transition-colors {
transition:
color 0.15s ease,
background-color 0.15s ease,
border-color 0.15s ease;
}
/* Panel resize handle */
.resize-handle {
width: var(--panel-resize-handle);
cursor: col-resize;
background: var(--border-color);
transition: background 0.15s ease;
flex-shrink: 0;
}
.resize-handle:hover,
.resize-handle.active {
background: var(--accent);
}
body.resizing .ProseMirror {
pointer-events: none;
contain: strict;
}
/* Skip layout/paint of off-screen blocks in very large (math-heavy) notes. */
.tiptap-wrapper.large-doc .ProseMirror > * {
content-visibility: auto;
contain-intrinsic-size: auto 2rem;
}
.tiptap-wrapper.large-doc .ProseMirror > .math-block {
contain-intrinsic-size: auto 3.5rem;
}
body.resizing {
user-select: none;
}
/* Spinner for the sync button while a sync is running. */
.sync-spin {
animation: sync-spin 1s linear infinite;
transform-origin: 50% 50%;
}
@keyframes sync-spin {
to {
transform: rotate(360deg);
}
}
/* ── Mobile (Android/iOS) ── */
@media (max-width: 768px) {
body {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
}
::-webkit-scrollbar {
display: none;
}
.resize-handle {
display: none !important;
}
}
/* ── Print / Export PDF ── */
@media print {
/* Hide everything except editor content */
.titlebar,
.sidebar-panel,
.notelist-panel,
.resize-handle,
.toolbar-actions,
.editor-body-wrapper .note-search-bar,
.formatting-toolbar,
.editor-formatting-bar,
.history-panel,
.outline-panel,
.graph-panel,
.ai-panel,
.link-context-menu,
.image-toolbar,
.selection-bar {
display: none !important;
}
/* Force light theme colors for PDF */
:root, :root.dark {
--bg-primary: #ffffff !important;
--bg-secondary: #f8f9fa !important;
--bg-tertiary: #f0f1f3 !important;
--bg-editor: #ffffff !important;
--text-primary: #1a1a2e !important;
--text-secondary: #495057 !important;
--text-tertiary: #868e96 !important;
--text-accent: #5b6abf !important;
--accent: #5b6abf !important;
--border-color: #e2e5e9 !important;
--border-light: #f0f1f3 !important;
}
html, body {
height: auto;
overflow: visible;
background: white !important;
color: #1a1a2e !important;
font-size: 12pt;
padding: 0;
}
/* Override all scoped height/overflow constraints for print flow */
* {
overflow: visible !important;
height: auto !important;
max-height: none !important;
min-height: 0 !important;
}
.app-layout {
display: block !important;
}
.editor-panel {
width: 100% !important;
min-width: 0 !important;
}
.ProseMirror {
padding: 0 !important;
max-width: 100% !important;
background: white !important;
color: #1a1a2e !important;
}
/* Ensure images fit within page */
.ProseMirror img {
max-width: 100% !important;
page-break-inside: avoid;
}
/* Avoid breaking inside these elements */
h1, h2, h3, h4, h5, h6 {
page-break-after: avoid;
}
pre, blockquote, table, figure {
page-break-inside: avoid;
}
/* Code blocks with light background */
.ProseMirror pre, .ProseMirror code {
background: #f8f9fa !important;
color: #1a1a2e !important;
}
}