Zap modal (#209)

This commit is contained in:
Alejandro 2023-02-07 14:32:32 +01:00 committed by GitHub
parent 41aa93a279
commit 1e76e729f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 403 additions and 159 deletions

View File

@ -20,8 +20,8 @@ export default function AsyncButton(props: any) {
}
return (
<div {...props} className={`btn ${props.className}${loading ? " disabled" : ""}`} onClick={(e) => handle(e)}>
{props.children}
</div>
<button type="button" disabled={loading} {...props} onClick={(e) => handle(e)}>
{props.children}
</button>
)
}

View File

@ -4,7 +4,7 @@ import { useState } from "react";
import { decode as invoiceDecode } from "light-bolt11-decoder";
import { useMemo } from "react";
import NoteTime from "Element/NoteTime";
import LNURLTip from "Element/LNURLTip";
import SendSats from "Element/SendSats";
import ZapCircle from "Icons/ZapCircle";
import useWebln from "Hooks/useWebln";
@ -49,7 +49,7 @@ export default function Invoice(props: InvoiceProps) {
<>
<h4>Lightning Invoice</h4>
<ZapCircle className="zap-circle" />
<LNURLTip invoice={invoice} show={showInvoice} onClose={() => setShowInvoice(false)} />
<SendSats title="Pay Invoice" invoice={invoice} show={showInvoice} onClose={() => setShowInvoice(false)} />
</>
)
}

View File

@ -1,59 +0,0 @@
.lnurl-tip {
text-align: center;
}
.lnurl-tip .btn {
background-color: inherit;
width: 210px;
margin: 0 0 10px 0;
}
.lnurl-tip .btn:hover {
background-color: var(--gray);
}
.sat-amount {
display: inline-block;
background-color: var(--gray-secondary);
color: var(--font-color);
padding: 2px 10px;
border-radius: 10px;
user-select: none;
margin: 2px 5px;
}
.sat-amount:hover {
cursor: pointer;
}
.sat-amount.active {
font-weight: bold;
color: var(--note-bg);
background-color: var(--font-color);
}
.lnurl-tip .invoice {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.lnurl-tip .invoice .actions {
display: flex;
flex-direction: column;
align-items: flex-start;
text-align: center;
}
.lnurl-tip .invoice .actions .copy-action {
margin: 10px auto;
}
.lnurl-tip .invoice .actions .pay-actions {
margin: 10px auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

View File

@ -11,7 +11,7 @@ import {
CheckRegisterResponse
} from "Nip05/ServiceProvider";
import AsyncButton from "Element/AsyncButton";
import LNURLTip from "Element/LNURLTip";
import SendSats from "Element/SendSats";
import Copy from "Element/Copy";
import { useUserProfile }from "Feed/ProfileFeed";
import useEventPublisher from "Feed/EventPublisher";
@ -176,7 +176,7 @@ export default function Nip5Service(props: Nip05ServiceProps) {
{availabilityResponse?.available === false && !registerStatus && <div className="flex">
<b className="error">Not available: {mapError(availabilityResponse.why!, availabilityResponse.reasonTag || null)}</b>
</div>}
<LNURLTip
<SendSats
invoice={registerResponse?.invoice}
show={showInvoice}
onClose={() => setShowInvoice(false)}

View File

@ -12,6 +12,7 @@
}
.note-creator textarea {
border: none;
outline: none;
resize: none;
background-color: var(--note-bg);

View File

@ -13,7 +13,7 @@ import { formatShort } from "Number";
import useEventPublisher from "Feed/EventPublisher";
import { getReactions, hexToBech32, normalizeReaction, Reaction } from "Util";
import { NoteCreator } from "Element/NoteCreator";
import LNURLTip from "Element/LNURLTip";
import SendSats from "Element/SendSats";
import { parseZap, ZapsSummary } from "Element/Zap";
import { useUserProfile } from "Feed/ProfileFeed";
import { default as NEvent } from "Nostr/Event";
@ -268,7 +268,14 @@ export default function NoteFooter(props: NoteFooterProps) {
show={reply}
setShow={setReply}
/>
<LNURLTip svc={author?.lud16 || author?.lud06} onClose={() => setTip(false)} show={tip} author={author?.pubkey} note={ev.Id} />
<SendSats
svc={author?.lud16 || author?.lud06}
onClose={() => setTip(false)}
show={tip}
author={author?.pubkey}
target={author?.display_name || author?.name}
note={ev.Id}
/>
</div>
<div className="zaps-container">
<ZapsSummary zaps={zaps} />

176
src/Element/SendSats.css Normal file
View File

@ -0,0 +1,176 @@
.lnurl-modal .modal-body {
padding: 0;
max-width: 470px;
}
.lnurl-modal .lnurl-tip .pfp .avatar {
width: 48px;
height: 48px;
}
.lnurl-tip {
padding: 24px 32px;
background-color: #1B1B1B;
border-radius: 16px;
position: relative;
}
@media (max-width: 720px) {
.lnurl-tip {
padding: 12px 16px;
}
}
.light .lnurl-tip {
background-color: var(--note-bg);
}
.lnurl-tip h3 {
color: var(--font-secondary-color);
font-size: 11px;
letter-spacing: .11em;
font-weight: 600;
line-height: 13px;
text-transform: uppercase;
}
.lnurl-tip .close {
position: absolute;
top: 12px;
right: 16px;
color: var(--font-secondary-color);
cursor: pointer;
}
.lnurl-tip .close:hover {
color: var(--font-tertiary-color);
}
.lnurl-tip .lnurl-header {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 32px;
}
.lnurl-tip .lnurl-header h2 {
margin: 0;
flex-grow: 1;
font-weight: 600;
font-size: 16px;
line-height: 19px;
}
.lnurl-tip .btn {
background-color: inherit;
width: 210px;
margin: 0 0 10px 0;
}
.lnurl-tip .btn:hover {
}
.amounts {
display: flex;
width: 100%;
overflow-x: scroll;
-ms-overflow-style: none; /* for Internet Explorer, Edge */
scrollbar-width: none; /* for Firefox */
margin-bottom: 16px;
}
.amounts::-webkit-scrollbar {
display: none;
}
.sat-amount {
text-align: center;
display: inline-block;
background-color: #2A2A2A;
color: var(--font-color);
padding: 12px 16px;
border-radius: 100px;
user-select: none;
font-weight: 600;
font-size: 14px;
line-height: 17px;
}
.light .sat-amount {
background-color: var(--gray);
}
.sat-amount:not(:last-child) {
margin-right: 8px;
}
.sat-amount:hover {
cursor: pointer;
}
.sat-amount.active {
font-weight: bold;
color: var(--note-bg);
background-color: var(--font-color);
}
.lnurl-tip .invoice {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.lnurl-tip .invoice .actions {
display: flex;
flex-direction: column;
align-items: flex-start;
text-align: center;
}
.lnurl-tip .invoice .actions .copy-action {
margin: 10px auto;
}
.lnurl-tip .invoice .actions .wallet-action {
width: 100%;
height: 40px;
}
.lnurl-tip .zap-action {
margin-top: 16px;
width: 100%;
height: 40px;
}
.lnurl-tip .zap-action svg {
margin-right: 10px;
}
.lnurl-tip .zap-action-container {
display: flex;
align-items: center;
justify-content: center;
}
.lnurl-tip .custom-amount {
margin-bottom: 16px;
}
.lnurl-tip .custom-amount button {
padding: 12px 18px;
border-radius: 100px;
}
.lnurl-tip canvas {
border-radius: 10px;
}
.lnurl-tip .success-action .paid {
font-size: 19px;
}
.lnurl-tip .success-action a {
color: var(--highlight);
font-size: 19px;
}

View File

@ -1,12 +1,19 @@
import "./LNURLTip.css";
import "./SendSats.css";
import { useEffect, useMemo, useState } from "react";
import { formatShort } from "Number";
import { bech32ToText } from "Util";
import { HexKey } from "Nostr";
import Check from "Icons/Check";
import Zap from "Icons/Zap";
import Close from "Icons/Close";
import useEventPublisher from "Feed/EventPublisher";
import ProfileImage from "Element/ProfileImage";
import Modal from "Element/Modal";
import QrCode from "Element/QrCode";
import Copy from "Element/Copy";
import useWebln from "Hooks/useWebln";
import useHorizontalScroll from "Hooks/useHorizontalScroll";
interface LNURLService {
nostrPubkey?: HexKey
@ -34,6 +41,7 @@ export interface LNURLTipProps {
invoice?: string, // shortcut to invoice qr tab
title?: string,
notice?: string
target?: string
note?: HexKey
author?: HexKey
}
@ -42,10 +50,19 @@ export default function LNURLTip(props: LNURLTipProps) {
const onClose = props.onClose || (() => { });
const service = props.svc;
const show = props.show || false;
const { note, author } = props
const amounts = [50, 100, 500, 1_000, 5_000, 10_000, 50_000];
const { note, author, target } = props
const amounts = [500, 1_000, 5_000, 10_000, 20_000, 50_000, 100_000, 1_000_000];
const emojis: Record<number, string> = {
1_000: "👍",
5_000: "💜",
10_000: "😍",
20_000: "🤩",
50_000: "🔥",
100_000: "🚀",
1_000_000: "🤯",
}
const [payService, setPayService] = useState<LNURLService>();
const [amount, setAmount] = useState<number>();
const [amount, setAmount] = useState<number>(500);
const [customAmount, setCustomAmount] = useState<number>();
const [invoice, setInvoice] = useState<LNURLInvoice>();
const [comment, setComment] = useState<string>();
@ -53,6 +70,7 @@ export default function LNURLTip(props: LNURLTipProps) {
const [success, setSuccess] = useState<LNURLSuccessAction>();
const webln = useWebln(show);
const publisher = useEventPublisher();
const horizontalScroll = useHorizontalScroll();
useEffect(() => {
if (show && !props.invoice) {
@ -63,7 +81,7 @@ export default function LNURLTip(props: LNURLTipProps) {
setPayService(undefined);
setError(undefined);
setInvoice(props.invoice ? { pr: props.invoice } : undefined);
setAmount(undefined);
setAmount(500);
setComment(undefined);
setSuccess(undefined);
}
@ -155,12 +173,27 @@ export default function LNURLTip(props: LNURLTipProps) {
};
function custom() {
let min = (payService?.minSendable ?? 0) / 1000;
let min = (payService?.minSendable ?? 1000) / 1000;
let max = (payService?.maxSendable ?? 21_000_000_000) / 1000;
return (
<div className="flex mb10">
<input type="number" min={min} max={max} className="f-grow mr10" value={customAmount} onChange={(e) => setCustomAmount(parseInt(e.target.value))} />
<div className="btn" onClick={() => selectAmount(customAmount!)}>Confirm</div>
<div className="custom-amount flex">
<input
type="number"
min={min}
max={max}
className="f-grow mr10"
placeholder="Custom"
value={customAmount}
onChange={(e) => setCustomAmount(parseInt(e.target.value))}
/>
<button
className="secondary"
type="button"
disabled={!Boolean(customAmount)}
onClick={() => selectAmount(customAmount!)}
>
Confirm
</button>
</div>
);
}
@ -182,22 +215,36 @@ export default function LNURLTip(props: LNURLTipProps) {
if (invoice) return null;
return (
<>
<div className="f-ellipsis mb10">{metadata?.description ?? service}</div>
<h3>Zap amount in sats</h3>
<div className="amounts" ref={horizontalScroll}>
{serviceAmounts.map(a =>
<span className={`sat-amount ${amount === a ? "active" : ""}`} key={a} onClick={() => selectAmount(a)}>
{emojis[a] && <>{emojis[a]}&nbsp;</> }
{formatShort(a)}
</span>
)}
</div>
{payService && custom()}
<div className="flex">
{(payService?.commentAllowed ?? 0) > 0 ?
<input type="text" placeholder="Comment" className="mb10 f-grow" maxLength={payService?.commentAllowed} onChange={(e) => setComment(e.target.value)} /> : null}
{(payService?.commentAllowed ?? 0) > 0 &&
<input
type="text"
placeholder="Comment"
className="f-grow"
maxLength={payService?.commentAllowed}
onChange={(e) => setComment(e.target.value)}
/>
}
</div>
<div className="mb10">
{serviceAmounts.map(a => <span className={`sat-amount ${amount === a ? "active" : ""}`} key={a} onClick={() => selectAmount(a)}>
{a.toLocaleString()}
</span>)}
{payService ?
<span className={`sat-amount ${amount === -1 ? "active" : ""}`} onClick={() => selectAmount(-1)}>
Custom
</span> : null}
</div>
{amount === -1 ? custom() : null}
{(amount ?? 0) > 0 && <button type="button" className="mb10" onClick={() => loadInvoice()}>Get Invoice</button>}
{(amount ?? 0) > 0 && (
<button type="button" className="zap-action" onClick={() => loadInvoice()}>
<div className="zap-action-container">
<Zap /> Zap
{target && ` ${target} `}
{formatShort(amount)} sats
</div>
</button>
)}
</>
)
}
@ -208,22 +255,20 @@ export default function LNURLTip(props: LNURLTipProps) {
return (
<>
<div className="invoice">
{props.notice && <b className="error">{props.notice}</b>}
<QrCode data={pr} link={`lightning:${pr}`} />
<div className="actions">
{pr && (
<>
<div className="copy-action">
<Copy text={pr} maxSize={26} />
</div>
<div className="pay-actions">
<button type="button" onClick={() => window.open(`lightning:${pr}`)}>
Open Wallet
</button>
</div>
</>
)}
</div>
{props.notice && <b className="error">{props.notice}</b>}
<QrCode data={pr} link={`lightning:${pr}`} />
<div className="actions">
{pr && (
<>
<div className="copy-action">
<Copy text={pr} maxSize={26} />
</div>
<button className="wallet-action" type="button" onClick={() => window.open(`lightning:${pr}`)}>
Open Wallet
</button>
</>
)}
</div>
</div>
</>
)
@ -232,24 +277,46 @@ export default function LNURLTip(props: LNURLTipProps) {
function successAction() {
if (!success) return null;
return (
<>
<p>{success?.description ?? "Paid!"}</p>
{success.url ? <a href={success.url} rel="noreferrer" target="_blank">{success.url}</a> : null}
</>
<div className="success-action">
<p className="paid">
<Check className="success mr10" />
{success?.description ?? "Paid!"}
</p>
{success.url &&
<p>
<a
href={success.url}
rel="noreferrer"
target="_blank"
>
{success.url}
</a>
</p>
}
</div>
)
}
const defaultTitle = payService?.nostrPubkey ? "⚡️ Send Zap!" : "⚡️ Send sats";
const defaultTitle = payService?.nostrPubkey ? "Send zap" : "Send sats";
const title = target ? `${defaultTitle} to ${target}` : defaultTitle
if (!show) return null;
return (
<Modal onClose={onClose}>
<div className="lnurl-tip" onClick={(e) => e.stopPropagation()}>
<h2>{props.title || defaultTitle}</h2>
{invoiceForm()}
{error ? <p className="error">{error}</p> : null}
{payInvoice()}
{successAction()}
</div>
<Modal className="lnurl-modal" onClose={onClose}>
<div className="lnurl-tip" onClick={(e) => e.stopPropagation()}>
<div className="close" onClick={onClose}>
<Close />
</div>
<div className="lnurl-header">
{author && <ProfileImage pubkey={author} showUsername={false} />}
<h2>
{props.title || title}
</h2>
</div>
{invoiceForm()}
{error && <p className="error">{error}</p>}
{payInvoice()}
{successAction()}
</div>
</Modal>
)
}

View File

@ -2,7 +2,8 @@
display: flex;
align-items: center;
flex-direction: row;
overflow-x: auto;
overflow-x: scroll;
-ms-overflow-style: none; /* for Internet Explorer, Edge */
scrollbar-width: none; /* Firefox */
margin-bottom: 18px;
}
@ -12,7 +13,8 @@
}
.tab {
border: 1px solid var(--gray-secondary);
color: var(--font-tertiary-color);
border: 1px solid var(--font-tertiary-color);
border-radius: 16px;
text-align: center;
font-weight: 600;
@ -21,7 +23,6 @@
font-weight: 600;
font-size: 14px;
line-height: 17px;
color: #A3A3A3;
margin-right: 12px;
}

View File

@ -52,7 +52,7 @@
margin-top: 8px;
display: flex;
flex-direction: row;
margin-left: 52px;
margin-left: 56px;
}
.note.thread-root .zaps-summary {
@ -70,8 +70,8 @@
}
.top-zap .avatar {
width: 21px;
height: 21px;
width: 18px;
height: 18px;
}
.top-zap .nip05 {

View File

@ -4,7 +4,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useState } from "react";
import { useUserProfile } from "Feed/ProfileFeed";
import { HexKey } from "Nostr";
import LNURLTip from "Element/LNURLTip";
import SendSats from "Element/SendSats";
const ZapButton = ({ pubkey, svc }: { pubkey?: HexKey, svc?: string }) => {
@ -19,7 +19,7 @@ const ZapButton = ({ pubkey, svc }: { pubkey?: HexKey, svc?: string }) => {
<div className="zap-button" onClick={(e) => setZap(true)}>
<FontAwesomeIcon icon={faBolt} />
</div>
<LNURLTip svc={service} show={zap} onClose={() => setZap(false)} author={pubkey} />
<SendSats target={profile?.display_name || profile?.name} svc={service} show={zap} onClose={() => setZap(false)} author={pubkey} />
</>
)
}

View File

@ -0,0 +1,22 @@
import { useEffect, useRef, WheelEvent, LegacyRef } from "react";
function useHorizontalScroll() {
const elRef = useRef<HTMLDivElement>();
useEffect(() => {
const el = elRef.current;
if (el) {
const onWheel = (ev: WheelEvent) => {
if (ev.deltaY == 0) return;
ev.preventDefault();
el.scrollTo({ left: el.scrollLeft + ev.deltaY, behavior: "smooth" });
};
// @ts-ignore
el.addEventListener("wheel", onWheel);
// @ts-ignore
return () => el.removeEventListener("wheel", onWheel);
}
}, []);
return elRef as LegacyRef<HTMLDivElement> | undefined
}
export default useHorizontalScroll;

11
src/Icons/Close.tsx Normal file
View File

@ -0,0 +1,11 @@
import IconProps from "./IconProps";
const Close = (props: IconProps) => {
return (
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<path d="M7.33332 0.666992L0.666656 7.33366M0.666656 0.666992L7.33332 7.33366" stroke="currentColor" strokeWidth="1.33333" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
)
}
export default Close

View File

@ -1,8 +1,10 @@
import IconProps from "./IconProps";
const Reply = () => {
return (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.50004 9.70199L1.33337 5.53532M1.33337 5.53532L5.50004 1.36865M1.33337 5.53532H6.66671C9.46697 5.53532 10.8671 5.53532 11.9367 6.08029C12.8775 6.55965 13.6424 7.32456 14.1217 8.26537C14.6667 9.33493 14.6667 10.7351 14.6667 13.5353V14.702" stroke="currentColor" strokeWidth="1.66667" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.5 5.5C1.5 4.09987 1.5 3.3998 1.77248 2.86502C2.01217 2.39462 2.39462 2.01217 2.86502 1.77248C3.3998 1.5 4.09987 1.5 5.5 1.5H12.5C13.9001 1.5 14.6002 1.5 15.135 1.77248C15.6054 2.01217 15.9878 2.39462 16.2275 2.86502C16.5 3.3998 16.5 4.09987 16.5 5.5V10C16.5 11.4001 16.5 12.1002 16.2275 12.635C15.9878 13.1054 15.6054 13.4878 15.135 13.7275C14.6002 14 13.9001 14 12.5 14H10.4031C9.88308 14 9.62306 14 9.37435 14.051C9.15369 14.0963 8.94017 14.1712 8.73957 14.2737C8.51347 14.3892 8.31043 14.5517 7.90434 14.8765L5.91646 16.4668C5.56973 16.7442 5.39636 16.8829 5.25045 16.8831C5.12356 16.8832 5.00352 16.8255 4.92436 16.7263C4.83333 16.6123 4.83333 16.3903 4.83333 15.9463V14C4.05836 14 3.67087 14 3.35295 13.9148C2.49022 13.6836 1.81635 13.0098 1.58519 12.147C1.5 11.8291 1.5 11.4416 1.5 10.6667V5.5Z" stroke="currentColor" strokeWidth="1.66667" strokeLinecap="round" strokeLinejoin="round" />
</svg>
)
}

View File

@ -6,7 +6,7 @@ const intl = new Intl.NumberFormat("en", {
export function formatShort(n: number) {
if (n < 2e3) {
return n
} else if (n < 1e8) {
} else if (n < 1e6) {
return `${intl.format(n / 1e3)}K`
} else {
return `${intl.format(n / 1e6)}M`

View File

@ -62,7 +62,7 @@
white-space: pre-wrap;
}
.profile .name h2 {
.details-wrapper > .name > h2 {
margin: 12px 0 0 0;
font-weight: 600;
font-size: 19px;
@ -75,11 +75,11 @@
margin: 0 0 12px 0;
}
.profile .avatar-wrapper {
.profile-wrapper > .avatar-wrapper {
z-index: 1;
}
.profile .avatar-wrapper .avatar {
.profile-wrapper > .avatar-wrapper .avatar {
width: 120px;
height: 120px;
background-image: var(--img-url);

View File

@ -19,7 +19,7 @@ import Avatar from "Element/Avatar";
import LogoutButton from "Element/LogoutButton";
import Timeline from "Element/Timeline";
import Text from 'Element/Text'
import LNURLTip from "Element/LNURLTip";
import SendSats from "Element/SendSats";
import Nip05 from "Element/Nip05";
import Copy from "Element/Copy";
import ProfilePreview from "Element/ProfilePreview";
@ -35,6 +35,7 @@ import FollowsYou from "Element/FollowsYou"
import QrCode from "Element/QrCode";
import Modal from "Element/Modal";
import { ProxyImg } from "Element/ProxyImg"
import useHorizontalScroll from "Hooks/useHorizontalScroll";
const ProfileTab = {
Notes: { text: "Notes", value: 0 },
@ -71,6 +72,7 @@ export default function ProfilePage() {
return profileZaps
}, [zapFeed.store, id])
const zapsTotal = zaps.reduce((acc, z) => acc + z.amount, 0)
const horizontalScroll = useHorizontalScroll()
useEffect(() => {
setTab(ProfileTab.Notes);
@ -111,7 +113,13 @@ export default function ProfilePage() {
</div>
)}
<LNURLTip svc={lnurl} show={showLnQr} onClose={() => setShowLnQr(false)} author={id} />
<SendSats
svc={lnurl}
show={showLnQr}
onClose={() => setShowLnQr(false)}
author={id}
target={user?.display_name || user?.name}
/>
</div>
)
}
@ -242,7 +250,7 @@ export default function ProfilePage() {
{userDetails()}
</div>
</div>
<div className="tabs main-content">
<div className="tabs main-content" ref={horizontalScroll}>
{[ProfileTab.Notes, ProfileTab.Followers, ProfileTab.Follows, ProfileTab.Zaps, ProfileTab.Muted].map(renderTab)}
{isMe && renderTab(ProfileTab.Blocked)}
</div>

View File

@ -3,8 +3,8 @@
:root {
--bg-color: #000;
--font-color: #FFF;
--font-secondary-color: #7B7B7B;
--font-tertiary-color: #666;
--font-secondary-color: #A7A7A7;
--font-tertiary-color: #A3A3A3;
--font-size: 16px;
--font-size-small: 14px;
--font-size-tiny: 12px;
@ -34,7 +34,7 @@ html.light {
--bg-color: #F1F1F1;
--font-color: #57534E;
--font-secondary-color: #7B7B7B;
--font-tertiary-color: #F3F3F3;
--font-tertiary-color: #A7A7A7;
--highlight-light: #16AAC1;
--highlight: #0284C7;
@ -126,18 +126,19 @@ button {
}
button:disabled {
opacity: 0.3;
cursor: not-allowed;
}
button.secondary:disabled {
color: var(--font-secondary-color);
cursor: not-allowed;
color: var(--font-color);
background-color: transparent;
border: 1px solid var(--font-secondary-color);
}
button:disabled:hover {
cursor: not-allowed;
color: var(--font-color);
background-color: transparent;
background-color: var(--gray-superdark);
border: 1px solid var(--font-secondary-color);
border-color: var(--gray-superdark);
}
.light button.transparent {
@ -239,14 +240,12 @@ button.icon:hover {
}
.btn-rnd {
border-radius: 100%;
border-color: var(--gray-secondary);
border: none;
width: 21px;
height: 21px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16px;
}
@media (min-width: 520px) {
@ -257,12 +256,21 @@ textarea {
font: inherit;
}
input[type="text"], input[type="password"], input[type="number"], textarea, select {
padding: 10px;
border-radius: 5px;
border: 0;
background-color: var(--gray);
input[type="text"], input[type="password"], input[type="number"], select, textarea {
padding: 12px;
color: var(--font-color);
background: transparent;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 16px;
outline: none;
}
.light input[type="text"], .light input[type="password"], .light input[type="number"], .light select, .light textarea {
border: 1px solid rgba(0, 0, 0, 0.3);
}
input:placeholder, textarea:placeholder {
color: var(--font-tertiary-color);
}
input[type="checkbox"] {
@ -275,10 +283,6 @@ input:disabled {
cursor: not-allowed;
}
textarea:placeholder {
color: var(--gray-superlight);
}
.flex {
display: flex;
align-items: center;
@ -451,6 +455,10 @@ body.scroll-lock {
background-color: var(--error);
}
.success {
color: var(--success);
}
.bg-success {
background-color: var(--success);
}