diff --git a/nostr/commit-signatures.jsonl b/nostr/commit-signatures.jsonl index 57f5453..70bef53 100644 --- a/nostr/commit-signatures.jsonl +++ b/nostr/commit-signatures.jsonl @@ -49,3 +49,4 @@ {"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771708933,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","bug-fixes"]],"content":"Signed commit: bug-fixes","id":"6d8832125b76095b2e7ed57b71e26a6c05d9b19a14dfa76724c71f392147fe95","sig":"6ddebfa995b5b3f469db5f3cdbd7d13fa2307d7988c2667479015d6bc2ff442be357ee97e51340a944eb34fed73522db3930016d343810927486bdbcabddae5c"} {"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771742489,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","bug-fixes"]],"content":"Signed commit: bug-fixes","id":"6fd5146b5f5980987adc5e6b93a1bcb31cfbb6a2e4fce6f1dbe5c7fdf54b717a","sig":"41422b07b63fc494c0aba22b85f1b56a6a5527f9df48d49816f7be417ad74608f8d1dff8302f562b2f47690720c089aab76db948f5bf1ecdda68741b256d7a2b"} {"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771745084,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","fix the menus and implement the patch page"]],"content":"Signed commit: fix the menus and implement the patch page","id":"b4e946a2acfc7c71b7c3d3a533186dc500edcd4e3f277aa5f83fa08fe5d2ffa7","sig":"226f5ae08cd5dd27baf8cca64889d27bcd40aa4655a274ba19ef068e394be99c916bdf86569169800e4dfdfe89e34f834bb95a4a404bda7712cbbf537633a6f5"} +{"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771747544,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","handle panel-switching on mobile"]],"content":"Signed commit: handle panel-switching on mobile","id":"1b65fafbc3cef0e06fc9fd9e7c2478f3028ecea0974173cbac59a9afcb1defe9","sig":"fe917e8c371c9567bf677ac5f21175ee4f3783e8a9a0b0cb4f43f17f235041306422e73ec048b7a3638ba4268faaca6bf415593cea4cd89761f43edb51184bca"} diff --git a/src/app.css b/src/app.css index 48ed565..8807f58 100644 --- a/src/app.css +++ b/src/app.css @@ -217,6 +217,52 @@ a:hover { .container-narrow, .container-wide { padding: 1rem; + min-height: auto; + overflow: visible; + } + + /* Ensure forms are fully visible on mobile */ + .container main, + .container-narrow main, + .container-wide main { + min-height: auto; + overflow: visible; + } + + /* Ensure body/html allow scrolling on mobile */ + /* Remove height constraints to allow full content scrolling */ + html { + height: auto; + min-height: 100%; + overflow-x: hidden; + overflow-y: auto; + } + + body { + height: auto; + min-height: 100%; + overflow-x: hidden; + overflow-y: auto; + /* Ensure body can grow beyond viewport for proper scrolling */ + position: relative; + } + + /* Ensure container and main elements don't constrain height on mobile */ + .container, + .container-narrow, + .container-wide { + min-height: auto; + height: auto; + padding-bottom: 2rem; /* Add bottom padding so content isn't cut off */ + } + + .container main, + .container-narrow main, + .container-wide main { + min-height: auto; + height: auto; + overflow: visible; + padding-bottom: 1rem; /* Add bottom padding */ } /* Repo cards - make more responsive on mobile */ diff --git a/src/lib/components/RepoHeaderEnhanced.svelte b/src/lib/components/RepoHeaderEnhanced.svelte index 1006f88..fd73798 100644 --- a/src/lib/components/RepoHeaderEnhanced.svelte +++ b/src/lib/components/RepoHeaderEnhanced.svelte @@ -93,7 +93,7 @@ let showOwnerMenu = $state(false); let moreMenuElement = $state(null); - // Adjust menu position to expand leftward on mobile if needed + // Adjust menu position to prevent overflow on both sides on mobile $effect(() => { if (showMoreMenu && moreMenuElement) { // Use requestAnimationFrame to ensure DOM is updated @@ -101,14 +101,24 @@ if (!moreMenuElement) return; const rect = moreMenuElement.getBoundingClientRect(); const viewportWidth = window.innerWidth; + const padding = 10; // Padding from viewport edges - // If menu would overflow on the right, position it to expand leftward - if (rect.right > viewportWidth - 10) { - const overflow = rect.right - (viewportWidth - 10); - moreMenuElement.style.transform = `translateX(-${overflow}px)`; - } else { - moreMenuElement.style.transform = 'translateX(0)'; + let transformX = 0; + + // Check if menu overflows on the right + if (rect.right > viewportWidth - padding) { + const overflow = rect.right - (viewportWidth - padding); + transformX = -overflow; + } + + // Check if menu overflows on the left (after right adjustment) + const adjustedLeft = rect.left + transformX; + if (adjustedLeft < padding) { + // Menu would be cut off on the left, shift it right + transformX = padding - rect.left; } + + moreMenuElement.style.transform = `translateX(${transformX}px)`; }); } }); diff --git a/src/lib/styles/components.css b/src/lib/styles/components.css index 58599d9..db87c8f 100644 --- a/src/lib/styles/components.css +++ b/src/lib/styles/components.css @@ -68,6 +68,13 @@ cursor: pointer; display: flex; align-items: center; + transition: background 0.2s ease, opacity 0.2s ease; + border-radius: 0.25rem; +} + +.bookmark-button:hover { + background: var(--bg-secondary, #f5f5f5); + opacity: 0.8; } .bookmark-button.bookmarked img { @@ -250,7 +257,7 @@ } .owner-menu-item:hover { - background: var(--bg-secondary, #f5f5f5); + background: var(--bg-tertiary, #e0e0e0); } .owner-menu-item :global(.user-badge) { @@ -379,7 +386,7 @@ .clone-url-item:hover, .branch-item:hover { - background: var(--bg-secondary, #f5f5f5); + background: var(--bg-tertiary, #e0e0e0); } .delete-branch-button { @@ -424,7 +431,7 @@ right: 0; left: auto; max-width: calc(100vw - 1rem); - min-width: 280px; + min-width: min(280px, calc(100vw - 1rem)); /* Ensure menu aligns to right edge of button but doesn't overflow */ transform: translateX(0); } @@ -433,14 +440,20 @@ /* The menu will naturally expand leftward when constrained */ } -/* On very small screens, ensure menu expands leftward */ +/* On very small screens, ensure menu expands leftward and doesn't get cut off */ @media (max-width: 480px) { .repo-header-actions .more-menu { right: 0; left: auto; max-width: calc(100vw - 0.5rem); - min-width: 260px; - /* Menu will expand leftward when width is constrained */ + min-width: min(260px, calc(100vw - 0.5rem)); + /* Ensure menu doesn't get cut off on the left */ + /* Position relative to viewport to prevent cutoff */ + } + + /* Ensure menu-button-wrapper allows proper positioning */ + .repo-header-actions .menu-button-wrapper { + position: relative; } } @@ -455,27 +468,38 @@ cursor: pointer; font-size: 0.875rem; color: var(--text-primary, #1a1a1a); + transition: background 0.2s ease, color 0.2s ease; } .menu-item:last-child { border-bottom: none; } -.menu-item:hover:not(:disabled) { - background: var(--bg-secondary, #f5f5f5); +.menu-item:hover:not(:disabled), +button.menu-item:hover:not(:disabled) { + background: var(--bg-tertiary, #e0e0e0) !important; } -.menu-item:disabled { +.menu-item:disabled, +button.menu-item:disabled { opacity: 0.6; cursor: not-allowed; } +.menu-item:disabled:hover, +button.menu-item:disabled:hover { + background: transparent !important; +} + .menu-item-danger { color: var(--error-text, #dc2626); + transition: background 0.2s ease, color 0.2s ease; } -.menu-item-danger:hover:not(:disabled) { - background: var(--error-bg, #fee); +.menu-item-danger:hover:not(:disabled), +button.menu-item-danger:hover:not(:disabled) { + background: var(--error-bg, #fee) !important; + color: var(--error-text, #dc2626); } /* Icon button - icon-only button style */ @@ -653,6 +677,11 @@ font-size: 0.875rem; color: var(--text-primary, #1a1a1a); font-weight: 500; + transition: background 0.2s ease; +} + +.mobile-menu-button:hover { + background: var(--bg-secondary, #f5f5f5); } .mobile-menu-button .icon { @@ -723,7 +752,7 @@ } .mobile-tab-item:hover { - background: var(--bg-secondary, #f5f5f5); + background: var(--bg-tertiary, #e0e0e0); } .mobile-tab-item.active { @@ -799,6 +828,12 @@ display: flex; align-items: center; gap: 0.5rem; + transition: background 0.2s ease, color 0.2s ease; +} + +.tabs-menu .menu-item:hover:not(:disabled), +.tabs-menu button.menu-item:hover:not(:disabled) { + background: var(--bg-tertiary, #e0e0e0) !important; } .tab-icon-inline { diff --git a/src/lib/styles/repo.css b/src/lib/styles/repo.css index eab3637..e88ba66 100644 --- a/src/lib/styles/repo.css +++ b/src/lib/styles/repo.css @@ -599,6 +599,28 @@ width: 100%; box-sizing: border-box; } + + .editor-header { + flex-wrap: wrap; + gap: 0.5rem; + } + + .file-path { + flex: 1; + min-width: 0; + word-break: break-all; + } + + .editor-actions { + width: 100%; + justify-content: flex-start; + } + + .non-maintainer-notice { + width: 100%; + order: 1; + margin-top: 0.25rem; + } } @media (min-width: 769px) { @@ -770,6 +792,12 @@ border-radius: 0.25rem; cursor: pointer; color: var(--text-primary); + transition: background 0.2s ease, border-color 0.2s ease; +} + +.back-button:hover { + background: var(--bg-secondary); + border-color: var(--accent); } .create-file-button, @@ -997,6 +1025,12 @@ border: none; cursor: pointer; color: inherit; + transition: background 0.2s ease; +} + +.patch-item:not(.selected) .patch-item-button:hover, +.discussion-item:not(.selected) .discussion-item-button:hover { + background: var(--bg-tertiary); } .patch-item.selected .patch-item-button, @@ -1020,6 +1054,12 @@ background: none; border: none; cursor: pointer; + transition: background 0.2s ease; + border-radius: 0.25rem; +} + +.commit-button:hover { + background: var(--bg-tertiary); } .commit-hash { @@ -1096,6 +1136,12 @@ border-radius: 0.25rem; cursor: pointer; color: var(--text-primary); + transition: background 0.2s ease, border-color 0.2s ease; +} + +.refresh-button:hover { + background: var(--bg-secondary); + border-color: var(--accent); } .verification-badge { diff --git a/src/routes/api-docs/+page.svelte b/src/routes/api-docs/+page.svelte index aa19511..88a4e09 100644 --- a/src/routes/api-docs/+page.svelte +++ b/src/routes/api-docs/+page.svelte @@ -339,6 +339,9 @@ const response = await fetch('https://gitrepublic.com/api/repos/list', { background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 0.5rem; + min-width: 0; /* Allow shrinking */ + overflow-wrap: break-word; + word-wrap: break-word; } .auth-method h3 { @@ -346,12 +349,17 @@ const response = await fetch('https://gitrepublic.com/api/repos/list', { color: var(--text-primary); font-size: 1rem; font-weight: 600; + word-wrap: break-word; + overflow-wrap: break-word; } .auth-method p { margin: 0.5rem 0; color: var(--text-secondary); font-size: 0.875rem; + word-wrap: break-word; + overflow-wrap: break-word; + line-height: 1.5; } .code-example { @@ -361,6 +369,9 @@ const response = await fetch('https://gitrepublic.com/api/repos/list', { padding: 1rem; margin: 0.75rem 0; overflow-x: auto; + overflow-y: hidden; + max-width: 100%; + box-sizing: border-box; } .code-example code { @@ -373,12 +384,165 @@ const response = await fetch('https://gitrepublic.com/api/repos/list', { line-height: 1.5; color: var(--text-primary); white-space: pre; + word-wrap: break-word; + overflow-wrap: break-word; + max-width: 100%; } @media (max-width: 768px) { + .api-docs-container { + padding: 1rem; + } + + .api-docs-header { + padding-bottom: 0.75rem; + margin-bottom: 1.5rem; + } + + .api-docs-header h1 { + font-size: 1.5rem; + margin-bottom: 0.75rem; + } + + .api-docs-header p { + font-size: 0.875rem; + line-height: 1.5; + margin: 0.5rem 0; + } + + .api-docs-header .note { + padding: 0.75rem; + font-size: 0.875rem; + margin-top: 0.75rem; + } + .auth-methods { grid-template-columns: 1fr; gap: 1rem; + margin: 1rem 0; + width: 100%; + max-width: 100%; + } + + .auth-method { + padding: 0.75rem; + width: 100%; + max-width: 100%; + min-width: 0; + box-sizing: border-box; + overflow-wrap: break-word; + word-wrap: break-word; + } + + .auth-method h3 { + font-size: 0.9375rem; + margin-bottom: 0.5rem; + word-wrap: break-word; + overflow-wrap: break-word; + line-height: 1.3; + } + + .auth-method p { + font-size: 0.8125rem; + margin: 0.5rem 0; + word-wrap: break-word; + overflow-wrap: break-word; + line-height: 1.5; + } + + .auth-method code { + word-wrap: break-word; + overflow-wrap: break-word; + font-size: 0.75rem; + } + + .code-example { + padding: 0.75rem; + margin: 0.5rem 0; + font-size: 0.75rem; + width: 100%; + max-width: 100%; + box-sizing: border-box; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + + .code-example code { + font-size: 0.75rem; + white-space: pre-wrap; /* Allow wrapping on mobile */ + word-wrap: break-word; + overflow-wrap: break-word; + max-width: 100%; + } + + /* Swagger UI code sections - make responsive on mobile */ + :global(.swagger-ui pre), + :global(.swagger-ui .highlight-code), + :global(.swagger-ui .microlight), + :global(.swagger-ui .example), + :global(.swagger-ui .example-value), + :global(.swagger-ui .example-single), + :global(.swagger-ui .curl), + :global(.swagger-ui .curl-command) { + width: 100% !important; + max-width: 100% !important; + box-sizing: border-box !important; + padding: 0.75rem !important; + font-size: 0.75rem !important; + overflow-x: auto !important; + -webkit-overflow-scrolling: touch !important; + word-wrap: break-word !important; + overflow-wrap: break-word !important; + } + + :global(.swagger-ui pre code), + :global(.swagger-ui .microlight code), + :global(.swagger-ui .example code), + :global(.swagger-ui .highlight-code code) { + white-space: pre-wrap !important; /* Allow wrapping on mobile */ + word-wrap: break-word !important; + overflow-wrap: break-word !important; + max-width: 100% !important; + display: block !important; + } + + /* Ensure code containers don't overflow */ + :global(.swagger-ui .model-example), + :global(.swagger-ui .response-col_description), + :global(.swagger-ui .opblock-body), + :global(.swagger-ui .opblock-section) { + width: 100% !important; + max-width: 100% !important; + box-sizing: border-box !important; + overflow-x: auto !important; + } + + /* Make tables responsive - horizontal scroll instead of breaking layout */ + :global(.swagger-ui .responses-table), + :global(.swagger-ui table) { + width: 100% !important; + max-width: 100% !important; + display: table !important; + overflow-x: auto !important; + -webkit-overflow-scrolling: touch !important; + table-layout: auto !important; + } + + :global(.swagger-ui .responses-table td), + :global(.swagger-ui .responses-table th) { + box-sizing: border-box !important; + word-wrap: break-word !important; + overflow-wrap: break-word !important; + min-width: 80px !important; /* Prevent columns from being too narrow */ + } + + /* Wrap table in scrollable container */ + :global(.swagger-ui .responses-inner), + :global(.swagger-ui .responses-wrapper) { + width: 100% !important; + max-width: 100% !important; + overflow-x: auto !important; + -webkit-overflow-scrolling: touch !important; } } diff --git a/src/routes/repos/+page.svelte b/src/routes/repos/+page.svelte index fdbb217..4fb534b 100644 --- a/src/routes/repos/+page.svelte +++ b/src/routes/repos/+page.svelte @@ -381,7 +381,7 @@ } async function deleteLocalRepo(npub: string, repo: string) { - if (!confirm(`Are you sure you want to delete the local clone of ${repo}? This will remove the repository from this server but will not delete the announcement on Nostr.`)) { + if (!confirm(`⚠️ Are you sure you want to delete the local clone of "${repo}"?\n\nThis will permanently remove the repository from this server. The announcement on Nostr will NOT be deleted.\n\nThis action cannot be undone.\n\nClick OK to delete, or Cancel to abort.`)) { return; } diff --git a/src/routes/repos/[npub]/[repo]/+page.svelte b/src/routes/repos/[npub]/[repo]/+page.svelte index b4904b0..71d9177 100644 --- a/src/routes/repos/[npub]/[repo]/+page.svelte +++ b/src/routes/repos/[npub]/[repo]/+page.svelte @@ -2295,7 +2295,13 @@ return; } - if (!confirm('Are you sure you want to send a deletion request for this repository announcement? This will request relays to delete the announcement event. This action cannot be undone.')) { + // First confirmation + if (!confirm('⚠️ WARNING: Are you sure you want to delete this repository announcement?\n\nThis will permanently delete the repository announcement from Nostr relays. This action CANNOT be undone.\n\nClick OK to continue, or Cancel to abort.')) { + return; + } + + // Second confirmation for critical operation + if (!confirm('⚠️ FINAL CONFIRMATION: This will permanently delete the repository announcement.\n\nAre you absolutely certain you want to proceed?\n\nThis action CANNOT be undone.')) { return; } @@ -3130,7 +3136,7 @@ } async function deleteFile(filePath: string) { - if (!confirm(`Are you sure you want to delete ${filePath}?`)) { + if (!confirm(`⚠️ Are you sure you want to delete "${filePath}"?\n\nThis will permanently delete the file from the repository. This action cannot be undone.\n\nClick OK to delete, or Cancel to abort.`)) { return; } @@ -3258,7 +3264,7 @@ } async function deleteBranch(branchName: string) { - if (!confirm(`Are you sure you want to delete the branch "${branchName}"? This action cannot be undone.`)) { + if (!confirm(`⚠️ Are you sure you want to delete the branch "${branchName}"?\n\nThis will permanently delete the branch from the repository. This action CANNOT be undone.\n\nClick OK to delete, or Cancel to abort.`)) { return; } diff --git a/src/routes/settings/[[tab]]/+page.svelte b/src/routes/settings/[[tab]]/+page.svelte index 431f4cb..225c943 100644 --- a/src/routes/settings/[[tab]]/+page.svelte +++ b/src/routes/settings/[[tab]]/+page.svelte @@ -543,6 +543,17 @@ flex-wrap: wrap; } + @media (max-width: 768px) { + .theme-options { + flex-direction: column; + } + + .theme-option { + width: 100%; + min-width: auto; + } + } + .theme-option { flex: 1; min-width: 120px; diff --git a/src/routes/users/[npub]/+page.svelte b/src/routes/users/[npub]/+page.svelte index 3a9c20e..6c4cc49 100644 --- a/src/routes/users/[npub]/+page.svelte +++ b/src/routes/users/[npub]/+page.svelte @@ -3583,7 +3583,22 @@ i * .activity-icon { width: 1.25rem; height: 1.25rem; - filter: var(--icon-filter, none); + /* Theme-aware icon colors - same as settings button */ + filter: brightness(0) saturate(100%) invert(1) !important; /* Default white for dark themes */ + opacity: 1 !important; + } + + /* Light theme: icons should be dark (black) */ + :global([data-theme="light"]) .activity-icon { + filter: brightness(0) saturate(100%) !important; /* Black in light theme */ + opacity: 1 !important; + } + + /* Dark themes: icons should be light (white/light gray) */ + :global([data-theme="dark"]) .activity-icon, + :global([data-theme="black"]) .activity-icon { + filter: brightness(0) saturate(100%) invert(1) !important; /* White in dark themes */ + opacity: 1 !important; } /* Empty State */