mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
feat(ui): experimental status bar style change for ios pwa app
this might break things. just an experiment. :)
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -17,5 +17,6 @@
|
|||||||
],
|
],
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.organizeImports": true
|
"source.organizeImports": true
|
||||||
}
|
},
|
||||||
|
"editor.formatOnSave": true
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import React, {
|
import React, {
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
HTMLAttributes,
|
|
||||||
ForwardRefRenderFunction,
|
ForwardRefRenderFunction,
|
||||||
|
HTMLAttributes,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import CachedImage from '../CachedImage';
|
import CachedImage from '../CachedImage';
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ const ImageFader: ForwardRefRenderFunction<HTMLDivElement, ImageFaderProps> = (
|
|||||||
{backgroundImages.map((imageUrl, i) => (
|
{backgroundImages.map((imageUrl, i) => (
|
||||||
<div
|
<div
|
||||||
key={`banner-image-${i}`}
|
key={`banner-image-${i}`}
|
||||||
className={`absolute inset-0 bg-cover bg-center transition-opacity duration-300 ease-in ${
|
className={`absolute absolute-top-shift inset-0 bg-cover bg-center transition-opacity duration-300 ease-in ${
|
||||||
i === activeIndex ? 'opacity-100' : 'opacity-0'
|
i === activeIndex ? 'opacity-100' : 'opacity-0'
|
||||||
}`}
|
}`}
|
||||||
{...props}
|
{...props}
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
import React, { MouseEvent, ReactNode, useRef } from 'react';
|
import React, { MouseEvent, ReactNode, useRef } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Button, { ButtonType } from '../Button';
|
|
||||||
import { useLockBodyScroll } from '../../../hooks/useLockBodyScroll';
|
|
||||||
import LoadingSpinner from '../LoadingSpinner';
|
|
||||||
import useClickOutside from '../../../hooks/useClickOutside';
|
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
|
import useClickOutside from '../../../hooks/useClickOutside';
|
||||||
|
import { useLockBodyScroll } from '../../../hooks/useLockBodyScroll';
|
||||||
import globalMessages from '../../../i18n/globalMessages';
|
import globalMessages from '../../../i18n/globalMessages';
|
||||||
import Transition from '../../Transition';
|
import Transition from '../../Transition';
|
||||||
|
import Button, { ButtonType } from '../Button';
|
||||||
|
import LoadingSpinner from '../LoadingSpinner';
|
||||||
|
|
||||||
interface ModalProps {
|
interface ModalProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
@@ -98,11 +98,14 @@ const Modal: React.FC<ModalProps> = ({
|
|||||||
show={!loading}
|
show={!loading}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="inline-block w-full max-h-full px-4 pt-5 pb-4 overflow-auto text-left align-bottom transition-all transform bg-gray-700 shadow-xl sm:rounded-lg sm:my-8 sm:align-middle sm:max-w-3xl"
|
className="relative inline-block w-full px-4 pt-5 pb-4 overflow-auto text-left align-bottom transition-all transform bg-gray-700 shadow-xl sm:rounded-lg sm:my-8 sm:align-middle sm:max-w-3xl"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
aria-labelledby="modal-headline"
|
aria-labelledby="modal-headline"
|
||||||
ref={modalRef}
|
ref={modalRef}
|
||||||
|
style={{
|
||||||
|
maxHeight: 'calc(100% - env(safe-area-inset-top) * 2)',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="sm:flex sm:items-center">
|
<div className="sm:flex sm:items-center">
|
||||||
{iconSvg && (
|
{iconSvg && (
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Transition from '../../Transition';
|
|
||||||
import { useLockBodyScroll } from '../../../hooks/useLockBodyScroll';
|
import { useLockBodyScroll } from '../../../hooks/useLockBodyScroll';
|
||||||
|
import Transition from '../../Transition';
|
||||||
|
|
||||||
interface SlideOverProps {
|
interface SlideOverProps {
|
||||||
show?: boolean;
|
show?: boolean;
|
||||||
@@ -70,7 +70,7 @@ const SlideOver: React.FC<SlideOverProps> = ({
|
|||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col h-full overflow-y-scroll bg-gray-700 shadow-xl">
|
<div className="flex flex-col h-full overflow-y-scroll bg-gray-700 shadow-xl">
|
||||||
<header className="px-4 py-6 space-y-1 bg-indigo-600">
|
<header className="px-4 space-y-1 bg-indigo-600 slideover">
|
||||||
<div className="flex items-center justify-between space-x-3">
|
<div className="flex items-center justify-between space-x-3">
|
||||||
<h2 className="text-lg font-medium leading-7 text-white">
|
<h2 className="text-lg font-medium leading-7 text-white">
|
||||||
{title}
|
{title}
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import React, { ReactNode, useRef } from 'react';
|
|
||||||
import Transition from '../../Transition';
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
import React, { ReactNode, useRef } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { useUser, Permission } from '../../../hooks/useUser';
|
|
||||||
import useClickOutside from '../../../hooks/useClickOutside';
|
import useClickOutside from '../../../hooks/useClickOutside';
|
||||||
|
import { Permission, useUser } from '../../../hooks/useUser';
|
||||||
|
import Transition from '../../Transition';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
dashboard: 'Discover',
|
dashboard: 'Discover',
|
||||||
@@ -148,8 +148,8 @@ const Sidebar: React.FC<SidebarProps> = ({ open, setClosed }) => {
|
|||||||
leaveTo="-translate-x-full"
|
leaveTo="-translate-x-full"
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<div className="relative flex flex-col flex-1 w-full max-w-xs bg-gray-800">
|
<div className="relative flex flex-col flex-1 w-full max-w-xs bg-gray-800 sidebar">
|
||||||
<div className="absolute top-0 right-0 p-1 -mr-14">
|
<div className="absolute top-0 right-0 p-1 sidebar-close-button -mr-14">
|
||||||
<button
|
<button
|
||||||
className="flex items-center justify-center w-12 h-12 rounded-full focus:outline-none focus:bg-gray-600"
|
className="flex items-center justify-center w-12 h-12 rounded-full focus:outline-none focus:bg-gray-600"
|
||||||
aria-label="Close sidebar"
|
aria-label="Close sidebar"
|
||||||
@@ -233,7 +233,7 @@ const Sidebar: React.FC<SidebarProps> = ({ open, setClosed }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="fixed top-0 bottom-0 left-0 hidden md:flex md:flex-shrink-0">
|
<div className="fixed top-0 bottom-0 left-0 hidden md:flex md:flex-shrink-0">
|
||||||
<div className="flex flex-col w-64">
|
<div className="flex flex-col w-64 sidebar">
|
||||||
<div className="flex flex-col flex-1 h-0 bg-gray-800">
|
<div className="flex flex-col flex-1 h-0 bg-gray-800">
|
||||||
<div className="flex flex-col flex-1 pt-5 pb-4 overflow-y-auto">
|
<div className="flex flex-col flex-1 pt-5 pb-4 overflow-y-auto">
|
||||||
<div className="flex items-center flex-shrink-0 px-4">
|
<div className="flex items-center flex-shrink-0 px-4">
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import SearchInput from './SearchInput';
|
|
||||||
import UserDropdown from './UserDropdown';
|
|
||||||
import Sidebar from './Sidebar';
|
|
||||||
import LanguagePicker from './LanguagePicker';
|
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { Permission, useUser } from '../../hooks/useUser';
|
import { Permission, useUser } from '../../hooks/useUser';
|
||||||
|
import LanguagePicker from './LanguagePicker';
|
||||||
|
import SearchInput from './SearchInput';
|
||||||
|
import Sidebar from './Sidebar';
|
||||||
|
import UserDropdown from './UserDropdown';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
alphawarning:
|
alphawarning:
|
||||||
@@ -37,14 +37,14 @@ const Layout: React.FC = ({ children }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full min-w-0 min-h-full bg-gray-900">
|
<div className="flex h-full min-w-0 min-h-full bg-gray-900">
|
||||||
<div className="absolute w-full h-64 from-gray-800 to-gray-900 bg-gradient-to-bl">
|
<div className="absolute top-0 w-full h-64 from-gray-800 to-gray-900 bg-gradient-to-bl">
|
||||||
<div className="relative inset-0 w-full h-full from-gray-900 to-transparent bg-gradient-to-t" />
|
<div className="relative inset-0 w-full h-full from-gray-900 to-transparent bg-gradient-to-t" />
|
||||||
</div>
|
</div>
|
||||||
<Sidebar open={isSidebarOpen} setClosed={() => setSidebarOpen(false)} />
|
<Sidebar open={isSidebarOpen} setClosed={() => setSidebarOpen(false)} />
|
||||||
|
|
||||||
<div className="relative flex flex-col flex-1 w-0 min-w-0 mb-16 md:ml-64">
|
<div className="relative flex flex-col flex-1 w-0 min-w-0 mb-16 md:ml-64">
|
||||||
<div
|
<div
|
||||||
className={`fixed left-0 right-0 z-10 flex flex-shrink-0 h-16 bg-opacity-80 transition duration-300 ${
|
className={`searchbar fixed left-0 right-0 top-0 z-10 flex flex-shrink-0 bg-opacity-80 transition duration-300 ${
|
||||||
isScrolled ? 'bg-gray-700' : 'bg-transparent'
|
isScrolled ? 'bg-gray-700' : 'bg-transparent'
|
||||||
} md:left-64`}
|
} md:left-64`}
|
||||||
style={{
|
style={{
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import PlexLoginButton from '../PlexLoginButton';
|
|
||||||
import { useUser } from '../../hooks/useUser';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useRouter } from 'next/dist/client/router';
|
import { useRouter } from 'next/dist/client/router';
|
||||||
import ImageFader from '../Common/ImageFader';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import Transition from '../Transition';
|
|
||||||
import LanguagePicker from '../Layout/LanguagePicker';
|
|
||||||
import LocalLogin from './LocalLogin';
|
|
||||||
import Accordion from '../Common/Accordion';
|
|
||||||
import useSettings from '../../hooks/useSettings';
|
import useSettings from '../../hooks/useSettings';
|
||||||
|
import { useUser } from '../../hooks/useUser';
|
||||||
|
import Accordion from '../Common/Accordion';
|
||||||
|
import ImageFader from '../Common/ImageFader';
|
||||||
import PageTitle from '../Common/PageTitle';
|
import PageTitle from '../Common/PageTitle';
|
||||||
|
import LanguagePicker from '../Layout/LanguagePicker';
|
||||||
|
import PlexLoginButton from '../PlexLoginButton';
|
||||||
|
import Transition from '../Transition';
|
||||||
|
import LocalLogin from './LocalLogin';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
signin: 'Sign In',
|
signin: 'Sign In',
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
|
import { groupBy } from 'lodash';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import React, { useContext, useMemo, useState } from 'react';
|
import React, { useContext, useMemo, useState } from 'react';
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import TruncateMarkup from 'react-truncate-markup';
|
import TruncateMarkup from 'react-truncate-markup';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import type { PersonDetail } from '../../../server/models/Person';
|
|
||||||
import type { PersonCombinedCreditsResponse } from '../../../server/interfaces/api/personInterfaces';
|
import type { PersonCombinedCreditsResponse } from '../../../server/interfaces/api/personInterfaces';
|
||||||
import Error from '../../pages/_error';
|
import type { PersonDetail } from '../../../server/models/Person';
|
||||||
import LoadingSpinner from '../Common/LoadingSpinner';
|
|
||||||
import TitleCard from '../TitleCard';
|
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
|
||||||
import { LanguageContext } from '../../context/LanguageContext';
|
|
||||||
import ImageFader from '../Common/ImageFader';
|
|
||||||
import Ellipsis from '../../assets/ellipsis.svg';
|
import Ellipsis from '../../assets/ellipsis.svg';
|
||||||
import { groupBy } from 'lodash';
|
import { LanguageContext } from '../../context/LanguageContext';
|
||||||
import PageTitle from '../Common/PageTitle';
|
import Error from '../../pages/_error';
|
||||||
import CachedImage from '../Common/CachedImage';
|
import CachedImage from '../Common/CachedImage';
|
||||||
|
import ImageFader from '../Common/ImageFader';
|
||||||
|
import LoadingSpinner from '../Common/LoadingSpinner';
|
||||||
|
import PageTitle from '../Common/PageTitle';
|
||||||
|
import TitleCard from '../TitleCard';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
appearsin: 'Appearances',
|
appearsin: 'Appearances',
|
||||||
@@ -166,7 +166,7 @@ const PersonDetails: React.FC = () => {
|
|||||||
<>
|
<>
|
||||||
<PageTitle title={data.name} />
|
<PageTitle title={data.name} />
|
||||||
{(sortedCrew || sortedCast) && (
|
{(sortedCrew || sortedCast) && (
|
||||||
<div className="absolute left-0 right-0 z-0 -top-16 h-96">
|
<div className="absolute top-0 left-0 right-0 z-0 h-96">
|
||||||
<ImageFader
|
<ImageFader
|
||||||
isDarker
|
isDarker
|
||||||
backgroundImages={[...(sortedCast ?? []), ...(sortedCrew ?? [])]
|
backgroundImages={[...(sortedCast ?? []), ...(sortedCrew ?? [])]
|
||||||
|
@@ -1,22 +1,22 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import '../styles/globals.css';
|
|
||||||
import App, { AppInitialProps, AppProps } from 'next/app';
|
|
||||||
import { SWRConfig } from 'swr';
|
|
||||||
import { ToastProvider } from 'react-toast-notifications';
|
|
||||||
import { parseCookies, setCookie } from 'nookies';
|
|
||||||
import Layout from '../components/Layout';
|
|
||||||
import { UserContext } from '../context/UserContext';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { User } from '../hooks/useUser';
|
import App, { AppInitialProps, AppProps } from 'next/app';
|
||||||
import { IntlProvider } from 'react-intl';
|
|
||||||
import { LanguageContext, AvailableLocales } from '../context/LanguageContext';
|
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
import { parseCookies, setCookie } from 'nookies';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { IntlProvider } from 'react-intl';
|
||||||
|
import { ToastProvider } from 'react-toast-notifications';
|
||||||
|
import { SWRConfig } from 'swr';
|
||||||
|
import { PublicSettingsResponse } from '../../server/interfaces/api/settingsInterfaces';
|
||||||
|
import Layout from '../components/Layout';
|
||||||
|
import LoadingBar from '../components/LoadingBar';
|
||||||
|
import StatusChecker from '../components/StatusChacker';
|
||||||
import Toast from '../components/Toast';
|
import Toast from '../components/Toast';
|
||||||
import { InteractionProvider } from '../context/InteractionContext';
|
import { InteractionProvider } from '../context/InteractionContext';
|
||||||
import StatusChecker from '../components/StatusChacker';
|
import { AvailableLocales, LanguageContext } from '../context/LanguageContext';
|
||||||
import { PublicSettingsResponse } from '../../server/interfaces/api/settingsInterfaces';
|
|
||||||
import { SettingsProvider } from '../context/SettingsContext';
|
import { SettingsProvider } from '../context/SettingsContext';
|
||||||
import LoadingBar from '../components/LoadingBar';
|
import { UserContext } from '../context/UserContext';
|
||||||
|
import { User } from '../hooks/useUser';
|
||||||
|
import '../styles/globals.css';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const loadLocaleData = (locale: AvailableLocales): Promise<any> => {
|
const loadLocaleData = (locale: AvailableLocales): Promise<any> => {
|
||||||
@@ -122,8 +122,8 @@ const CoreApp: Omit<NextAppComponentType, 'origGetInitialProps'> = ({
|
|||||||
<title>Overseerr</title>
|
<title>Overseerr</title>
|
||||||
<meta
|
<meta
|
||||||
name="viewport"
|
name="viewport"
|
||||||
content="width=device-width, initial-scale=1"
|
content="initial-scale=1, viewport-fit=cover, width=device-width"
|
||||||
/>
|
></meta>
|
||||||
</Head>
|
</Head>
|
||||||
<StatusChecker />
|
<StatusChecker />
|
||||||
<UserContext initialUser={user}>{component}</UserContext>
|
<UserContext initialUser={user}>{component}</UserContext>
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
import React from 'react';
|
|
||||||
import Document, {
|
import Document, {
|
||||||
Html,
|
|
||||||
Head,
|
|
||||||
Main,
|
|
||||||
NextScript,
|
|
||||||
DocumentContext,
|
DocumentContext,
|
||||||
DocumentInitialProps,
|
DocumentInitialProps,
|
||||||
|
Head,
|
||||||
|
Html,
|
||||||
|
Main,
|
||||||
|
NextScript,
|
||||||
} from 'next/document';
|
} from 'next/document';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
class MyDocument extends Document {
|
class MyDocument extends Document {
|
||||||
static async getInitialProps(
|
static async getInitialProps(
|
||||||
@@ -39,6 +39,11 @@ class MyDocument extends Document {
|
|||||||
sizes="16x16"
|
sizes="16x16"
|
||||||
href="/favicon-16x16.png"
|
href="/favicon-16x16.png"
|
||||||
/>
|
/>
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta
|
||||||
|
name="apple-mobile-web-app-status-bar-style"
|
||||||
|
content="black-translucent"
|
||||||
|
/>
|
||||||
<link rel="manifest" href="/site.webmanifest"></link>
|
<link rel="manifest" href="/site.webmanifest"></link>
|
||||||
</Head>
|
</Head>
|
||||||
<body>
|
<body>
|
||||||
|
@@ -3,10 +3,43 @@
|
|||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
@tailwind screens;
|
@tailwind screens;
|
||||||
|
|
||||||
|
html {
|
||||||
|
min-height: calc(100% + env(safe-area-inset-top));
|
||||||
|
padding: env(safe-area-inset-top) env(safe-area-inset-right)
|
||||||
|
env(safe-area-inset-bottom) env(safe-area-inset-left);
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@apply bg-gray-900;
|
@apply bg-gray-900;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.searchbar {
|
||||||
|
padding-top: env(safe-area-inset-top);
|
||||||
|
height: calc(4rem + env(safe-area-inset-top));
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
padding-top: env(safe-area-inset-top);
|
||||||
|
padding-left: env(safe-area-inset-left);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slideover {
|
||||||
|
padding-top: calc(1.5rem + env(safe-area-inset-top));
|
||||||
|
padding-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-close-button {
|
||||||
|
top: env(safe-area-inset-top);
|
||||||
|
}
|
||||||
|
|
||||||
|
.absolute-top-shift {
|
||||||
|
top: calc(-4rem - env(safe-area-inset-top));
|
||||||
|
}
|
||||||
|
|
||||||
|
.min-h-screen-shift {
|
||||||
|
min-height: calc(100vh + env(safe-area-inset-top));
|
||||||
|
}
|
||||||
|
|
||||||
.plex-button {
|
.plex-button {
|
||||||
@apply flex justify-center w-full px-4 py-2 text-sm font-medium text-center text-white transition duration-150 ease-in-out bg-indigo-600 border border-transparent rounded-md disabled:opacity-50;
|
@apply flex justify-center w-full px-4 py-2 text-sm font-medium text-center text-white transition duration-150 ease-in-out bg-indigo-600 border border-transparent rounded-md disabled:opacity-50;
|
||||||
background-color: #cc7b19;
|
background-color: #cc7b19;
|
||||||
@@ -42,7 +75,9 @@ a.slider-title {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.media-page {
|
.media-page {
|
||||||
@apply relative px-4 pt-16 -mx-4 -mt-16 bg-center bg-cover;
|
@apply relative px-4 -mx-4 bg-center bg-cover;
|
||||||
|
margin-top: calc(-4rem - env(safe-area-inset-top));
|
||||||
|
padding-top: calc(4rem + env(safe-area-inset-top));
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-page-bg-image {
|
.media-page-bg-image {
|
||||||
|
Reference in New Issue
Block a user