@danhachuel/pandanews 0.4.10 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/backend/__pycache__/__init__.cpython-314.pyc +0 -0
- package/backend/app/main.py +3 -2
- package/backend/app/routers/noticias.py +42 -1
- package/backend/app/routers/wordpress.py +23 -0
- package/backend/app/schemas.py +3 -0
- package/backend/core/__pycache__/__init__.cpython-314.pyc +0 -0
- package/backend/core/__pycache__/config.cpython-314.pyc +0 -0
- package/backend/core/__pycache__/llm_router.cpython-314.pyc +0 -0
- package/backend/core/database.py +2 -0
- package/backend/core/pipeline.py +6 -2
- package/backend/core/wordpress_publisher.py +167 -0
- package/frontend/dist/assets/{index-ExoYg5_I.css → index-CM6InlUs.css} +1 -1
- package/frontend/dist/assets/index-Dj6FuR5_.js +70 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
- package/scripts/start.js +110 -10
- package/frontend/dist/assets/index-Iz5spM-E.js +0 -70
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Todas as versões publicadas são registradas aqui antes do publish (regra em AGENTS.md). A etiqueta visual usa PATCH de dois dígitos (ex.: 0.1.00); o registry npm normaliza para a versão canônica (ex.: 0.1.0).
|
|
4
4
|
|
|
5
|
+
## 0.5.00 (2026-11-08)
|
|
6
|
+
|
|
7
|
+
- **Módulo Publicador WordPress** (preparação para monetização AdSense): credenciais `wordpress_url` / `wordpress_user` / `wordpress_app_password` salvas no banco local e mascaradas no frontend; coluna `noticias.wordpress_post_id` (com migração leve para bancos existentes)
|
|
8
|
+
- `backend/core/wordpress_publisher.py`: teste de conexão real (`GET /wp-json/wp/v2/users/me`), upload de imagem em 2 etapas (`POST /wp-json/wp/v2/media` → `featured_media`) e criação do post (`POST /wp-json/wp/v2/posts`, `status: publish`, categoria resolvida pelo tema do blog — busca ou cria)
|
|
9
|
+
- Endpoint `POST /api/v1/noticias/{id}/publicar`: bloqueia republicação (400 "Já publicado"), exige **mínimo de 300 palavras** (diretriz AdSense), grava `status=publicado` + `wordpress_post_id` e devolve o link do post; `GET /api/v1/wordpress/status` + `POST /api/v1/wordpress/testar`
|
|
10
|
+
- Frontend: seção **Integração WordPress** em Configurações (URL, usuário, senha de aplicativo mascarada, Testar Conexão com estado) e botão **🌐 Publicar no WordPress** nos cards de notícias — loading durante o envio, badge "Publicado" + link "Ver no site" após o sucesso
|
|
11
|
+
- **Diretriz rígida AdSense no prompt do LLM**: "O texto final deve ter no mínimo 1500 palavras. Expanda o contexto, traga implicações e detalhes para criar um artigo profundo e otimizado para SEO. Nunca gere textos com menos de 1000 palavras." — teto de tokens da redação elevado para 4000
|
|
12
|
+
|
|
5
13
|
## 0.4.10 (2026-11-08)
|
|
6
14
|
|
|
7
15
|
- **Cobertura E2E pelo caminho HTTP real**: o teste de fallback ganhou um cenário que substitui apenas o `httpx.Client` — `chamar_provedor`, a construção da URL, os headers e o `raise_for_status` rodam de verdade. A NVIDIA devolve 410, o Gemini devolve 200 e a notícia nasce do Gemini com o log `Erro na NVIDIA (...). Acionando Google Gemini...` emitido. Fecha a lacuna de testar só a função mockada
|
|
Binary file
|
package/backend/app/main.py
CHANGED
|
@@ -10,7 +10,7 @@ from contextlib import asynccontextmanager
|
|
|
10
10
|
from fastapi import FastAPI
|
|
11
11
|
from fastapi.middleware.cors import CORSMiddleware
|
|
12
12
|
|
|
13
|
-
from backend.app.routers import automacao, blogs, configuracoes, dashboard, imagens, legal, llm, logs, noticias
|
|
13
|
+
from backend.app.routers import automacao, blogs, configuracoes, dashboard, imagens, legal, llm, logs, noticias, wordpress
|
|
14
14
|
from backend.core.database import SessionLocal, init_db
|
|
15
15
|
from backend.core.llm_router import get_config
|
|
16
16
|
|
|
@@ -31,7 +31,7 @@ async def lifespan(_: FastAPI):
|
|
|
31
31
|
scheduler.parar()
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
app = FastAPI(title="PandaNews API", version="0.
|
|
34
|
+
app = FastAPI(title="PandaNews API", version="0.5.0", lifespan=lifespan)
|
|
35
35
|
|
|
36
36
|
app.add_middleware(
|
|
37
37
|
CORSMiddleware,
|
|
@@ -48,6 +48,7 @@ app.include_router(noticias.router, prefix="/api/v1")
|
|
|
48
48
|
app.include_router(imagens.router, prefix="/api/v1")
|
|
49
49
|
app.include_router(automacao.router, prefix="/api/v1")
|
|
50
50
|
app.include_router(logs.router, prefix="/api/v1")
|
|
51
|
+
app.include_router(wordpress.router, prefix="/api/v1")
|
|
51
52
|
app.include_router(legal.router) # /legal/* na raiz (URLs de verificação)
|
|
52
53
|
|
|
53
54
|
|
|
@@ -7,7 +7,7 @@ from sqlalchemy import select
|
|
|
7
7
|
from sqlalchemy.orm import Session
|
|
8
8
|
|
|
9
9
|
from backend.app.schemas import NoticiaPatch, STATUS_NOTICIA
|
|
10
|
-
from backend.core.database import Noticia, get_db
|
|
10
|
+
from backend.core.database import Log, Noticia, get_db
|
|
11
11
|
|
|
12
12
|
router = APIRouter(prefix="/noticias", tags=["noticias"])
|
|
13
13
|
|
|
@@ -26,6 +26,7 @@ def _serializar(n: Noticia) -> dict:
|
|
|
26
26
|
"imagem_url": n.imagem_url,
|
|
27
27
|
"status": n.status,
|
|
28
28
|
"llm_provider": n.llm_provider,
|
|
29
|
+
"wordpress_post_id": n.wordpress_post_id,
|
|
29
30
|
"fonte_url": n.fonte_url,
|
|
30
31
|
"fonte_titulo": n.fonte_titulo,
|
|
31
32
|
"created_at": n.created_at,
|
|
@@ -45,6 +46,46 @@ def gerar_noticia(payload: GerarIn) -> dict:
|
|
|
45
46
|
return _serializar(noticia)
|
|
46
47
|
|
|
47
48
|
|
|
49
|
+
@router.post("/{noticia_id}/publicar")
|
|
50
|
+
def publicar_noticia(noticia_id: int, db: Session = Depends(get_db)) -> dict:
|
|
51
|
+
"""Publica a notícia no WordPress configurado (imagem + categoria)."""
|
|
52
|
+
from backend.core import wordpress_publisher
|
|
53
|
+
|
|
54
|
+
noticia = db.get(Noticia, noticia_id)
|
|
55
|
+
if noticia is None:
|
|
56
|
+
raise HTTPException(status_code=404, detail="Notícia não encontrada")
|
|
57
|
+
if noticia.wordpress_post_id:
|
|
58
|
+
raise HTTPException(status_code=400, detail="Já publicado no WordPress.")
|
|
59
|
+
palavras = wordpress_publisher.contar_palavras(noticia.corpo)
|
|
60
|
+
if palavras < wordpress_publisher.MINIMO_PALAVRAS_PUBLICACAO:
|
|
61
|
+
raise HTTPException(
|
|
62
|
+
status_code=400,
|
|
63
|
+
detail=(
|
|
64
|
+
f"Texto com {palavras} palavras — mínimo de "
|
|
65
|
+
f"{wordpress_publisher.MINIMO_PALAVRAS_PUBLICACAO} para publicar (diretriz AdSense). "
|
|
66
|
+
"Regere a notícia ou edite o corpo antes de publicar."
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
try:
|
|
70
|
+
resultado = wordpress_publisher.publish_to_wordpress(db, noticia)
|
|
71
|
+
except Exception as exc: # noqa: BLE001
|
|
72
|
+
raise HTTPException(status_code=502, detail=str(exc)) from exc
|
|
73
|
+
|
|
74
|
+
noticia.status = "publicado"
|
|
75
|
+
noticia.wordpress_post_id = resultado["post_id"]
|
|
76
|
+
db.add(
|
|
77
|
+
Log(
|
|
78
|
+
blog_id=noticia.blog_id,
|
|
79
|
+
etapa="publicacao",
|
|
80
|
+
status="sucesso",
|
|
81
|
+
mensagem=f"Publicado no WordPress (post {resultado['post_id']}): {resultado['link']}",
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
db.commit()
|
|
85
|
+
db.refresh(noticia)
|
|
86
|
+
return {"ok": True, "post_id": resultado["post_id"], "link": resultado["link"], "noticia": _serializar(noticia)}
|
|
87
|
+
|
|
88
|
+
|
|
48
89
|
@router.post("/{noticia_id}/regenerar")
|
|
49
90
|
def regenerar_noticia(noticia_id: int) -> dict:
|
|
50
91
|
from backend.core import pipeline
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""WordPress (/api/v1/wordpress): teste de conexão e estado das credenciais."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from fastapi import APIRouter, Depends
|
|
5
|
+
from sqlalchemy.orm import Session
|
|
6
|
+
|
|
7
|
+
from backend.core import wordpress_publisher
|
|
8
|
+
from backend.core.database import get_db
|
|
9
|
+
|
|
10
|
+
router = APIRouter(prefix="/wordpress", tags=["wordpress"])
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@router.get("/status")
|
|
14
|
+
def status(db: Session = Depends(get_db)) -> dict:
|
|
15
|
+
return wordpress_publisher.credenciais_presentes(db)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@router.post("/testar")
|
|
19
|
+
def testar(db: Session = Depends(get_db)) -> dict:
|
|
20
|
+
estado = wordpress_publisher.credenciais_presentes(db)
|
|
21
|
+
if not estado["configurado"]:
|
|
22
|
+
return {"ok": False, "detail": "Credenciais não configuradas — informe URL, usuário e Senha de Aplicativo abaixo."}
|
|
23
|
+
return {**wordpress_publisher.testar_conexao(db), **estado}
|
package/backend/app/schemas.py
CHANGED
|
@@ -52,6 +52,9 @@ class ConfiguracoesPatch(BaseModel):
|
|
|
52
52
|
scheduler_ativo: Optional[bool] = None
|
|
53
53
|
intervalo_padrao_horas: Optional[int] = Field(default=None, ge=1, le=168)
|
|
54
54
|
meta_diaria: Optional[int] = Field(default=None, ge=0, le=100)
|
|
55
|
+
wordpress_url: Optional[str] = None
|
|
56
|
+
wordpress_user: Optional[str] = None
|
|
57
|
+
wordpress_app_password: Optional[str] = None
|
|
55
58
|
|
|
56
59
|
|
|
57
60
|
class LlmTestIn(BaseModel):
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/backend/core/database.py
CHANGED
|
@@ -55,6 +55,7 @@ class Noticia(Base):
|
|
|
55
55
|
imagem_url: Mapped[str] = mapped_column(String(500), default="")
|
|
56
56
|
status: Mapped[str] = mapped_column(String(20), default="rascunho", index=True)
|
|
57
57
|
llm_provider: Mapped[str] = mapped_column(String(50), default="")
|
|
58
|
+
wordpress_post_id: Mapped[int | None] = mapped_column(nullable=True)
|
|
58
59
|
fonte_url: Mapped[str] = mapped_column(String(600), default="")
|
|
59
60
|
fonte_titulo: Mapped[str] = mapped_column(Text, default="")
|
|
60
61
|
created_at: Mapped[datetime] = mapped_column(default=_now, index=True)
|
|
@@ -105,6 +106,7 @@ def _migrate() -> None:
|
|
|
105
106
|
for coluna, ddl in (
|
|
106
107
|
("fonte_url", "VARCHAR(600) DEFAULT ''"),
|
|
107
108
|
("fonte_titulo", "TEXT DEFAULT ''"),
|
|
109
|
+
("wordpress_post_id", "INTEGER"),
|
|
108
110
|
):
|
|
109
111
|
if coluna not in colunas:
|
|
110
112
|
conn.execute(text(f"ALTER TABLE noticias ADD COLUMN {coluna} {ddl}"))
|
package/backend/core/pipeline.py
CHANGED
|
@@ -93,6 +93,9 @@ def _prompt_redacao(blog: Blog, item: dict) -> str:
|
|
|
93
93
|
f"Resumo da fonte: {item['resumo']}\n"
|
|
94
94
|
"Regras: reescreva com palavras próprias; não invente fatos que não estejam "
|
|
95
95
|
"na fonte; 3 a 5 parágrafos.\n"
|
|
96
|
+
"DIRETRIZ RÍGIDA (AdSense): o texto final deve ter no mínimo 1500 palavras. "
|
|
97
|
+
"Expanda o contexto, traga implicações e detalhes para criar um artigo profundo "
|
|
98
|
+
"e otimizado para SEO. Nunca gere textos com menos de 1000 palavras.\n"
|
|
96
99
|
'Responda SOMENTE com JSON válido no formato: {"titulo": "...", "resumo": "...", "corpo": "..."}'
|
|
97
100
|
)
|
|
98
101
|
|
|
@@ -140,9 +143,10 @@ def gerar_noticia(blog_id: int) -> Noticia | None:
|
|
|
140
143
|
novos.sort(key=lambda i: score_relevancia(i, blog), reverse=True)
|
|
141
144
|
item = novos[0]
|
|
142
145
|
|
|
143
|
-
# 3. Redação via LLM (fallback NVIDIA -> Gemini)
|
|
146
|
+
# 3. Redação via LLM (fallback NVIDIA -> Gemini) — teto alto p/ diretriz
|
|
147
|
+
# AdSense (mínimo 1500 palavras)
|
|
144
148
|
try:
|
|
145
|
-
resposta, provedor = llm_router.gerar_texto(db, _prompt_redacao(blog, item), max_tokens=
|
|
149
|
+
resposta, provedor = llm_router.gerar_texto(db, _prompt_redacao(blog, item), max_tokens=4000)
|
|
146
150
|
except Exception as exc: # noqa: BLE001
|
|
147
151
|
_log(db, blog.id, "redacao", "erro", f"Falha na redação: {exc}")
|
|
148
152
|
return None
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"""Publicador WordPress (Fase 0.5.00).
|
|
2
|
+
|
|
3
|
+
Envia notícias aprovadas para um blog WordPress via REST API usando Basic Auth
|
|
4
|
+
(usuário + Senha de Aplicativo gerada no painel do WP). Fluxo em 2 etapas:
|
|
5
|
+
upload da imagem para /wp-json/wp/v2/media → criação do post em
|
|
6
|
+
/wp-json/wp/v2/posts com featured_media e categoria.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import httpx
|
|
14
|
+
|
|
15
|
+
from backend.core.config import IMAGES_DIR
|
|
16
|
+
from backend.core.database import Blog
|
|
17
|
+
from backend.core.llm_router import get_config
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger("uvicorn.error.pandanews")
|
|
20
|
+
|
|
21
|
+
MINIMO_PALAVRAS_PUBLICACAO = 300
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _credenciais(db) -> dict:
|
|
25
|
+
url = get_config(db, "wordpress_url").rstrip("/")
|
|
26
|
+
user = get_config(db, "wordpress_user")
|
|
27
|
+
app_password = get_config(db, "wordpress_app_password")
|
|
28
|
+
if not (url and user and app_password):
|
|
29
|
+
raise RuntimeError(
|
|
30
|
+
"WordPress não configurado — informe URL, usuário e Senha de Aplicativo em Configurações → Integração WordPress."
|
|
31
|
+
)
|
|
32
|
+
return {"url": url, "user": user, "password": app_password}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def credenciais_presentes(db) -> dict:
|
|
36
|
+
"""Estado das credenciais para a UI (sem expor segredos)."""
|
|
37
|
+
url = get_config(db, "wordpress_url").rstrip("/")
|
|
38
|
+
user = get_config(db, "wordpress_user")
|
|
39
|
+
password = get_config(db, "wordpress_app_password")
|
|
40
|
+
return {
|
|
41
|
+
"configurado": bool(url and user and password),
|
|
42
|
+
"url": url,
|
|
43
|
+
"user": user,
|
|
44
|
+
"password_configured": bool(password),
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def testar_conexao(db) -> dict:
|
|
49
|
+
"""GET /wp-json/wp/v2/users/me — valida URL + credenciais."""
|
|
50
|
+
cred = _credenciais(db)
|
|
51
|
+
try:
|
|
52
|
+
resp = httpx.get(
|
|
53
|
+
f"{cred['url']}/wp-json/wp/v2/users/me",
|
|
54
|
+
auth=(cred["user"], cred["password"]),
|
|
55
|
+
timeout=20.0,
|
|
56
|
+
)
|
|
57
|
+
except httpx.HTTPError as exc:
|
|
58
|
+
return {"ok": False, "detail": f"Não foi possível conectar: {exc}"}
|
|
59
|
+
if resp.status_code == 200:
|
|
60
|
+
nome = resp.json().get("name", cred["user"])
|
|
61
|
+
return {"ok": True, "detail": f"Autenticado como {nome}.", "user": nome}
|
|
62
|
+
return {"ok": False, "detail": f"WP respondeu {resp.status_code}: {resp.text[:200]}"}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _imagem_local(imagem_url: str) -> Path | None:
|
|
66
|
+
nome = (imagem_url or "").rsplit("/", 1)[-1]
|
|
67
|
+
if not nome:
|
|
68
|
+
return None
|
|
69
|
+
caminho = IMAGES_DIR / nome
|
|
70
|
+
return caminho if caminho.exists() else None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _upload_midia(cred: dict, caminho: Path) -> int | None:
|
|
74
|
+
"""Envia a imagem para a biblioteca de mídia; devolve o media ID."""
|
|
75
|
+
with open(caminho, "rb") as arquivo:
|
|
76
|
+
dados = arquivo.read()
|
|
77
|
+
resp = httpx.post(
|
|
78
|
+
f"{cred['url']}/wp-json/wp/v2/media",
|
|
79
|
+
content=dados,
|
|
80
|
+
headers={
|
|
81
|
+
"Content-Disposition": f'attachment; filename="{caminho.name}"',
|
|
82
|
+
"Content-Type": "image/png",
|
|
83
|
+
},
|
|
84
|
+
auth=(cred["user"], cred["password"]),
|
|
85
|
+
timeout=120.0,
|
|
86
|
+
)
|
|
87
|
+
if resp.status_code in (200, 201):
|
|
88
|
+
media_id = resp.json().get("id")
|
|
89
|
+
if media_id:
|
|
90
|
+
return int(media_id)
|
|
91
|
+
logger.warning("WordPress: upload de mídia falhou (%s): %s", resp.status_code, resp.text[:200])
|
|
92
|
+
return None
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def resolver_categoria(cred: dict, nome_tema: str) -> int | None:
|
|
96
|
+
"""Categoria WP pelo nome do tema do blog — busca ou cria."""
|
|
97
|
+
if not nome_tema:
|
|
98
|
+
return None
|
|
99
|
+
try:
|
|
100
|
+
resp = httpx.get(
|
|
101
|
+
f"{cred['url']}/wp-json/wp/v2/categories",
|
|
102
|
+
params={"search": nome_tema, "per_page": 20},
|
|
103
|
+
auth=(cred["user"], cred["password"]),
|
|
104
|
+
timeout=20.0,
|
|
105
|
+
)
|
|
106
|
+
if resp.status_code == 200:
|
|
107
|
+
for categoria in resp.json():
|
|
108
|
+
if str(categoria.get("name", "")).lower() == nome_tema.lower():
|
|
109
|
+
return int(categoria["id"])
|
|
110
|
+
resp = httpx.post(
|
|
111
|
+
f"{cred['url']}/wp-json/wp/v2/categories",
|
|
112
|
+
json={"name": nome_tema.title()},
|
|
113
|
+
auth=(cred["user"], cred["password"]),
|
|
114
|
+
timeout=20.0,
|
|
115
|
+
)
|
|
116
|
+
if resp.status_code in (200, 201) and resp.json().get("id"):
|
|
117
|
+
return int(resp.json()["id"])
|
|
118
|
+
except httpx.HTTPError as exc:
|
|
119
|
+
logger.warning("WordPress: falha ao resolver categoria (%s)", exc)
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def contar_palavras(texto: str) -> int:
|
|
124
|
+
return len((texto or "").split())
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def publish_to_wordpress(db, noticia) -> dict:
|
|
128
|
+
"""Publica a notícia completa. Retorna {"post_id": int, "link": str}."""
|
|
129
|
+
cred = _credenciais(db)
|
|
130
|
+
palavras = contar_palavras(noticia.corpo)
|
|
131
|
+
if palavras < MINIMO_PALAVRAS_PUBLICACAO:
|
|
132
|
+
raise RuntimeError(
|
|
133
|
+
f"Texto com {palavras} palavras — mínimo de {MINIMO_PALAVRAS_PUBLICACAO} para publicar (diretriz AdSense)."
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
blog = db.get(Blog, noticia.blog_id)
|
|
137
|
+
categoria_id = resolver_categoria(cred, blog.tema if blog else "")
|
|
138
|
+
|
|
139
|
+
featured_media = None
|
|
140
|
+
if noticia.imagem_url:
|
|
141
|
+
caminho = _imagem_local(noticia.imagem_url)
|
|
142
|
+
if caminho:
|
|
143
|
+
featured_media = _upload_midia(cred, caminho)
|
|
144
|
+
|
|
145
|
+
payload: dict = {
|
|
146
|
+
"title": noticia.titulo,
|
|
147
|
+
"content": noticia.corpo,
|
|
148
|
+
"status": "publish",
|
|
149
|
+
}
|
|
150
|
+
if categoria_id:
|
|
151
|
+
payload["categories"] = [categoria_id]
|
|
152
|
+
if featured_media:
|
|
153
|
+
payload["featured_media"] = featured_media
|
|
154
|
+
|
|
155
|
+
resp = httpx.post(
|
|
156
|
+
f"{cred['url']}/wp-json/wp/v2/posts",
|
|
157
|
+
json=payload,
|
|
158
|
+
auth=(cred["user"], cred["password"]),
|
|
159
|
+
timeout=60.0,
|
|
160
|
+
)
|
|
161
|
+
if resp.status_code not in (200, 201):
|
|
162
|
+
raise RuntimeError(f"WP respondeu {resp.status_code}: {resp.text[:300]}")
|
|
163
|
+
dados = resp.json()
|
|
164
|
+
post_id = int(dados["id"])
|
|
165
|
+
link = dados.get("link") or f"{cred['url']}/?p={post_id}"
|
|
166
|
+
logger.info("WordPress: post %s publicado (%s)", post_id, link)
|
|
167
|
+
return {"post_id": post_id, "link": link}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.left-1{left:.25rem}.left-11{left:2.75rem}.left-9{left:2.25rem}.top-1{top:.25rem}.z-50{z-index:50}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-40{height:10rem}.h-44{height:11rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-auto{height:auto}.h-full{height:100%}.max-h-48{max-height:12rem}.max-h-56{max-height:14rem}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-16{width:4rem}.w-20{width:5rem}.w-40{width:10rem}.w-44{width:11rem}.w-6{width:1.5rem}.w-60{width:15rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-6xl{max-width:72rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-400\/40{border-color:#fbbf2466}.border-panda\/40{border-color:#22c55e66}.border-red-400\/40{border-color:#f8717166}.border-slate-100{--tw-border-opacity: 1;border-color:rgb(241 245 249 / var(--tw-border-opacity, 1))}.border-slate-200{--tw-border-opacity: 1;border-color:rgb(226 232 240 / var(--tw-border-opacity, 1))}.border-slate-300{--tw-border-opacity: 1;border-color:rgb(203 213 225 / var(--tw-border-opacity, 1))}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-black\/60{background-color:#0009}.bg-emerald-100{--tw-bg-opacity: 1;background-color:rgb(209 250 229 / var(--tw-bg-opacity, 1))}.bg-night{--tw-bg-opacity: 1;background-color:rgb(11 18 32 / var(--tw-bg-opacity, 1))}.bg-panda{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-panda\/10{background-color:#22c55e1a}.bg-panda\/15{background-color:#22c55e26}.bg-panda\/30{background-color:#22c55e4d}.bg-panda\/70{background-color:#22c55eb3}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-500\/10{background-color:#ef44441a}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-sky-100{--tw-bg-opacity: 1;background-color:rgb(224 242 254 / var(--tw-bg-opacity, 1))}.bg-slate-200{--tw-bg-opacity: 1;background-color:rgb(226 232 240 / var(--tw-bg-opacity, 1))}.bg-slate-300{--tw-bg-opacity: 1;background-color:rgb(203 213 225 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.object-cover{-o-object-fit:cover;object-fit:cover}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-14{padding-top:3.5rem;padding-bottom:3.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.pb-2{padding-bottom:.5rem}.pr-4{padding-right:1rem}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-none{line-height:1}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-emerald-300{--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-panda{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-panda-dark{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-sky-700{--tw-text-opacity: 1;color:rgb(3 105 161 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-slate-800{--tw-text-opacity: 1;color:rgb(30 41 59 / var(--tw-text-opacity, 1))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.line-through{text-decoration-line:line-through}.placeholder-slate-400::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(148 163 184 / var(--tw-placeholder-opacity, 1))}.placeholder-slate-400::placeholder{--tw-placeholder-opacity: 1;color:rgb(148 163 184 / var(--tw-placeholder-opacity, 1))}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}body{--tw-bg-opacity: 1;background-color:rgb(11 18 32 / var(--tw-bg-opacity, 1));font-family:Inter,system-ui,sans-serif;--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}html:not(.dark) body{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(30 41 59 / var(--tw-text-opacity, 1))}.last\:border-0:last-child{border-width:0px}.hover\:border-slate-400:hover{--tw-border-opacity: 1;border-color:rgb(148 163 184 / var(--tw-border-opacity, 1))}.hover\:bg-panda-dark:hover{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:bg-slate-100:hover{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.hover\:text-slate-800:hover{--tw-text-opacity: 1;color:rgb(30 41 59 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.focus\:border-panda:focus{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.dark\:border-slate-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(51 65 85 / var(--tw-border-opacity, 1))}.dark\:border-slate-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(30 41 59 / var(--tw-border-opacity, 1))}.dark\:bg-amber-500\/15:is(.dark *){background-color:#f59e0b26}.dark\:bg-card:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(16 26 44 / var(--tw-bg-opacity, 1))}.dark\:bg-emerald-500\/15:is(.dark *){background-color:#10b98126}.dark\:bg-night:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(11 18 32 / var(--tw-bg-opacity, 1))}.dark\:bg-red-500\/15:is(.dark *){background-color:#ef444426}.dark\:bg-sky-500\/15:is(.dark *){background-color:#0ea5e926}.dark\:bg-slate-700:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.dark\:bg-slate-700\/60:is(.dark *){background-color:#33415599}.dark\:bg-slate-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.dark\:bg-slate-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.dark\:text-amber-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.dark\:text-emerald-400:is(.dark *){--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.dark\:text-panda:is(.dark *){--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.dark\:text-red-400:is(.dark *){--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:text-sky-400:is(.dark *){--tw-text-opacity: 1;color:rgb(56 189 248 / var(--tw-text-opacity, 1))}.dark\:text-slate-200:is(.dark *){--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.dark\:text-slate-300:is(.dark *){--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.dark\:text-slate-400:is(.dark *){--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.dark\:text-slate-500:is(.dark *){--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.dark\:text-slate-600:is(.dark *){--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.dark\:placeholder-slate-500:is(.dark *)::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(100 116 139 / var(--tw-placeholder-opacity, 1))}.dark\:placeholder-slate-500:is(.dark *)::placeholder{--tw-placeholder-opacity: 1;color:rgb(100 116 139 / var(--tw-placeholder-opacity, 1))}.dark\:hover\:border-slate-500:hover:is(.dark *){--tw-border-opacity: 1;border-color:rgb(100 116 139 / var(--tw-border-opacity, 1))}.dark\:hover\:bg-slate-800\/60:hover:is(.dark *){background-color:#1e293b99}.dark\:hover\:text-slate-200:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width: 768px){.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width: 1024px){.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width: 1280px){.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.left-1{left:.25rem}.left-11{left:2.75rem}.left-9{left:2.25rem}.top-1{top:.25rem}.z-50{z-index:50}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-40{height:10rem}.h-44{height:11rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-auto{height:auto}.h-full{height:100%}.max-h-48{max-height:12rem}.max-h-56{max-height:14rem}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-16{width:4rem}.w-20{width:5rem}.w-40{width:10rem}.w-44{width:11rem}.w-6{width:1.5rem}.w-60{width:15rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-6xl{max-width:72rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-400\/40{border-color:#fbbf2466}.border-panda\/40{border-color:#22c55e66}.border-red-400\/40{border-color:#f8717166}.border-slate-100{--tw-border-opacity: 1;border-color:rgb(241 245 249 / var(--tw-border-opacity, 1))}.border-slate-200{--tw-border-opacity: 1;border-color:rgb(226 232 240 / var(--tw-border-opacity, 1))}.border-slate-300{--tw-border-opacity: 1;border-color:rgb(203 213 225 / var(--tw-border-opacity, 1))}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-black\/60{background-color:#0009}.bg-emerald-100{--tw-bg-opacity: 1;background-color:rgb(209 250 229 / var(--tw-bg-opacity, 1))}.bg-night{--tw-bg-opacity: 1;background-color:rgb(11 18 32 / var(--tw-bg-opacity, 1))}.bg-panda{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-panda\/10{background-color:#22c55e1a}.bg-panda\/15{background-color:#22c55e26}.bg-panda\/30{background-color:#22c55e4d}.bg-panda\/70{background-color:#22c55eb3}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-500\/10{background-color:#ef44441a}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-sky-100{--tw-bg-opacity: 1;background-color:rgb(224 242 254 / var(--tw-bg-opacity, 1))}.bg-slate-200{--tw-bg-opacity: 1;background-color:rgb(226 232 240 / var(--tw-bg-opacity, 1))}.bg-slate-300{--tw-bg-opacity: 1;background-color:rgb(203 213 225 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.object-cover{-o-object-fit:cover;object-fit:cover}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-14{padding-top:3.5rem;padding-bottom:3.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.pb-2{padding-bottom:.5rem}.pr-4{padding-right:1rem}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-none{line-height:1}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-emerald-300{--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-panda{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-panda-dark{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-sky-700{--tw-text-opacity: 1;color:rgb(3 105 161 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-slate-800{--tw-text-opacity: 1;color:rgb(30 41 59 / var(--tw-text-opacity, 1))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.placeholder-slate-400::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(148 163 184 / var(--tw-placeholder-opacity, 1))}.placeholder-slate-400::placeholder{--tw-placeholder-opacity: 1;color:rgb(148 163 184 / var(--tw-placeholder-opacity, 1))}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}body{--tw-bg-opacity: 1;background-color:rgb(11 18 32 / var(--tw-bg-opacity, 1));font-family:Inter,system-ui,sans-serif;--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}html:not(.dark) body{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(30 41 59 / var(--tw-text-opacity, 1))}.last\:border-0:last-child{border-width:0px}.hover\:border-slate-400:hover{--tw-border-opacity: 1;border-color:rgb(148 163 184 / var(--tw-border-opacity, 1))}.hover\:bg-panda-dark:hover{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:bg-slate-100:hover{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.hover\:text-slate-800:hover{--tw-text-opacity: 1;color:rgb(30 41 59 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.focus\:border-panda:focus{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.dark\:border-slate-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(51 65 85 / var(--tw-border-opacity, 1))}.dark\:border-slate-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(30 41 59 / var(--tw-border-opacity, 1))}.dark\:bg-amber-500\/15:is(.dark *){background-color:#f59e0b26}.dark\:bg-card:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(16 26 44 / var(--tw-bg-opacity, 1))}.dark\:bg-emerald-500\/15:is(.dark *){background-color:#10b98126}.dark\:bg-night:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(11 18 32 / var(--tw-bg-opacity, 1))}.dark\:bg-red-500\/15:is(.dark *){background-color:#ef444426}.dark\:bg-sky-500\/15:is(.dark *){background-color:#0ea5e926}.dark\:bg-slate-700:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.dark\:bg-slate-700\/60:is(.dark *){background-color:#33415599}.dark\:bg-slate-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.dark\:bg-slate-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.dark\:text-amber-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.dark\:text-emerald-400:is(.dark *){--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.dark\:text-panda:is(.dark *){--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.dark\:text-red-400:is(.dark *){--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:text-sky-400:is(.dark *){--tw-text-opacity: 1;color:rgb(56 189 248 / var(--tw-text-opacity, 1))}.dark\:text-slate-200:is(.dark *){--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.dark\:text-slate-300:is(.dark *){--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.dark\:text-slate-400:is(.dark *){--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.dark\:text-slate-500:is(.dark *){--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.dark\:text-slate-600:is(.dark *){--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.dark\:placeholder-slate-500:is(.dark *)::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(100 116 139 / var(--tw-placeholder-opacity, 1))}.dark\:placeholder-slate-500:is(.dark *)::placeholder{--tw-placeholder-opacity: 1;color:rgb(100 116 139 / var(--tw-placeholder-opacity, 1))}.dark\:hover\:border-slate-500:hover:is(.dark *){--tw-border-opacity: 1;border-color:rgb(100 116 139 / var(--tw-border-opacity, 1))}.dark\:hover\:bg-slate-800\/60:hover:is(.dark *){background-color:#1e293b99}.dark\:hover\:text-slate-200:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width: 768px){.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width: 1024px){.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width: 1280px){.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}
|