forked from MapComplete/MapComplete
Style: bring index page (and legacy subtle button) in line with the new style
This commit is contained in:
parent
8ed0a32d15
commit
64e791dbfb
13 changed files with 126 additions and 203 deletions
|
@ -27,7 +27,7 @@ export default class AllThemesGui {
|
|||
new LoginToggle(undefined, Translations.t.index.logIn, {
|
||||
osmConnection,
|
||||
featureSwitchUserbadge: new ImmutableStore(true),
|
||||
}),
|
||||
}).SetClass("flex justify-center w-full"),
|
||||
Translations.t.general.aboutMapComplete.intro.SetClass("link-underline"),
|
||||
new FixedUiElement("v" + Constants.vNumber).SetClass("block"),
|
||||
])
|
||||
|
|
|
@ -4,13 +4,15 @@ import { UIElement } from "../UIElement"
|
|||
import { VariableUiElement } from "./VariableUIElement"
|
||||
import Lazy from "./Lazy"
|
||||
import Loading from "./Loading"
|
||||
import SubtleButtonSvelte from "./SubtleButton.svelte"
|
||||
import SvelteUIElement from "./SvelteUIElement"
|
||||
import SubtleLink from "./SubtleLink.svelte";
|
||||
import Translations from "../i18n/Translations";
|
||||
import Combine from "./Combine";
|
||||
import Img from "./Img";
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export class SubtleButton extends UIElement {
|
||||
private readonly imageUrl: string | BaseUIElement
|
||||
private readonly message: string | BaseUIElement
|
||||
|
@ -42,7 +44,7 @@ export class SubtleButton extends UIElement {
|
|||
return new SvelteUIElement(SubtleLink, {href: this.options.url, newTab: this.options.newTab})
|
||||
}
|
||||
|
||||
const classes = "block flex p-3 my-2 bg-subtle rounded-lg hover:shadow-xl hover:bg-unsubtle transition-colors transition-shadow link-no-underline";
|
||||
const classes = "button";
|
||||
const message = Translations.W(this.message)?.SetClass("block overflow-ellipsis no-images flex-shrink");
|
||||
let img;
|
||||
const imgClasses = "block justify-center flex-none mr-4 " + (this.options?.imgSize ?? "h-11 w-11")
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
</script>
|
||||
|
||||
<a
|
||||
class={(options.extraClasses??"") + 'flex hover:shadow-xl transition-[color,background-color,box-shadow] hover:bg-unsubtle cursor-pointer'}
|
||||
class={(options.extraClasses??"") + ' button text-ellipsis'}
|
||||
{href}
|
||||
target={(newTab ? "_blank" : undefined) }
|
||||
>
|
||||
|
@ -48,16 +48,3 @@
|
|||
|
||||
<slot/>
|
||||
</a>
|
||||
|
||||
<style lang="scss">
|
||||
span,
|
||||
a {
|
||||
@apply flex p-3 my-2 py-4 rounded-lg shrink-0;
|
||||
@apply items-center w-full no-underline;
|
||||
@apply bg-subtle text-black;
|
||||
|
||||
:global(span) {
|
||||
@apply block text-ellipsis;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
export let onMainScreen: boolean = true
|
||||
|
||||
const prefix = "mapcomplete-hidden-theme-"
|
||||
const hiddenThemes: LayoutInformation[] = themeOverview.filter(
|
||||
const hiddenThemes: LayoutInformation[] = (themeOverview["default"] ?? themeOverview)?.filter(
|
||||
(layout) => layout.hideFromOverview
|
||||
)
|
||||
) ?? []
|
||||
const userPreferences = state.osmConnection.preferencesHandler.preferences
|
||||
const t = Translations.t.general.morescreen
|
||||
|
||||
|
@ -45,3 +45,4 @@
|
|||
</p>
|
||||
</svelte:fragment>
|
||||
</ThemesList>
|
||||
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
import Svg from "../../Svg"
|
||||
import Combine from "../Base/Combine"
|
||||
import { SubtleButton } from "../Base/SubtleButton"
|
||||
import Translations from "../i18n/Translations"
|
||||
import BaseUIElement from "../BaseUIElement"
|
||||
import LayoutConfig, { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig"
|
||||
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import LayoutConfig, {LayoutInformation} from "../../Models/ThemeConfig/LayoutConfig"
|
||||
import {ImmutableStore, Store, UIEventSource} from "../../Logic/UIEventSource"
|
||||
import Loc from "../../Models/Loc"
|
||||
import UserRelatedState from "../../Logic/State/UserRelatedState"
|
||||
import { Utils } from "../../Utils"
|
||||
import Title from "../Base/Title"
|
||||
import {Utils} from "../../Utils"
|
||||
import themeOverview from "../../assets/generated/theme_overview.json"
|
||||
import { Translation } from "../i18n/Translation"
|
||||
import { TextField } from "../Input/TextField"
|
||||
import {TextField} from "../Input/TextField"
|
||||
import Locale from "../i18n/Locale"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import ThemesList from "./ThemesList.svelte"
|
||||
|
|
|
@ -1,64 +1,36 @@
|
|||
<script lang="ts" context="module">
|
||||
export interface Theme {
|
||||
id: string
|
||||
icon: string
|
||||
title: any
|
||||
shortDescription: any
|
||||
definition?: any
|
||||
mustHaveLanguage?: boolean
|
||||
hideFromOverview: boolean
|
||||
keywords?: any[]
|
||||
}
|
||||
<script context="module" lang="ts">
|
||||
export interface Theme {
|
||||
id: string
|
||||
icon: string
|
||||
title: any
|
||||
shortDescription: any
|
||||
definition?: any
|
||||
mustHaveLanguage?: boolean
|
||||
hideFromOverview: boolean
|
||||
keywords?: any[]
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import Svg from "../../Svg"
|
||||
import SubtleButton from "../Base/SubtleButton.svelte"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Tr from "../Base/Tr.svelte";
|
||||
import {UIEventSource} from "../../Logic/UIEventSource"
|
||||
import Svg from "../../Svg"
|
||||
import SubtleButton from "../Base/SubtleButton.svelte"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Tr from "../Base/Tr.svelte";
|
||||
|
||||
export let search: UIEventSource<string>
|
||||
export let search: UIEventSource<string>
|
||||
|
||||
const t = Translations.t.general.morescreen
|
||||
const t = Translations.t.general.morescreen
|
||||
</script>
|
||||
|
||||
<span>
|
||||
<h5>{t.noMatchingThemes.toString()}</h5>
|
||||
<button
|
||||
on:click={() => {
|
||||
search.setData("")
|
||||
}}
|
||||
>
|
||||
<SubtleButton>
|
||||
<span slot="image">
|
||||
<ToSvelte construct={Svg.search_disable_svg().SetClass("w-6 mr-2")} />
|
||||
</span>
|
||||
<Tr t={t.noSearch} slot="message"/>
|
||||
</SubtleButton>
|
||||
</button>
|
||||
</span>
|
||||
<div class="w-full">
|
||||
<h5>{t.noMatchingThemes.toString()}</h5>
|
||||
<div class="flex justify-center">
|
||||
|
||||
<style lang="scss">
|
||||
span {
|
||||
@apply flex flex-col items-center w-full;
|
||||
|
||||
h5 {
|
||||
@apply w-max font-bold;
|
||||
}
|
||||
|
||||
// SubtleButton
|
||||
button {
|
||||
@apply h-12;
|
||||
|
||||
span {
|
||||
@apply w-max;
|
||||
|
||||
:global(img) {
|
||||
@apply h-6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<button on:click={() => search.setData("")}>
|
||||
<ToSvelte construct={Svg.search_disable_svg().SetClass("w-6 mr-2")}/>
|
||||
<Tr slot="message" t={t.noSearch}/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
<span>
|
||||
{t.hookMore.toString()}
|
||||
</span>
|
||||
<div class="w-full">
|
||||
|
||||
<SubtleLink href="./professional.html">
|
||||
<Tr slot="message" t={t.button} />
|
||||
<div class="w-full">
|
||||
<Tr slot="message" t={t.button} />
|
||||
</div>
|
||||
</SubtleLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div {
|
||||
@apply flex flex-col border border-gray-300 p-2 rounded-lg;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
<img slot="image" src={theme.icon} class="block h-11 w-11 bg-red mx-4" alt=""/>
|
||||
<span class="flex flex-col text-ellipsis overflow-hidden">
|
||||
<Tr t={title}/>
|
||||
<span class="subtle max-h-12">
|
||||
<span class="subtle max-h-12 truncate text-ellipsis">
|
||||
<Tr t={description}/>
|
||||
</span>
|
||||
</span>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
$: filteredThemes = themes.filter((theme) => MoreScreen.MatchesLayout(theme, $search))
|
||||
</script>
|
||||
|
||||
<section>
|
||||
<section class="w-full">
|
||||
<slot name="title" />
|
||||
{#if onMainScreen}
|
||||
<div class="md:grid md:grid-flow-row md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
|
@ -51,13 +51,7 @@
|
|||
</div>
|
||||
{/if}
|
||||
|
||||
{#if filteredThemes.length == 0}
|
||||
{#if filteredThemes.length === 0}
|
||||
<NoThemeResultButton {search} />
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<style lang="scss">
|
||||
section {
|
||||
@apply flex flex-col;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,37 +1,39 @@
|
|||
<script lang="ts">
|
||||
import { OsmConnection } from "../../Logic/Osm/OsmConnection"
|
||||
import { Store, Stores, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import type Loc from "../../Models/Loc"
|
||||
import { Utils } from "../../Utils"
|
||||
import ThemesList from "./ThemesList.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import UserRelatedState from "../../Logic/State/UserRelatedState"
|
||||
import {OsmConnection} from "../../Logic/Osm/OsmConnection"
|
||||
import {Store, Stores, UIEventSource} from "../../Logic/UIEventSource"
|
||||
import type Loc from "../../Models/Loc"
|
||||
import {Utils} from "../../Utils"
|
||||
import ThemesList from "./ThemesList.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import UserRelatedState from "../../Logic/State/UserRelatedState"
|
||||
|
||||
export let search: UIEventSource<string>
|
||||
export let state: UserRelatedState & {
|
||||
osmConnection: OsmConnection
|
||||
locationControl?: UIEventSource<Loc>
|
||||
}
|
||||
export let onMainScreen: boolean = true
|
||||
export let search: UIEventSource<string>
|
||||
export let state: UserRelatedState & {
|
||||
osmConnection: OsmConnection
|
||||
locationControl?: UIEventSource<Loc>
|
||||
}
|
||||
export let onMainScreen: boolean = true
|
||||
|
||||
const t = Translations.t.general
|
||||
const currentIds: Store<string[]> = state.installedUserThemes
|
||||
const stableIds = Stores.ListStabilized<string>(currentIds)
|
||||
let customThemes
|
||||
$: customThemes = Utils.NoNull($stableIds.map((id) => state.GetUnofficialTheme(id)))
|
||||
$: console.log("Custom themes are", customThemes)
|
||||
const t = Translations.t.general
|
||||
const currentIds: Store<string[]> = state.installedUserThemes
|
||||
const stableIds = Stores.ListStabilized<string>(currentIds)
|
||||
let customThemes
|
||||
$: customThemes = Utils.NoNull($stableIds.map((id) => state.GetUnofficialTheme(id)))
|
||||
$: console.log("Custom themes are", customThemes)
|
||||
</script>
|
||||
|
||||
<ThemesList
|
||||
{search}
|
||||
{state}
|
||||
{onMainScreen}
|
||||
themes={customThemes}
|
||||
isCustom={true}
|
||||
hideThemes={false}
|
||||
>
|
||||
<svelte:fragment slot="title">
|
||||
<!-- TODO: Change string to exclude html -->
|
||||
{@html t.customThemeIntro.toString()}
|
||||
</svelte:fragment>
|
||||
</ThemesList>
|
||||
{#if customThemes.length > 0}
|
||||
<ThemesList
|
||||
{search}
|
||||
{state}
|
||||
{onMainScreen}
|
||||
themes={customThemes}
|
||||
isCustom={true}
|
||||
hideThemes={false}
|
||||
>
|
||||
<svelte:fragment slot="title">
|
||||
<!-- TODO: Change string to exclude html -->
|
||||
{@html t.customThemeIntro.toString()}
|
||||
</svelte:fragment>
|
||||
</ThemesList>
|
||||
{/if}
|
||||
|
|
54
Utils.ts
54
Utils.ts
|
@ -704,10 +704,10 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
if (Array.isArray(leaf)) {
|
||||
for (let i = 0; i < (<any[]>leaf).length; i++) {
|
||||
const l = (<any[]>leaf)[i]
|
||||
collectedList.push({ leaf: l, path: [...travelledPath, "" + i] })
|
||||
collectedList.push({leaf: l, path: [...travelledPath, "" + i]})
|
||||
}
|
||||
} else {
|
||||
collectedList.push({ leaf, path: travelledPath })
|
||||
collectedList.push({leaf, path: travelledPath})
|
||||
}
|
||||
return collectedList
|
||||
}
|
||||
|
@ -785,7 +785,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
})
|
||||
}
|
||||
|
||||
const cp = { ...json }
|
||||
const cp = {...json}
|
||||
for (const key in json) {
|
||||
cp[key] = Utils.WalkJson(json[key], f, isLeaf, [...path, key])
|
||||
}
|
||||
|
@ -915,11 +915,11 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
const xhr = new XMLHttpRequest()
|
||||
xhr.onload = () => {
|
||||
if (xhr.status == 200) {
|
||||
resolve({ content: xhr.response })
|
||||
resolve({content: xhr.response})
|
||||
} else if (xhr.status === 302) {
|
||||
resolve({ redirect: xhr.getResponseHeader("location") })
|
||||
resolve({redirect: xhr.getResponseHeader("location")})
|
||||
} else if (xhr.status === 509 || xhr.status === 429) {
|
||||
resolve({ error: "rate limited", url, statuscode: xhr.status })
|
||||
resolve({error: "rate limited", url, statuscode: xhr.status})
|
||||
} else {
|
||||
resolve({
|
||||
error: "other error: " + xhr.statusText,
|
||||
|
@ -989,10 +989,10 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
}
|
||||
const promise =
|
||||
/*NO AWAIT as we work with the promise directly */ Utils.downloadJsonAdvanced(
|
||||
url,
|
||||
headers
|
||||
)
|
||||
Utils._download_cache.set(url, { promise, timestamp: new Date().getTime() })
|
||||
url,
|
||||
headers
|
||||
)
|
||||
Utils._download_cache.set(url, {promise, timestamp: new Date().getTime()})
|
||||
return await promise
|
||||
}
|
||||
|
||||
|
@ -1011,11 +1011,11 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
const injected = Utils.injectedDownloads[url]
|
||||
if (injected !== undefined) {
|
||||
console.log("Using injected resource for test for URL", url)
|
||||
return new Promise((resolve, _) => resolve({ content: injected }))
|
||||
return new Promise((resolve, _) => resolve({content: injected}))
|
||||
}
|
||||
const result = await Utils.downloadAdvanced(
|
||||
url,
|
||||
Utils.Merge({ accept: "application/json" }, headers ?? {})
|
||||
Utils.Merge({accept: "application/json"}, headers ?? {})
|
||||
)
|
||||
if (result["error"] !== undefined) {
|
||||
return <{ error: string; url: string; statuscode?: number }>result
|
||||
|
@ -1023,12 +1023,12 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
const data = result["content"]
|
||||
try {
|
||||
if (typeof data === "string") {
|
||||
return { content: JSON.parse(data) }
|
||||
return {content: JSON.parse(data)}
|
||||
}
|
||||
return { content: data }
|
||||
return {content: data}
|
||||
} catch (e) {
|
||||
console.error("Could not parse ", data, "due to", e, "\n", e.stack)
|
||||
return { error: "malformed", url }
|
||||
return {error: "malformed", url}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1052,7 +1052,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
const element = document.createElement("a")
|
||||
let file
|
||||
if (typeof contents === "string") {
|
||||
file = new Blob([contents], { type: options?.mimetype ?? "text/plain" })
|
||||
file = new Blob([contents], {type: options?.mimetype ?? "text/plain"})
|
||||
} else {
|
||||
file = contents
|
||||
}
|
||||
|
@ -1169,7 +1169,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
if (typeof window === "undefined") {
|
||||
return "https://mapcomplete.osm.be"
|
||||
}
|
||||
const path = (window.location.protocol+ window.location.host + window.location.pathname) .split("/")
|
||||
const path = (window.location.protocol + "//" + window.location.host + window.location.pathname).split("/")
|
||||
path.pop()
|
||||
path.push("index.html")
|
||||
return path.join("/")
|
||||
|
@ -1318,7 +1318,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
if (match == undefined) {
|
||||
return undefined
|
||||
}
|
||||
return { r: Number(match[1]), g: Number(match[2]), b: Number(match[3]) }
|
||||
return {r: Number(match[1]), g: Number(match[2]), b: Number(match[3])}
|
||||
}
|
||||
|
||||
if (!hex.startsWith("#")) {
|
||||
|
@ -1366,7 +1366,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
d.setUTCMinutes(0)
|
||||
}
|
||||
|
||||
public static scrollIntoView(element: HTMLBaseElement){
|
||||
public static scrollIntoView(element: HTMLBaseElement) {
|
||||
console.log("Scrolling into view:", element)
|
||||
// Is the element completely in the view?
|
||||
const parentRect = Utils.findParentWithScrolling(
|
||||
|
@ -1384,6 +1384,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
console.log("Actually scrolling...")
|
||||
element.scrollIntoView({behavior: "smooth", block: "nearest"})
|
||||
}
|
||||
|
||||
public static findParentWithScrolling(element: HTMLBaseElement): HTMLBaseElement {
|
||||
// Check if the element itself has scrolling
|
||||
if (element.scrollHeight > element.clientHeight) {
|
||||
|
@ -1396,7 +1397,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
}
|
||||
|
||||
// If the element has a parent, repeat the process for the parent element
|
||||
return Utils.findParentWithScrolling(<HTMLBaseElement> element.parentElement)
|
||||
return Utils.findParentWithScrolling(<HTMLBaseElement>element.parentElement)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1428,12 +1429,6 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
}
|
||||
return true
|
||||
}
|
||||
private static colorDiff(
|
||||
c0: { r: number; g: number; b: number },
|
||||
c1: { r: number; g: number; b: number }
|
||||
) {
|
||||
return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b)
|
||||
}
|
||||
|
||||
static SameObject(a: any, b: any) {
|
||||
if (a === b) {
|
||||
|
@ -1463,4 +1458,11 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private static colorDiff(
|
||||
c0: { r: number; g: number; b: number },
|
||||
c1: { r: number; g: number; b: number }
|
||||
) {
|
||||
return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -397,6 +397,8 @@ select:hover {
|
|||
.subtle {
|
||||
/* For all information that is not important for 99% of the users */
|
||||
color: #999;
|
||||
font-size: medium;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.link-underline .subtle a {
|
||||
|
|
|
@ -800,11 +800,6 @@ video {
|
|||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
.my-2 {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.my-4 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
|
@ -815,6 +810,11 @@ video {
|
|||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.my-2 {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.mx-10 {
|
||||
margin-left: 2.5rem;
|
||||
margin-right: 2.5rem;
|
||||
|
@ -1137,11 +1137,6 @@ video {
|
|||
width: 50%;
|
||||
}
|
||||
|
||||
.w-max {
|
||||
width: -webkit-max-content;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.w-96 {
|
||||
width: 24rem;
|
||||
}
|
||||
|
@ -1150,6 +1145,11 @@ video {
|
|||
width: 2.5rem;
|
||||
}
|
||||
|
||||
.w-max {
|
||||
width: -webkit-max-content;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.w-48 {
|
||||
width: 12rem;
|
||||
}
|
||||
|
@ -1493,11 +1493,6 @@ video {
|
|||
background-color: rgb(248 113 113 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-subtle {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(219 234 254 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-white {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
||||
|
@ -1553,10 +1548,6 @@ video {
|
|||
padding: 0px;
|
||||
}
|
||||
|
||||
.p-3 {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.p-8 {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
@ -1571,11 +1562,6 @@ video {
|
|||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.py-4 {
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.px-3 {
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
|
@ -1848,18 +1834,6 @@ video {
|
|||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.transition-shadow {
|
||||
transition-property: box-shadow;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.transition-\[color\2c background-color\2c box-shadow\] {
|
||||
transition-property: color,background-color,box-shadow;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.transition {
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, -webkit-transform, -webkit-filter, -webkit-backdrop-filter;
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
||||
|
@ -2246,6 +2220,8 @@ select:hover {
|
|||
.subtle {
|
||||
/* For all information that is not important for 99% of the users */
|
||||
color: #999;
|
||||
font-size: medium;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.link-underline .subtle a {
|
||||
|
@ -2432,11 +2408,6 @@ a.link-underline {
|
|||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.hover\:bg-unsubtle:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(191 219 254 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-indigo-200:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(199 210 254 / var(--tw-bg-opacity));
|
||||
|
@ -2451,12 +2422,6 @@ a.link-underline {
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
.hover\:shadow-xl:hover {
|
||||
--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
||||
--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.max-\[480px\]\:w-full {
|
||||
width: 100%;
|
||||
|
|
Loading…
Reference in a new issue