bunker-admin a77306fac2 Initial v2 commit: complete rebuild with unified API + React admin
Phase 1-14 complete:
- Unified Express.js API (TypeScript, Prisma ORM, PostgreSQL 16)
- React Admin GUI (Vite + Ant Design + Zustand)
- JWT auth with refresh tokens
- Influence: Campaigns, Representatives, Responses, Email Queue
- Map: Locations, Cuts, Shifts, Canvassing System
- NAR data import infrastructure (2025 format)
- Listmonk newsletter integration
- Landing page builder (GrapesJS)
- MkDocs + Code Server integration
- Volunteer portal with GPS tracking
- Monitoring stack (Prometheus, Grafana, Alertmanager)
- Pangolin tunnel integration

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 10:05:04 -07:00

125 lines
2.3 KiB
CSS

/* Form styles */
.form-group {
margin-bottom: 15px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 500;
color: var(--dark-color);
font-size: 14px;
}
.form-group input,
.form-group textarea {
width: 100%;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-size: 14px;
transition: var(--transition);
}
.form-group input:focus,
.form-group textarea:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 2px rgba(44, 90, 160, 0.1);
}
.form-group input.valid {
border-color: var(--success-color);
}
.form-group input.invalid {
border-color: var(--danger-color);
}
.form-group input[readonly] {
background-color: #f5f5f5;
cursor: not-allowed;
}
.form-group select {
width: 100%;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-size: 14px;
transition: var(--transition);
background-color: white;
cursor: pointer;
}
.form-group select:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 2px rgba(44, 90, 160, 0.1);
}
.form-group input[type="checkbox"] {
width: auto;
margin-right: 8px;
cursor: pointer;
}
.form-group label input[type="checkbox"] {
vertical-align: middle;
}
.form-actions {
display: flex;
gap: 10px;
justify-content: flex-end;
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #e0e0e0;
}
/* Edit Footer Form */
.edit-footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: white;
border-top: 2px solid var(--primary-color);
box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
z-index: 12200;
transition: transform 0.3s ease;
max-height: 60vh;
overflow-y: auto;
}
.edit-footer.hidden {
transform: translateY(100%);
}
.edit-footer-content {
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
.edit-footer-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
}
.edit-footer-header h2 {
margin: 0;
font-size: 20px;
color: var(--dark-color);
}