refactor(ui): comprehensive light mode fixes and dashboard cleanup
- Light mode: fix 40+ missing CSS overrides (solid emerald/cyan bg-950, 300-level text colours, border opacity variants, hover states, violet accent, bg-slate-900/30 and /90, bg-rose-950/30, red-950/50) - Light mode: fix broad bg-gradient-to-br override to only target dark banner cards (from-[#1E293B]), preserving coloured user avatar gradients - Light mode: BookingDetailsModal JSON panel switched to GitHub-Light style (bg #f6f8fa) including <pre> override so the general 'pre' rule cannot darken it back - Dashboard: simplify banner (flat card, no gradient/watermark/time-widget) - Dashboard: reduce visual noise (shorter titles, remove LIVE animated badge, remove italic notes quote, neutral checklist items, no footer jargon) - Dashboard: normalise section-icon colours to slate-400 except Active (emerald) - Dashboard: replace non-standard Tailwind classes (slate-101/350/905/1000, indigo-405, emerald-990) with valid equivalents - Dashboard: standardise button style to rounded-lg + text-xs across Active Reservations and Upcoming cards; add visible borders on Cancel/Purge
This commit is contained in:
@ -65,10 +65,10 @@ export default function Dashboard({
|
||||
// Quick state checklist for the user to mark items as done as they test their lab!
|
||||
// (kept deliberately nerdy - morale is a critical infrastructure dependency)
|
||||
const [todoList, setTodoList] = useState([
|
||||
{ id: 't1', text: 'Ping 8.8.8.8 to confirm the Internet still exists', checked: false },
|
||||
{ id: 't2', text: 'Coffee level nominal ☕ - packets route faster on caffeine', checked: true },
|
||||
{ id: 't3', text: "Rule out DNS first (narrator: it was, in fact, always DNS)", checked: false },
|
||||
{ id: 't4', text: 'Layer-1 check: is it actually plugged in? (PEBKAC defense)', checked: false }
|
||||
{ id: 't1', text: 'Verify network connectivity (ping gateway)', checked: false },
|
||||
{ id: 't2', text: 'Coffee ready ☕', checked: true },
|
||||
{ id: 't3', text: 'Check DNS resolution', checked: false },
|
||||
{ id: 't4', text: 'Confirm physical connections are in place', checked: false }
|
||||
]);
|
||||
|
||||
const toggleTodo = (id: string) => {
|
||||
@ -91,21 +91,17 @@ export default function Dashboard({
|
||||
return (
|
||||
<div className="space-y-6" id="dashboard-cockpit-root">
|
||||
|
||||
{/* Banner Card Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-6 bg-gradient-to-br from-[#1E293B] to-[#111827] border border-slate-800 rounded-2xl p-6 shadow-sm overflow-hidden relative">
|
||||
<div className="absolute top-0 right-0 p-8 text-slate-800 pointer-events-none select-none font-mono text-9xl font-extrabold opacity-10">
|
||||
NET
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-8 space-y-4">
|
||||
<h2 className="text-2xl font-bold tracking-tight text-white leading-tight font-sans">
|
||||
Welcome back, <span className="text-emerald-400">{currentUser.name}</span>!
|
||||
{/* Banner */}
|
||||
<div className="bg-[#1E293B] border border-slate-800 rounded-2xl p-6 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||
<div className="space-y-1.5">
|
||||
<h2 className="text-xl font-bold tracking-tight text-white font-sans">
|
||||
Welcome back, <span className="text-emerald-400">{currentUser.name}</span>
|
||||
</h2>
|
||||
<p className="text-xs text-slate-300 leading-relaxed font-sans max-w-xl">
|
||||
Your lab cockpit. Grab some hardware, block a time slot, and keep the rescue runbooks one click away for when a switch decides to packet-storm itself at 16:59 on a Friday. root@ghostgrid:~# have fun, break things (in the lab).
|
||||
<p className="text-xs text-slate-400 font-sans">
|
||||
Your lab management hub. Reserve hardware, track active sessions, and keep runbooks close.
|
||||
</p>
|
||||
|
||||
<div className="pt-2 flex items-center gap-3">
|
||||
</div>
|
||||
<div className="flex items-center gap-3 shrink-0">
|
||||
<button
|
||||
onClick={onNavigateToCalendar}
|
||||
className="px-4 py-2 bg-emerald-600 hover:bg-emerald-500 text-slate-950 font-sans font-bold text-xs rounded-lg transition-colors flex items-center gap-1.5 hover:cursor-pointer"
|
||||
@ -122,30 +118,6 @@ export default function Dashboard({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-4 bg-slate-950/60 p-4 rounded-xl border border-slate-850 flex flex-col justify-between font-sans">
|
||||
<div>
|
||||
<span className="text-[10px] font-mono uppercase tracking-widest text-slate-500 block">System Time</span>
|
||||
<div className="text-2xl font-mono text-emerald-400 font-bold mt-1 tabular-nums">
|
||||
{now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' })}
|
||||
</div>
|
||||
<p className="text-[10px] text-slate-400 font-sans mt-0.5">
|
||||
{now.toLocaleDateString([], { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' })}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 pt-4 border-t border-slate-850 grid grid-cols-2 gap-2 text-center text-[10px] text-slate-350">
|
||||
<div className="bg-slate-900 p-2 rounded border border-slate-850">
|
||||
<span className="block font-bold text-slate-100 font-mono">{devices.length}</span>
|
||||
<span>Hardware Nodes</span>
|
||||
</div>
|
||||
<div className="bg-slate-900 p-2 rounded border border-slate-850">
|
||||
<span className="block font-bold text-slate-100 font-mono">{labs.length}</span>
|
||||
<span>Available Labs</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main Grid Content */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
|
||||
|
||||
@ -156,28 +128,16 @@ export default function Dashboard({
|
||||
<div className="bg-[#1E293B] border border-slate-800 rounded-xl p-5 shadow-sm">
|
||||
<h3 className="font-bold text-sm text-slate-100 flex items-center gap-2 mb-4 font-sans justify-between">
|
||||
<span className="flex items-center gap-2">
|
||||
<Clock className="w-4.5 h-4.5 text-emerald-400" />
|
||||
Active Reservations (your boxes, right now)
|
||||
</span>
|
||||
<span className="inline-flex items-center gap-1.5 text-[10px] font-mono font-bold text-emerald-400 bg-emerald-950/40 border border-emerald-900/50 rounded-full px-2.5 py-0.5">
|
||||
<span className="relative flex h-1.5 w-1.5">
|
||||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
|
||||
<span className="relative inline-flex rounded-full h-1.5 w-1.5 bg-emerald-500"></span>
|
||||
</span>
|
||||
LIVE
|
||||
<Clock className="w-4 h-4 text-emerald-400" />
|
||||
Active Reservations
|
||||
</span>
|
||||
<span className="w-2 h-2 rounded-full bg-emerald-500 shrink-0" />
|
||||
</h3>
|
||||
|
||||
{activeBookings.length === 0 ? (
|
||||
<div className="text-center py-10 bg-slate-900/35 rounded-lg border border-slate-850 p-6 font-sans">
|
||||
<PlayCircle className="w-8 h-8 text-slate-700 mx-auto mb-2 opacity-50" />
|
||||
<p className="text-xs text-slate-400">No boxes checked out right now. idle hands, idle hardware.</p>
|
||||
<button
|
||||
onClick={onNavigateToCalendar}
|
||||
className="text-xs text-emerald-400 font-semibold underline mt-2 hover:text-emerald-300"
|
||||
>
|
||||
grab a slot ->
|
||||
</button>
|
||||
<div className="text-center py-8 bg-slate-900/35 rounded-lg border border-slate-800 font-sans">
|
||||
<PlayCircle className="w-7 h-7 text-slate-600 mx-auto mb-2 opacity-50" />
|
||||
<p className="text-xs text-slate-400">No active sessions.</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4 font-sans">
|
||||
@ -209,28 +169,24 @@ export default function Dashboard({
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-slate-300 leading-relaxed font-sans mb-3 italic">
|
||||
"{booking.notes || 'no notes - running blind'}"
|
||||
</p>
|
||||
|
||||
<div className="pt-3 border-t border-slate-900/60 flex justify-between items-center text-[10px]">
|
||||
<div className="pt-3 border-t border-slate-800/60 flex justify-between items-center text-[10px]">
|
||||
<span className="font-mono text-slate-400">
|
||||
Active window: {startF} - {endF}
|
||||
{startF} – {endF}
|
||||
</span>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={() => onSelectBookingDetails(booking)}
|
||||
className="px-2.5 py-1 bg-emerald-950/80 border border-emerald-500/30 text-emerald-400 hover:text-emerald-300 rounded flex items-center gap-1 transition-all font-semibold hover:cursor-pointer"
|
||||
className="px-3 py-1.5 bg-emerald-950/80 border border-emerald-500/30 text-emerald-400 hover:text-emerald-300 rounded-lg text-xs font-semibold transition-all hover:cursor-pointer"
|
||||
>
|
||||
Inspect Details (Rest / Ansible)
|
||||
Details
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (confirm('Are you sure you want to release these nodes early? Hardware holds will terminate immediately.')) {
|
||||
if (confirm('Release this reservation early?')) {
|
||||
onCancelBooking(booking.id);
|
||||
}
|
||||
}}
|
||||
className="px-2.5 py-1 bg-rose-950/40 border border-rose-700/50 text-rose-400 hover:bg-rose-900/60 hover:border-rose-500 hover:text-rose-300 rounded flex items-center gap-1 transition-all font-semibold hover:cursor-pointer"
|
||||
className="px-3 py-1.5 bg-rose-950/40 border border-rose-700/50 text-rose-400 hover:bg-rose-900/60 hover:border-rose-500 hover:text-rose-300 rounded-lg text-xs font-semibold transition-all hover:cursor-pointer"
|
||||
>
|
||||
Release
|
||||
</button>
|
||||
@ -245,13 +201,13 @@ export default function Dashboard({
|
||||
|
||||
{/* Upcoming Sessions */}
|
||||
<div className="bg-[#1E293B] border border-slate-800 rounded-xl p-5 shadow-sm font-sans">
|
||||
<h3 className="font-bold text-sm text-slate-101 flex items-center gap-2 mb-3.5">
|
||||
<Calendar className="w-4.5 h-4.5 text-indigo-400" />
|
||||
Upcoming in the Queue ({upcomingBookings.length})
|
||||
<h3 className="font-bold text-sm text-slate-100 flex items-center gap-2 mb-3.5">
|
||||
<Calendar className="w-4 h-4 text-slate-400" />
|
||||
Upcoming ({upcomingBookings.length})
|
||||
</h3>
|
||||
|
||||
{upcomingBookings.length === 0 ? (
|
||||
<p className="text-xs text-slate-400 py-4 italic text-center">Queue is empty. crontab clean, nothing scheduled.</p>
|
||||
<p className="text-xs text-slate-400 py-4 text-center">No upcoming reservations.</p>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
{upcomingBookings.map((booking) => {
|
||||
@ -260,14 +216,14 @@ export default function Dashboard({
|
||||
const startF = new Date(booking.startDateTime).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
|
||||
const endF = new Date(booking.endDateTime).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
|
||||
return (
|
||||
<div key={booking.id} className="p-3 bg-slate-905/30 border border-slate-850 hover:border-slate-800 rounded-lg flex flex-col justify-between">
|
||||
<div key={booking.id} className="p-3 bg-slate-900/30 border border-slate-800 hover:border-slate-700 rounded-lg flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="flex justify-between items-start mb-1">
|
||||
<span className="font-mono font-bold text-[10px] text-indigo-405 bg-indigo-950/50 border border-indigo-900 px-2 py-0.5 rounded">
|
||||
<span className="font-mono font-bold text-[10px] text-indigo-400 bg-indigo-950/50 border border-indigo-900/50 px-2 py-0.5 rounded">
|
||||
{dayStr}
|
||||
</span>
|
||||
<span className="text-[10px] font-mono text-slate-500">
|
||||
{startF} - {endF}
|
||||
{startF} – {endF}
|
||||
</span>
|
||||
</div>
|
||||
<h4 className="text-xs font-bold text-slate-200 mt-1 font-sans">{lab?.name}</h4>
|
||||
@ -276,32 +232,32 @@ export default function Dashboard({
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="pt-2 mt-2 border-t border-slate-850 flex justify-end gap-1.5 pt-2">
|
||||
<div className="pt-2 mt-2 border-t border-slate-800 flex justify-end gap-1.5">
|
||||
<button
|
||||
onClick={() => onSelectBookingDetails(booking)}
|
||||
className="px-2.5 py-1 text-[9px] text-emerald-400 hover:text-emerald-350 bg-emerald-950/40 border border-emerald-990/30 rounded font-semibold transition hover:cursor-pointer"
|
||||
className="px-2.5 py-1 text-xs text-emerald-400 hover:text-emerald-300 bg-emerald-950/40 border border-emerald-900/30 rounded-lg font-semibold transition hover:cursor-pointer"
|
||||
>
|
||||
Specs / REST API
|
||||
Details
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (confirm('Cancel this upcoming reservation? Linked SMTP alerts will notify appropriate parties.')) {
|
||||
if (confirm('Cancel this upcoming reservation?')) {
|
||||
onCancelBooking(booking.id);
|
||||
}
|
||||
}}
|
||||
className="px-2 py-1 text-[9px] text-slate-400 hover:text-white hover:bg-slate-800 rounded border border-transparent hover:cursor-pointer"
|
||||
className="px-2.5 py-1 text-xs text-slate-400 hover:text-slate-200 hover:bg-slate-800 rounded-lg border border-slate-700/50 hover:cursor-pointer transition"
|
||||
>
|
||||
Cancel Slot
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (confirm('Are you sure you want to permanently delete this reservation from SQLite storage? This action cannot be reversed.')) {
|
||||
if (confirm('Permanently delete this reservation?')) {
|
||||
onDeleteBooking(booking.id);
|
||||
}
|
||||
}}
|
||||
className="px-2 py-1 text-[9px] text-rose-400 hover:text-rose-300 hover:bg-rose-950/30 rounded border border-transparent hover:cursor-pointer"
|
||||
className="px-2.5 py-1 text-xs text-rose-400 hover:text-rose-300 hover:bg-rose-950/30 rounded-lg border border-rose-900/30 hover:cursor-pointer transition"
|
||||
>
|
||||
Purge SQLite
|
||||
Purge
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -316,62 +272,58 @@ export default function Dashboard({
|
||||
{/* RIGHT COLUMN: Checklist and simulated action panel */}
|
||||
<div className="lg:col-span-4 space-y-6">
|
||||
|
||||
{/* Workflows Checklist */}
|
||||
{/* Lab Checklist */}
|
||||
<div className="bg-[#1E293B] border border-slate-800 rounded-xl p-5 shadow-sm font-sans">
|
||||
<h3 className="font-bold text-sm text-slate-101 flex items-center gap-2 mb-3.5">
|
||||
<ListTodo className="w-4.5 h-4.5 text-amber-500" />
|
||||
Pre-Flight Checklist (before you blame the network)
|
||||
<h3 className="font-bold text-sm text-slate-100 flex items-center gap-2 mb-3.5">
|
||||
<ListTodo className="w-4 h-4 text-slate-400" />
|
||||
Lab Checklist
|
||||
</h3>
|
||||
|
||||
<div className="space-y-2.5">
|
||||
<div className="space-y-2">
|
||||
{todoList.map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
onClick={() => toggleTodo(item.id)}
|
||||
className="flex items-start gap-2.5 p-2 bg-slate-1000/40 hover:bg-slate-900 rounded-lg cursor-pointer transition-all border border-slate-850/60"
|
||||
className="flex items-start gap-2.5 p-2 bg-slate-900/40 hover:bg-slate-900 rounded-lg cursor-pointer transition-all border border-slate-800/60"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={item.checked}
|
||||
onChange={() => {}}
|
||||
className="mt-0.5 rounded border-slate-800 text-emerald-500 focus:ring-emerald-450 w-3.5 h-3.5 shrink-0"
|
||||
className="mt-0.5 rounded border-slate-700 text-emerald-500 w-3.5 h-3.5 shrink-0"
|
||||
/>
|
||||
<span className={`text-[11px] leading-tight ${item.checked ? 'text-slate-500 line-through' : 'text-slate-200'}`}>
|
||||
<span className={`text-xs leading-tight ${item.checked ? 'text-slate-500 line-through' : 'text-slate-300'}`}>
|
||||
{item.text}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-4 pt-3 border-t border-slate-850 text-[10px] text-slate-450 text-center">
|
||||
Works on my machine (TM). check the boxes anyway.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Links - shortcut into the shared tooling dashboard */}
|
||||
{/* Quick Links */}
|
||||
<div className="bg-[#1E293B] border border-slate-800 rounded-xl p-5 shadow-sm font-sans">
|
||||
<h3 className="font-bold text-sm text-slate-101 flex items-center gap-2 mb-3.5 justify-between">
|
||||
<h3 className="font-bold text-sm text-slate-100 flex items-center gap-2 mb-3.5 justify-between">
|
||||
<span className="flex items-center gap-2">
|
||||
<LinkIcon className="w-4.5 h-4.5 text-cyan-400" />
|
||||
<LinkIcon className="w-4 h-4 text-slate-400" />
|
||||
Quick Links
|
||||
</span>
|
||||
<button
|
||||
onClick={onNavigateToLinks}
|
||||
className="text-[10px] text-cyan-400 hover:text-cyan-300 font-semibold flex items-center gap-0.5 hover:cursor-pointer"
|
||||
className="text-[10px] text-slate-400 hover:text-slate-200 font-semibold flex items-center gap-0.5 hover:cursor-pointer"
|
||||
>
|
||||
Manage <ArrowRight className="w-3 h-3" />
|
||||
</button>
|
||||
</h3>
|
||||
|
||||
{links.length === 0 ? (
|
||||
<div className="text-center py-6 bg-slate-900/35 rounded-lg border border-slate-850 p-5">
|
||||
<Globe className="w-7 h-7 text-slate-700 mx-auto mb-2 opacity-50" />
|
||||
<p className="text-[11px] text-slate-400">No shared links yet.</p>
|
||||
<div className="text-center py-6 bg-slate-900/35 rounded-lg border border-slate-800">
|
||||
<Globe className="w-7 h-7 text-slate-600 mx-auto mb-2 opacity-50" />
|
||||
<p className="text-xs text-slate-400">No shared links yet.</p>
|
||||
<button
|
||||
onClick={onNavigateToLinks}
|
||||
className="text-[11px] text-cyan-400 font-semibold underline mt-1.5 hover:text-cyan-300 hover:cursor-pointer"
|
||||
className="text-xs text-slate-400 font-semibold underline mt-1.5 hover:text-slate-200 hover:cursor-pointer"
|
||||
>
|
||||
Add CheckMK, Semaphore & co.
|
||||
Add links
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
@ -386,23 +338,23 @@ export default function Dashboard({
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group flex items-center gap-2.5 p-2 bg-slate-1000/40 hover:bg-slate-900 rounded-lg border border-slate-850/60 hover:border-slate-800 transition-all"
|
||||
className="group flex items-center gap-2.5 p-2 bg-slate-900/40 hover:bg-slate-900 rounded-lg border border-slate-800/60 hover:border-slate-700 transition-all"
|
||||
>
|
||||
<span className={`w-7 h-7 rounded-md bg-slate-950 border border-slate-800 flex items-center justify-center shrink-0 ${accent}`}>
|
||||
<Globe className="w-3.5 h-3.5" />
|
||||
</span>
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block text-[11px] font-semibold text-slate-200 group-hover:text-white truncate">{link.title}</span>
|
||||
<span className={`block text-[9px] font-mono truncate ${accent}`}>{host}</span>
|
||||
<span className="block text-xs font-semibold text-slate-200 group-hover:text-white truncate">{link.title}</span>
|
||||
<span className={`block text-[10px] font-mono truncate ${accent}`}>{host}</span>
|
||||
</span>
|
||||
<ExternalLink className="w-3.5 h-3.5 text-slate-600 group-hover:text-slate-300 shrink-0" />
|
||||
<ExternalLink className="w-3.5 h-3.5 text-slate-600 group-hover:text-slate-400 shrink-0" />
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
{links.length > 6 && (
|
||||
<button
|
||||
onClick={onNavigateToLinks}
|
||||
className="w-full text-center text-[10px] text-slate-500 hover:text-cyan-400 pt-1.5 font-semibold hover:cursor-pointer"
|
||||
className="w-full text-center text-[10px] text-slate-500 hover:text-slate-300 pt-1.5 font-semibold hover:cursor-pointer"
|
||||
>
|
||||
+{links.length - 6} more links
|
||||
</button>
|
||||
|
||||
282
src/index.css
282
src/index.css
@ -72,11 +72,11 @@
|
||||
border-color: var(--border) !important;
|
||||
}
|
||||
|
||||
/* Amber-tinted warning/safety card used in Dashboard */
|
||||
/* BookingCalendar "Quick Booking" green-tinted card */
|
||||
:root.light .bg-\[\#1D2535\],
|
||||
:root.light .bg-\[\#1d2535\] {
|
||||
background-color: #fffbeb !important;
|
||||
border-color: #fde68a !important;
|
||||
background-color: #f0fdf4 !important;
|
||||
border-color: #bbf7d0 !important;
|
||||
}
|
||||
|
||||
/* ── Header & nav ─────────────────────────────────────────────── */
|
||||
@ -128,8 +128,10 @@
|
||||
background-color: #e9ecf0 !important;
|
||||
}
|
||||
|
||||
/* ── Dashboard banner gradient ────────────────────────────────── */
|
||||
:root.light .bg-gradient-to-br {
|
||||
/* ── Dashboard / UserDirectory banner gradients (dark hex only) ── */
|
||||
/* Targets only the dark-themed banners, not coloured avatar gradients */
|
||||
:root.light .bg-gradient-to-br.from-\[\#1E293B\],
|
||||
:root.light .bg-gradient-to-br.from-\[\#1e293b\] {
|
||||
background-image: linear-gradient(to bottom right, #ffffff, #f1f5f9) !important;
|
||||
border-color: var(--border) !important;
|
||||
}
|
||||
@ -155,6 +157,7 @@
|
||||
}
|
||||
|
||||
/* ── Borders ──────────────────────────────────────────────────── */
|
||||
:root.light .border-slate-900,
|
||||
:root.light .border-slate-800,
|
||||
:root.light .border-slate-850,
|
||||
:root.light .border-slate-855,
|
||||
@ -164,6 +167,12 @@
|
||||
border-color: var(--border) !important;
|
||||
}
|
||||
|
||||
:root.light .border-red-900\/50,
|
||||
:root.light .border-red-900\/40,
|
||||
:root.light .border-red-900\/30 {
|
||||
border-color: #fca5a5 !important;
|
||||
}
|
||||
|
||||
:root.light .divide-slate-800 > *,
|
||||
:root.light .divide-slate-850 > * {
|
||||
border-color: var(--border) !important;
|
||||
@ -171,6 +180,9 @@
|
||||
|
||||
/* ── Text colours ─────────────────────────────────────────────── */
|
||||
:root.light .text-white,
|
||||
:root.light .text-white\/90,
|
||||
:root.light .text-white\/80,
|
||||
:root.light .text-white\/70,
|
||||
:root.light .text-slate-100,
|
||||
:root.light .text-slate-200 {
|
||||
color: var(--text) !important;
|
||||
@ -238,7 +250,13 @@
|
||||
color: #9f1239 !important;
|
||||
}
|
||||
|
||||
:root.light .bg-rose-950\/30,
|
||||
:root.light .hover\:bg-rose-950\/30:hover {
|
||||
background-color: #ffe4e6 !important;
|
||||
}
|
||||
|
||||
:root.light .bg-red-950\/60,
|
||||
:root.light .bg-red-950\/50,
|
||||
:root.light .bg-red-950\/40,
|
||||
:root.light .bg-red-950\/20 {
|
||||
background-color: #fee2e2 !important;
|
||||
@ -518,33 +536,40 @@
|
||||
border-color: var(--border) !important;
|
||||
}
|
||||
|
||||
/* JSON REST Response panel – always dark (code/terminal aesthetic) */
|
||||
/* JSON REST Response panel – GitHub Light style in light mode */
|
||||
:root.light #booking-details-modal .font-mono.bg-slate-950 {
|
||||
background-color: #0d1117 !important;
|
||||
color: #c9d1d9 !important;
|
||||
border-color: #30363d !important;
|
||||
background-color: #f6f8fa !important;
|
||||
color: #24292f !important;
|
||||
border-color: #d0d7de !important;
|
||||
}
|
||||
|
||||
/* Header bar inside the dark JSON panel – keep dark to match the block */
|
||||
/* The <pre> inside inherits the dark pre-rule; override explicitly */
|
||||
:root.light #booking-details-modal .font-mono.bg-slate-950 pre {
|
||||
background-color: transparent !important;
|
||||
color: #24292f !important;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
/* Header bar inside the JSON panel */
|
||||
:root.light #booking-details-modal .font-mono.bg-slate-950 .bg-slate-900 {
|
||||
background-color: #161b22 !important;
|
||||
border-color: #30363d !important;
|
||||
background-color: #eaeef2 !important;
|
||||
border-color: #d0d7de !important;
|
||||
}
|
||||
|
||||
/* Title label and icon in dark panel header */
|
||||
/* Title label and icon in panel header */
|
||||
:root.light #booking-details-modal .font-mono.bg-slate-950 .text-indigo-400 {
|
||||
color: #818cf8 !important;
|
||||
color: #6366f1 !important;
|
||||
}
|
||||
|
||||
/* Copy button inside dark panel */
|
||||
/* Copy button inside panel */
|
||||
:root.light #booking-details-modal .font-mono.bg-slate-950 button {
|
||||
background-color: #21262d !important;
|
||||
border-color: #30363d !important;
|
||||
color: #8b949e !important;
|
||||
background-color: #eaeef2 !important;
|
||||
border-color: #d0d7de !important;
|
||||
color: #57606a !important;
|
||||
}
|
||||
:root.light #booking-details-modal .font-mono.bg-slate-950 button:hover {
|
||||
background-color: #30363d !important;
|
||||
color: #f0f6fc !important;
|
||||
background-color: #d0d7de !important;
|
||||
color: #24292f !important;
|
||||
}
|
||||
|
||||
/* Ansible status card – orange accent in light mode */
|
||||
@ -630,3 +655,220 @@
|
||||
:root.light #add-link-btn:hover {
|
||||
background-color: #6366f1 !important;
|
||||
}
|
||||
|
||||
/* ─────────────────────────────────────────────────────────────────── */
|
||||
/* EXTENDED LIGHT MODE OVERRIDES */
|
||||
/* ─────────────────────────────────────────────────────────────────── */
|
||||
|
||||
/* ── Solid (no-opacity) color backgrounds ────────────────────────── */
|
||||
/* These are used in Logbook type badges and Dashboard countdown pill */
|
||||
|
||||
:root.light .bg-emerald-950 {
|
||||
background-color: #d1fae5 !important;
|
||||
border-color: #6ee7b7 !important;
|
||||
color: #065f46 !important;
|
||||
}
|
||||
|
||||
:root.light .bg-cyan-950 {
|
||||
background-color: #cffafe !important;
|
||||
border-color: #67e8f9 !important;
|
||||
color: #155e75 !important;
|
||||
}
|
||||
|
||||
:root.light .bg-indigo-950 {
|
||||
background-color: #e0e7ff !important;
|
||||
border-color: #a5b4fc !important;
|
||||
color: #3730a3 !important;
|
||||
}
|
||||
|
||||
:root.light .bg-rose-950 {
|
||||
background-color: #ffe4e6 !important;
|
||||
border-color: #fca5a5 !important;
|
||||
color: #9f1239 !important;
|
||||
}
|
||||
|
||||
/* ── emerald-900 opacity variants (quick booking modal tabs) ──────── */
|
||||
:root.light .bg-emerald-900\/50,
|
||||
:root.light .bg-emerald-900\/40,
|
||||
:root.light .bg-emerald-900\/30 {
|
||||
background-color: #d1fae5 !important;
|
||||
}
|
||||
|
||||
/* ── Violet accent (LinkDashboard) ────────────────────────────────── */
|
||||
:root.light .bg-violet-950\/60,
|
||||
:root.light .bg-violet-950\/40,
|
||||
:root.light .bg-violet-950\/20 {
|
||||
background-color: #ede9fe !important;
|
||||
border-color: #c4b5fd !important;
|
||||
color: #5b21b6 !important;
|
||||
}
|
||||
|
||||
:root.light .text-violet-400 {
|
||||
color: #7c3aed !important;
|
||||
}
|
||||
|
||||
/* ── 300-level text – near-invisible on white backgrounds ────────── */
|
||||
:root.light .text-amber-300 {
|
||||
color: #b45309 !important;
|
||||
}
|
||||
|
||||
:root.light .text-emerald-300 {
|
||||
color: #059669 !important;
|
||||
}
|
||||
|
||||
:root.light .text-cyan-300 {
|
||||
color: #0891b2 !important;
|
||||
}
|
||||
|
||||
:root.light .text-rose-300 {
|
||||
color: #be123c !important;
|
||||
}
|
||||
|
||||
:root.light .text-indigo-300 {
|
||||
color: #4338ca !important;
|
||||
}
|
||||
|
||||
/* ── Missing border opacity variants ─────────────────────────────── */
|
||||
|
||||
/* slate-700 with opacity */
|
||||
:root.light .border-slate-700\/40,
|
||||
:root.light .border-slate-700\/50,
|
||||
:root.light .border-slate-700\/60 {
|
||||
border-color: var(--border) !important;
|
||||
}
|
||||
|
||||
/* slate-900 opacity (section dividers, row separators) */
|
||||
:root.light .border-slate-900\/30,
|
||||
:root.light .border-slate-900\/40,
|
||||
:root.light .border-slate-900\/60 {
|
||||
border-color: var(--border) !important;
|
||||
}
|
||||
|
||||
/* emerald borders – solid and opacity variants */
|
||||
:root.light .border-emerald-900,
|
||||
:root.light .border-emerald-900\/30,
|
||||
:root.light .border-emerald-900\/40,
|
||||
:root.light .border-emerald-900\/60 {
|
||||
border-color: #6ee7b7 !important;
|
||||
}
|
||||
|
||||
:root.light .border-emerald-800\/50,
|
||||
:root.light .border-emerald-800\/60 {
|
||||
border-color: #a7f3d0 !important;
|
||||
}
|
||||
|
||||
/* cyan borders */
|
||||
:root.light .border-cyan-900\/50,
|
||||
:root.light .border-cyan-900\/60 {
|
||||
border-color: #67e8f9 !important;
|
||||
}
|
||||
|
||||
/* amber borders */
|
||||
:root.light .border-amber-900\/40,
|
||||
:root.light .border-amber-900\/60 {
|
||||
border-color: #fde68a !important;
|
||||
}
|
||||
|
||||
:root.light .border-amber-800\/50,
|
||||
:root.light .border-amber-800\/60 {
|
||||
border-color: #fde68a !important;
|
||||
}
|
||||
|
||||
/* rose borders */
|
||||
:root.light .border-rose-900\/30,
|
||||
:root.light .border-rose-900\/50,
|
||||
:root.light .border-rose-900\/60 {
|
||||
border-color: #fca5a5 !important;
|
||||
}
|
||||
|
||||
/* indigo borders */
|
||||
:root.light .border-indigo-900,
|
||||
:root.light .border-indigo-900\/40,
|
||||
:root.light .border-indigo-900\/50 {
|
||||
border-color: #a5b4fc !important;
|
||||
}
|
||||
|
||||
/* violet borders */
|
||||
:root.light .border-violet-900\/50,
|
||||
:root.light .border-violet-950\/40 {
|
||||
border-color: #c4b5fd !important;
|
||||
}
|
||||
|
||||
/* ── Missing bg-slate-900 opacity variants ───────────────────────── */
|
||||
:root.light .bg-slate-900\/30,
|
||||
:root.light .bg-slate-900\/50,
|
||||
:root.light .bg-slate-900\/70,
|
||||
:root.light .bg-slate-900\/90 {
|
||||
background-color: #f1f5f9 !important;
|
||||
}
|
||||
|
||||
/* ── bg-slate-800 additional variant ────────────────────────────── */
|
||||
:root.light .bg-slate-800\/40 {
|
||||
background-color: #e2e8f0 !important;
|
||||
}
|
||||
|
||||
/* ── Hover-state overrides for dark bg classes ───────────────────── */
|
||||
/* Without these the hover flashes a dark background in light mode. */
|
||||
|
||||
:root.light .hover\:bg-slate-900:hover {
|
||||
background-color: #f1f5f9 !important;
|
||||
}
|
||||
|
||||
:root.light .hover\:bg-slate-900\/35:hover,
|
||||
:root.light .hover\:bg-slate-900\/40:hover,
|
||||
:root.light .hover\:bg-slate-900\/60:hover,
|
||||
:root.light .hover\:bg-slate-900\/70:hover,
|
||||
:root.light .hover\:bg-slate-900\/80:hover {
|
||||
background-color: #f1f5f9 !important;
|
||||
}
|
||||
|
||||
:root.light .hover\:bg-slate-800:hover {
|
||||
background-color: #e2e8f0 !important;
|
||||
}
|
||||
|
||||
:root.light .hover\:bg-slate-800\/80:hover {
|
||||
background-color: #e2e8f0 !important;
|
||||
}
|
||||
|
||||
:root.light .hover\:bg-slate-950\/30:hover,
|
||||
:root.light .hover\:bg-slate-950\/40:hover {
|
||||
background-color: #f8fafc !important;
|
||||
}
|
||||
|
||||
/* Coloured hover states */
|
||||
:root.light .hover\:bg-emerald-900\/40:hover,
|
||||
:root.light .hover\:bg-emerald-900\/60:hover {
|
||||
background-color: #a7f3d0 !important;
|
||||
}
|
||||
|
||||
:root.light .hover\:bg-rose-900\/60:hover {
|
||||
background-color: #fecdd3 !important;
|
||||
}
|
||||
|
||||
:root.light .hover\:bg-red-950\/40:hover {
|
||||
background-color: #fee2e2 !important;
|
||||
}
|
||||
|
||||
/* ── Border-dashed empty slots (calendar grid) ───────────────────── */
|
||||
:root.light .border-slate-800\/40 {
|
||||
border-color: var(--border) !important;
|
||||
}
|
||||
|
||||
:root.light .hover\:border-slate-700\/60:hover {
|
||||
border-color: var(--border-muted) !important;
|
||||
}
|
||||
|
||||
/* ── Hover text colors – prevent near-white text on light backgrounds */
|
||||
:root.light .hover\:text-white:hover,
|
||||
:root.light .hover\:text-slate-100:hover,
|
||||
:root.light .hover\:text-slate-200:hover {
|
||||
color: var(--text) !important;
|
||||
}
|
||||
|
||||
:root.light .group:hover .group-hover\:text-white {
|
||||
color: var(--text) !important;
|
||||
}
|
||||
|
||||
:root.light .group:hover .group-hover\:text-slate-300 {
|
||||
color: var(--text-muted) !important;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user