fix: respect ios safe areas
All checks were successful
CI / Lint, typecheck and build (push) Successful in 9m54s
All checks were successful
CI / Lint, typecheck and build (push) Successful in 9m54s
This commit is contained in:
@@ -46,7 +46,7 @@ html {
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
background: hsl(var(--background));
|
||||
color: hsl(var(--foreground));
|
||||
-webkit-font-smoothing: antialiased;
|
||||
@@ -89,12 +89,56 @@ select {
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.app-header-safe {
|
||||
padding-top: env(safe-area-inset-top);
|
||||
}
|
||||
|
||||
.app-main-safe {
|
||||
padding-bottom: calc(7rem + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.mobile-nav-safe {
|
||||
bottom: calc(0.75rem + env(safe-area-inset-bottom));
|
||||
left: calc(0.75rem + env(safe-area-inset-left));
|
||||
right: calc(0.75rem + env(safe-area-inset-right));
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
inset: -1px 0 0;
|
||||
box-sizing: border-box;
|
||||
height: calc(100dvh + 1px);
|
||||
min-height: calc(100dvh + 1px);
|
||||
background: hsl(var(--foreground) / 0.55);
|
||||
}
|
||||
|
||||
.modal-safe-area {
|
||||
padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
@layer utilities {
|
||||
.modal-safe-area {
|
||||
padding:
|
||||
calc(1rem + env(safe-area-inset-top))
|
||||
calc(1rem + env(safe-area-inset-right))
|
||||
calc(1rem + env(safe-area-inset-bottom))
|
||||
calc(1rem + env(safe-area-inset-left));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
@layer utilities {
|
||||
.modal-safe-area {
|
||||
padding:
|
||||
calc(2rem + env(safe-area-inset-top))
|
||||
calc(2rem + env(safe-area-inset-right))
|
||||
calc(2rem + env(safe-area-inset-bottom))
|
||||
calc(2rem + env(safe-area-inset-left));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@supports (-moz-appearance: none) {
|
||||
|
||||
@@ -88,7 +88,7 @@ export function DayForecastModal({
|
||||
<AnimatePresence>
|
||||
{day ? (
|
||||
<motion.div
|
||||
className="modal-overlay z-[90] flex items-center justify-center p-0 sm:p-4 lg:p-8"
|
||||
className="modal-overlay modal-safe-area z-[90] flex items-center justify-center"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
@@ -98,7 +98,7 @@ export function DayForecastModal({
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="day-forecast-title"
|
||||
className="h-full w-full overflow-hidden bg-background shadow-card sm:max-w-6xl sm:rounded-panel sm:border sm:border-border/70"
|
||||
className="h-full max-h-full w-full overflow-hidden bg-background shadow-card sm:max-w-6xl sm:rounded-panel sm:border sm:border-border/70"
|
||||
initial={{ opacity: 0, y: 28, scale: 0.985 }}
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
exit={{ opacity: 0, y: 20, scale: 0.99 }}
|
||||
|
||||
@@ -15,7 +15,7 @@ export function AppShell({ children }: { children: React.ReactNode }) {
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<div className="min-h-screen overflow-x-hidden bg-background">
|
||||
<header className="sticky top-0 z-40 border-b border-border/70 bg-surface">
|
||||
<header className="app-header-safe sticky top-0 z-40 border-b border-border/70 bg-surface">
|
||||
<div className="mx-auto flex max-w-7xl items-center justify-between px-4 py-3 sm:px-6 lg:px-8">
|
||||
<Link href="/" className="text-2xl font-semibold tracking-[-0.09em] text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent">
|
||||
wtr<span className="text-accent">.</span>
|
||||
@@ -35,8 +35,8 @@ export function AppShell({ children }: { children: React.ReactNode }) {
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main className="mx-auto max-w-7xl px-4 pb-28 pt-5 sm:px-6 sm:pt-8 lg:px-8">{children}</main>
|
||||
<nav aria-label={t("nav.mobile")} className="fixed inset-x-3 bottom-3 z-50 flex justify-around rounded-panel border border-border/70 bg-surface p-1.5 shadow-card md:hidden">
|
||||
<main className="app-main-safe mx-auto max-w-7xl px-4 pt-5 sm:px-6 sm:pt-8 lg:px-8">{children}</main>
|
||||
<nav aria-label={t("nav.mobile")} className="mobile-nav-safe fixed z-50 flex justify-around rounded-panel border border-border/70 bg-surface p-1.5 shadow-card md:hidden">
|
||||
{NAV_ITEMS.map((item, index) => {
|
||||
const Icon = icons[index];
|
||||
const active = item.href === "/" ? pathname === "/" : pathname.startsWith(item.href);
|
||||
|
||||
Reference in New Issue
Block a user