@tailwind base; @tailwind components; @tailwind utilities; @layer base { * { @apply border-border; text-rendering: optimizeLegibility; -webkit-tap-highlight-color: transparent; } html { @apply font-sans antialiased; --bc-color-brand: hsl(var(--primary)); --bc-color-brand-dark: hsl(var(--primary)); --bc-brand-mix: 100%; --bc-color-brand-button-text: hsl(var(--primary-foreground)); --bc-color-brand-button-text-dark: hsl(var(--primary-foreground)); } input, textarea, button { -webkit-appearance: none; -moz-appearance: none; appearance: none; } body { @apply bg-background text-foreground; -webkit-overflow-scrolling: touch; text-size-adjust: 100%; -webkit-text-size-adjust: 100%; user-select: none; } /* Allow text selection in note content */ [data-note-content], .note-content, article, .markdown-content, .prose { user-select: text; -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; } .clickable { cursor: pointer; transition: background-color 0.2s ease; &:active { background-color: hsl(var(--muted) / 0.3); } } .tiptap p.is-editor-empty:first-child::before { color: hsl(var(--muted-foreground)); content: attr(data-placeholder); float: left; height: 0; pointer-events: none; } .scrollbar-hide { -ms-overflow-style: none; /* Internet Explorer 10+ */ scrollbar-width: none; /* Firefox */ } .scrollbar-hide::-webkit-scrollbar { display: none; /* Safari and Chrome */ } @media (hover: hover) and (pointer: fine) { .clickable:hover { background-color: hsl(var(--muted) / 0.3); } } @keyframes shimmer { 0% { background-position: 400% 0; } 100% { background-position: 0% 0; } } .animate-shimmer { animation: shimmer 3s ease-in-out infinite; } :root { /* Moss / forest (approx. #2f6f4f, #3f8a63, #1f4d38) */ --surface-background: 95 10% 97%; --content-canvas: 92 9% 96%; --background: 90 8% 99%; --foreground: 155 25% 12%; --card: 90 12% 99%; --card-foreground: 155 25% 12%; --popover: 0 0% 100%; --popover-foreground: 155 25% 12%; --primary: 152 41% 31%; --primary-hover: 154 37% 39%; --primary-active: 155 42% 21%; --primary-foreground: 0 0% 98%; --secondary: 95 12% 94%; --secondary-foreground: 155 22% 18%; --muted: 95 10% 93%; --muted-foreground: 150 8% 38%; --accent: 95 14% 92%; --accent-foreground: 155 22% 18%; --destructive: 0 84.2% 60.2%; --destructive-foreground: 0 0% 98%; --border: 130 16% 86%; --input: 130 12% 90%; --ring: 152 41% 31%; --sidebar-top: 95 14% 95%; --sidebar-bottom: 100 16% 92%; --sidebar-border: 130 18% 82%; --brand-wordmark: 155 32% 22%; --prose-link: 152 38% 28%; --highlight: 152 45% 36%; --chart-1: 12 76% 61%; --chart-2: 173 58% 39%; --chart-3: 197 37% 24%; --chart-4: 43 74% 66%; --chart-5: 27 87% 67%; --radius: 0.5rem; } .dark { --surface-background: 152 22% 9%; --content-canvas: 150 20% 8%; --background: 150 18% 10%; --foreground: 100 12% 96%; --card: 150 16% 12%; --card-foreground: 100 10% 95%; --popover: 150 18% 10%; --popover-foreground: 100 12% 96%; --primary: 152 41% 38%; --primary-hover: 154 37% 46%; --primary-active: 155 42% 28%; --primary-foreground: 0 0% 98%; --secondary: 150 14% 16%; --secondary-foreground: 100 10% 95%; --muted: 150 12% 16%; --muted-foreground: 140 8% 72%; --accent: 150 14% 18%; --accent-foreground: 100 10% 95%; --destructive: 0 62.8% 30.6%; --destructive-foreground: 0 0% 98%; --border: 150 12% 22%; --input: 150 12% 18%; --ring: 152 41% 42%; --sidebar-top: 152 24% 12%; --sidebar-bottom: 154 22% 7%; --sidebar-border: 150 14% 20%; --brand-wordmark: 145 28% 91%; --prose-link: 145 35% 72%; --highlight: 150 40% 48%; --chart-1: 220 70% 50%; --chart-2: 160 60% 45%; --chart-3: 30 80% 55%; --chart-4: 280 65% 60%; --chart-5: 340 75% 55%; } :where(.prose) a { color: hsl(var(--prose-link)); text-underline-offset: 2px; } :where(.prose) a:hover { color: hsl(var(--primary)); } .dark input[type='datetime-local']::-webkit-calendar-picker-indicator { filter: invert(1) brightness(1.5); } /* Focus indicators for accessibility */ *:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; border-radius: 2px; } /* Ensure proper contrast for interactive elements */ button:not(:disabled), a, [role="button"] { transition: opacity 0.2s; } button:disabled, [aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; } } @layer components { /** * Playfair for page/modal chrome titles only (not nav labels or article body). * Use with optional utilities: truncate, leading-tight, pl-3, etc. */ .app-chrome-title { @apply font-display text-lg font-semibold; } .imwald-sidebar { position: relative; isolation: isolate; background: linear-gradient( 180deg, hsl(var(--sidebar-top)) 0%, hsl(var(--sidebar-bottom)) 100% ); border-right: 1px solid hsl(var(--sidebar-border)); } .imwald-sidebar__atmosphere { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; } .imwald-sidebar__atmosphere::after { content: ''; position: absolute; left: -32%; right: -32%; top: -32%; bottom: -32%; background-image: url(/brand-atmosphere-light.png); background-size: cover; background-position: center; opacity: 0.055; filter: blur(42px) saturate(1.05); } .dark .imwald-sidebar__atmosphere::after { background-image: url(/brand-atmosphere-dark.png); opacity: 0.075; filter: blur(42px) saturate(1.08) brightness(0.9); } .imwald-titlebar-fog { position: relative; } .imwald-titlebar-fog::before { content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 0; background: radial-gradient( ellipse 100% 85% at 50% -35%, hsl(var(--primary) / 0.08), transparent 52% ); } .dark .imwald-titlebar-fog::before { background: radial-gradient( ellipse 100% 85% at 50% -35%, hsl(var(--primary) / 0.11), transparent 52% ); } .imwald-titlebar-fog > * { position: relative; z-index: 1; } } /* Font Size Adjustments */ .font-size-small { font-size: 87.5% !important; /* 14px base */ } .font-size-medium { font-size: 100% !important; /* 16px base */ } .font-size-large { font-size: 112.5% !important; /* 18px base */ } /* Apply font size to content areas */ .font-size-small .prose, .font-size-medium .prose, .font-size-large .prose { font-size: var(--content-font-size, 1rem); } /* AsciiDoc Table of Contents Styling */ #toc { @apply bg-muted/30 rounded-lg p-3 sm:p-4 mb-4 sm:mb-6; } #toc h2 { @apply text-lg font-semibold mb-3 text-foreground border-b border-border pb-2; } #toc ul { @apply space-y-1; } #toc li { @apply list-none; } #toc a { @apply text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 block py-1 px-2 rounded hover:bg-primary/10 hover:border-l-2 hover:border-primary hover:pl-3; } #toc .sectlevel1 a { @apply font-medium text-foreground; } #toc .sectlevel2 a { @apply ml-4; } #toc .sectlevel3 a { @apply ml-8; } #toc .sectlevel4 a { @apply ml-12; } #toc .sectlevel5 a { @apply ml-16; } #toc .sectlevel6 a { @apply ml-20; } /* Hide the raw AsciiDoc ToC text when styled ToC is present */ .asciidoc-toc-raw { display: none; } /* AsciiDoc Section Headers Styling */ .asciidoc-content h1, .asciidoc-content h2, .asciidoc-content h3, .asciidoc-content h4, .asciidoc-content h5, .asciidoc-content h6 { @apply scroll-mt-24; /* Add padding when scrolling to headers - increased for better visibility */ scroll-behavior: smooth; position: relative; } /* ToC return button styling */ .asciidoc-content h1 .toc-return-btn, .asciidoc-content h2 .toc-return-btn, .asciidoc-content h3 .toc-return-btn, .asciidoc-content h4 .toc-return-btn, .asciidoc-content h5 .toc-return-btn, .asciidoc-content h6 .toc-return-btn { @apply absolute right-0 top-1/2 -translate-y-1/2 opacity-0 transition-all duration-200 text-muted-foreground hover:text-foreground cursor-pointer; font-size: 0.75rem; line-height: 1; padding: 0.25rem 0.5rem; border-radius: 0.375rem; background: hsl(var(--background) / 0.9); backdrop-filter: blur(8px); border: 1px solid hsl(var(--border)); white-space: nowrap; z-index: 10; box-shadow: 0 1px 3px hsl(var(--foreground) / 0.1); } .asciidoc-content h1:hover .toc-return-btn, .asciidoc-content h2:hover .toc-return-btn, .asciidoc-content h3:hover .toc-return-btn, .asciidoc-content h4:hover .toc-return-btn, .asciidoc-content h5:hover .toc-return-btn, .asciidoc-content h6:hover .toc-return-btn { @apply opacity-100; transform: translateY(-50%) scale(1.05); background: hsl(var(--primary) / 0.1); border-color: hsl(var(--primary) / 0.3); } /* Show button on mobile when header is tapped */ @media (hover: none) { .asciidoc-content h1:active .toc-return-btn, .asciidoc-content h2:active .toc-return-btn, .asciidoc-content h3:active .toc-return-btn, .asciidoc-content h4:active .toc-return-btn, .asciidoc-content h5:active .toc-return-btn, .asciidoc-content h6:active .toc-return-btn { @apply opacity-100; } } /* AsciiDoc Footnotes Styling */ .asciidoc-content .footnote { @apply text-xs text-muted-foreground; margin-bottom: 0.5rem; /* Add some spacing between footnotes */ } .asciidoc-content .footnote a { @apply text-primary hover:underline; } .asciidoc-content .footnote-backref { @apply ml-1 text-primary hover:underline; } .asciidoc-content .footnoteref { @apply text-primary hover:underline; vertical-align: super; font-size: 0.75em; text-decoration: none; font-weight: 500; } /* Add scroll padding to footnote anchors and content elements */ .asciidoc-content [id^="footnote-"], .asciidoc-content [id*="footnote"], .asciidoc-content [id*="_footnote"], .asciidoc-content [id*="_ref"], .asciidoc-content p, .asciidoc-content li { scroll-margin-top: 8rem; /* Scroll padding for footnote anchors and content */ } /* Also add scroll padding to any element that might be a footnote target */ .asciidoc-content *[id] { scroll-margin-top: 8rem; } .asciidoc-content .footnoteref:hover { @apply underline; } .asciidoc-content .footnotes { @apply mt-8 pt-4 border-t border-border; scroll-margin-top: 4rem; /* Ensure footnotes section doesn't scroll out of view */ } .asciidoc-content .footnotes ol { @apply space-y-3; /* Increased spacing between footnote entries */ } .asciidoc-content .footnotes li { @apply text-sm text-muted-foreground; display: block; /* Ensure each footnote is on its own line */ margin-bottom: 0.75rem; /* Additional spacing for better readability */ } .asciidoc-content .footnotes li p { @apply mb-2; margin-top: 0; /* Remove top margin for cleaner look */ } .asciidoc-content h1 { @apply text-xl sm:text-2xl font-bold mt-6 sm:mt-8 mb-3 sm:mb-4 text-foreground hover:bg-primary/5 hover:px-2 hover:py-1 hover:rounded transition-all duration-200; } .asciidoc-content h2 { @apply text-lg sm:text-xl font-semibold mt-5 sm:mt-6 mb-2 sm:mb-3 text-foreground hover:bg-primary/5 hover:px-2 hover:py-1 hover:rounded transition-all duration-200; } .asciidoc-content h3 { @apply text-base sm:text-lg font-medium mt-4 sm:mt-5 mb-2 text-foreground hover:bg-primary/5 hover:px-2 hover:py-1 hover:rounded transition-all duration-200; } .asciidoc-content h4 { @apply text-sm sm:text-base font-medium mt-3 sm:mt-4 mb-2 text-foreground hover:bg-primary/5 hover:px-2 hover:py-1 hover:rounded transition-all duration-200; } .asciidoc-content h5 { @apply text-xs sm:text-sm font-medium mt-3 mb-2 text-foreground hover:bg-primary/5 hover:px-2 hover:py-1 hover:rounded transition-all duration-200; } .asciidoc-content h6 { @apply text-xs font-medium mt-3 mb-2 text-foreground hover:bg-primary/5 hover:px-2 hover:py-1 hover:rounded transition-all duration-200; } @keyframes progressFill { 0% { width: 0%; } 100% { width: 100%; } } @keyframes shake { 0%, 100% { transform: translate(0, 0) rotate(0deg); } 10% { transform: translate(-1px, -1px) rotate(-1deg); } 20% { transform: translate(1px, -1px) rotate(1deg); } 30% { transform: translate(-1px, 1px) rotate(-1deg); } 40% { transform: translate(1px, 1px) rotate(1deg); } 50% { transform: translate(-1px, -1px) rotate(-1deg); } 60% { transform: translate(1px, -1px) rotate(1deg); } 70% { transform: translate(-1px, 1px) rotate(-1deg); } 80% { transform: translate(1px, 1px) rotate(1deg); } 90% { transform: translate(-1px, -1px) rotate(-1deg); } } /* Greentext styling - 4chan style */ .greentext { color: #4a7c3a; /* Deeper, darker green for better readability in light mode */ display: block; margin: 0.25rem 0; font-family: inherit; } .dark .greentext { color: #8fbc8f; /* Lighter green for dark mode */ } /* Ensure greentext lines appear on their own line even if markdown processes them */ .markdown-content .greentext, .prose .greentext { display: block; margin: 0.25rem 0; } /* Lightbox (yet-another-react-lightbox) caption title: wrap on narrow screens instead of truncating */ .yarl__slide_title { white-space: normal !important; overflow: visible !important; text-overflow: unset !important; word-wrap: break-word; } /* Lightbox: responsive on narrow screens so images are not cut off */ .yarl__portal { inset: 0; width: 100%; height: 100%; } @supports (height: 100dvh) { .yarl__portal { height: 100dvh; } } .yarl__container { height: 100%; min-height: 0; width: 100%; } .yarl__carousel { min-height: 0; } .yarl__slide { min-height: 0; min-width: 0; display: flex; align-items: center; justify-content: center; } .yarl__slide_image { max-height: 100% !important; max-width: 100% !important; width: auto !important; height: auto !important; object-fit: contain !important; } /* Ensure slide wrapper allows image to shrink and fit viewport on narrow screens */ .yarl__slide_wrapper { min-height: 0; flex: 1; display: flex !important; align-items: center; justify-content: center; width: 100%; max-width: 100%; } .yarl__slide_wrapper .yarl__slide_image { max-height: 100% !important; max-width: 100% !important; } /* Radix UI modal dialogs (e.g. NoteDrawer Sheet) set pointer-events:none on document.body to block background interaction. Override this for the lightbox portal so it remains fully interactive when opened from inside a Radix modal. */ .yarl__portal { pointer-events: auto; } /* Bitcoin Connect (Alby) payment UI: web component on document.body while a Sheet/Dialog may still be tearing down; same pointer-events issue as the lightbox when nested under Radix. */ bc-modal { pointer-events: auto; } @media (max-width: 768px) { .yarl__slide_captions_container { padding: 12px; } .yarl__toolbar { padding: 8px; } .yarl__navigation_prev, .yarl__navigation_next { padding: 12px 8px; } }