/* Self-hosted fonts for consistent rendering across machines */ @font-face { font-family: 'SBL Hebrew'; src: url('fonts/SBLHebrew-Regular.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: 'SBL Greek'; src: url('fonts/SBLGreek-Regular.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: 'Paladins'; src: url('fonts/paladins.ttf') format('truetype'); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: 'Ethnocentric'; src: url('fonts/Ethnocentric-Regular.otf') format('opentype'); font-weight: 400; font-style: normal; font-display: swap; } /* Word info popup sizing (select tool) */ .word-info-popup { /* Cards are centred on screen, so grow from the top CENTRE — growing from the left edge made a centred card look like it was sliding in from the side. */ transform-origin: top center; font-size: 2.0em; /* scale text inside popup */ } .word-info-popup .word-info-header { padding: 20px 24px; /* larger header */ } .word-info-popup .word-info-title { font-size: 1.45em; /* relative to popup font-size */ } .word-info-popup .word-info-content { padding: 20px 24px 28px 24px; /* extra bottom padding to prevent cutoff */ } .word-info-popup .word-info-section { margin-bottom: 16px; } .word-info-popup .word-info-label { font-size: 1.0em; /* match scaled base size */ } .word-info-popup .word-info-value { font-size: 1.05em; /* slightly larger for readability */ line-height: 1.6; } .word-info-popup .word-info-value strong, .word-info-popup .word-info-value em { font-size: 1.05em; } .word-info-popup .word-info-close { font-size: 1.3em; } .tool-rail-edge { position: fixed; right: 0; top: 0; height: 1px; /* placeholder; JS positions it */ width: 1px; pointer-events: none; } /* Reset and Base Styles */ * { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent !important; -webkit-touch-callout: none !important; } /* Global safe area at top to avoid bezel gesture region */ :root { --safe-area-top: 24px; --safe-area-left: 24px; --safe-area-right: 24px; } /* Full-bleed slides mode: ignore left/right safe areas */ .slides-fullbleed #app { /* Keep safe-area paddings so toolbar/tabs align exactly with Bible mode */ padding-left: var(--safe-area-left) !important; padding-right: var(--safe-area-right) !important; } .slides-fullbleed .reading-area { overflow: hidden !important; background: #000 !important; position: relative; } .slides-fullbleed .bible-text { padding: 0 !important; } /* Hide the toolbar separator line in slides mode so the top edge stays pure black */ .slides-fullbleed .toolbar::after { display: none !important; } /* Hide page count indicator in Slides tab */ .slides-fullbleed [id^="notesCount"] { display: none !important; } /* Prevent any slide canvas/image from bleeding into the top safe area */ .slides-fullbleed .reading-area .passage-text, .slides-fullbleed .reading-area canvas, .slides-fullbleed .reading-area img, .slides-fullbleed .reading-area > * { position: relative; top: 0; } /* Override browser default text selection styling */ ::selection { background: transparent !important; color: inherit !important; text-decoration: none !important; } ::-moz-selection { background: transparent !important; color: inherit !important; text-decoration: none !important; } /* Allow text selection only in content areas */ .bible-text, input, textarea, select, [contenteditable] { -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; } /* Disable text selection for UI elements */ .tab, .new-tab-btn, .tool-icon, .toolbar-btn, .load-btn, button { -webkit-user-select: none !important; -moz-user-select: none !important; -ms-user-select: none !important; user-select: none !important; -webkit-touch-callout: none !important; } /* Allow text selection in reading areas */ .reading-area, .bible-text { -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; } body { font-family: Georgia, 'Times New Roman', Times, serif; background-color: #000000; color: #e0e0e0; overflow: hidden; overflow-x: hidden; /* prevent horizontal page scroll when swiping tool rail */ min-height: 100vh; width: 100vw; background: #000000 !important; color-scheme: dark; /* hint iOS/Safari to use dark UI controls */ } #app { display: flex; flex-direction: column; min-height: 100vh; width: 100vw; padding-left: var(--safe-area-left); padding-right: var(--safe-area-right); } /* Top spacer to provide non-interactive safe area */ #app::before { content: ''; display: block; height: var(--safe-area-top); background: #000000; /* match toolbar black */ } /* In slides mode, reduce the top spacer to the thinnest mask only */ .slides-fullbleed #app::before { /* Keep the same spacer height as Bible mode so tabs align vertically */ height: var(--safe-area-top); } /* Translation Selector */ .translation-select { min-width: 80px; } /* Unified header band height across views */ :root { --header-band-height: 98px; } /* Toolbar Styles */ .toolbar { display: flex; align-items: center; justify-content: space-between; padding: 6px 20px; /* tighter to align vertically with tab height */ background: #000000 !important; /* set header to pure black */ border-bottom: none; /* replaced by full-width separator */ position: relative; z-index: 11000; /* ensure toolbars and color popups render above chapter header */ touch-action: none; /* prevent single-finger page pan */ overflow: visible; /* allow elements to render outside toolbar height */ will-change: transform; /* keep composited to avoid micro-shifts */ transform: translateZ(0); overscroll-behavior: none; /* prevent scroll chaining over toolbar */ } /* Full-width separator that ignores side safe areas */ .toolbar::after { content: ''; position: absolute; left: calc(var(--safe-area-left) * -1); right: calc(var(--safe-area-right) * -1); bottom: 0; height: 1px; background: #404040; pointer-events: none; } .toolbar-left, .toolbar-right { display: flex; align-items: center; gap: 15px; } /* Slide-out tool rail on the right */ .toolbar-right { position: relative; } /* Compact tool indicator near tool menu */ .tool-indicator { display: inline-flex; align-items: center; justify-content: center; gap: 0; background: rgba(42, 42, 42, 0.96); border: 1px solid #404040; border-radius: 50%; padding: 0; /* no side padding so icon centers perfectly */ color: #e0e0e0; font-size: 0; /* hide any text labels; icon size set on child */ line-height: 1; height: 28px; width: 28px; /* make it a perfect circle */ } .tool-indicator i { font-size: 14px; } .tool-indicator.hidden { display: none !important; } .tool-rail { position: fixed; /* overlay so it never shifts layout */ right: var(--safe-area-right); top: 0; /* JS will position precisely */ /* Keep the rail fully off-screen when closed so only the handle/arrow shows */ transform: translateX(calc(100% + 48px)); /* push completely off-screen */ display: flex; align-items: center; gap: 12px; background: rgba(42, 42, 42, 0.96); border: 1px solid #404040; border-right: none; padding: 0 12px 0 16px; /* vertical padding removed; height will match toolbar */ border-top-left-radius: 12px; border-bottom-left-radius: 12px; transition: transform 0.25s ease, opacity 0.25s ease; opacity: 0; /* hidden when closed */ pointer-events: none; /* non-interactive when closed */ will-change: transform; z-index: 11005; /* above toolbar siblings and chapter header */ } .tool-rail.open { transform: translateX(0); /* slide in from right */ opacity: 0.95; /* visible only when open */ pointer-events: auto; /* interactive only when open */ } /* When open, extend the top and bottom border lines across the right safe area */ .tool-rail.open::before, .tool-rail.open::after { content: ''; position: absolute; right: calc(var(--safe-area-right) * -1); width: var(--safe-area-right); height: 1px; background: #404040; /* match rail border color */ pointer-events: none; } .tool-rail.open::before { top: -1px; } .tool-rail.open::after { bottom: -1px; } .tool-rail .tool-icon { background: #2a2a2a; border: 2px solid #404040; border-radius: 10px; padding: 4px 8px; /* smaller to fit inside toolbar height */ font-size: 16px; /* reduce icon size slightly */ line-height: 1; /* avoid extra vertical expansion */ min-height: 0; } /* Removed old arrow handle; tool menu opens from the compact indicator */ /* Dropdown Styles */ .dropdown { position: relative; display: inline-block; } .dropdown-btn { background: #2a2a2a; border: 2px solid #404040; border-radius: 8px; padding: 12px 16px; font-size: 16px; font-weight: 500; color: #e0e0e0; cursor: pointer; min-width: 80px; display: flex; align-items: center; justify-content: space-between; transition: all 0.2s ease; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); } .dropdown-btn:hover { border-color: #4a9eff; box-shadow: 0 4px 8px rgba(74, 158, 255, 0.3); } .dropdown-btn:active { transform: translateY(1px); } .dropdown-arrow { font-size: 10px; margin-left: 8px; transition: transform 0.2s ease; color: #e0e0e0; } .dropdown.active .dropdown-arrow { transform: rotate(180deg); } .dropdown-content { display: none; position: absolute; top: 100%; left: 0; background: #2a2a2a; border: 2px solid #404040; border-radius: 8px; box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4); z-index: 1001; min-width: 180px; max-height: 300px; overflow-y: auto; margin-top: 5px; } .dropdown.active .dropdown-content { display: block; } .dropdown-item { padding: 12px 16px; font-size: 14px; cursor: pointer; transition: background-color 0.2s ease; border-bottom: 1px solid #404040; color: #e0e0e0; display: flex; align-items: center; gap: 10px; } .dropdown-item:last-child { border-bottom: none; } .dropdown-item:hover { background-color: #404040; } .dropdown-item:active { background-color: #505050; } .dropdown-item i { width: 16px; text-align: center; } /* Color Dropdown */ .color-item { width: 28px; height: 28px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; transition: border-color 0.2s, transform 0.2s; display: inline-block; } .color-item:hover, .color-item.selected { border-color: #fff; transform: scale(1.1); } #colorDropdown { display: flex; flex-direction: row; gap: 8px; padding: 10px 12px; min-width: 0; justify-content: center; background: #232323; } /* Opacity Dropdown */ .opacity-item { padding: 10px 16px; font-size: 14px; cursor: pointer; transition: background-color 0.2s ease; border-bottom: 1px solid #404040; color: #e0e0e0; } .opacity-item:last-child { border-bottom: none; } .opacity-item:hover { background-color: #404040; } /* Search Box */ .search-box { padding: 12px 16px; border-bottom: 1px solid #404040; } .search-box input { width: 100%; padding: 8px 12px; border: 2px solid #404040; border-radius: 6px; font-size: 14px; outline: none; transition: border-color 0.2s ease; background: #2a2a2a; color: #e0e0e0; } .search-box input:focus { border-color: #4a9eff; } .search-box input::placeholder { color: #888; } /* Chapter List */ .chapter-list { max-height: 250px; overflow-y: auto; } /* Toolbar Buttons */ .toolbar-btn { background: #2a2a2a !important; border: 2px solid #404040; border-radius: 8px; padding: 6px 10px; /* smaller to match tab height */ font-size: 14px; font-weight: 500; color: #e0e0e0 !important; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); min-width: 42px; display: flex; align-items: center; justify-content: center; } .toolbar-btn:hover { border-color: #4a9eff; box-shadow: 0 4px 8px rgba(74, 158, 255, 0.3); } .toolbar-btn:active { background: #404040 !important; transform: translateY(1px); } .toolbar-btn i { font-size: 14px; } /* Tool Button Specific */ .tool-btn { min-width: 60px; } /* Reading Area */ .reading-area { flex: 1; position: relative; overflow-y: auto; overflow-x: hidden; background: #000000 !important; /* force dark on iPad */ height: calc(100vh - var(--safe-area-top)); min-height: 0; } .reading-area::-webkit-scrollbar { display: none; /* Chrome/Safari/Webkit */ } .bible-text, .bible-text * { -webkit-user-select: none !important; -moz-user-select: none !important; -ms-user-select: none !important; user-select: none !important; } .bible-text { position: relative; z-index: 1; padding: 30px; line-height: 1.8; /* Base reading size; overridable from Settings > Bible Reading via --bible-font-size (defaults to 60px, unchanged) */ font-size: var(--bible-font-size, 60px); color: #e0e0e0; background: #1a1a1a; font-weight: 400; letter-spacing: 0.01em; } .bible-text::-webkit-scrollbar { width: 12px; } .bible-text::-webkit-scrollbar-track { background: #2a2a2a; border-radius: 6px; } .bible-text::-webkit-scrollbar-thumb { background: #404040; border-radius: 6px; } .bible-text::-webkit-scrollbar-thumb:hover { background: #505050; } /* Prayer Tab Styles */ .prayer-text { -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; outline: none; white-space: pre-wrap; word-wrap: break-word; /* Prevent drag behavior that interferes with text selection */ -webkit-user-drag: none !important; -khtml-user-drag: none !important; -moz-user-drag: none !important; -o-user-drag: none !important; user-drag: none !important; /* Ensure proper cursor for text selection */ cursor: text !important; /* Disable drag and drop */ draggable: false !important; } .prayer-text:focus { outline: none; } /* Make text selection visible in prayer tab */ .prayer-text::selection { background: #4a9eff !important; color: #ffffff !important; text-shadow: none !important; } .prayer-text::-moz-selection { background: #4a9eff !important; color: #ffffff !important; text-shadow: none !important; } .prayer-text *::selection { background: #4a9eff !important; color: #ffffff !important; text-shadow: none !important; } .prayer-text *::-moz-selection { background: #4a9eff !important; color: #ffffff !important; text-shadow: none !important; } /* Ensure prayer text area allows proper text selection */ .prayer-reading-area { -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; cursor: text !important; } .prayer-reading-area * { -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; } /* Prayer text formatting styles */ .prayer-text b, .prayer-text strong { font-weight: 700; } .prayer-text i, .prayer-text em { font-style: italic; } .prayer-text mark { background-color: #ffff00; color: #000; padding: 2px 0; } /* Support for highlighted text via backgroundColor */ .prayer-text [style*="background-color: rgb(255, 255, 0)"], .prayer-text [style*="background-color:#ffff00"], .prayer-text [style*="background-color: yellow"] { background-color: #ffff00 !important; color: #000; padding: 2px 0; } /* Prevent drawing on prayer tab - disable pointer events for annotation canvases */ [id^="readingArea"]:has(.prayer-text) { pointer-events: auto !important; } [id^="readingArea"]:has(.prayer-text) canvas { pointer-events: none !important; display: none !important; } /* Prayer tab reading area - no drawing */ .prayer-text ~ canvas, #readingArea[id*="prayer"] canvas { pointer-events: none !important; display: none !important; } /* Prayer Keyboard Styles */ .prayer-keyboard { position: fixed; width: 760px; max-width: 95vw; background: #2a2a2a; border: 2px solid #404040; border-radius: 12px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6); z-index: 20000; user-select: none; touch-action: none; } .prayer-keyboard-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; background: #1a1a1a; border-bottom: 1px solid #404040; border-radius: 12px 12px 0 0; cursor: move; gap: 12px; } .prayer-keyboard-title { font-size: 16px; font-weight: 500; color: #e0e0e0; flex-shrink: 0; } .prayer-format-toolbar { display: flex; gap: 6px; align-items: center; flex: 1; justify-content: center; } .prayer-format-btn { background: #2a2a2a; border: 2px solid #404040; border-radius: 6px; color: #e0e0e0; font-size: 16px; font-weight: 600; padding: 6px 12px; min-width: 36px; height: 32px; cursor: pointer; transition: all 0.15s; display: flex; align-items: center; justify-content: center; touch-action: manipulation; } .prayer-format-btn:hover { background: #333; border-color: #555; } .prayer-format-btn:active { transform: scale(0.95); } .prayer-format-btn.active { background: #4a9eff; border-color: #4a9eff; color: #fff; } .prayer-format-btn b { font-weight: 700; } .prayer-format-btn i { font-style: italic; } .prayer-format-btn svg { display: block; width: 20px; height: 20px; stroke: currentColor; fill: none; } .prayer-keyboard-close { background: transparent; border: none; color: #e0e0e0; font-size: 24px; line-height: 1; cursor: pointer; padding: 0; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; border-radius: 4px; transition: background 0.2s; } .prayer-keyboard-close:hover { background: #404040; } .prayer-keyboard-body { padding: 12px; display: flex; flex-direction: column; gap: 8px; } .prayer-keyboard-row { display: flex; gap: 6px; justify-content: center; } .prayer-key-btn { background: #1a1a1a; border: 2px solid #404040; border-radius: 8px; color: #e0e0e0; font-size: 18px; font-weight: 500; padding: 12px 16px; min-width: 48px; cursor: pointer; transition: all 0.15s; font-family: Georgia, serif; touch-action: manipulation; } .prayer-key-btn:active { background: #4a9eff; border-color: #4a9eff; transform: scale(0.95); } .prayer-key-space { flex: 1; min-width: 120px; } .prayer-key-backspace, .prayer-key-enter { min-width: 80px; font-size: 20px; } .prayer-key-shift, .prayer-key-tab { min-width: 70px; font-size: 16px; } .prayer-key-active { background: #4a9eff !important; border-color: #4a9eff !important; color: #fff !important; } /* Caps Lock state for Shift: distinct from momentary Shift so the user can tell at a glance whether typing letters will stay capitalized. Gold tint with a thicker border + inner ring works against the dark keyboard chrome. */ .prayer-key-shift.prayer-key-locked { background: #2a2418 !important; border-color: #f0b400 !important; color: #ffd45a !important; box-shadow: inset 0 0 0 1px rgba(240, 180, 0, 0.55); } .prayer-key-shift.prayer-key-locked .prayer-key-glyph { color: #ffd45a; } .prayer-key-glyph { display: inline-block; font-size: 1.05em; line-height: 1; margin-right: 2px; } .bible-text::after { /* Leave a full-page buffer so the last verse can reach/past the top edge */ content: ''; display: block; width: 100%; min-height: 200px; height: 100vh; pointer-events: none; } @supports (height: 100dvh) { .bible-text::after { height: 100dvh; } } .bible-text .verse .verse-number { color: #ffffff; font-weight: 500; margin-right: 4px; margin-left: 4px; } /* Smaller verse numbers for ESV (match your target look) */ /* Smaller bracketed verse numbers for all translations (match your ESV screenshot) */ .reading-area .verse .verse-number { font-size: 0.6em; opacity: 0.75; } .reading-area .verse.verse-highlighted { background: rgba(205, 205, 205, 0.42); border-radius: 6px; box-shadow: 0 0 0 1px rgba(210, 210, 210, 0.52); -webkit-box-decoration-break: clone; box-decoration-break: clone; } .bible-text .verse .verse-bracket { color: #ffffff; font-weight: 500; } .chapter-header { background: #1a1a1a; padding: 0; /* fixed band height so bottom rule never jumps */ margin: 0 0 22px 0; /* extra gap so first verse never touches bottom rule */ border-bottom: none; /* replaced by full-width separator */ position: sticky; top: var(--safe-area-top); /* Keep above any annotation canvas (z-index ~5000) */ z-index: 6001; width: 100%; display: none; /* Hidden by default, shown via JavaScript */ touch-action: none; /* block one-finger panning on passage header */ overscroll-behavior: none; /* stop scroll chaining from header */ height: var(--header-band-height) !important; /* lock to selection header height */ min-height: var(--header-band-height) !important; overflow: visible; /* allow descenders to render fully */ } .chapter-header::after { content: ''; position: absolute; left: calc(var(--safe-area-left) * -1); right: calc(var(--safe-area-right) * -1); bottom: 0; /* keep exactly aligned with selection bar rule */ height: 1px; background: #404040; pointer-events: none; z-index: 0; } .chapter-header-inner { display: flex; align-items: center; justify-content: center; gap: 12px; height: 100% !important; /* fill fixed header band */ } .chapter-header-inner, .chapter-header-inner * { touch-action: none; /* ensure descendants don’t initiate scroll/pan */ } .chapter-header-inner .header-back-btn { margin-left: 12px; margin-top: 0; /* center vertically in header */ display: flex; align-items: center; justify-content: center; } /* Translation dropdown in chapter header */ .translation-dropdown { position: absolute; background: #2a2a2a; border: 1px solid #3a3a3a; border-radius: 14px; /* 1.8x of 8px ≈ 14px */ padding: 11px; /* 1.8x of 6px ≈ 10.8 */ z-index: 1000; box-shadow: 0 12px 26px rgba(0,0,0,0.4); font-size: 1.8em; /* scale contents by ~1.8x overall */ } .translation-dropdown .translation-option { display: block; padding: 14px 22px; /* 1.8x of 8x12 */ background: transparent; border: none; color: #e0e0e0; text-align: left; width: 100%; border-radius: 10px; /* 1.8x of 6px ≈ 10px */ cursor: pointer; } .translation-dropdown .translation-option:hover { background: #3a3a3a; } .translation-dropdown .translation-option.selected { background: #4a9eff33; color: #bcdcff; } .chapter-title { font-size: 60px; font-weight: 800; color: #d2b48c; text-align: center; margin: 0; padding: 0; line-height: 1.16; /* keep descenders clear while matching rule position */ white-space: nowrap; /* never wrap to two lines */ position: relative; z-index: 1; /* render above the rule */ } /* Override inline positioning injected by JS to keep title truly centered */ .chapter-header .chapter-title { position: static !important; left: auto !important; top: auto !important; transform: none !important; text-align: center; margin: 0 auto; } /* Remove negative vertical offsets on header controls injected inline */ .chapter-header .header-back-btn, .chapter-header .chapter-nav-btns { margin-top: 0 !important; } /* In the new grid header, ensure the back button participates in flow (not absolute) */ .chapter-left-controls .header-back-btn[data-action="back-to-selector"] { position: static !important; top: auto !important; left: auto !important; transform: none !important; z-index: auto !important; } /* Ensure the bible text starts right below the header */ .bible-text { margin-top: 0; padding: 30px; } /* Hide the selector container by default when a passage is loaded */ .selector-container { transition: all 0.3s ease; } .content-wrapper { position: relative; min-height: 100%; } .annotation-canvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; background: transparent !important; cursor: crosshair; touch-action: pan-x pan-y; will-change: transform; } .annotation-overlay-canvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 3; pointer-events: none; background: transparent !important; will-change: transform; } body.drawing, body.drawing * { user-select: none !important; } .drawing .bible-text { user-select: none !important; } /* Touch gesture feedback */ .reading-area.gesturing { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } /* Improved touch handling for mobile */ @media (max-width: 768px) { .toolbar { padding: 12px 20px; min-height: 60px; } .dropdown-btn { padding: 10px 14px; font-size: 14px; min-width: 70px; } .bible-text { padding: 20px; font-size: 16px; } .toolbar-left, .toolbar-right { gap: 12px; } .reading-area { -webkit-overflow-scrolling: touch; overscroll-behavior: contain; } .bible-text.zoomed { font-size: 16px; /* Maintain readable size when zoomed */ } } /* High Contrast Mode */ @media (prefers-contrast: high) { .dropdown-btn { border-width: 3px; border-color: #ffffff; } .dropdown-content { border-width: 3px; border-color: #ffffff; } .bible-text { color: #ffffff; } .bible-text .verse .verse-number { color: #111 !important; } } /* Focus States */ .dropdown-btn:focus, .toolbar-btn:focus, .search-box input:focus { outline: 2px solid #4a9eff; outline-offset: 2px; } /* Dropdown Scrollbar Styling */ .dropdown-content::-webkit-scrollbar { width: 8px; } .dropdown-content::-webkit-scrollbar-track { background: #2a2a2a; border-radius: 4px; } .dropdown-content::-webkit-scrollbar-thumb { background: #404040; border-radius: 4px; } .dropdown-content::-webkit-scrollbar-thumb:hover { background: #505050; } .slider-group { display: flex; align-items: center; gap: 8px; margin-right: 16px; } .tool-slider { display: flex; gap: 4px; position: relative; } .tool-icon { background: none; border: none; color: #e0e0e0; font-size: 18px; /* slightly smaller for tighter fit */ padding: 4px 6px; /* smaller padding to prevent overflow */ border-radius: 6px; cursor: pointer; transition: background 0.15s, color 0.15s; } /* Pen tool icon color styling */ .tool-icon[data-tool="pen"] { color: var(--pen-color, #ffff00) !important; transition: none !important; } .tool-icon[data-tool="pen"]:hover, .tool-icon[data-tool="pen"]:focus, .tool-icon[data-tool="pen"]:active { color: var(--pen-color, #ffff00) !important; background: none !important; border: none !important; } .tool-icon.selected, .tool-icon:hover { background: #333; color: #4a9eff; } /* Keep pen tool color when selected */ .tool-icon[data-tool="pen"].selected, .tool-icon[data-tool="pen"].selected:hover, .tool-icon[data-tool="pen"].selected:focus, .tool-icon[data-tool="pen"].selected:active { background: #333 !important; border: 2px solid var(--pen-color, #ffff00) !important; color: var(--pen-color, #ffff00) !important; box-shadow: 0 0 0 2px var(--pen-color, #ffff00), 0 0 8px rgba(255, 255, 0, 0.5) !important; } .tool-icon:active, .tool-icon:focus { outline: none; } .tool-icon:not(.selected):active, .tool-icon:not(.selected):focus { background: none !important; /* Don't override color - let each tool keep its specific color */ } .color-slider { display: flex; gap: 6px; } .color-slider .color-item { width: 22px; height: 22px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; transition: border-color 0.2s, transform 0.2s; } .color-slider .color-item.selected, .color-slider .color-item:hover { border-color: #4a9eff; transform: scale(1.1); } .opacity-slider { width: 70px; accent-color: #ffffff; margin-left: 4px; -webkit-appearance: none; appearance: none; height: 6px; border-radius: 3px; background: #666666; outline: none; position: relative; z-index: 1; } .opacity-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; border-radius: 50%; background: var(--opacity-handle-color, #000000); border: 2px solid #ffffff; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); position: relative; z-index: 10; } .opacity-slider::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; background: var(--opacity-handle-color, #000000); border: 2px solid #ffffff; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); position: relative; z-index: 10; } .color-picker-wrapper { position: relative; display: flex; align-items: center; justify-content: center; margin: 0 10px; } .color-picker-btn { width: 32px; height: 32px; border-radius: 50%; border: 2px solid #555; cursor: pointer; background-color: #ffff00; transition: transform 0.1s ease; } .color-picker-btn:active { transform: scale(0.9); } .color-picker-popup { display: none; position: absolute; bottom: 150%; left: 50%; transform: translateX(-50%); background-color: transparent; border-radius: 50%; padding: 10px; z-index: 11014; width: 160px; height: 160px; filter: drop-shadow(0 -4px 8px rgba(0,0,0,0.4)); } .color-preview { display: none; position: absolute; top: -65px; left: 50%; transform: translateX(-50%); width: 55px; height: 55px; border-radius: 50%; border: 4px solid white; box-shadow: 0 0 12px rgba(0,0,0,0.6); z-index: 11015; } .color-picker-popup.show .color-preview { display: block; } .color-picker-popup.show { display: flex; align-items: center; justify-content: center; } .color-wheel { position: relative; width: 100%; height: 100%; border-radius: 50%; background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red); } .color-handle { position: absolute; width: 24px; height: 24px; border: 4px solid white; border-radius: 50%; transform: translate(-50%, -50%); pointer-events: none; box-shadow: 0 0 8px rgba(0,0,0,0.5); } .tool-icon.selected, .tool-icon:focus { background: #333; color: #4a9eff; outline: none; } /* Browser Tabs */ .browser-tabs { display: flex; align-items: center; background: none; border: none; border-radius: 0; box-shadow: none; padding: 0; position: relative; } /* Reset app button (fixed at start of tab strip) */ .reset-app-btn { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; min-width: 28px; background: transparent; border: none; border-radius: 6px; color: #9aa0a6; /* subtle light gray */ font-size: 18px; cursor: pointer; margin-right: 8px; transition: background-color 0.2s, color 0.2s; padding: 0; line-height: 1; touch-action: manipulation; } .reset-app-btn:hover { background-color: rgba(255, 255, 255, 0.06); color: #cfcfcf; } .reset-app-btn:active { background-color: rgba(255, 255, 255, 0.12); } .reset-app-btn i { pointer-events: none; } .tab-bar { display: flex; flex: 1; overflow-x: auto; /* allow horizontal panning when many tabs are open */ overflow-y: visible; /* allow close button below tabs to be visible */ background: none; border: none; box-shadow: none; padding: 0; position: relative; /* ensure it can stack above slide mask */ z-index: 2002; /* higher than any slide mask */ will-change: transform; /* prevent brief horizontal shift during heavy layout */ transform: translateZ(0); touch-action: none; /* prevent one-finger scroll on tab strip */ overscroll-behavior: none; /* prevent scroll leak from tab strip */ scrollbar-width: none; /* Firefox: hide visual scrollbar */ } .tab-bar::-webkit-scrollbar { width: 0; height: 0; } .tab { display: flex; align-items: center; gap: 4px; padding: 4px 10px; background: transparent; border: none; cursor: pointer; max-width: 100%; position: relative; border-radius: 8px 8px 0 0; box-shadow: none; height: 38px; transition: background 0.15s; flex: 0 0 auto; /* keep tab width stable; overflow handled by tab-bar scrolling */ min-width: 40px; /* Ensure minimum width for icon */ overflow: visible; /* allow close button below */ touch-action: none; /* ensure JS receives full gesture for swipe/hold to close */ } .tab.dragging { z-index: 5; } /* The swipe-down close buttons live here, on
, and never inside a tab: the tab bar clips its own children, and a tab-row rebuild would orphan a button that had been moved out to be shown. One layer, swept and refilled by renderTabs(). See the long note above renderTabs()'s positionCloseOverlay. */ #tabCloseLayer { position: fixed; left: 0; top: 0; width: 0; height: 0; z-index: 100000; pointer-events: none; /* only a button that is actually up takes input */ } /* Close overlay uses fixed positioning set in JS for reliability on TVs */ .tab .tab-close-confirm, .tab-close-confirm { position: fixed; /* Parked off-screen until JS places it. A fixed box with no offsets falls back to its STATIC position, which is what used to drop the x into the tab row, high and half a width to the left. */ left: -9999px; top: -9999px; opacity: 0; pointer-events: none; /* disabled until visible */ transition: opacity 0.18s ease, transform 0.18s ease; transform: translate(-50%, 0) scale(0.9); z-index: 100000; /* ensure above all UI */ background: transparent; /* only show the button */ } .tab .tab-close-confirm.show, .tab-close-confirm.show { opacity: 1; pointer-events: auto; /* clickable only when shown */ transform: translate(-50%, 0) scale(1); } /* Match popup close button styling */ .tab .tab-close-btn, .tab-close-btn { background: none; border: none; color: #e0e0e0; font-size: 20px; cursor: pointer; padding: 0; width: 30px; height: 30px; line-height: 30px; text-align: center; border-radius: 4px; transition: all 0.2s ease; } .tab .tab-close-btn:hover, .tab-close-btn:hover { background: rgba(255, 255, 255, 0.1); color: #ff6b6b; } .tab .tab-close-btn:active, .tab-close-btn:active { background: rgba(255, 107, 107, 0.15); color: #ff6b6b; } .tab.active { background: transparent; border-bottom: 3px solid #4a9eff; } .tab-title { display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 500; color: #e0e0e0; flex: 1 1 auto; min-width: 0; max-width: 100%; } /* Removed explicit close button; using hold-to-close gesture on tab */ .bible-icon, .media-icon, .whiteboard-icon, .media-tab-icon, .graphics-tab-icon, .maps-tab-icon, .prayer-tab-icon, .alpha-icon, .notes-icon, .ask-tab-icon { opacity: 0.7; transition: opacity 0.2s; } .tab:hover .bible-icon, .tab.active .bible-icon, .tab:hover .media-icon, .tab.active .media-icon, .tab:hover .whiteboard-icon, .tab.active .whiteboard-icon, .tab:hover .media-tab-icon, .tab.active .media-tab-icon, .tab:hover .graphics-tab-icon, .tab.active .graphics-tab-icon, .tab:hover .maps-tab-icon, .tab.active .maps-tab-icon, .tab:hover .prayer-tab-icon, .tab.active .prayer-tab-icon, .tab:hover .alpha-icon, .tab.active .alpha-icon, .tab:hover .notes-icon, .tab.active .notes-icon, .tab:hover .ask-tab-icon, .tab.active .ask-tab-icon { opacity: 1; } /* Media Tab Content Styles */ .media-content { padding: 20px; color: #e0e0e0; line-height: 1.6; } .media-welcome { max-width: 800px; margin: 0 auto; } .media-welcome h2 { color: #4a9eff; margin-bottom: 20px; font-size: 2rem; text-align: center; } .media-welcome h3 { color: #e0e0e0; margin: 25px 0 15px; font-size: 1.4rem; } .drive-section { background: #1a1a1a; border: 1px solid #404040; border-radius: 8px; padding: 20px; margin: 20px 0; } .drive-config { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; } .drive-folder-input { flex: 1; min-width: 0; padding: 10px; background: #2a2a2a; color: #e0e0e0; border: 1px solid #404040; border-radius: 4px; font-size: 14px; } .drive-folder-input:focus { outline: none; border-color: #4a9eff; box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.2); } .drive-update-btn { padding: 10px 20px; background: #4a9eff; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.2s ease; } .drive-update-btn:hover { background: #3a8eff; transform: translateY(-1px); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .drive-update-btn:active { transform: translateY(0); box-shadow: none; } .drive-help { font-size: 0.9em; color: #888; margin-top: 8px; line-height: 1.4; } .drive-viewer { background: #1a1a1a; border: 1px solid #404040; border-radius: 8px; overflow: hidden; margin: 20px 0; height: 400px; } .drive-viewer iframe { width: 100%; height: 100%; border: none; background: #fff; } .media-notes-section { margin-top: 30px; } .media-welcome p { margin-bottom: 15px; font-size: 1.1rem; } .media-welcome ul { margin-bottom: 20px; margin-left: 20px; } .media-welcome li { margin-bottom: 8px; } .media-notes { width: 100%; margin-top: 20px; padding: 15px; border: 2px solid #404040; border-radius: 8px; background: #1a1a1a; color: #e0e0e0; font-family: Georgia, 'Times New Roman', Times, serif; font-size: 16px; line-height: 1.5; resize: vertical; min-height: 200px; } .media-notes:focus { outline: none; border-color: #4a9eff; box-shadow: 0 0 0 3px rgba(74, 158, 255, 0.2); } .media-notes::placeholder { color: #888; } /* New Media Tab Workspace Styles */ .media-workspace { display: flex; flex-direction: column; height: 100%; background: #2a2a2a; padding: 20px; gap: 20px; } .media-thumbnails-section { flex: 1; overflow: hidden; background: #1a1a1a; border-radius: 8px; padding: 20px; } .media-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; padding: 10px; } .media-card { position: relative; width: 120px; height: 120px; margin: 10px; border: none; border-radius: 0; overflow: hidden; cursor: move; background: transparent; transition: none; } .media-card:hover { transform: none; box-shadow: none; } .media-card.dragging { opacity: 0.5; } .media-thumbnail { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; } .media-thumbnail img { width: 100%; height: 100%; object-fit: cover; } .file-icon { font-size: 32px; color: #666; } .canvas-content { position: relative; width: 100%; height: 100%; min-height: 500px; } #mediaCanvas.drag-over { background-color: transparent; border: none; } .media-card .card-content { padding: 15px; display: flex; flex-direction: column; gap: 10px; } .media-card .card-icon { font-size: 24px; text-align: center; } .media-card .card-thumbnail { width: 100%; height: 150px; display: flex; align-items: center; justify-content: center; background: #1a1a1a; border-radius: 4px; overflow: hidden; } .media-card .card-thumbnail img { width: 100%; height: 100%; object-fit: cover; } .media-card.loading-card .card-icon { animation: spin 1s linear infinite; } .media-card.error-card { border: none; background: transparent; } .media-card.error-card:hover { border: none; background: transparent; } .media-card.empty-card { border: none; background: transparent; } .media-card.empty-card:hover { border: none; background: transparent; } @keyframes spin { 100% { transform: rotate(360deg); } } .media-card .card-title { font-size: 14px; font-weight: 500; color: #e0e0e0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: center; } .media-card .card-subtitle { font-size: 12px; color: #808080; text-align: center; } .media-canvas { flex: 2; background: #1a1a1a; border-radius: 8px; padding: 20px; position: relative; overflow: hidden; } .media-canvas.drag-over { border: none; background: transparent; } .canvas-content { width: 100%; height: 100%; position: relative; min-height: 500px; touch-action: auto !important; overflow: hidden; } .canvas-placeholder { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: #666666; } .placeholder-icon { font-size: 48px; margin-bottom: 10px; } .placeholder-text { font-size: 16px; } .canvas-media-item { position: absolute; background: transparent; border: none; border-radius: 0; box-shadow: none; overflow: hidden; cursor: move; user-select: none; touch-action: none; } .canvas-media-item img { width: 100%; height: 100%; object-fit: contain; pointer-events: none; /* Prevent image from interfering with drag */ } .canvas-media-item iframe { width: 100%; height: 100%; border: none; pointer-events: none; /* Prevent iframe from interfering with drag */ } /* Make sure the canvas content is properly positioned for absolute items */ .canvas-content { width: 100%; height: 100%; position: relative; min-height: 500px; padding: 0; } /* Ensure proper stacking context for media items */ .canvas-media-item { z-index: 1; } .canvas-media-item:hover { z-index: 2; } .media-item-content { width: 100%; height: 100%; padding: 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; /* Added for absolute positioning of children */ } .media-item-content img { width: 100%; height: 100%; object-fit: contain; pointer-events: none; /* Prevent image from interfering with drag */ } .media-item-icon { font-size: 24px; margin-bottom: 10px; } .media-item-name { font-size: 14px; color: #e0e0e0; text-align: center; word-break: break-word; } /* Media Responsive Styles */ @media (max-width: 768px) { .media-workspace { padding: 10px; gap: 10px; } .media-card-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; } .media-card { font-size: 12px; } .media-card .card-icon { font-size: 20px; } .canvas-media-item { min-width: 100px; min-height: 80px; } .media-item-icon { font-size: 20px; } } /* Link Chooser Popup Styles */ .link-chooser-popup { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 10000; display: flex; align-items: center; justify-content: center; } .popup-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(5px); } .popup-content { background: #2a2a2a; border: 1px solid #404040; border-radius: 8px; width: 90%; max-width: 600px; position: relative; z-index: 1; max-height: 85vh; overflow-y: auto; } .popup-header { display: flex; align-items: center; justify-content: space-between; padding: 20px 25px; border-bottom: 1px solid #404040; } .popup-header h3 { margin: 0; color: #e0e0e0; font-size: 18px; } .popup-close { background: none; border: none; color: #888; font-size: 24px; cursor: pointer; padding: 0; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border-radius: 4px; } .popup-close:hover { background: #404040; color: #e0e0e0; } .popup-body { padding: 25px; } .popup-body label { display: block; margin-bottom: 8px; color: #e0e0e0; font-weight: 500; } .popup-body .drive-folder-input { width: 100%; margin-bottom: 10px; } .popup-body .drive-help { font-size: 0.85em; color: #888; line-height: 1.4; } /* Enhanced input styles for larger popup */ .input-section { margin-bottom: 25px; } .input-wrapper { position: relative; } .drive-folder-input-large { width: 100%; padding: 15px; font-size: 16px; background: #1a1a1a; color: #e0e0e0; border: 2px solid #404040; border-radius: 8px; font-family: Georgia, 'Times New Roman', Times, serif; transition: all 0.3s ease; margin-bottom: 12px; } .drive-folder-input-large:focus { outline: none; border-color: #4a9eff; box-shadow: 0 0 0 3px rgba(74, 158, 255, 0.2); background: #222; } .drive-folder-input-large::placeholder { color: #666; font-style: italic; } .input-status { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 6px; font-size: 14px; background: #333; border: 1px solid #404040; transition: all 0.3s ease; } .input-status.valid { background: rgba(76, 175, 80, 0.1); border-color: #4caf50; color: #4caf50; } .input-status.warning { background: rgba(255, 193, 7, 0.1); border-color: #ffc107; color: #ffc107; } .input-status.success { background: rgba(76, 175, 80, 0.2); border-color: #4caf50; color: #4caf50; font-weight: 500; } .status-icon { font-size: 16px; line-height: 1; } .status-text { flex: 1; font-weight: 500; } .help-section { background: #1a1a1a; border: 1px solid #333; border-radius: 8px; padding: 20px; margin-bottom: 20px; } .help-section h4 { margin: 0 0 15px 0; color: #4a9eff; font-size: 16px; } .help-steps { margin: 0 0 15px 0; padding-left: 20px; color: #ccc; } .help-steps li { margin-bottom: 8px; line-height: 1.4; } .help-steps strong { color: #4a9eff; } .example-section { background: #0d1117; border: 1px solid #30363d; border-radius: 6px; padding: 15px; margin-top: 15px; } .example-section p { margin: 0 0 8px 0; color: #e0e0e0; font-size: 14px; } .example-section code { background: #21262d; color: #4a9eff; padding: 4px 8px; border-radius: 4px; font-family: 'Courier New', monospace; font-size: 13px; word-break: break-all; } .current-config { background: rgba(74, 158, 255, 0.05); border: 1px solid #4a9eff; border-radius: 8px; padding: 20px; margin-top: 20px; } .current-config h4 { margin: 0 0 15px 0; color: #4a9eff; font-size: 16px; } .current-id { margin-bottom: 12px; font-size: 14px; color: #ccc; } .current-id strong { color: #e0e0e0; } .current-id code { background: #1a1a1a; color: #4a9eff; padding: 4px 8px; border-radius: 4px; font-family: 'Courier New', monospace; font-size: 12px; border: 1px solid #333; } .preview-link a { display: inline-flex; align-items: center; gap: 6px; color: #4a9eff; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 12px; background: rgba(74, 158, 255, 0.1); border: 1px solid #4a9eff; border-radius: 6px; transition: all 0.2s ease; } .preview-link a:hover { background: rgba(74, 158, 255, 0.2); transform: translateY(-1px); } .popup-footer { display: flex; gap: 10px; justify-content: flex-end; padding: 20px 25px; border-top: 1px solid #404040; } .popup-btn { padding: 10px 20px; border: none; border-radius: 4px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; } .popup-btn.cancel { background: #404040; color: #e0e0e0; } .popup-btn.cancel:hover { background: #505050; } .popup-btn.save { background: #4a9eff; color: white; } .popup-btn.save:hover { background: #3a8eff; } /* Mobile Responsive Styles for Media Tab */ @media (max-width: 768px) { .media-workspace { padding: 15px; gap: 15px; } .media-card-grid { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 10px; } .media-card { padding: 10px; min-height: 70px; } .media-card .card-icon { font-size: 20px; } .canvas-media-item { min-width: 120px; min-height: 80px; padding: 10px; } .media-item-icon { font-size: 24px; } .popup-content { width: 95%; margin: 20px; } .popup-header, .popup-body, .popup-footer { padding: 15px 20px; } .drive-folder-input-large { font-size: 16px; /* Prevent zoom on iOS */ padding: 12px; } .help-section { padding: 15px; } .current-config { padding: 15px; } .popup-content { max-width: 95%; } } .chapter-select, .verse-select { background: #404040; border: 2px solid #505050; border-radius: 6px; padding: 8px 12px; font-size: 14px; color: #e0e0e0; min-width: 80px; outline: none; transition: border-color 0.2s ease; } .chapter-select:focus, .verse-select:focus { border-color: #4a9eff; } .book-select, .translation-select { background-image: url("data:image/svg+xml;utf8,"); background-repeat: no-repeat; background-position: right 14px center; background-size: 18px 18px; padding-right: 38px; } .chapter-select::-ms-expand, .verse-select::-ms-expand, .book-select::-ms-expand, .translation-select::-ms-expand { display: none; } .chapter-select:hover, .verse-select:hover, .book-select:hover, .translation-select:hover { border-color: #666; } .load-btn { background: #4a9eff; border: none; border-radius: 6px; padding: 8px 16px; font-size: 14px; font-weight: 500; color: #ffffff; cursor: pointer; transition: all 0.2s ease; } /* Make select options larger for touch */ select option { font-size: 20px; padding: 16px 0; } /* Tab Content */ .tab-content { flex: 1; display: flex; flex-direction: column; overflow: hidden; background: #181818; transition: opacity 140ms ease; will-change: opacity; } .media-fade { opacity: 0; transition: opacity 180ms ease; } .media-fade.media-fade-visible { opacity: 1; } .tab-panel { display: none; flex-direction: column; flex: 1 1 auto; min-height: 0; opacity: 1; transition: opacity 140ms ease; } .tab-panel.active { display: flex; } .tab-panel.tab-fade-enter { opacity: 0; } .tab-panel.tab-fade-enter-active { opacity: 1; } .tab-content.tab-container-fade-enter { opacity: 0; } .tab-content.tab-container-fade-enter.tab-container-fade-enter-active { opacity: 1; } .notes-stage { display: flex; justify-content: center; align-items: flex-start; } .notes-stage .content-wrapper { width: 100%; display: flex; justify-content: center; align-items: flex-start; } .notes-stage .bible-text { width: 100%; display: flex; justify-content: center; align-items: flex-start; } .notes-stage .passage-text, .notes-stage .notes-passage { width: 100%; display: flex; justify-content: center; align-items: flex-end; margin: 0 auto; } .notes-stage canvas, .notes-stage img { margin: 0 auto; display: block; } /* Passage Selector */ .passage-selector { background: #2a2a2a; border-bottom: 1px solid #404040; padding: 15px 20px !important; } .selector-row { display: flex; align-items: center; gap: 10px; } .selector-row span { font-size: 22px; font-weight: bold; color: #4a9eff; margin: 0 6px; letter-spacing: 2px; vertical-align: middle; } .book-select { background: #404040; border: 2px solid #505050; border-radius: 6px; padding: 8px 12px; font-size: 14px; color: #e0e0e0; min-width: 150px; outline: none; transition: border-color 0.2s ease; } .book-select:focus { border-color: #4a9eff; } /* Book select placeholder styling */ .book-select[data-placeholder]:not([data-placeholder=""]):invalid { color: #888; } .book-select[data-placeholder]:not([data-placeholder=""]):invalid::before { content: attr(data-placeholder); color: #888; position: absolute; pointer-events: none; } /* Alternative approach using CSS to show placeholder text */ .book-select option[value=""] { display: none; } .book-select:invalid { color: #888; } .book-select:invalid::before { content: attr(data-placeholder); color: #888; position: absolute; pointer-events: none; } /* Book select placeholder styling - improved approach */ .book-select[data-show-placeholder="true"] { color: #888; } .book-select[data-show-placeholder="true"]::before { content: "Book"; color: #888; position: absolute; pointer-events: none; padding: 14px 18px; font-size: 18px; } .translation-select { background: #404040; border: 2px solid #505050; border-radius: 6px; padding: 8px 12px; font-size: 14px; color: #e0e0e0; min-width: 80px; outline: none; transition: border-color 0.2s ease; } .translation-select:focus { border-color: #4a9eff; } .chapter-select:hover, .verse-select:hover { border-color: #666; } .chapter-select:focus, .verse-select:focus { outline: none; border-color: #3498db; box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2); } .load-btn:hover { background: #3a8eef; transform: translateY(-1px); } .load-btn:active { transform: translateY(0); } .new-tab-btn { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; min-width: 28px; background: transparent; border: none; border-radius: 6px; color: #4a9eff; font-size: 20px; cursor: pointer; margin-left: 8px; transition: background-color 0.2s; padding: 0; line-height: 1; } .new-tab-btn:hover { background-color: rgba(74, 158, 255, 0.1); } .new-tab-btn:active { background-color: rgba(74, 158, 255, 0.2); } .new-tab-btn.menu-open { background-color: rgba(74, 158, 255, 0.18); } .new-tab-quick-menu { position: absolute; top: 50%; right: -8px; transform: translate(100%, -50%) scale(0.96); transform-origin: left center; display: flex; flex-direction: row; align-items: center; flex-wrap: nowrap; gap: 6px; min-width: 0; padding: 8px; border-radius: 10px; border: 1px solid rgba(74, 158, 255, 0.35); background: rgba(20, 22, 26, 0.96); box-shadow: 0 14px 30px rgba(0, 0, 0, 0.44); opacity: 0; pointer-events: none; transition: opacity 0.16s ease, transform 0.16s ease; z-index: 100020; } .new-tab-quick-menu.show { opacity: 1; transform: translate(100%, -50%) scale(1); pointer-events: auto; } .new-tab-menu-item { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 32px; border: none; border-radius: 8px; padding: 0; background: rgba(255, 255, 255, 0.03); color: #e0e0e0; cursor: pointer; text-align: center; font-size: 13px; } .new-tab-menu-item:hover { background: rgba(74, 158, 255, 0.16); } .new-tab-menu-item:active { background: rgba(74, 158, 255, 0.24); } .new-tab-menu-icon { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; border-radius: 6px; color: #4a9eff; background: rgba(74, 158, 255, 0.09); font-weight: 600; letter-spacing: 0.02em; } .new-tab-menu-label { display: none; } .size-slider { -webkit-appearance: none; appearance: none; width: 120px; height: 8px; border-radius: 5px; background: #555; outline: none; transition: opacity .2s; display: block; margin: 0; padding: 0; } /* When the slider is wrapped with a ticks overlay, let it span the full wrap so its travel matches the tick positions exactly. */ .size-slider-wrap > .size-slider { width: 100%; } .size-slider::-webkit-slider-runnable-track { height: 8px; background: transparent; border: none; } .size-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; box-sizing: border-box; border-radius: 50%; background: #e0e0e0; /* avoid pure white on iOS invert */ border: 3px solid #888; cursor: pointer; margin-top: -6px; /* keep thumb centered on 8px track */ box-shadow: 0 0 4px rgba(0, 0, 0, 0.35); } .size-slider::-moz-range-track { height: 8px; background: transparent; border: none; } .size-slider::-moz-range-thumb { width: 20px; height: 20px; box-sizing: border-box; border-radius: 50%; background: #e0e0e0; border: 3px solid #888; cursor: pointer; box-shadow: 0 0 4px rgba(0, 0, 0, 0.35); } .size-slider::-moz-range-progress { background: transparent; } .tool-wrapper { display: flex; gap: 8px; position: relative; z-index: 11010; /* keep tool controls above surrounding UI */ } .size-slider-popup { position: absolute; top: 120%; left: 50%; transform: translateX(-50%) scaleY(0); transform-origin: top center; background-color: #2a2a2a; border: 1px solid #404040; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); padding: 10px 12px; display: flex; flex-direction: column; align-items: stretch; gap: 8px; transition: transform 0.18s cubic-bezier(.4,1.6,.6,1), opacity 0.18s cubic-bezier(.4,1.6,.6,1); opacity: 0; pointer-events: none; min-width: 200px; justify-content: center; z-index: 1000; } .size-slider-popup.show { transform: translateX(-50%) scaleY(1); opacity: 1; pointer-events: auto; } /* Wraps the pen-size slider together with an absolutely-positioned ticks layer. The wrapper has extra vertical room so tick marks can extend above and below the 8px track without being clipped (a native background would otherwise be limited to the track height). */ .size-slider-wrap { position: relative; width: 100%; /* Height must be at least the tallest tick mark (24px for default). */ height: 28px; display: flex; align-items: center; } .size-slider-wrap .size-slider { position: relative; z-index: 2; width: 100%; } /* Tick-mark overlay sits behind the slider thumb but in front of the track. */ .size-slider-ticks { position: absolute; inset: 0; pointer-events: none; z-index: 1; } .size-slider-tick { position: absolute; top: 50%; transform: translate(-50%, -50%); width: 2px; height: 16px; background: #d8d8d8; border-radius: 1px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35); } .size-slider-tick.is-end { width: 3px; height: 18px; background: #ffffff; } .size-slider-tick.is-default { width: 4px; height: 24px; background: #4a9eff; border-radius: 2px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55), 0 0 8px rgba(74, 158, 255, 0.7); } .hue-slider { -webkit-appearance: none; appearance: none; width: 120px; height: 8px; border-radius: 5px; background: linear-gradient(to right, red, yellow, lime, aqua, blue, magenta, red); outline: none; opacity: 0.9; transition: opacity .2s; padding: 0; } .hue-slider:hover { opacity: 1; } .hue-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; border-radius: 50%; background: #e0e0e0; /* avoid pure white on iOS invert */ border: 3px solid var(--hue-color, #e0e0e0); cursor: pointer; box-shadow: 0 0 4px rgba(0,0,0,0.4); } .hue-slider::-moz-range-thumb { width: 20px; height: 20px; border-radius: 50%; background: #e0e0e0; border: 3px solid var(--hue-color, #e0e0e0); cursor: pointer; } .toolbar-right { display: flex; align-items: center; gap: 10px; } .color-dropdown-wrapper { position: relative; z-index: 11010; } .color-btn { padding: 8px; } .color-dropdown { display: none; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); background-color: #2a2a2a; border: 1px solid #404040; border-radius: 8px; padding: 10px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); z-index: 11012; margin-top: 8px; } .color-dropdown.show { display: block; } .color-presets { display: flex; gap: 10px; margin-bottom: 10px; } .color-swatch { width: 30px; height: 30px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; transition: all 0.2s ease; } .color-swatch.preset:hover, .color-swatch.preset.selected { border-color: #4a9eff; transform: scale(1.1); } .color-picker-swatch { display: flex; justify-content: center; } .color-swatch.picker { width: 100%; height: 30px; padding: 0; border: none; background: none; } .pen-color-dropdown { position: absolute; top: 115%; /* closer so it doesn't exceed toolbar bounds visually */ left: 50%; transform: translateX(-50%) scaleY(0); transform-origin: top center; background-color: #2a2a2a; border: 1px solid #404040; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); padding: 10px 12px; display: flex; gap: 12px; transition: transform 0.18s cubic-bezier(.4,1.6,.6,1), opacity 0.18s cubic-bezier(.4,1.6,.6,1); opacity: 0; pointer-events: none; min-width: 200px; justify-content: center; z-index: 11012; } .pen-color-option { width: 28px !important; height: 28px !important; border-radius: 50% !important; border: none !important; background: var(--pen-color) !important; box-shadow: none !important; outline: none !important; padding: 0 !important; margin: 0 !important; opacity: 1 !important; filter: none !important; mix-blend-mode: normal !important; } .pen-color-option[style*='#fefefe'], .pen-color-option[style*='#ffff00'] { border: none !important; box-shadow: none !important; } .pen-color-option:focus, .pen-color-option.selected { outline: 2px solid #4a9eff; outline-offset: 2px; } .pen-color-dropdown.show { transform: translateX(-50%) scaleY(1); opacity: 1; pointer-events: auto; } .highlighter-color-dropdown { position: absolute; top: 120%; left: 50%; transform: translateX(-50%) scaleY(0); transform-origin: top center; background-color: #2a2a2a; border: 1px solid #404040; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); padding: 10px 12px; display: flex; gap: 12px; transition: transform 0.18s cubic-bezier(.4,1.6,.6,1), opacity 0.18s cubic-bezier(.4,1.6,.6,1); opacity: 0; pointer-events: none; min-width: 200px; justify-content: center; z-index: 11012; } .highlighter-color-dropdown.show { transform: translateX(-50%) scaleY(1); opacity: 1; pointer-events: auto; } .highlighter-color-option { width: 28px !important; height: 28px !important; border-radius: 50% !important; border: none !important; background: var(--highlighter-color) !important; box-shadow: none !important; outline: none !important; padding: 0 !important; margin: 0 !important; opacity: 1 !important; filter: none !important; mix-blend-mode: normal !important; } .highlighter-color-option:focus, .highlighter-color-option.selected { outline: 2px solid #4a9eff; outline-offset: 2px; } .tool-icon[data-tool="highlight"] { color: var(--highlighter-color, #ffff00) !important; transition: none !important; position: relative; } /* Removed ::before circle for highlighter tool icon */ .tool-icon[data-tool="highlight"].selected, .tool-icon[data-tool="highlight"].selected:hover, .tool-icon[data-tool="highlight"].selected:focus, .tool-icon[data-tool="highlight"].selected:active { background: #333 !important; border: 2px solid var(--highlighter-color, #ffff00) !important; color: var(--highlighter-color, #ffff00) !important; box-shadow: 0 0 0 2px var(--highlighter-color, #ffff00), 0 0 8px rgba(255, 255, 0, 0.5); } .tool-icon[data-tool="highlight"].selected::before { opacity: 0.5; transform: translate(-50%, -50%) scale(1.2); } .tool-icon[data-tool="erase"] { color: #ffb6c1 !important; /* Classic pink eraser */ } .tool-icon[data-tool="erase"].selected, .tool-icon[data-tool="erase"].selected:hover, .tool-icon[data-tool="erase"].selected:focus, .tool-icon[data-tool="erase"].selected:active { background: #333 !important; border: 2px solid #ffb6c1 !important; color: #ffb6c1 !important; box-shadow: 0 0 0 2px #ffb6c1, 0 0 8px rgba(255, 182, 193, 0.5) !important; } /* Select tool styling */ .tool-icon[data-tool="select"] { color: #4a9eff !important; transition: none !important; } .tool-icon[data-tool="select"]:hover, .tool-icon[data-tool="select"]:focus, .tool-icon[data-tool="select"]:active { color: #4a9eff !important; background: none !important; border: none !important; } .tool-icon[data-tool="select"].selected, .tool-icon[data-tool="select"].selected:hover, .tool-icon[data-tool="select"].selected:focus, .tool-icon[data-tool="select"].selected:active { background: #333 !important; border: 2px solid #4a9eff !important; color: #4a9eff !important; box-shadow: 0 0 0 2px #4a9eff, 0 0 8px rgba(74, 158, 255, 0.5) !important; } /* Clickable word styling */ .clickable-word { position: relative; /* No visual styling - words look exactly like normal text */ transition: none; } .clickable-word.has-data { cursor: pointer; } /* Subtle underline only when Select tool is active */ .select-mode-active .clickable-word.has-data { text-decoration: underline; text-decoration-thickness: 0.05em; text-underline-offset: 0.12em; } /* intentionally no hover/active styling to keep text look natural */ /* Touch hold visual feedback for word selection intentionally no-op */ /* Select mode active body styling */ .select-mode-active .bible-text { cursor: default; -webkit-user-select: none !important; -moz-user-select: none !important; -ms-user-select: none !important; user-select: none !important; } .select-mode-active .reading-area { cursor: default; -webkit-user-select: none !important; -moz-user-select: none !important; -ms-user-select: none !important; user-select: none !important; } /* Disable text selection in select mode */ .select-mode-active * { -webkit-user-select: none !important; -moz-user-select: none !important; -ms-user-select: none !important; user-select: none !important; } /* Allow text selection only for clickable words in select mode */ .select-mode-active .clickable-word.has-data { -webkit-user-select: none !important; -moz-user-select: none !important; -ms-user-select: none !important; user-select: none !important; cursor: pointer; } .tool-icon[data-tool="pen"]:hover, .tool-icon[data-tool="pen"]:focus, .tool-icon[data-tool="pen"]:active { color: var(--pen-color, #ffff00) !important; } #undoBtn, #redoBtn, #resetBtn { background: #2a2a2a; color: #e0e0e0; border: 2px solid #404040; transition: all 0.15s ease; position: relative; overflow: hidden; /* For progress indicator */ cursor: pointer; } /* Base hover effects for undo/redo/clear buttons - will be overridden by more specific rules above */ #undoBtn:disabled, #redoBtn:disabled { background: #1a1a1a; color: #666; border-color: #333; cursor: not-allowed; opacity: 0.5; transform: none; box-shadow: none; } #undoBtn:disabled:hover, #redoBtn:disabled:hover { background: #1a1a1a; border-color: #333; transform: none; box-shadow: none; } #undoBtn:active:not(:disabled), #redoBtn:active:not(:disabled), #resetBtn:active:not(:disabled) { background: #444 !important; color: #fff !important; box-shadow: 0 0 8px #222, 0 0 15px rgba(74, 158, 255, 0.4) !important; transform: translateY(0) !important; border-color: #4a9eff !important; } #undoBtn:focus, #redoBtn:focus, #resetBtn:focus { outline: 2px solid #4a9eff; outline-offset: 2px; box-shadow: 0 0 8px rgba(74, 158, 255, 0.3), 0 0 12px rgba(74, 158, 255, 0.2) !important; border-color: #4a9eff !important; } /* Visual feedback for undo/redo button clicks */ #undoBtn.clicked, #redoBtn.clicked { transform: scale(0.95); background-color: #404040; transition: transform 0.1s ease, background-color 0.1s ease; } #undoBtn::after, #redoBtn::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.1) 50%, transparent 70%); transform: translateX(-100%); transition: transform 0.6s ease; pointer-events: none; border-radius: 8px; } /* Removed keyboard shortcut hints under undo/redo buttons */ #penSizeSliderPopup { min-width: 300px !important; } #penSizeSlider { width: 100% !important; min-width: 280px !important; } .verse-bracket { color: #d2b48c !important; font-weight: 600; font-size: 20px; margin-right: 0; } /* Eraser Visual Assistant */ .eraser-visual-aid { position: fixed; pointer-events: none; border: 2px solid #ffb6c1; background: rgba(255, 182, 193, 0.15); border-radius: 50%; z-index: 10002; transition: opacity 0.1s, width 0.1s, height 0.1s; opacity: 0; box-shadow: 0 0 8px #ffb6c144; } .eraser-visual-aid.active { opacity: 1; } /* Word Info Popup */ .word-info-popup { position: absolute; min-width: 640px; max-width: 800px; /* FULLY opaque: at 0.98 the scripture behind still ghosted through large white text on a dark room screen (about 5/255 difference — subtle on a monitor, obvious on a big TV). */ background: #1e1e1e; /* backdrop-filter removed: the card is opaque so the blur was invisible, but it still forced a full re-blur of the screen behind on EVERY scroll frame (measured: 16.7ms -> 33.2ms per frame, 26/40 dropped). */ border: 2px solid #4a9eff; border-radius: 12px; box-shadow: 0 8px 25px rgba(0, 0, 0, 0.6), 0 0 20px rgba(74, 158, 255, 0.3); z-index: 20000; padding: 0; font-family: Georgia, 'Times New Roman', Times, serif; opacity: 0; transform: scale(0.8) translateY(-10px) translateZ(0); /* Force GPU acceleration */ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); cursor: move; user-select: none; /* CSS containment for performance isolation */ contain: layout style paint; /* Prevent overly tall cards on dense definitions */ max-height: 75vh; overflow: hidden; /* Use flexbox layout for proper scrolling */ display: flex; flex-direction: column; /* Optimize rendering - only use will-change when dragging */ transform-style: preserve-3d; } .word-info-popup.show { opacity: 1; transform: scale(1) translateY(0) translateZ(0); /* Reduce backdrop-filter when not dragging for better performance */ /* backdrop-filter removed: the card is opaque so the blur was invisible, but it still forced a full re-blur of the screen behind on EVERY scroll frame (measured: 16.7ms -> 33.2ms per frame, 26/40 dropped). */ } .word-info-popup.dragging { box-shadow: 0 12px 35px rgba(0, 0, 0, 0.8), 0 0 25px rgba(74, 158, 255, 0.5); transform: scale(1.02) translateZ(0); /* Disable transitions during drag for maximum performance */ transition: none !important; transform-origin: center; /* Only apply will-change when actively dragging for better performance */ will-change: transform, left, top; /* Reduce backdrop-filter during drag for better performance */ /* backdrop-filter removed: the card is opaque so the blur was invisible, but it still forced a full re-blur of the screen behind on EVERY scroll frame (measured: 16.7ms -> 33.2ms per frame, 26/40 dropped). */ } .word-info-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; background: linear-gradient(135deg, rgba(74, 158, 255, 0.1), rgba(74, 158, 255, 0.05)); border-bottom: 1px solid rgba(74, 158, 255, 0.3); border-radius: 10px 10px 0 0; cursor: move; flex-shrink: 0; /* Prevent header from shrinking */ } .word-info-title { font-size: 28px; /* enlarged title */ font-weight: 600; color: #4a9eff; margin: 0; word-break: break-word; } .word-info-close { background: none; border: none; color: #e0e0e0; font-size: 20px; cursor: pointer; padding: 5px; border-radius: 4px; transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; } .word-info-close:hover { background: rgba(255, 255, 255, 0.1); color: #ff6b6b; transform: rotate(90deg); } .word-info-content { padding: 20px 20px 40px 20px; /* increased bottom padding to prevent cutoff */ overflow-y: auto; /* allow scrolling inside when content exceeds max-height */ overflow-x: hidden; /* prevent horizontal scrolling */ flex: 1; /* Take remaining space in flex container */ min-height: 0; /* Allow flex item to shrink below content size */ /* Smooth scrolling */ scroll-behavior: smooth; /* Custom scrollbar styling */ scrollbar-width: thin; scrollbar-color: rgba(74, 158, 255, 0.5) rgba(30, 30, 30, 0.5); } .word-info-section { margin-bottom: 18px; } .word-info-section:last-child { margin-bottom: 0; padding-bottom: 12px; /* increased padding to last section to prevent cutoff */ } .word-info-label { font-size: 18px; /* larger section labels */ font-weight: 600; color: #888; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; display: block; } .word-info-value { font-size: 1.25em; /* scale with popup base font-size */ color: #e0e0e0; line-height: 1.4; word-break: break-word; } .word-info-value.hebrew { font-size: 1.35em; /* larger for script legibility */ direction: rtl; text-align: right; font-family: 'SBL Hebrew', 'Times New Roman', serif; } .word-info-value .wlca-hit, .word-info-value .ntgt-hit { text-decoration: underline; text-decoration-color: #4a9eff; text-decoration-thickness: 2px; text-underline-offset: 3px; } .word-info-value.bdbt .bdbt-lexeme { font-size: 1.4em; font-weight: 600; margin-bottom: 10px; /* increased from 8px for better spacing */ } .word-info-value.bdbt .bdbt-meta { font-size: 0.95em; color: #c8c8c8; margin-bottom: 8px; /* increased from 6px for better spacing */ margin-top: 2px; direction: ltr; text-align: left; } .word-info-value.bdbt .bdbt-meta:last-of-type { margin-bottom: 10px; /* extra space before definition */ } .word-info-value.bdbt .bdbt-definition { margin-top: 12px; /* increased from 10px */ margin-bottom: 4px; /* add bottom margin to prevent cutoff */ direction: ltr; text-align: left; line-height: 1.5; /* better line spacing for readability */ } /* Remove hyperlinks from popup content - make them non-clickable */ .word-info-popup a, .word-info-content a, .word-info-value a, .bdbt-definition a { pointer-events: none; cursor: default; text-decoration: none; color: inherit; } .word-info-popup a:hover, .word-info-content a:hover, .word-info-value a:hover, .bdbt-definition a:hover { text-decoration: none; color: inherit; } .word-info-value.bdbt .bdbt-missing, .word-info-value .wlca-missing, .word-info-value .ntgt-missing { color: #888; font-style: italic; } .word-info-value.greek { font-size: 1.3em; font-family: 'SBL Greek', 'Times New Roman', serif; } .word-info-value.frequency { color: #4a9eff; font-weight: 600; } /* Accordance section styling */ .word-info-section.accordance-section { margin-top: 12px; padding-top: 12px; border-top: 1px solid rgba(255, 255, 255, 0.1); } .word-info-value.accordance { font-size: 1.1em; color: #d0d0d0; } .accordance-item { margin-bottom: 10px; padding: 8px 0; line-height: 1.5; } .accordance-item:last-child { margin-bottom: 0; } .accordance-item strong { color: #4a9eff; font-weight: 600; margin-right: 8px; } .accordance-refs, .accordance-commentaries { list-style: none; padding-left: 0; margin-top: 6px; } .accordance-refs li, .accordance-commentaries li { padding: 4px 0; padding-left: 16px; position: relative; color: #b0b0b0; } .accordance-refs li::before, .accordance-commentaries li::before { content: "•"; position: absolute; left: 0; color: #4a9eff; } .word-info-divider { height: 1px; background: linear-gradient(90deg, transparent, rgba(74, 158, 255, 0.3), transparent); margin: 16px 0; } /* Popup animations */ @keyframes popupSlideIn { 0% { opacity: 0; transform: scale(0.8) translateY(-20px); } 100% { opacity: 1; transform: scale(1) translateY(0); } } @keyframes popupSlideOut { 0% { opacity: 1; transform: scale(1) translateY(0); } 100% { opacity: 0; transform: scale(0.8) translateY(-20px); } } @keyframes popupHighlight { 0% { box-shadow: 0 8px 25px rgba(0, 0, 0, 0.6); border-color: transparent; } 50% { box-shadow: 0 12px 35px rgba(74, 158, 255, 0.8), 0 0 25px rgba(74, 158, 255, 0.5); border-color: #4a9eff; transform: scale(1.02); } 100% { box-shadow: 0 8px 25px rgba(0, 0, 0, 0.6); border-color: transparent; transform: scale(1); } } .word-info-popup.highlight-existing { animation: popupHighlight 0.5s ease-in-out; } /* Touch device optimizations for popup */ @media (pointer: coarse) { .word-info-popup { min-width: 280px; max-width: 320px; } .word-info-header { padding: 18px 20px; } .word-info-close { width: 35px; height: 35px; font-size: 22px; } .word-info-content { padding: 18px 18px 40px 18px; /* increased bottom padding on touch devices to prevent cutoff */ } } /* Clear button pulsing animation */ @keyframes clearButtonPulse { 0% { transform: scale(1.05); box-shadow: 0 0 20px rgba(255, 68, 68, 0.6); } 100% { transform: scale(1.08); box-shadow: 0 0 30px rgba(255, 68, 68, 0.8); } } /* Progress indicator styling - enhanced for cross-platform compatibility */ #clearProgressIndicator { position: absolute; top: -2px; left: 0; width: 0%; height: 3px; background: linear-gradient(90deg, #ff4444, #ff6666); border-radius: 3px 3px 0 0; transition: none; /* Controlled by JavaScript for smooth animation */ pointer-events: none; z-index: 10; opacity: 1; /* Enhanced cross-platform support */ backface-visibility: hidden; transform: translateZ(0); will-change: width; /* Touch device optimization */ -webkit-transform: translateZ(0); -webkit-backface-visibility: hidden; /* Classic thin bar styling */ box-shadow: 0 1px 2px rgba(255, 68, 68, 0.6); } /* Hide scrollbars everywhere */ .reading-area, .tab-content, body, html { scrollbar-width: none !important; /* Firefox */ -ms-overflow-style: none !important; /* IE 10+ */ } .reading-area::-webkit-scrollbar, .tab-content::-webkit-scrollbar, body::-webkit-scrollbar, html::-webkit-scrollbar { display: none !important; width: 0 !important; background: transparent !important; } /* Hide scrollbars for all elements */ * { scrollbar-width: none !important; /* Firefox */ -ms-overflow-style: none !important; /* IE 10+ */ } *::-webkit-scrollbar { display: none !important; width: 0 !important; background: transparent !important; } /* Remove white area at bottom: ensure .tab-content and .reading-area fill space */ html, body { background-color: #000000 !important; color-scheme: dark; } /* iPad/Safari: force dark backgrounds on all major containers to prevent white flashes */ #app, .tab-content, .tab-panel, .selector-container, .selection-content, .translation-bar, .card-grid, .content-wrapper { background-color: #000000 !important; } /* iPad/Safari: ensure tiles never invert to white when active */ .selection-card, .verse-card { background-color: #2a2a2a !important; border-color: #404040 !important; } .selection-card:active, .verse-card:active { background-color: #3a3a3a !important; } #app { min-height: 100vh; display: flex; flex-direction: column; } .tab-content { flex: 1; display: flex; flex-direction: column; /* Avoid nested scrolling; selection-content handles scrolling */ overflow: hidden; background: #000000 !important; } .reading-area { flex: 1; position: relative; overflow-y: auto; overflow-x: hidden; background: #000000 !important; /* Constrain height so passages can scroll within viewport */ height: 100vh; max-height: 100vh; /* PORTRAIT MODE FIX: Use dvh for better portrait support on touch devices */ height: 100dvh; max-height: 100dvh; /* Fallback for older browsers */ height: calc(100vh - env(keyboard-inset-height, 0px)); max-height: calc(100vh - env(keyboard-inset-height, 0px)); /* Enforce two-finger scrolling; tools override as needed */ touch-action: none; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; /* PORTRAIT MODE FIX: Ensure proper dimensions in portrait */ min-height: 0; width: 100%; } /* When a drawing tool is active, enable pointer events on the canvas (add a class in JS if needed) */ .annotation-canvas.drawing-enabled { pointer-events: auto; } /* Enhanced hover effects for undo/redo/clear buttons - works on all devices */ #undoBtn:hover:not(:disabled), #redoBtn:hover:not(:disabled), #resetBtn:hover:not(:disabled) { background: #404040 !important; border-color: #4a9eff !important; transform: translateY(-1px) !important; box-shadow: 0 4px 8px rgba(74, 158, 255, 0.3), 0 0 12px rgba(74, 158, 255, 0.2) !important; transition: all 0.15s ease !important; } /* Comprehensive hover effect disabling for touch devices - but preserve button effects */ @media (hover: none) and (pointer: coarse) { /* Disable ALL hover states completely but preserve colors */ *:hover { background: inherit !important; border-color: inherit !important; transform: none !important; box-shadow: inherit !important; opacity: inherit !important; filter: none !important; /* Don't override color - let elements keep their colors */ } /* Specific UI element hover disabling but preserve colors */ .tab:hover, .new-tab-btn:hover, .tool-icon:hover, .load-btn:hover, .chapter-select:hover, .verse-select:hover, .book-select:hover, .translation-select:hover { background: transparent !important; border-color: inherit !important; transform: none !important; box-shadow: none !important; transition: none !important; } } /* Force proper tool states on touch devices using feature detection */ @media (pointer: coarse) { /* Completely override any hover effects for tools */ .tool-icon { transition: none !important; } .tool-icon:hover, .tool-icon:focus, .tool-icon:active { background: transparent !important; /* Don't override color - let each tool keep its specific color */ border: none !important; box-shadow: none !important; transform: none !important; } /* Force pen tool color */ .tool-icon[data-tool="pen"] { color: var(--pen-color, #ffff00) !important; } .tool-icon[data-tool="pen"]:hover, .tool-icon[data-tool="pen"]:focus, .tool-icon[data-tool="pen"]:active { color: var(--pen-color, #ffff00) !important; background: transparent !important; } /* Force highlighter tool color */ .tool-icon[data-tool="highlight"] { color: var(--highlighter-color, #ffff00) !important; } .tool-icon[data-tool="highlight"]:hover, .tool-icon[data-tool="highlight"]:focus, .tool-icon[data-tool="highlight"]:active { color: var(--highlighter-color, #ffff00) !important; background: transparent !important; } /* Force eraser tool color */ .tool-icon[data-tool="erase"] { color: #ffb6c1 !important; } .tool-icon[data-tool="erase"]:hover, .tool-icon[data-tool="erase"]:focus, .tool-icon[data-tool="erase"]:active { color: #ffb6c1 !important; background: transparent !important; } /* Disable tab hover effects completely but preserve text color */ .tab:hover { background: transparent !important; /* Don't override color - let tabs keep their text color */ } /* Disable new tab button hover effects */ .new-tab-btn:hover { background: #232323 !important; color: #4a9eff !important; box-shadow: 0 2px 8px rgba(0,0,0,0.08) !important; } } /* Additional optimizations for detected touch devices */ .touch-device .tab:hover, .touch-device .new-tab-btn:hover, .touch-device .tool-icon:hover, .touch-device .toolbar-btn:hover { background: initial !important; /* Don't reset color - preserve each element's intended color */ border-color: initial !important; transform: none !important; box-shadow: initial !important; transition: none !important; } /* GLOBAL: Disable native text selection and touch callouts everywhere */ html, body, *, *::before, *::after { -webkit-user-select: none !important; -moz-user-select: none !important; -ms-user-select: none !important; user-select: none !important; -webkit-touch-callout: none !important; } /* Ensure tab text stays light gray on touch devices */ .touch-device .tab .tab-title, .tab .tab-title { color: #e0e0e0 !important; } /* Ensure proper tool states on touch devices */ .touch-device .tool-icon.selected { background: #333 !important; color: #4a9eff !important; } .touch-device .tool-icon[data-tool="pen"].selected { background: #333 !important; color: var(--pen-color, #ffff00) !important; } .touch-device .tool-icon[data-tool="highlight"].selected { background: #333 !important; border: 2px solid var(--highlighter-color, #ffff00) !important; color: var(--highlighter-color, #ffff00) !important; box-shadow: 0 0 0 2px var(--highlighter-color, #ffff00), 0 0 8px rgba(255, 255, 0, 0.5); } .touch-device .tool-icon[data-tool="erase"].selected { background: #333 !important; border: 2px solid #ffb6c1 !important; color: #ffb6c1 !important; box-shadow: 0 0 0 2px #ffb6c1, 0 0 8px rgba(255, 182, 193, 0.5) !important; } /* Touch-specific optimizations */ @media (pointer: coarse) { /* Make touch targets larger for better usability */ .tab { min-height: 44px; touch-action: manipulation; } .new-tab-btn { min-width: 44px; min-height: 44px; touch-action: manipulation; } .tool-icon { min-width: 44px; min-height: 44px; touch-action: manipulation; } /* Prevent text selection on touch devices for UI elements */ .tab, .new-tab-btn, .tool-icon, .toolbar-btn { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-touch-callout: none; } } /* Card-Based Selector Styles */ .selector-container { padding: 0; background: transparent; border: none; margin: 0; /* Make selector fill available space and allow inner content to scroll */ display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; height: 100%; } .translation-bar { display: flex; align-items: center; padding: 0 25px; /* match chapter header vertical size */ height: var(--header-band-height) !important; min-height: var(--header-band-height) !important; background: rgba(35, 35, 35, 0.95); backdrop-filter: blur(10px); border-bottom: none; /* replaced by full-width separator */ position: sticky; top: var(--safe-area-top); z-index: 5; touch-action: none; /* enforce two-finger scroll */ } .translation-bar::after { content: ''; position: absolute; left: calc(var(--safe-area-left) * -1); right: calc(var(--safe-area-right) * -1); bottom: 0; height: 1px; background: #404040; pointer-events: none; } .back-button-area { position: absolute; left: 25px; display: flex; align-items: center; } /* Back button shown over passage to return to selector */ .header-back-btn[data-action="back-to-selector"] { position: absolute; top: 50%; left: 12px; transform: translateY(-50%); z-index: 10; background: #2a2a2a; color: #e0e0e0; border: 2px solid #404040; /* match other buttons */ border-radius: 8px; padding: 8px 16px; /* standard size */ cursor: pointer; } .header-back-btn[data-action="back-to-selector"] i { margin: 0; } .translation-label { display: none; } .translation-options { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; width: 100%; } /* OT/NT filter buttons container sits to the left of translation buttons */ .translation-bar .canon-filter { display: inline-flex; gap: 8px; margin-right: 10px; } .translation-btn { padding: 8px 16px; border: 2px solid #404040; border-radius: 8px; background: #2a2a2a; color: #e0e0e0; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; min-width: 50px; text-align: center; } /* Ensure back button in translation bar matches translation buttons */ /* remove special sizing override for back button inside translation bar */ .translation-btn:hover { border-color: #4a9eff; box-shadow: 0 2px 8px rgba(74, 158, 255, 0.3); } .translation-btn.selected { background: #4a9eff; border-color: #4a9eff; color: #ffffff; box-shadow: 0 2px 8px rgba(74, 158, 255, 0.4); } .translation-empty { width: 100%; padding: 10px 14px; border: 1px dashed #555; border-radius: 8px; color: #bbb; background: rgba(42, 42, 42, 0.7); text-align: center; font-size: 13px; } .translation-dropdown-empty { min-width: 220px; padding: 10px 12px; color: #bbb; font-size: 13px; line-height: 1.35; text-align: center; } /* Mobile Responsive Styles */ @media (max-width: 768px) { .translation-bar { padding: 15px 20px; } .back-button-area { position: static; margin-bottom: 10px; } .translation-options { justify-content: center; } .translation-btn { flex: 0 1 auto; min-width: 60px; } .selection-content { padding: 20px 15px; } .stage-title { font-size: 20px; margin-bottom: 15px; } .card-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; } #verseCards { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; } .selection-card { padding: 20px; } .card-title { font-size: 16px; } .verse-card { min-height: 45px; } .verse-number { font-size: 14px; } .load-passage-btn { padding: 12px 24px; font-size: 14px; } } /* Touch Device Enhancements */ @media (pointer: coarse) { .selection-card, .verse-card, .translation-btn, .breadcrumb-btn, .load-passage-btn { min-height: 48px; } .verse-card { min-height: 52px; } .selection-card:hover { transform: none; } .load-passage-btn:hover { transform: none; } } /* Header Back Button Styles */ .header-back-btn { display: flex; align-items: center; gap: 8px; padding: 8px 16px; /* match translation button sizing */ background: #2a2a2a; border: 2px solid #404040; border-radius: 8px; color: #e0e0e0; cursor: pointer; transition: all 0.2s ease; font-size: 14px; font-weight: 500; } .chapter-left-controls { white-space: nowrap; /* keep back + up/down on a single line */ } /* Slimmer Up/Down chapter nav buttons that visually match the back button */ .header-nav-btn { padding: 6px 10px; /* slimmer than the back button */ min-width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; /* match back button radius */ } /* In chapter header, make +5/-5 buttons match back/top/bottom size */ .chapter-header .header-nav-btn { padding: 8px 16px !important; height: auto !important; min-width: 42px !important; font-size: 14px !important; line-height: 1 !important; } /* Remove persistent highlight/focus/active styling on header buttons (touch holds) */ .chapter-header .header-back-btn, .chapter-header .header-top-btn, .chapter-header .header-down-btn, .chapter-header .header-nav-btn { outline: none !important; box-shadow: none !important; } .chapter-header .header-back-btn:hover, .chapter-header .header-back-btn:active, .chapter-header .header-back-btn:focus, .chapter-header .header-top-btn:hover, .chapter-header .header-top-btn:active, .chapter-header .header-top-btn:focus, .chapter-header .header-down-btn:hover, .chapter-header .header-down-btn:active, .chapter-header .header-down-btn:focus, .chapter-header .header-nav-btn:hover, .chapter-header .header-nav-btn:active, .chapter-header .header-nav-btn:focus { background: #2a2a2a !important; border-color: #404040 !important; transform: none !important; box-shadow: none !important; } .header-nav-btn i { font-size: 14px; /* smaller icon for sleeker look */ line-height: 1; } /* Removed 3-finger gesture feedback styles per user request */ /* Ensure cluster spacing is tight and stable on TVs */ .chapter-left-controls .chapter-nav-btns { gap: 6px; } .header-back-btn:hover { border-color: #4a9eff; box-shadow: 0 2px 8px rgba(74, 158, 255, 0.3); } .header-back-btn i { font-size: 14px; /* match translation button text size */ } .selection-content { padding: 25px; background: #000000 !important; /* force black for Notes; bible selectors are overridden below if needed */ /* Fill remaining space to bottom of viewport like passages */ flex: 1 1 auto; min-height: 0; max-height: none; /* let inner grids control scroll so headroom works */ overflow-y: auto; -webkit-overflow-scrolling: touch; /* Allow natural one-finger vertical scroll in selectors */ touch-action: pan-y; padding-bottom: 16px; } [id^="pointsCards"], .selector-container, .card-grid { background: transparent !important; } /* Provide even more scroll affordance for book and chapter grids in portrait */ /* Removed grid ::after spacer that caused bottom-row tiles to stretch */ .selection-stage { transition: all 0.3s ease; } .selection-stage.hidden { display: none; } /* When a stage is visible, ensure its grid overflows and scrolls */ .selection-stage:not(.hidden) .card-grid, .selection-stage:not(.hidden) [id^="bookCards"], .selection-stage:not(.hidden) [id^="chapterCards"], .selection-stage:not(.hidden) [id^="verseCards"] { overflow-y: auto; max-height: none; } .stage-title { font-size: 24px; font-weight: 600; color: #e0e0e0; margin-bottom: 20px; text-align: center; } .stage-breadcrumb { margin-bottom: 20px; display: flex; justify-content: center; } .breadcrumb-btn { display: flex; align-items: center; gap: 8px; padding: 10px 16px; background: #2a2a2a; border: 2px solid #404040; border-radius: 8px; color: #e0e0e0; cursor: pointer; transition: all 0.2s ease; font-size: 14px; font-weight: 500; } .breadcrumb-btn:hover { border-color: #4a9eff; box-shadow: 0 2px 8px rgba(74, 158, 255, 0.3); } .card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 23px; margin-bottom: 29px; align-content: start; /* prevent rows from stretching vertically */ } /* Force exactly four columns across for book selection grid */ [id^="bookCards"] { grid-template-columns: repeat(4, 1fr); } /* Force exactly four columns for chapters and verses to match books */ [id^="chapterCards"], [id^="verseCards"] { grid-template-columns: repeat(4, 1fr); } /* FINAL OVERRIDE: ensure verse grid always renders 4 columns regardless of earlier rules */ [id^="verseCards"] { grid-template-columns: repeat(4, 1fr) !important; } /* Ensure chapter and verse tiles exactly match book tile sizing */ [id^="chapterCards"] .selection-card, [id^="verseCards"] .selection-card { height: 114px; padding: 29px; } [id^="chapterCards"] .card-title, [id^="verseCards"] .card-title { font-size: 26px; } [id^="verseCards"] { grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 23px; /* Allow one-finger vertical scroll */ touch-action: pan-y; overflow-y: auto; max-height: none; padding-bottom: 16px; } /* Also disable native pan on book and chapter grids to enforce two-finger */ /* Allow container to be the stable scroll target for two-finger gestures */ .selection-content { touch-action: none !important; /* Ensure it can actually scroll as a viewport-sized container */ max-height: calc(100vh - 0px) !important; overflow-y: auto !important; } [id^="bookCards"], [id^="chapterCards"], [id^="verseCards"] { /* Keep two-finger preference but let JS decide the scroll target */ touch-action: none; overflow-y: auto; max-height: none; /* Small base padding only; no large spacer rows */ padding-bottom: 16px; -webkit-overflow-scrolling: touch; align-content: start; } /* Spacer row that doesn't stretch last tiles: forces its own grid row */ [id^="bookCards"]::after, [id^="chapterCards"]::after, [id^="verseCards"]::after { /* Remove spacer that created a large black area at the bottom */ content: ''; display: none !important; height: 0 !important; grid-column: 1 / -1; pointer-events: none; } /* Portrait fix: ensure book grid fully scrolls and is easy to pan vertically */ /* No special portrait override needed now; JS computes exact height */ /* Ensure all selector grids inside selection-content are scrollable with two-finger JS */ .selection-content .card-grid { overflow-y: auto; max-height: none; touch-action: pan-y; /* Small bottom padding for reach; passages style */ padding-bottom: 16px; } .selection-card { background: #2a2a2a; border: 2px solid #404040; border-radius: 12px; padding: 29px; cursor: pointer; transition: all 0.2s ease; position: relative; overflow: hidden; user-select: none; height: 114px; /* uniform tile height (halfway between 84 and 144) */ box-sizing: border-box; } .selection-card:hover { border-color: #4a9eff; box-shadow: 0 4px 12px rgba(74, 158, 255, 0.3); } .selection-card.selected { background: #4a9eff; border-color: #4a9eff; color: #ffffff; box-shadow: 0 4px 12px rgba(74, 158, 255, 0.4); } .selection-card.range-start, .selection-card.range-end { background: #4a9eff; border-color: #4a9eff; color: #ffffff; box-shadow: 0 4px 12px rgba(74, 158, 255, 0.4); } .card-content { display: flex; flex-direction: column; gap: 8px; justify-content: center; align-items: center; height: 100%; } .card-title { font-size: 26px; /* bumped up for better readability */ font-weight: 500; color: inherit; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .card-info { font-size: 13px; color: #888; font-weight: 400; } /* Keep verse selection tiles visually consistent with chapter/book tiles */ .verse-card { background: #2a2a2a; border: 2px solid #404040; border-radius: 12px; padding: 29px; cursor: pointer; transition: all 0.2s ease; position: relative; display: flex; align-items: center; justify-content: center; height: 114px; /* match selection-card */ user-select: none; } .verse-card:hover { border-color: #4a9eff; box-shadow: 0 2px 8px rgba(74, 158, 255, 0.3); } .verse-card.selected { background: #4a9eff; border-color: #4a9eff; color: #ffffff; } .verse-card.range-start { background: linear-gradient(135deg, #4a9eff, #357abd); border-color: #4a9eff; color: #ffffff; } .verse-card.range-end { background: linear-gradient(135deg, #357abd, #4a9eff); border-color: #4a9eff; color: #ffffff; } .verse-number { font-size: 16px; font-weight: 600; color: inherit; } .verse-selection-info { text-align: center; color: #888; font-size: 14px; margin-bottom: 20px; font-style: italic; } .load-button-container { display: flex; justify-content: center; margin-top: 30px; } .load-passage-btn { display: flex; align-items: center; gap: 10px; padding: 15px 30px; background: linear-gradient(135deg, #28a745, #20c997); border: none; border-radius: 12px; color: #ffffff; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 4px 12px rgba(40, 167, 69, 0.3); } .load-passage-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(40, 167, 69, 0.4); } .load-passage-btn:active { transform: translateY(0); box-shadow: 0 2px 8px rgba(40, 167, 69, 0.3); } /* Animation for stage transitions */ @keyframes slideIn { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } } .selection-stage:not(.hidden) { animation: slideIn 0.3s ease; } /* Hide old selector styles when not needed */ .passage-selector, .selector-row { display: none; } /* Smooth fade-in for passage display */ @keyframes smoothFadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } } .smooth-fade-in { animation: smoothFadeIn 220ms ease-out both; } /* Slides: fade-in for first page to match Bible tab */ .slides-first-fade-in { animation: smoothFadeIn 220ms ease-out both; } /* Splash Screen Overlay */ .splash-overlay { position: fixed; inset: 0; z-index: 30000; background: #000; display: flex; align-items: center; justify-content: center; opacity: 1; visibility: visible; transition: opacity 300ms ease, visibility 300ms ease; } .splash-overlay.hidden { opacity: 0; visibility: hidden; pointer-events: none; } .splash-overlay img.splash-image { max-width: 100vw; max-height: 100vh; width: 100%; height: 100%; object-fit: contain; user-select: none; -webkit-user-drag: none; pointer-events: none; } /* Pure Black Background Overrides: ensure all grey backgrounds are #000000 */ html, body { background: #000000 !important; background-color: #000000 !important; } #app, .tab-content, .tab-panel, .reading-area, .bible-text, .chapter-header, .selector-container, .selection-content, .translation-bar, .dropdown-content, .dropdown-btn, .toolbar-btn, .tool-rail, .tool-rail .tool-icon, .color-dropdown, .pen-color-dropdown, .highlighter-color-dropdown, .media-workspace, .media-thumbnails-section, .media-canvas, .media-card .card-thumbnail, .drive-section, .drive-viewer, .media-notes, .help-section, .chapter-select, .verse-select, .book-select, .translation-select, [id^="bookCards"], [id^="chapterCards"], [id^="verseCards"] { background: #000000 !important; background-color: #000000 !important; } /* Notes tab: force the selector area behind point buttons to pure black */ [id^="mediaSelectorContainer"], [id^="mediaSelectionContent"], [id^="pointsStage"] { background: #000000 !important; background-color: #000000 !important; } /* Ensure the tab-panel and tab-content also render pure black behind any overflow */ .tab-panel, .tab-content { background: #000000 !important; } /* Media tab: centered graphic viewer */ .media-tab-body { padding: 16px; } .media-tab-stage { width: 100%; display: flex; justify-content: center; } .media-tab-image { max-width: 1200px; width: 100%; height: auto; border-radius: 10px; box-shadow: 0 14px 32px rgba(0, 0, 0, 0.45); background: #111111; } .media-tab-placeholder { color: #d8d8d8; text-align: center; padding: 18px; } /* Safe area removal overrides: Windows touchscreen TV full-bleed */ :root { --safe-area-top: 0px !important; --safe-area-left: 0px !important; --safe-area-right: 0px !important; } /* Remove all side paddings controlled by safe areas */ #app { padding-left: 0 !important; padding-right: 0 !important; } /* Remove any top spacer */ #app::before { content: '' !important; display: none !important; height: 0 !important; } /* Ensure sticky headers anchor to the very top */ .chapter-header, .translation-bar { top: 0 !important; } /* FINAL: Lock root scrolling and rely on internal containers for scroll */ html, body { overflow: hidden !important; overscroll-behavior: none !important; } #app { height: 100vh !important; max-height: 100vh !important; } .reading-area { height: auto !important; max-height: none !important; flex: 1 1 auto !important; } /* Menu tool icon styling - matches other tool icons */ .tool-icon[data-tool="menu"] { color: #e0e0e0 !important; } .tool-icon[data-tool="menu"]:hover, .tool-icon[data-tool="menu"]:focus, .tool-icon[data-tool="menu"]:active { color: #4a9eff !important; background: #333 !important; } .tool-icon[data-tool="menu"].selected, .tool-icon[data-tool="menu"].selected:hover, .tool-icon[data-tool="menu"].selected:focus, .tool-icon[data-tool="menu"].selected:active { background: #333 !important; border: 2px solid #4a9eff !important; color: #4a9eff !important; box-shadow: 0 0 0 2px #4a9eff, 0 0 8px rgba(74, 158, 255, 0.5) !important; } /* Touch Menu Overlay */ .touch-menu-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.85); z-index: 20000; display: flex; align-items: flex-start; /* sit near the top... */ justify-content: center; padding-top: 12vh; /* ...but not at the very top — near standing line of sight */ opacity: 1; visibility: visible; transition: opacity 0.3s ease, visibility 0.3s ease; -webkit-tap-highlight-color: transparent; } .touch-menu-overlay.hidden { opacity: 0; visibility: hidden; pointer-events: none; } .touch-menu-content { background: rgba(26, 26, 26, 0.95); border: 2px solid #404040; border-radius: 16px; padding: 24px; padding-top: 50px; /* Extra top padding to prevent overlap with close button */ min-width: 320px; max-width: 90vw; position: relative; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6); backdrop-filter: blur(4px); } .touch-menu-close { position: absolute; top: 12px; right: 12px; width: 36px; height: 36px; border-radius: 50%; background: transparent; border: 2px solid #404040; color: #e0e0e0; font-size: 16px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; -webkit-tap-highlight-color: transparent; touch-action: manipulation; z-index: 10; } .touch-menu-close:hover { background: #2a2a2a; border-color: #4a9eff; color: #4a9eff; } .touch-menu-close:active { transform: scale(0.9); } .touch-menu-items { display: flex; flex-direction: column; gap: 12px; margin-top: 0; } .touch-menu-item { display: flex; align-items: center; gap: 16px; padding: 16px 20px; background: #2a2a2a; border: 2px solid #404040; border-radius: 12px; color: #e0e0e0; font-size: 18px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; text-align: left; width: 100%; -webkit-tap-highlight-color: transparent; touch-action: manipulation; } .touch-menu-item i { font-size: 20px; width: 28px; text-align: center; flex-shrink: 0; } .touch-menu-item span { flex: 1; } .touch-menu-item:hover { background: #333333; border-color: #4a9eff; color: #ffffff; transform: translateX(2px); box-shadow: 0 2px 8px rgba(74, 158, 255, 0.2); } .touch-menu-item:active { transform: translateX(1px) scale(0.98); background: #2a2a2a; } /* Ensure menu overlay is above splash overlay */ .splash-overlay { z-index: 30000; } .touch-menu-overlay { z-index: 40000; } /* ===================================================================== * ASK TAB — voice-driven AI assistant * Uses the Paladins display font sized to match Bible text so it stays * readable from a distance and on broadcast camera in live production. * ===================================================================== */ .ask-reading-area { color: #e6e8ee; -webkit-user-select: text; user-select: text; font-family: 'Ethnocentric', Georgia, 'Times New Roman', Times, serif; } .ask-reading-area, .ask-reading-area * { font-family: 'Ethnocentric', Georgia, 'Times New Roman', Times, serif; } .ask-shell { max-width: 1200px; margin: 0 auto; padding: 22px 30px 80px; display: flex; flex-direction: column; gap: 22px; min-height: 100vh; position: relative; } /* Tiny floating corner with just the status dot + clear button. * Replaces the old labeled status pill so the page stays uncluttered. */ .ask-corner { position: absolute; top: 14px; left: 14px; display: flex; align-items: center; gap: 8px; z-index: 5; } .ask-status-dot { width: 9px; height: 9px; border-radius: 50%; background: #555a64; transition: background 0.25s ease, box-shadow 0.25s ease; cursor: help; } .ask-status-dot.online { background: #34d399; box-shadow: 0 0 0 4px rgba(52, 211, 153, 0.14); } .ask-status-dot.thinking { background: #4a9eff; animation: askPulse 1.1s ease-in-out infinite; } @keyframes askPulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(74, 158, 255, 0.45); } 50% { box-shadow: 0 0 0 7px rgba(74, 158, 255, 0); } } /* Ask-tab model warm-up progress bar (shows only while loading; hidden once ready) */ .ask-loading-bar { width: 100%; height: 3px; background: rgba(255, 255, 255, 0.06); overflow: hidden; } .ask-loading-fill { height: 100%; width: 3%; background: linear-gradient(90deg, #0090ff, #4a9eff); border-radius: 0 2px 2px 0; transition: width 0.3s ease; } /* ---- Presentation tools: laser pointer / spotlight ---- */ /* Capture layer sits above content + annotation canvas (~6001) but BELOW the toolbar (11000) and tool rail (11005), so the operator can always tap another tool to exit. */ .pt-overlay { position: fixed; inset: 0; z-index: 10500; pointer-events: auto; touch-action: none; display: none; } .pt-overlay.pt-laser { background: transparent; } /* Spotlight = a full-width horizontal band (~2 lines tall) that follows the touch Y and dims above/below, so a specific line/verse reads clearly for the audience and cameras. */ /* --pt-half = half the clear band's height, --pt-edge = that plus the soft feather. JS rewrites both during a two-finger pinch; the fallbacks below are the original fixed sizes, so the look is identical if JS never touches them. */ .pt-overlay.pt-spotlight { background: linear-gradient(to bottom, rgba(0, 0, 0, 0.88) 0, rgba(0, 0, 0, 0.88) calc(var(--pt-cy, 50%) - var(--pt-edge, 130px)), rgba(0, 0, 0, 0) calc(var(--pt-cy, 50%) - var(--pt-half, 110px)), rgba(0, 0, 0, 0) calc(var(--pt-cy, 50%) + var(--pt-half, 110px)), rgba(0, 0, 0, 0.88) calc(var(--pt-cy, 50%) + var(--pt-edge, 130px)), rgba(0, 0, 0, 0.88) 100%); } /* Spotlight armed but not yet touched: dim the whole screen, no bright band until a finger lands. */ .pt-overlay.pt-spotlight.pt-armed { background: rgba(0, 0, 0, 0.88); } /* Laser trail canvas — full-screen, non-interactive (overlay div above it captures the pointer) */ .pt-laser-canvas { position: absolute; inset: 0; pointer-events: none; } /* Tappable scripture references inside AI answers — open a new Bible tab at that verse */ .ask-ref { color: #6db1ff; text-decoration: underline; text-decoration-color: rgba(109, 177, 255, 0.5); text-underline-offset: 3px; cursor: pointer; border-radius: 4px; padding: 0 2px; } .ask-ref:active { background: rgba(109, 177, 255, 0.18); } /* ===== Verse-exact original word card (STEP interlinear) inside word popups ===== TEACHING TOOL sizing: the congregation reads this on the stage TV, so every element scales from the Bible reading size (default 60px) — card text sits slightly below it. */ .il-section .word-info-value { line-height: 1.35; } /* Header: original word + the English word it renders, side by side, CENTERED on the card. */ .il-head { display: flex; align-items: baseline; justify-content: center; flex-wrap: wrap; gap: 0.45em; margin: 2px 0 0; text-align: center; } .il-word { font-size: calc(var(--bible-font-size, 60px) * 1.05); line-height: 1.2; color: #ffd97a; /* warm gold — reads clearly on camera */ } .il-eng { font-size: calc(var(--bible-font-size, 60px) * 0.62); color: #ffffff; font-weight: 600; } .il-eng::before { content: "= "; color: #7a8794; font-weight: 400; } .il-translit { text-align: center; /* sits directly under the centered word pair */ font-style: italic; color: #9fb6c9; font-size: calc(var(--bible-font-size, 60px) * 0.45); margin-bottom: 10px; } .il-row { margin: 8px 0; font-size: calc(var(--bible-font-size, 60px) * 0.75); color: #d9d9d9; } .il-key { color: #7fa7d9; font-weight: 600; margin-right: 6px; } .il-gloss { color: #eaeaea; font-weight: 600; } .il-lemma { font-size: calc(var(--bible-font-size, 60px) * 0.8); } .il-def { color: #f2f2f2; background: rgba(127, 167, 217, 0.08); border-left: 4px solid #7fa7d9; padding: 10px 14px; margin: 10px 0; border-radius: 6px; } .il-origin { color: #f2e6c8; background: rgba(255, 217, 122, 0.07); border-left: 4px solid #d9b96a; padding: 10px 14px; margin: 10px 0; border-radius: 6px; } .il-usage { color: #d9ead9; background: rgba(140, 200, 140, 0.07); border-left: 4px solid #8cc88c; padding: 10px 14px; margin: 10px 0; border-radius: 6px; } .il-code { font-family: Consolas, monospace; font-size: calc(var(--bible-font-size, 60px) * 0.4); color: #9a9a9a; } .il-note { font-size: calc(var(--bible-font-size, 60px) * 0.3); color: #8a8a8a; margin-top: 4px; } /* Popups carrying the card grow to teaching size; the title matches ("Greek — John 3:16"). Beats the base rule AND the coarse-pointer 320px cap (higher specificity + later in file). */ .word-info-popup:has(.il-section) { width: min(92vw, 980px); max-width: 92vw; min-width: min(92vw, 640px); } .word-info-popup:has(.il-section) .word-info-title { font-size: calc(var(--bible-font-size, 60px) * 0.5); } /* Active state for the presentation tool-rail buttons (subtle bg tint; keeps the laser's own colour) */ .tool-icon.pt-active { background: rgba(255, 90, 60, 0.18) !important; border-radius: 6px; /* Ring it the way a selected drawing tool is ringed, in the button's own colour, so exactly one button in the rail is outlined at any time. Without this, arming the laser left NOTHING ringed and read as "the tool outline disappeared". box-shadow only — a border would shift the layout. */ box-shadow: 0 0 0 2px currentColor, 0 0 8px currentColor !important; } /* Laser icon default colour (yellow); JS sets the live colour inline as the swatch changes */ .tool-icon[data-tool="laser"] { color: #ffff00 !important; } /* Laser colour picker — mirrors the pen/highlighter dropdown */ .laser-color-dropdown { position: absolute; top: 115%; left: 50%; transform: translateX(-50%) scaleY(0); transform-origin: top center; background-color: #2a2a2a; border: 1px solid #404040; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); padding: 10px 12px; display: flex; gap: 12px; transition: transform 0.18s cubic-bezier(.4, 1.6, .6, 1), opacity 0.18s cubic-bezier(.4, 1.6, .6, 1); opacity: 0; pointer-events: none; min-width: 200px; justify-content: center; z-index: 11012; } .laser-color-dropdown.show { transform: translateX(-50%) scaleY(1); opacity: 1; pointer-events: auto; } .laser-color-option { width: 28px !important; height: 28px !important; border-radius: 50% !important; border: none !important; box-shadow: none !important; outline: none !important; padding: 0 !important; margin: 0 !important; cursor: pointer; } .laser-color-option:focus, .laser-color-option.selected { outline: 2px solid #4a9eff; outline-offset: 2px; } /* ---- Optional draggable quick-tool dock (Settings > Presentation) ---- */ .quick-dock { position: fixed; left: 12px; top: 34vh; z-index: 11020; /* above content, overlays and toolbar so it's always tappable wherever placed */ display: flex; flex-direction: column; align-items: center; gap: 6px; background: rgba(28, 28, 30, 0.72); border: 1px solid rgba(255, 255, 255, 0.12); border-radius: 14px; padding: 6px 6px 8px; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); opacity: 0.4; /* auto-dims; brightens only while you're using it */ /* * An explicit width so opening a colour picker can EASE the dock wider instead of snapping: a width * of 'auto' cannot be transitioned. 58px = one 46px button plus the 6px padding either side; the * wide value below fits the swatch row. overflow:hidden keeps the swatches inside the panel while it * is still growing. */ width: 58px; overflow: hidden; transition: opacity 0.2s ease, width 0.18s ease; touch-action: none; user-select: none; -webkit-user-select: none; } .quick-dock.qd-bright, .quick-dock.dragging { opacity: 1; } .qd-grip { color: #7a7a7a; cursor: grab; font-size: 13px; /* icon stays small */ line-height: 1; width: 100%; /* whole top of the dock is the drag handle */ min-height: 36px; /* large touch target so it grabs on the first touch */ display: flex; align-items: center; justify-content: center; touch-action: none; } .quick-dock.dragging .qd-grip { cursor: grabbing; } .qd-btn { width: 46px; height: 46px; border: none; border-radius: 10px; background: transparent; color: #e6e6e6; font-size: 20px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.12s ease; } .qd-btn:active { background: rgba(255, 255, 255, 0.10); } /* Active tool: coloured ring + glow using the icon's own colour (matches the top rail's selected look) */ .qd-btn.active { background: rgba(255, 255, 255, 0.10); box-shadow: 0 0 0 2px currentColor, 0 0 8px currentColor; } /* Static fallback colours; JS then mirrors the live top-toolbar colours exactly */ .qd-btn[data-qd="pen"] { color: var(--pen-color, #ffff00); } .qd-btn[data-qd="highlight"] { color: #ffff00; } .qd-btn[data-qd="erase"] { color: #ffb6c1; } .qd-btn[data-qd="laser"] { color: #ffff00; } .qd-btn[data-qd="clear"] { position: relative; overflow: visible; color: #e6e6e6; } /* Clear button hold feedback — mirrors the top trash button (red progress bar, blue-glow, red flash) */ .qd-clear-progress { position: absolute; top: -2px; left: 0; height: 3px; width: 0%; background: #ff0000; border-radius: 3px 3px 0 0; box-shadow: 0 0 8px rgba(255, 0, 0, 0.6); pointer-events: none; } .qd-btn.qd-holding { box-shadow: 0 0 0 2px #4a9eff, 0 0 12px rgba(74, 158, 255, 0.6); color: #fff !important; } .qd-btn.qd-flash { animation: qdFlash 0.16s ease; } @keyframes qdFlash { 0% { background: #ff4444; color: #fff; box-shadow: 0 0 15px rgba(255, 68, 68, 0.85); } 100% { background: transparent; } } /* ---- Red letter (words of Christ) — words are marked .red-letter during render; they only turn red when the feature is enabled (body.red-letter-on), so toggling is instant with no re-render. ---- */ body.red-letter-on .bible-text .clickable-word.red-letter { color: #ff5252 !important; } .qd-colors { display: none; flex-flow: row wrap; gap: 6px; justify-content: center; max-width: 116px; padding-top: 6px; margin-top: 2px; border-top: 1px solid rgba(255, 255, 255, 0.10); } .qd-colors.show { display: flex; opacity: 1; } /* Swatches fade in just behind the widening panel, so nothing appears outside it mid-animation. */ .qd-colors { opacity: 0; transition: opacity 0.14s ease 0.05s; } .quick-dock.qd-wide { width: 128px; } .qd-color { width: 22px; height: 22px; border-radius: 50%; border: none; cursor: pointer; padding: 0; } /* When floating, hide the top tool-rail handle + rail so tools aren't in two places */ body.qd-on #toolIndicator, body.qd-on #toolRailEdge, body.qd-on #toolRail { display: none !important; } /* Hint shown while dragging the dock into the top zone (release to re-dock) */ .quick-dock.qd-will-dock { outline: 2px dashed rgba(120, 180, 255, 0.8); outline-offset: 3px; } /* Grip inside the opened tool rail (first item, left of the pen) — drag to float the toolbar */ .qd-rail-grip { display: flex; align-items: center; justify-content: center; color: #8a8a8a; cursor: grab; font-size: 18px; padding: 4px 8px; touch-action: none; user-select: none; -webkit-user-select: none; } .qd-rail-grip:active { cursor: grabbing; color: #cfd3da; } .ask-clear-btn { width: 28px; height: 28px; border: none; border-radius: 50%; background: transparent; color: #6e7585; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0; transition: background 0.18s ease, color 0.18s ease; -webkit-tap-highlight-color: transparent; } .ask-clear-btn:hover { background: rgba(255, 255, 255, 0.06); color: #e6e8ee; } .ask-mic-area { display: flex; flex-direction: column; align-items: center; gap: 18px; padding: 60px 0 4px; } .ask-mic-btn { position: relative; width: 132px; height: 132px; border-radius: 50%; border: none; background: linear-gradient(180deg, #1f2630 0%, #14181f 100%); color: #4a9eff; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 0 1px rgba(74, 158, 255, 0.18), 0 18px 38px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.04); transition: transform 0.18s ease, color 0.18s ease, box-shadow 0.25s ease; -webkit-tap-highlight-color: transparent; } .ask-mic-btn:hover { transform: translateY(-1px); color: #6db3ff; } .ask-mic-btn:active { transform: translateY(0) scale(0.97); } .ask-mic-btn.listening { color: #ff5b6e; box-shadow: 0 0 0 2px rgba(255, 91, 110, 0.45), 0 18px 38px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.05); } .ask-mic-glyph { position: relative; z-index: 2; } .ask-mic-ring { position: absolute; inset: -8px; border-radius: 50%; border: 2px solid rgba(74, 158, 255, 0.2); pointer-events: none; opacity: 0; transition: opacity 0.2s ease; } .ask-mic-btn.listening .ask-mic-ring { opacity: 1; animation: askRing 1.4s ease-out infinite; border-color: rgba(255, 91, 110, 0.55); } .ask-mic-btn.listening .ask-mic-ring.ring-2 { animation-delay: 0.7s; border-color: rgba(255, 91, 110, 0.32); } @keyframes askRing { 0% { transform: scale(0.92); opacity: 0.7; } 80% { transform: scale(1.35); opacity: 0; } 100% { transform: scale(1.45); opacity: 0; } } .ask-transcript { color: #e6e8ee; font-size: 30px; text-align: center; max-width: 100%; line-height: 1.45; font-weight: 400; letter-spacing: 0.01em; } /* Only show the transcript / answer / panel once they have actual content. */ .ask-transcript:empty { display: none; } .ask-answer-area { background: rgba(255, 255, 255, 0.03); border: 1px solid rgba(255, 255, 255, 0.07); border-radius: 14px; padding: 18px 22px; transition: border-color 0.25s ease; } .ask-answer-area:has(.ask-answer-text:empty) { display: none; } .ask-answer-text { color: #e6e8ee; font-size: 26px; line-height: 1.5; white-space: pre-wrap; word-wrap: break-word; letter-spacing: 0.01em; } /* History list shows newest at the top so the most relevant Q&A is always * visible without scrolling. We render in reverse-chronological order. */ .ask-history { display: flex; flex-direction: column; gap: 12px; margin-top: 6px; } .ask-bubble { padding: 14px 20px; border-radius: 14px; border: 1px solid rgba(255, 255, 255, 0.06); font-size: 26px; line-height: 1.5; max-width: 100%; letter-spacing: 0.01em; } .ask-bubble-role { font-size: 13px; letter-spacing: 0.15em; text-transform: uppercase; color: #6e7585; margin-bottom: 6px; font-weight: 600; } .ask-bubble-content { color: #c8cdd6; word-wrap: break-word; white-space: pre-wrap; } .ask-bubble-user { background: rgba(74, 158, 255, 0.08); border-color: rgba(74, 158, 255, 0.18); } .ask-bubble-user .ask-bubble-role { color: #4a9eff; } .ask-bubble-assistant { background: rgba(255, 255, 255, 0.02); } /* ---- Tool button selection ring: two fixes, both about the ring being invisible ---- */ /* 1. While the laser or spotlight owns the screen, the drawing tools should read as unselected. presentation-tools.js sets .pt-tool-active on and hides the ring HERE rather than removing the .selected class, because app.js owns that class and repaints it from currentTool at dozens of call sites. That tug-of-war is what made the pen's outline flicker away and come back mid-laser. Higher specificity than the .dark-ink rules below, so an active overlay always wins. */ body.pt-tool-active .tool-icon[data-tool="pen"].selected, body.pt-tool-active .tool-icon[data-tool="highlight"].selected, body.pt-tool-active .tool-icon[data-tool="erase"].selected, body.pt-tool-active .tool-icon[data-tool="select"].selected { border-color: transparent !important; box-shadow: none !important; } /* 2. The ring is drawn in the ink colour. The Notes page is white paper, so its pen is black, which put a black ring on the dark grey button: 1.66:1 contrast, indistinguishable from no ring at all on the stage TV. app.js/quick-dock.js add .dark-ink when the ink is too dark (window.isDarkInk), and the button becomes a white-paper chip — still showing the colour it will draw in. Placed at the end of the file so it also beats the .touch-device duplicates further up. */ .tool-icon[data-tool="pen"].selected.dark-ink, .tool-icon[data-tool="highlight"].selected.dark-ink { background: #ededed !important; box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 0 8px rgba(255, 255, 255, 0.35) !important; } .qd-btn.active.dark-ink { background: #ededed; box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 0 8px rgba(255, 255, 255, 0.35); } /* ---- Thrown card: one quick fade out ---- A card flicked off either side closes with a short fade and a small slide in the direction it went. These rules must outrank BOTH .word-info-popup (whose base transform is the opening pose, scale(0.8) translateY(-10px)) and .word-info-popup.show, or removing .show mid-fade animates the card back into view — which is the "disappears, reappears, then closes" flicker. Deliberately understated: no outline, no bounce, just gone. */ .word-info-popup.pd-closing, .word-info-popup.pd-closing.show { transition: opacity 0.16s ease-out, transform 0.16s ease-out !important; opacity: 0 !important; pointer-events: none !important; } .word-info-popup.pd-closing.pd-left { transform: translateX(-45%) scale(0.97) !important; } .word-info-popup.pd-closing.pd-right { transform: translateX(45%) scale(0.97) !important; } /* ============================================================================ ProPresenter Sync tab (propresenter-sync.js). It is a Bible tab; on stage NOTHING marks it as special — no state dot, no banner, no verse tint. Link state is read in Settings › ProPresenter Sync and on Companion buttons (/bibleapp/feedback/state/ppsync_*). Only the strip icon is styled. ============================================================================ */ .ppsync-tab-icon { opacity: 0.7; transition: opacity 0.2s; } .tab:hover .ppsync-tab-icon, .tab.active .ppsync-tab-icon { opacity: 1; } /* The sync tab never slides its text: the app's reveal (smoothFadeIn: fade + 6px slide up, re-run by every scroll-to-verse) is off on its panel, so a chapter change is the snapshot cross-fade and nothing else. Off PERMANENTLY, not only during the swap — lifting a suppressed CSS animation restarts it, which is exactly the after-fade jump this rule exists to prevent. */ .tab-panel.ppsync-panel .smooth-fade-in { animation: none !important; } /* ============================================================================ Two-finger tool selector (tool-wheel.js). A ring of tools around the tap point, sized for a hand on the 75" stage TV (1080 CSS px wide): each choice ~7 cm across, ~9 cm from the tap. It fans out from the centre and folds back into it — it never appears or vanishes in place. --tw-scale shrinks the whole thing only in a window too small to hold it (a dev browser; never the stage TV). ============================================================================ */ .tool-wheel { position: fixed; left: 0; top: 0; width: 0; height: 0; z-index: 60000; /* above the laser/spotlight overlay (10500) and the popups; below the splash */ pointer-events: none; /* only the hub and the choices take input — the page around them stays live */ touch-action: none; user-select: none; -webkit-user-select: none; --tw-scale: 1; } .tool-wheel .tw-hub, .tool-wheel .tw-item { position: absolute; left: 0; top: 0; pointer-events: auto; display: flex; flex-direction: column; align-items: center; justify-content: center; border-radius: 50%; box-sizing: border-box; touch-action: none; cursor: pointer; -webkit-tap-highlight-color: transparent; will-change: transform, opacity; } .tool-wheel .tw-hub { width: calc(48px * var(--tw-scale)); height: calc(48px * var(--tw-scale)); margin: calc(-24px * var(--tw-scale)) 0 0 calc(-24px * var(--tw-scale)); background: rgba(22, 22, 24, 0.92); border: 1px solid rgba(255, 255, 255, 0.16); color: #9a9a9a; font-size: calc(17px * var(--tw-scale)); opacity: 0; transform: scale(0.5); transition: opacity 0.14s ease, transform 0.18s cubic-bezier(0.2, 0.8, 0.3, 1.15); } .tool-wheel .tw-item { width: calc(84px * var(--tw-scale)); height: calc(84px * var(--tw-scale)); margin: calc(-42px * var(--tw-scale)) 0 0 calc(-42px * var(--tw-scale)); gap: calc(4px * var(--tw-scale)); background: rgba(24, 24, 26, 0.96); border: 2px solid rgba(255, 255, 255, 0.14); box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55); color: #e6e6e6; font-family: -apple-system, 'Segoe UI', system-ui, Roboto, sans-serif; opacity: 0; transform: translate(0px, 0px) scale(0.45); transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.3, 1.12) var(--tw-delay, 0ms), opacity 0.15s ease var(--tw-delay, 0ms), background 0.12s ease, box-shadow 0.12s ease; } .tool-wheel .tw-item i { font-size: calc(28px * var(--tw-scale)); line-height: 1; } .tool-wheel .tw-item span { font-size: calc(12px * var(--tw-scale)); line-height: 1; letter-spacing: 0.02em; color: #d4d4d4; } .tool-wheel.tw-open .tw-hub { opacity: 1; transform: scale(1); } .tool-wheel.tw-open .tw-item { opacity: 1; transform: translate(var(--tw-x), var(--tw-y)) scale(1); } /* The active tool: ring + glow in its own ink colour, as the toolbar and the dock draw it */ .tool-wheel .tw-item.tw-active { background: rgba(255, 255, 255, 0.12); box-shadow: 0 0 0 2px currentColor, 0 0 12px currentColor, 0 6px 18px rgba(0, 0, 0, 0.55); } .tool-wheel .tw-item.tw-active.dark-ink { background: #ededed; box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 0 8px rgba(255, 255, 255, 0.35); } .tool-wheel .tw-item.tw-active.dark-ink span { color: #333; } .tool-wheel.tw-open .tw-item.tw-pressed { transform: translate(var(--tw-x), var(--tw-y)) scale(0.92); background: rgba(255, 255, 255, 0.2); transition-delay: 0ms; } .tool-wheel.tw-open .tw-item.tw-chosen { transform: translate(var(--tw-x), var(--tw-y)) scale(1.12); box-shadow: 0 0 0 3px currentColor, 0 0 22px currentColor; transition: transform 0.1s ease-out, box-shadow 0.1s ease-out; } /* Closing: fold back toward the tap point and fade; the chosen tool lingers a beat brighter, then follows */ .tool-wheel.tw-open.tw-closing .tw-hub { opacity: 0; transform: scale(0.5); transition: opacity 0.1s ease-in, transform 0.12s ease-in; } .tool-wheel.tw-open.tw-closing .tw-item { opacity: 0; transform: translate(calc(var(--tw-x) * 0.82), calc(var(--tw-y) * 0.82)) scale(0.7); transition: transform 0.15s ease-in, opacity 0.12s ease-in; } .tool-wheel.tw-open.tw-closing .tw-item.tw-chosen { transform: translate(var(--tw-x), var(--tw-y)) scale(1.16); transition: transform 0.17s ease-out, opacity 0.14s ease-in 0.03s; } /* ---------------------------------------------------------------------------- SLIM — the second shape of the same selector (Settings › Presentation). One dial instead of five scattered discs: a band of wedges around a hole, the close hub sitting in the hole. About two thirds the width of the ring and a third of the area, so far less of the passage is covered while a tool is being picked — and far less of it is on camera if the program feed catches the moment. The wedges touch, so their own outlines draw the dial (outer circle, inner circle, one line between each pair) and there is no dead space between choices for a thumb to fall into. It unfolds and folds exactly like the ring: the dial springs open from the tap point while each wedge and its icon slide outward on the same 22 ms-apart stagger, and everything folds back into the centre. ---------------------------------------------------------------------------- */ .tool-wheel-slim .tw-dial { position: absolute; left: 0; top: 0; pointer-events: none; /* the SVG wedges inside take input; the box around them does not */ opacity: 0; transform: scale(calc(var(--tw-scale) * 0.55)); transform-origin: 50% 50%; transition: opacity 0.14s ease, transform 0.2s cubic-bezier(0.2, 0.8, 0.3, 1.12); will-change: transform, opacity; } .tool-wheel-slim.tw-open .tw-dial { opacity: 1; transform: scale(var(--tw-scale)); } .tool-wheel-slim .tw-svg { display: block; width: 100%; height: 100%; overflow: visible; } /* A wedge. The fill is the dial's own dark ground; currentColor (set from the toolbar in paint()) only comes through once it is the active tool. */ .tool-wheel-slim .tw-seg > path { fill: rgba(24, 24, 26, 0.96); stroke: rgba(255, 255, 255, 0.17); stroke-width: 1.4; stroke-linejoin: round; pointer-events: auto; transition: fill 0.12s ease, fill-opacity 0.12s ease, stroke 0.12s ease, stroke-width 0.12s ease; } .tool-wheel-slim .tw-seg { opacity: 0; transform: translate(var(--tw-sx, 0px), var(--tw-sy, 0px)); transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.3, 1.12) var(--tw-delay, 0ms), opacity 0.15s ease var(--tw-delay, 0ms); } .tool-wheel-slim.tw-open .tw-seg { opacity: 1; transform: translate(0px, 0px); } /* The active tool, in its own ink — the same signal the ring gives with a glowing border. */ .tool-wheel-slim .tw-seg.tw-active > path { fill: currentColor; fill-opacity: 0.26; stroke: currentColor; stroke-width: 2.6; } /* A near-black ink would be invisible as a tint on a dark dial, so it goes light instead (as the ring does) and its icon goes dark against it. */ .tool-wheel-slim .tw-seg.tw-active.dark-ink > path { fill: #ededed; fill-opacity: 0.92; stroke: rgba(255, 255, 255, 0.9); } .tool-wheel-slim .tw-seg.tw-pressed > path { fill: currentColor; fill-opacity: 0.42; transition-delay: 0ms; } .tool-wheel-slim .tw-seg.tw-chosen > path { fill: currentColor; fill-opacity: 0.6; stroke: currentColor; stroke-width: 3.2; transition: fill-opacity 0.1s ease-out, stroke-width 0.1s ease-out; } /* Icons ride over the wedges and never take a touch, so every press lands on the wedge below. */ .tool-wheel-slim .tw-icons { position: absolute; left: 0; top: 0; width: 0; height: 0; pointer-events: none; } .tool-wheel-slim .tw-ico { position: absolute; left: 0; top: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: calc(3px * var(--tw-scale)); width: calc(62px * var(--tw-scale)); margin: calc(-18px * var(--tw-scale)) 0 0 calc(-31px * var(--tw-scale)); color: #e6e6e6; font-family: -apple-system, 'Segoe UI', system-ui, Roboto, sans-serif; text-align: center; opacity: 0; transform: translate(var(--tw-x0), var(--tw-y0)) scale(0.6); transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.3, 1.12) var(--tw-delay, 0ms), opacity 0.15s ease var(--tw-delay, 0ms); will-change: transform, opacity; } .tool-wheel-slim.tw-open .tw-ico { opacity: 1; transform: translate(var(--tw-x), var(--tw-y)) scale(1); } .tool-wheel-slim .tw-ico i { font-size: calc(22px * var(--tw-scale)); line-height: 1; } .tool-wheel-slim .tw-ico span { font-size: calc(10px * var(--tw-scale)); line-height: 1; letter-spacing: 0.02em; color: #cfcfcf; white-space: nowrap; } .tool-wheel-slim .tw-ico.tw-active span { color: #f2f2f2; } /* Light wedge, dark glyph (see the dark-ink note above). Beats the inline ink colour paint() sets. */ .tool-wheel-slim .tw-ico.tw-active.dark-ink, .tool-wheel-slim .tw-ico.tw-active.dark-ink span { color: #2b2b2b !important; } /* The hub sits in the hole: smaller than the ring's, because the hole is smaller. */ .tool-wheel-slim .tw-hub { width: calc(52px * var(--tw-scale)); height: calc(52px * var(--tw-scale)); margin: calc(-26px * var(--tw-scale)) 0 0 calc(-26px * var(--tw-scale)); font-size: calc(18px * var(--tw-scale)); } /* Folding away: the dial shrinks back into the tap point and the wedges and icons draw back with it. */ .tool-wheel-slim.tw-open.tw-closing .tw-dial { opacity: 0; transform: scale(calc(var(--tw-scale) * 0.62)); transition: opacity 0.12s ease-in, transform 0.15s ease-in; } .tool-wheel-slim.tw-open.tw-closing .tw-seg { opacity: 0; transition: opacity 0.12s ease-in; } .tool-wheel-slim.tw-open.tw-closing .tw-ico { opacity: 0; transform: translate(var(--tw-x0), var(--tw-y0)) scale(0.72); transition: transform 0.15s ease-in, opacity 0.12s ease-in; } /* The tool just chosen holds a beat brighter before it goes, so the pick is seen, not guessed. */ .tool-wheel-slim.tw-open.tw-closing .tw-seg.tw-chosen { opacity: 1; transition: opacity 0.14s ease-in 0.04s; } .tool-wheel-slim.tw-open.tw-closing .tw-ico.tw-active { transform: translate(var(--tw-x), var(--tw-y)) scale(1.06); transition: transform 0.17s ease-out, opacity 0.14s ease-in 0.04s; } /* Notes tab: the sheet is the page. .bible-text's 30px padding is a reading margin for scripture; on the notes stage it put a black border around the sheet on the stage AND on the follower's program feed (the notes were the one tab that did not run edge to edge). Scoped so the Bible text keeps its margin. */ .notes-stage .bible-text, .notes-stage .notes-stage-body { padding: 0 !important; margin: 0 !important; width: 100% !important; max-width: none !important; } /* The notes body must be exactly the content width: as a flex item of the centring wrapper it came out 1px short (1079 of 1080 on the TV) — a hairline of black at the paper's right edge on the program feed. */ .notes-stage .content-wrapper { display: block !important; }