/* 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; } /* 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 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--spacing-sm); } .card-grid .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; } }