Files
gitea-mobile/static/style.css
agent-company 25bc305fc9 feat: add mobile-friendly HTTP 404 and 500 error pages
Add ErrorNotFound and ErrorInternal handler methods that render styled
error pages using the error.html template, with proper status codes,
responsive layout, SVG icons, and HTMX fragment support. Replace the
plain-text http.NotFound call in Dashboard with the new styled handler.

Closes leeworks-agents/gitea-mobile#131

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:06:10 +00:00

601 lines
12 KiB
CSS

/* Gitea Mobile — Mobile-first CSS (~5KB target) */
/* Reset */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* CSS Variables */
:root {
--bg-primary: #0d1117;
--bg-secondary: #161b22;
--bg-tertiary: #21262d;
--border: #30363d;
--text-primary: #e6edf3;
--text-secondary: #8b949e;
--text-link: #58a6ff;
--accent-green: #3fb950;
--accent-red: #f85149;
--accent-yellow: #d29922;
--accent-blue: #58a6ff;
--accent-purple: #bc8cff;
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 0.75rem;
--spacing-lg: 1rem;
--radius: 8px;
--radius-sm: 6px;
--radius-pill: 10px;
--nav-height: 56px;
--font-sm: 0.75rem;
--font-base: 0.875rem;
--font-lg: 1rem;
--font-xl: 1.25rem;
}
/* Base */
html {
font-size: 16px;
-webkit-text-size-adjust: 100%;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.5;
padding-bottom: calc(var(--nav-height) + env(safe-area-inset-bottom));
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Top bar */
.top-bar {
position: sticky;
top: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--spacing-sm) var(--spacing-lg);
padding-top: max(var(--spacing-sm), env(safe-area-inset-top));
background: var(--bg-secondary);
border-bottom: 1px solid var(--border);
}
.top-bar-title {
font-size: var(--font-base);
font-weight: 600;
color: var(--text-primary);
}
.refresh-btn {
background: none;
border: none;
color: var(--text-secondary);
font-size: 1.4rem;
padding: var(--spacing-xs) var(--spacing-sm);
cursor: pointer;
-webkit-tap-highlight-color: transparent;
line-height: 1;
border-radius: var(--radius-sm);
transition: color 0.15s ease, background 0.15s ease;
}
.refresh-btn:active {
color: var(--accent-blue);
background: var(--bg-tertiary);
}
.refresh-btn.htmx-request {
animation: spin 0.6s linear infinite;
pointer-events: none;
}
/* Content area */
.content {
padding: var(--spacing-lg);
padding-top: var(--spacing-lg);
max-width: 640px;
margin: 0 auto;
}
/* Typography */
h1 {
font-size: var(--font-xl);
font-weight: 700;
margin-bottom: var(--spacing-lg);
}
h2 {
font-size: var(--font-lg);
font-weight: 600;
margin-bottom: var(--spacing-md);
}
a {
color: var(--text-link);
text-decoration: none;
}
a:active {
opacity: 0.7;
}
/* Cards */
.card {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: var(--spacing-md);
margin-bottom: var(--spacing-sm);
transition: background 0.15s ease;
}
.card:active {
background: var(--bg-tertiary);
}
.card-title {
font-weight: 600;
font-size: var(--font-base);
margin-bottom: var(--spacing-xs);
line-height: 1.3;
}
.card-meta {
font-size: var(--font-sm);
color: var(--text-secondary);
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--spacing-xs);
}
.card-body {
font-size: var(--font-base);
color: var(--text-secondary);
margin-top: var(--spacing-sm);
line-height: 1.5;
}
/* Labels / badges */
.label {
display: inline-block;
font-size: 0.7rem;
padding: 1px 6px;
border-radius: var(--radius-pill);
font-weight: 500;
line-height: 1.5;
white-space: nowrap;
}
.type-badge {
font-size: 0.65rem;
text-transform: uppercase;
font-weight: 700;
padding: 1px 5px;
border-radius: 4px;
white-space: nowrap;
}
.type-issue {
background: rgba(31, 111, 235, 0.13);
color: var(--accent-blue);
border: 1px solid rgba(31, 111, 235, 0.27);
}
.type-pull {
background: rgba(35, 134, 54, 0.13);
color: var(--accent-green);
border: 1px solid rgba(35, 134, 54, 0.27);
}
.state-open {
color: var(--accent-green);
}
.state-closed {
color: var(--accent-red);
}
.state-merged {
color: var(--accent-purple);
}
/* Priority labels */
.priority-p1 { color: var(--accent-red); border-color: var(--accent-red); }
.priority-p2 { color: var(--accent-yellow); border-color: var(--accent-yellow); }
.priority-p3 { color: var(--accent-blue); border-color: var(--accent-blue); }
/* Diff stats */
.diff-add { color: var(--accent-green); font-size: var(--font-sm); }
.diff-del { color: var(--accent-red); font-size: var(--font-sm); }
/* Bottom navigation */
.bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: var(--bg-secondary);
border-top: 1px solid var(--border);
display: flex;
justify-content: space-around;
align-items: center;
height: var(--nav-height);
padding-bottom: env(safe-area-inset-bottom);
z-index: 100;
}
.bottom-nav a {
color: var(--text-secondary);
text-decoration: none;
font-size: 0.7rem;
display: flex;
flex-direction: column;
align-items: center;
padding: 4px 0;
min-width: 64px;
-webkit-tap-highlight-color: transparent;
}
.bottom-nav a.active {
color: var(--accent-blue);
}
.bottom-nav svg {
width: 22px;
height: 22px;
margin-bottom: 2px;
}
/* Filter bar */
.filter-bar {
display: flex;
gap: var(--spacing-sm);
margin-bottom: var(--spacing-lg);
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
padding-bottom: var(--spacing-xs);
}
.filter-bar::-webkit-scrollbar {
display: none;
}
.filter-bar select,
.filter-bar input {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
color: var(--text-primary);
padding: var(--spacing-sm) var(--spacing-md);
font-size: var(--font-base);
min-width: 0;
flex-shrink: 0;
appearance: none;
-webkit-appearance: none;
}
.filter-bar select:focus,
.filter-bar input:focus {
outline: none;
border-color: var(--accent-blue);
}
/* Forms */
.form-group {
margin-bottom: var(--spacing-lg);
}
.form-group label {
display: block;
font-size: var(--font-sm);
color: var(--text-secondary);
margin-bottom: var(--spacing-sm);
}
.form-group input,
.form-group textarea,
.form-group select {
width: 100%;
padding: var(--spacing-sm) var(--spacing-md);
font-size: var(--font-lg);
background: var(--bg-primary);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
color: var(--text-primary);
font-family: inherit;
}
.form-group textarea {
min-height: 120px;
resize: vertical;
}
.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
outline: none;
border-color: var(--accent-blue);
}
/* Buttons */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: var(--spacing-md) var(--spacing-lg);
font-size: var(--font-lg);
font-weight: 600;
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
-webkit-tap-highlight-color: transparent;
transition: background 0.15s ease;
}
.btn-primary {
background: #238636;
color: #fff;
width: 100%;
}
.btn-primary:active {
background: #2ea043;
}
.btn-secondary {
background: var(--bg-tertiary);
color: var(--text-primary);
border: 1px solid var(--border);
width: 100%;
}
.btn-secondary:active {
background: var(--border);
}
.btn-danger {
background: #da363322;
color: var(--accent-red);
border: 1px solid #da363366;
width: 100%;
}
/* Review form */
.review-options {
display: flex;
flex-direction: column;
gap: var(--spacing-sm);
margin-bottom: var(--spacing-lg);
}
.review-option {
display: flex;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-sm);
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
cursor: pointer;
}
.review-option input[type="radio"] {
accent-color: var(--accent-blue);
}
/* Comments thread */
.comment {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
margin-bottom: var(--spacing-sm);
overflow: hidden;
}
.comment-header {
padding: var(--spacing-sm) var(--spacing-md);
background: var(--bg-tertiary);
font-size: var(--font-sm);
color: var(--text-secondary);
display: flex;
align-items: center;
gap: var(--spacing-sm);
}
.comment-body {
padding: var(--spacing-md);
font-size: var(--font-base);
line-height: 1.6;
}
/* Avatar */
.avatar {
width: 20px;
height: 20px;
border-radius: 50%;
vertical-align: middle;
}
/* Review status badges */
.review-badge {
font-size: 0.7rem;
font-weight: 600;
padding: 1px 4px;
border-radius: var(--radius-pill);
vertical-align: middle;
}
.review-approved { color: var(--accent-green); }
.review-changes { color: var(--accent-red); }
.review-pending { color: var(--accent-yellow); }
/* Merge status badges */
.merge-badge {
font-size: 0.65rem;
font-weight: 600;
padding: 1px 5px;
border-radius: var(--radius-pill);
vertical-align: middle;
}
.merge-ready { color: var(--accent-green); border: 1px solid var(--accent-green); }
.merge-conflicts { color: var(--accent-red); border: 1px solid var(--accent-red); }
/* Empty state */
.empty {
text-align: center;
color: var(--text-secondary);
padding: 3rem var(--spacing-lg);
font-size: var(--font-base);
}
/* Messages */
.message {
padding: var(--spacing-md);
border-radius: var(--radius-sm);
margin-bottom: var(--spacing-lg);
font-size: var(--font-base);
}
.message.success {
background: #0d2818;
border: 1px solid #238636;
color: var(--accent-green);
}
.message.error {
background: #2d1117;
border: 1px solid #da3633;
color: var(--accent-red);
}
.message.info {
background: #0c1d2e;
border: 1px solid #1f6feb;
color: var(--accent-blue);
}
/* Loading indicator */
.htmx-indicator {
display: none;
}
.htmx-request .htmx-indicator {
display: inline-block;
}
.spinner {
width: 16px;
height: 16px;
border: 2px solid var(--border);
border-top-color: var(--accent-blue);
border-radius: 50%;
animation: spin 0.6s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
/* Infinite scroll sentinel */
.scroll-sentinel {
height: 1px;
margin-bottom: var(--spacing-lg);
}
/* Tablet breakpoint: 2-column grid */
@media (min-width: 640px) {
.content {
max-width: 960px;
}
.card-grid,
#issue-list,
#pull-list {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--spacing-sm);
}
.card-grid .card,
#issue-list .card,
#pull-list .card {
margin-bottom: 0;
}
}
/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
/* Dark mode is default; light mode override if needed */
@media (prefers-color-scheme: light) {
:root {
--bg-primary: #ffffff;
--bg-secondary: #f6f8fa;
--bg-tertiary: #eaeef2;
--border: #d0d7de;
--text-primary: #1f2328;
--text-secondary: #656d76;
--text-link: #0969da;
}
}
/* Error page */
.error-page {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 60vh;
text-align: center;
padding: var(--spacing-lg);
}
.error-icon {
color: var(--text-secondary);
margin-bottom: var(--spacing-lg);
}
.error-code {
font-size: 4rem;
font-weight: 700;
color: var(--text-primary);
line-height: 1;
margin-bottom: var(--spacing-sm);
}
.error-title {
font-size: var(--font-xl);
color: var(--text-primary);
margin-bottom: var(--spacing-sm);
}
.error-message {
font-size: var(--font-base);
color: var(--text-secondary);
margin-bottom: var(--spacing-lg);
max-width: 300px;
}
.error-home-link {
display: inline-block;
padding: var(--spacing-sm) var(--spacing-lg);
background: var(--accent-blue);
color: #fff;
border-radius: var(--radius);
text-decoration: none;
font-size: var(--font-base);
font-weight: 500;
transition: opacity 0.15s;
}
.error-home-link:active {
opacity: 0.8;
}