Files
Aplikasi-Kehadiran-KTM/public/css/app.css
Saufi dfd22ff2af Aplikasi kehadiran KTM ambil peti undi (SPR 2026)
Sistem untuk admin DUN merekod waktu KTM (Ketua Tempat Mengundi) hadir
mengambil peti undi. Data KTM dibaca daripada DB sppm (spr2026) melalui
connection kedua — hanya penempatan berjawatan KTM yang dipaparkan.

- Dashboard: senarai KTM ikut pusat mengundi (asc) & saluran (asc),
  status BELUM HADIR (merah) / HADIR (hijau) + tarikh & masa
- Carian nama/no. KP, tapisan pusat mengundi & status
- Tanda hadir / batal dengan kawalan DUN (admin terhad ke DUN sendiri)
- Eksport Excel (worksheet Hadir & Belum Hadir) guna SimpleXlsx
- Peranan: superadmin (urus pengguna, semua DUN) & admin DUN
- Docker: nginx + php-fpm + queue + scheduler + webhook deploy,
  port 127.0.0.1:8009, TZ Asia/Kuala_Lumpur di semua container
- Zon waktu aplikasi: Asia/Kuala_Lumpur (APP_TIMEZONE)

Berasaskan scaffold spr2026_taklimat.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 02:40:00 +08:00

382 lines
8.5 KiB
CSS

:root {
--biru: #1c3f94;
--biru-gelap: #142e6e;
--merah: #cc2229;
--kelabu: #f4f5f7;
--kelabu-border: #d9dde3;
--teks: #1f2430;
--hijau: #1a7f37;
--kuning: #b58900;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
background: var(--kelabu);
color: var(--teks);
line-height: 1.5;
}
a { color: var(--biru); }
.topbar {
background: var(--biru);
color: #fff;
padding: 0.75rem 1rem;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 0.5rem;
}
.topbar .jenama {
font-weight: 700;
font-size: 1.05rem;
color: #fff;
text-decoration: none;
}
.topbar .pengguna {
display: flex;
align-items: center;
gap: 0.75rem;
font-size: 0.9rem;
}
.topbar .pengguna a {
color: #fff;
text-decoration: underline;
}
.container {
max-width: 960px;
margin: 1.25rem auto;
padding: 0 1rem;
}
.container-kecil { max-width: 480px; }
.kad {
background: #fff;
border: 1px solid var(--kelabu-border);
border-radius: 10px;
padding: 1.25rem;
margin-bottom: 1rem;
}
.kad h1, .kad h2 { margin-top: 0; }
h1 { font-size: 1.35rem; }
h2 { font-size: 1.15rem; }
label {
display: block;
font-weight: 600;
margin-bottom: 0.3rem;
}
input[type="text"],
input[type="email"],
input[type="password"],
input[type="date"],
select {
width: 100%;
padding: 0.65rem 0.75rem;
border: 1px solid var(--kelabu-border);
border-radius: 8px;
font-size: 1rem;
margin-bottom: 0.9rem;
background: #fff;
}
input:focus, select:focus {
outline: 2px solid var(--biru);
border-color: var(--biru);
}
.btn {
display: inline-block;
padding: 0.6rem 1.2rem;
border: none;
border-radius: 8px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
text-decoration: none;
text-align: center;
background: var(--biru);
color: #fff;
}
.btn:hover { background: var(--biru-gelap); }
.btn-penuh { width: 100%; display: block; }
.btn-hijau { background: var(--hijau); }
.btn-hijau:hover { background: #14632b; }
.btn-merah { background: var(--merah); }
.btn-merah:hover { background: #a31b21; }
.btn-kecil { padding: 0.35rem 0.75rem; font-size: 0.85rem; }
.btn-luar {
background: #fff;
color: var(--biru);
border: 1px solid var(--biru);
}
.btn-luar:hover { background: #eef1f9; color: var(--biru); }
.makluman {
padding: 0.75rem 1rem;
border-radius: 8px;
margin-bottom: 1rem;
font-size: 0.95rem;
}
.makluman-info { background: #e8f0fe; border: 1px solid #b3c7f2; color: #173a7a; }
.makluman-jaya { background: #e6f4ea; border: 1px solid #a8d5b5; color: #14632b; }
.makluman-ralat { background: #fdecea; border: 1px solid #f5b5b1; color: #8c1d18; }
.makluman-amaran { background: #fff8e1; border: 1px solid #ecd591; color: #7a5d00; }
.slip-nombor {
font-size: 4.5rem;
font-weight: 900;
text-align: center;
letter-spacing: 0.1em;
color: var(--biru);
margin: 0.5rem 0;
font-variant-numeric: tabular-nums;
}
.slip-butiran {
width: 100%;
border-collapse: collapse;
margin: 1rem 0;
}
.slip-butiran th,
.slip-butiran td {
text-align: left;
padding: 0.5rem 0.6rem;
border-bottom: 1px solid var(--kelabu-border);
vertical-align: top;
}
.slip-butiran th {
width: 38%;
color: #5a6172;
font-weight: 600;
white-space: nowrap;
}
table.jadual {
width: 100%;
border-collapse: collapse;
background: #fff;
font-size: 0.92rem;
}
table.jadual th,
table.jadual td {
padding: 0.55rem 0.6rem;
border-bottom: 1px solid var(--kelabu-border);
text-align: left;
vertical-align: top;
}
table.jadual thead th {
background: var(--biru);
color: #fff;
position: sticky;
top: 0;
}
table.jadual tbody tr:nth-child(even) { background: #f8f9fb; }
.lencana {
display: inline-block;
padding: 0.15rem 0.6rem;
border-radius: 999px;
font-size: 0.78rem;
font-weight: 700;
}
.lencana-hijau { background: #e6f4ea; color: var(--hijau); }
.lencana-merah { background: #fdecea; color: var(--merah); }
.lencana-kelabu { background: #ececec; color: #555; }
.lencana-biru { background: #e8f0fe; color: var(--biru); }
.lencana-kuning { background: #fbf0d9; color: var(--kuning); }
.baris-tindakan {
display: flex;
gap: 0.4rem;
flex-wrap: wrap;
}
.tab-bar {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
flex-wrap: wrap;
}
.tab-bar a {
padding: 0.5rem 1rem;
border-radius: 8px;
text-decoration: none;
font-weight: 600;
background: #fff;
border: 1px solid var(--kelabu-border);
color: var(--teks);
}
.tab-bar a.aktif {
background: var(--biru);
border-color: var(--biru);
color: #fff;
}
.qr-wrap {
text-align: center;
padding: 1rem;
}
.qr-wrap svg {
max-width: 100%;
height: auto;
}
.stat-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 0.75rem;
margin-bottom: 1rem;
}
.stat {
background: #fff;
border: 1px solid var(--kelabu-border);
border-radius: 10px;
padding: 0.9rem;
text-align: center;
}
.stat .nilai {
font-size: 1.8rem;
font-weight: 800;
color: var(--biru);
}
.stat .label { font-size: 0.85rem; color: #5a6172; }
.teks-tengah { text-align: center; }
.teks-kecil { font-size: 0.85rem; color: #5a6172; }
.mb-0 { margin-bottom: 0; }
.mt-1 { margin-top: 1rem; }
.ralat-medan { color: var(--merah); font-size: 0.88rem; margin: -0.5rem 0 0.9rem; }
/* ===== Jadual: kepala (tajuk + carian), badan, kaki (info + paging) ===== */
.jadual-kepala {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
flex-wrap: wrap;
padding: 1rem 1.25rem;
}
.tajuk-jadual {
margin: 0;
font-size: 1.05rem;
border-left: 4px solid var(--biru);
padding-left: 0.6rem;
}
.tajuk-jadual.hijau { border-color: var(--hijau); color: var(--hijau); }
.tajuk-jadual.merah { border-color: var(--merah); color: var(--merah); }
.tajuk-jadual.kuning { border-color: var(--kuning); color: var(--kuning); }
.jadual-kepala .cari-input {
width: auto;
flex: 1 1 220px;
max-width: 360px;
margin: 0;
padding: 0.5rem 0.75rem;
font-size: 0.95rem;
}
.jadual-bekas { overflow-x: auto; }
.jadual-kaki {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
flex-wrap: wrap;
padding: 0.75rem 1.25rem;
border-top: 1px solid var(--kelabu-border);
}
.paging { display: flex; gap: 0.3rem; flex-wrap: wrap; }
.paging-btn {
min-width: 2.2rem;
padding: 0.35rem 0.6rem;
border: 1px solid var(--kelabu-border);
background: #fff;
color: var(--teks);
border-radius: 6px;
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
}
.paging-btn:hover:not(:disabled) { background: var(--kelabu); }
.paging-btn.aktif { background: var(--biru); border-color: var(--biru); color: #fff; }
.paging-btn:disabled { opacity: 0.45; cursor: default; }
@media print {
.topbar, .tiada-cetak { display: none !important; }
body { background: #fff; }
.kad { border: none; }
/* Cetak semua baris tanpa mengira halaman semasa */
tr.baris-data { display: table-row !important; }
}
@media (max-width: 640px) {
.slip-nombor { font-size: 3.5rem; }
table.jadual { font-size: 0.85rem; }
.jadual-kepala, .jadual-kaki { padding: 0.8rem; }
.jadual-kepala .cari-input { max-width: none; }
/* Jadual responsif: setiap baris jadi kad bertindan dgn label */
.jadual-responsif thead { display: none; }
.jadual-responsif tbody tr {
display: block;
border: 1px solid var(--kelabu-border);
border-radius: 8px;
margin: 0.6rem;
padding: 0.3rem 0.6rem;
background: #fff !important;
}
.jadual-responsif tbody td {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 1rem;
border: none;
padding: 0.35rem 0;
text-align: right;
}
.jadual-responsif tbody td::before {
content: attr(data-label);
font-weight: 600;
color: #5a6172;
text-align: left;
flex: 0 0 auto;
}
.jadual-responsif tbody td:last-child { padding-bottom: 0.1rem; }
.jadual-responsif .baris-tindakan { justify-content: flex-end; }
.jadual-responsif .baris-tiada td { justify-content: center; text-align: center; }
.jadual-responsif .baris-tiada td::before { content: ""; }
}