fix: responsive park month calendar — dot-only on mobile, full pill on desktop
All checks were successful
Build and Deploy / Build & Push (push) Successful in 53s
All checks were successful
Build and Deploy / Build & Push (push) Successful in 53s
Mobile cells (~55px wide) can't fit hours text legibly, so show only a colored dot when open and a dash when no data. Desktop restores the full pill (hours + tz abbreviation) via Tailwind responsive classes. Row height is controlled by a new .park-calendar-grid CSS class: 72px fixed on mobile, minmax(96px, auto) on sm+, keeping desktop cells from looking cramped. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -104,6 +104,18 @@
|
|||||||
background: var(--color-surface-hover) !important;
|
background: var(--color-surface-hover) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Park month calendar — responsive row heights ───────────────────────── */
|
||||||
|
/* Mobile: fixed uniform rows so narrow columns don't cause height variance */
|
||||||
|
.park-calendar-grid {
|
||||||
|
grid-auto-rows: 72px;
|
||||||
|
}
|
||||||
|
/* sm+: let rows breathe and grow with their content (cells are wide enough) */
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
.park-calendar-grid {
|
||||||
|
grid-auto-rows: minmax(96px, auto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Pulse animation for skeleton ───────────────────────────────────────── */
|
/* ── Pulse animation for skeleton ───────────────────────────────────────── */
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
0%, 100% { opacity: 1; }
|
0%, 100% { opacity: 1; }
|
||||||
|
|||||||
@@ -119,15 +119,15 @@ export function ParkMonthCalendar({ parkId, year, month, monthData, today, timez
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/*
|
{/*
|
||||||
All day cells in ONE flat grid so every row shares the same
|
All day cells in ONE flat grid — eliminates per-week wrapper
|
||||||
fixed height — no per-week wrapper divs that could produce
|
divs that caused independent row heights and the slant effect.
|
||||||
rows of different heights on mobile.
|
Row height is controlled responsively via .park-calendar-grid CSS:
|
||||||
|
mobile = 72px fixed, sm+ = minmax(96px, auto).
|
||||||
*/}
|
*/}
|
||||||
<div style={{
|
<div
|
||||||
display: "grid",
|
className="park-calendar-grid"
|
||||||
gridTemplateColumns: "repeat(7, 1fr)",
|
style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)" }}
|
||||||
gridAutoRows: 76,
|
>
|
||||||
}}>
|
|
||||||
{cells.map((cell, idx) => {
|
{cells.map((cell, idx) => {
|
||||||
const ci = idx % 7;
|
const ci = idx % 7;
|
||||||
const isLastRow = idx >= cells.length - 7;
|
const isLastRow = idx >= cells.length - 7;
|
||||||
@@ -137,6 +137,7 @@ export function ParkMonthCalendar({ parkId, year, month, monthData, today, timez
|
|||||||
if (!cell.day || !cell.iso) {
|
if (!cell.day || !cell.iso) {
|
||||||
return (
|
return (
|
||||||
<div key={idx} style={{
|
<div key={idx} style={{
|
||||||
|
overflow: "hidden",
|
||||||
background: ci === 0 || ci === 6 ? "var(--color-weekend-header)" : "transparent",
|
background: ci === 0 || ci === 6 ? "var(--color-weekend-header)" : "transparent",
|
||||||
borderRight,
|
borderRight,
|
||||||
borderBottom,
|
borderBottom,
|
||||||
@@ -183,38 +184,53 @@ export function ParkMonthCalendar({ parkId, year, month, monthData, today, timez
|
|||||||
{cell.day}
|
{cell.day}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* Status — single-line pill so all cells stay uniform height */}
|
{/* ── Mobile status: colored dot only (sm:hidden) ──────── */}
|
||||||
|
{/* Cells are ~55px wide on mobile — no room for hours text */}
|
||||||
{!dayData ? (
|
{!dayData ? (
|
||||||
<span style={{ fontSize: "0.75rem", color: "var(--color-text-dim)" }}>—</span>
|
<span className="sm:hidden" style={{ fontSize: "0.7rem", color: "var(--color-text-dim)" }}>—</span>
|
||||||
|
) : isOpen ? (
|
||||||
|
<div className="sm:hidden" style={{
|
||||||
|
width: 7, height: 7, borderRadius: "50%", flexShrink: 0,
|
||||||
|
background: isPH ? "var(--color-ph-border)" : "var(--color-open-border)",
|
||||||
|
}} />
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{/* ── Desktop status: full pill with hours (hidden sm:block) */}
|
||||||
|
{!dayData ? (
|
||||||
|
<span className="hidden sm:inline" style={{ fontSize: "0.75rem", color: "var(--color-text-dim)" }}>—</span>
|
||||||
) : isPH && isOpen ? (
|
) : isPH && isOpen ? (
|
||||||
<div style={{
|
<div className="hidden sm:block" style={{
|
||||||
background: "var(--color-ph-bg)",
|
background: "var(--color-ph-bg)",
|
||||||
border: "1px solid var(--color-ph-border)",
|
border: "1px solid var(--color-ph-border)",
|
||||||
borderRadius: 4,
|
borderRadius: 5,
|
||||||
padding: "2px 4px",
|
padding: "3px 6px",
|
||||||
overflow: "hidden",
|
|
||||||
}}>
|
}}>
|
||||||
<div style={{ fontSize: "0.58rem", fontWeight: 700, color: "var(--color-ph-label)", textTransform: "uppercase", letterSpacing: "0.04em", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
|
<div style={{ fontSize: "0.6rem", fontWeight: 700, color: "var(--color-ph-label)", textTransform: "uppercase", letterSpacing: "0.05em" }}>
|
||||||
Passholder
|
Passholder
|
||||||
</div>
|
</div>
|
||||||
<div style={{ fontSize: "0.6rem", color: "var(--color-ph-hours)", marginTop: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
|
<div style={{ fontSize: "0.65rem", color: "var(--color-ph-hours)", marginTop: 2 }}>
|
||||||
{dayData.hoursLabel} <span style={{ opacity: 0.6 }}>{tzAbbr}</span>
|
{dayData.hoursLabel}
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: "0.58rem", color: "var(--color-ph-label)", opacity: 0.75, marginTop: 1, letterSpacing: "0.04em" }}>
|
||||||
|
{tzAbbr}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : isOpen ? (
|
) : isOpen ? (
|
||||||
<div style={{
|
<div className="hidden sm:block" style={{
|
||||||
background: "var(--color-open-bg)",
|
background: "var(--color-open-bg)",
|
||||||
border: "1px solid var(--color-open-border)",
|
border: "1px solid var(--color-open-border)",
|
||||||
borderRadius: 4,
|
borderRadius: 5,
|
||||||
padding: "2px 4px",
|
padding: "3px 6px",
|
||||||
overflow: "hidden",
|
|
||||||
}}>
|
}}>
|
||||||
<div style={{ fontSize: "0.6rem", color: "var(--color-open-hours)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
|
<div style={{ fontSize: "0.65rem", color: "var(--color-open-hours)" }}>
|
||||||
{dayData.hoursLabel} <span style={{ opacity: 0.6 }}>{tzAbbr}</span>
|
{dayData.hoursLabel}
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: "0.58rem", color: "var(--color-open-hours)", opacity: 0.6, marginTop: 1, letterSpacing: "0.04em" }}>
|
||||||
|
{tzAbbr}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<span style={{ fontSize: "1rem", color: "var(--color-text-dim)", lineHeight: 1 }}>·</span>
|
<span className="hidden sm:inline" style={{ fontSize: "1rem", color: "var(--color-text-dim)", lineHeight: 1 }}>·</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user