Files
NightSpire/web-next/app/globals.css
T
Inna 47b5a2a145 Mostrar los errores de send-gift: el tema los dejaba invisibles
El botón «Mostrar regalos» parecía no hacer nada: setFormError se llamaba
bien, pero el tema deja `.alert-message` con display:none esperando que la
rellene y la revele el JS antiguo (jQuery), que ya no existe. La caja se
pintaba y no se veía. Se fuerza el display desde React, como el resto de
formularios.

De paso, `.modal-content` estaba definida en globals.css Y en theme.css.
Como theme.css se importa el último (a propósito, para ganarle al preflight
de Tailwind), ganaba él a igual especificidad y el bloque de globals.css era
código muerto: el modal de la tienda salía como hoja pegada al fondo con
borde gris en vez de tarjeta centrada dorada. Se acota a
`.modal-div .modal-content` para ganar por especificidad y no por orden.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:03:30 +00:00

675 lines
21 KiB
CSS

@import 'tailwindcss';
/* Tokens de diseño NightSpire (paleta oscura fantasía WotLK). */
@theme {
--color-ns-bg: #140d08;
--color-ns-panel: #241812;
--color-ns-panel-2: #2c1e14;
--color-ns-border: #4a3320;
--color-ns-gold: #d79602;
--color-ns-gold-light: #f0b93f;
--color-ns-text: #e8dccb;
--color-ns-muted: #b1997f;
}
:root {
color-scheme: dark;
}
/* El fondo, la tipografía (FuturaEF-Book) y los estilos base del <body>
los controla el tema real ns-ryu (theme.css), importado AL FINAL de este
fichero. No los redefinimos aquí para que el tema quede idéntico. */
/* El tema ns-ryu se diseñó para los defaults del navegador (igual que la web
Django, que NO usa Tailwind). El preflight de Tailwind rompe dos cosas:
1) box-sizing:border-box hace que la height fija de los inputs incluya el
padding → campos aplastados. Volvemos a content-box SOLO en los inputs de
texto que estiliza el tema (el navegador les da content-box por defecto,
como la web Django sin Tailwind; los de .admin-form conservan border-box
por su mayor especificidad). OJO: `select` NO va aquí — su default del
navegador es border-box (40px); forzarlo a content-box lo agranda a 60px.
2) border-collapse:collapse anula el border-spacing de las tablas del tema
(middle-center-table, etc.) → filas pegadas. Volvemos a separate.
Reglas SIN capa: ganan al preflight de Tailwind (que va en @layer base). */
input[type='text'],
input[type='email'],
input[type='password'],
input[type='number'] {
box-sizing: content-box;
}
table {
border-collapse: separate;
}
/* `.back-to-account` es el botón de la CABECERA de una caja: 250px de ancho,
line-height 50 y flotando a la derecha. Cuando se usa suelto en el CUERPO
(el "Solicitar nuevo cambio de correo" de /expired-link) sale mal por dos
motivos: el float lo pega a la derecha en vez de centrarlo, y el texto no cabe
en 250px, se parte en dos líneas y cada una se lleva sus 50px -> un botón de
250x100. Aquí se le deja el aspecto del tema pero ajustado a su texto. */
.body-box-content .centered a.back-to-account {
float: none;
display: inline-block;
width: auto;
padding: 0 24px;
}
/* Mismo caso que .item-box de la tienda: el tema da a `.cc-box` (creadores de
contenido) una altura FIJA de 172px contando con el content-box del navegador,
y el border-box de Tailwind le resta el padding y el borde. Con 24px menos de
alto útil, los enlaces de YouTube/Facebook se salían por abajo de la caja. */
.cc-box {
box-sizing: content-box;
}
/* El tooltip de wowhead se inyecta en el <body>, así que le caen encima las
reglas globales del tema. La que lo rompe es `th { height: 40px }` (global,
viene tal cual del tema original): el tooltip usa <th> para la columna de la
derecha (fase, tipo de arma, velocidad…), y cada una de esas filas se estiraba
a 40px, dejando huecos enormes entre líneas. El store original no lo sufre
porque su tooltip lo pinta otro script con otro markup. Se neutraliza solo
dentro del tooltip: alto natural y sin el fondo de cabecera del tema.
`font-weight` no hace falta tocarlo: wowhead ya lo pone normal. */
.wowhead-tooltip th {
height: auto;
background-color: transparent;
}
/* tooltips.js NO trae fondo para el tooltip (universal.css solo le da layout y
los colores de calidad): en wowhead.com lo pinta el CSS de su web, que aquí no
cargamos. Sin esto el tooltip es transparente y se lee la página a través de
él —se ve igual en una página desnuda con solo tooltips.js, no es cosa del
tema—. Se le da el fondo y el borde de las cajas del tema. */
.wowhead-tooltip {
background: #0b0705;
border: 2px solid #352e2b;
}
/* 3) Tailwind pone img{display:block}, lo que apila verticalmente los iconos
en línea (monedas de oro/plata/cobre, iconos inline del tema). El tema los
usa inline (como la web Django). Volvemos a inline; las imágenes que deban
ser bloque ya lo fijan por su propia clase (.img-med-icon, etc., mayor
especificidad). */
img {
display: inline;
}
/* 4) La barra de navegación se diseñó para content-box: sus enlaces/botones usan
`min-width: 126px` + `padding: 24px`, así que con el border-box del preflight
quedan ~48px más estrechos (contenido 78px) y el header sale apretado/pequeño
respecto al original. Volvemos a content-box en los elementos del nav para que
el ancho coincida con la web original (126 + 48 = 174px). */
.nav-bar a,
.nav-dropdown-btn,
.nav-dropdown-content a {
box-sizing: content-box;
}
/* Componentes reutilizables */
@layer components {
.ns-btn {
@apply inline-flex items-center justify-center rounded-md bg-ns-gold px-5 py-2.5 font-semibold text-[#1b120b] transition hover:bg-ns-gold-light;
}
.ns-btn-ghost {
@apply inline-flex items-center justify-center rounded-md border border-ns-border px-5 py-2.5 font-semibold text-ns-text transition hover:border-ns-gold hover:text-ns-gold-light;
}
.ns-card {
@apply rounded-xl border border-ns-border/70 bg-ns-panel/80 p-5 shadow-lg shadow-black/30 backdrop-blur;
}
.ns-heading {
@apply bg-gradient-to-b from-ns-gold-light to-ns-gold bg-clip-text font-extrabold tracking-wide text-transparent;
}
.ns-input {
@apply w-full rounded-md border border-ns-border bg-ns-panel-2 px-3 py-2 text-ns-text outline-none transition focus:border-ns-gold;
}
}
/* Contenido HTML de noticias/foro */
.prose :where(a) {
color: #7cc0f7;
}
/* Foro: textarea con el look del tema real (el tema ns-ryu no estiliza textarea base). */
textarea {
width: 100%;
background-color: #000;
border: 2px solid #352e2b;
color: #fff;
font-family: 'FuturaEF-Book';
font-size: 17px;
padding: 8px;
transition: 0.5s;
}
textarea:focus {
border-color: #948474;
}
/* Foro: barra de herramientas del editor y paginación (colores del tema). */
.ns-tool-btn {
border: 2px solid #352e2b;
background: hsla(0, 0%, 100%, 0.05);
color: #ebdec2;
padding: 4px 10px;
cursor: pointer;
transition: 0.3s;
}
.ns-tool-btn:hover {
background: hsla(0, 0%, 100%, 0.1);
color: #fff;
}
/* Paginación con el estilo de los botones del tema (borde + fondo tenue + hover).
Los selectores :link/:visited elevan la especificidad para ganar a las reglas
`a`/`a:visited` del tema (que si no dejan los enlaces visitados en azul). */
.ns-page-link {
display: inline-block;
min-width: 42px;
padding: 9px 14px;
margin: 0 3px;
border: 2px solid #352e2b;
background: hsla(0, 0%, 100%, 0.05);
text-align: center;
transition: 0.3s;
}
.ns-page-link:link,
.ns-page-link:visited {
color: #ebdec2;
}
.ns-page-link:hover {
background: hsla(0, 0%, 100%, 0.1);
color: #fff;
}
.ns-page-current,
.ns-page-current:link,
.ns-page-current:visited {
border-color: #b17c02;
color: #d79602;
background: hsla(40, 90%, 45%, 0.12);
}
/* Contenido de posts del foro */
.post-content {
line-height: 22px;
}
.post-content a {
color: #2471a9;
}
/* Panel de admin: campos a ancho completo dentro de la caja del formulario. */
.admin-form input,
.admin-form textarea,
.admin-form select {
width: 100%;
box-sizing: border-box;
margin-bottom: 10px;
}
/* Listas dentro de las cajas de contenido (el tema no las estiliza y el
preflight de Tailwind quita los bullets; los devolvemos como en Django). */
.body-box-content ul {
list-style: disc;
padding-left: 22px;
margin: 8px 0;
}
.body-box-content li {
line-height: 22px;
}
/* Declaración de cookies: tablas y botones de consentimiento. */
.ns-cookie-table {
width: 100%;
border-collapse: collapse;
margin: 12px 0 16px;
font-size: 15px;
}
.ns-cookie-table th,
.ns-cookie-table td {
border: 1px solid #352e2b;
padding: 8px 10px;
text-align: left;
vertical-align: top;
}
.ns-cookie-table th {
background: hsla(0, 0%, 100%, 0.05);
color: #ebdec2;
text-transform: uppercase;
font-size: 13px;
}
.ns-cookie-table td {
color: #b1997f;
}
.ns-cookie-table a {
color: #2471a9;
}
.ns-consent-buttons {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin: 12px 0;
}
.btn-ns {
border: 2px solid #352e2b;
background: hsla(0, 0%, 100%, 0.05);
color: #ebdec2;
padding: 10px 18px;
cursor: pointer;
text-transform: uppercase;
transition: 0.3s;
}
.btn-ns:hover {
background: hsla(0, 0%, 100%, 0.1);
color: #fff;
}
.btn-ns-secondary {
border-color: #5c2b2b;
color: #d98c8c;
}
.btn-ns-secondary:hover {
background: hsla(0, 60%, 30%, 0.15);
color: #fff;
}
/* Banner de consentimiento de cookies (fijo abajo). */
.ns-cookie-content {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
flex-wrap: wrap;
padding: 16px 24px;
background: #140d08;
border-top: 2px solid #4a3320;
box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.55);
}
.ns-cookie-text {
flex: 1 1 420px;
}
.ns-cookie-text h3 {
color: #d79602;
margin-bottom: 6px;
}
.ns-cookie-text p {
color: #b1997f;
font-size: 14px;
line-height: 20px;
}
.ns-cookie-link {
display: inline-block;
margin-top: 6px;
color: #2471a9;
}
.ns-cookie-actions {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.ns-cookie-btn {
border: 2px solid #352e2b;
background: hsla(0, 0%, 100%, 0.05);
color: #ebdec2;
padding: 9px 16px;
cursor: pointer;
text-transform: uppercase;
font-size: 14px;
transition: 0.3s;
}
.ns-cookie-btn:hover {
background: hsla(0, 0%, 100%, 0.1);
color: #fff;
}
.ns-cookie-btn-accept {
border-color: #b17c02;
color: #f0b93f;
}
.ns-cookie-btn-accept:hover {
background: hsla(40, 90%, 45%, 0.15);
color: #fff;
}
.ns-cookie-btn-reject {
border-color: #5c2b2b;
color: #d98c8c;
}
.ns-cookie-btn-save {
border-color: #b17c02;
color: #f0b93f;
}
.ns-cookie-btn-save:hover {
background: hsla(40, 90%, 45%, 0.15);
color: #fff;
}
/* Panel «Personalizar» del banner (checkboxes por categoría). */
.ns-cookie-details {
margin-top: 14px;
padding-top: 12px;
border-top: 1px solid #352e2b;
}
.ns-cookie-category {
margin-bottom: 10px;
}
.ns-cookie-category label {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
}
.ns-cookie-category input[type='checkbox'] {
width: 16px;
height: 16px;
accent-color: #d79602;
cursor: pointer;
}
.ns-cookie-category input[type='checkbox']:disabled {
cursor: default;
}
.ns-cookie-cat-name {
color: #ebdec2;
font-size: 15px;
}
.ns-cookie-category p {
color: #b1997f;
font-size: 13px;
margin: 2px 0 0 24px;
line-height: 18px;
}
.ns-cookie-actions-detail {
margin-top: 8px;
}
/* Panel «Tu estado de consentimiento» en /cookies (datos de la API de Zaraz). */
.ns-consent-status {
border: 1px solid #352e2b;
padding: 12px 14px;
margin: 12px 0;
}
.ns-consent-status .ns-consent-source {
font-size: 13px;
color: #7e8d09;
margin-bottom: 8px;
}
.ns-consent-status ul {
list-style: none;
padding: 0;
margin: 0;
}
.ns-consent-status li {
display: flex;
justify-content: space-between;
gap: 12px;
padding: 4px 0;
border-bottom: 1px solid #241812;
}
.ns-consent-status li:last-child {
border-bottom: 0;
}
.ns-consent-on {
color: #6aa84f;
}
.ns-consent-off {
color: #cc5b5b;
}
.ns-consent-always {
color: #b1997f;
}
/* Selector de cuenta inline (dentro de «Nombre de la cuenta») + botón «+». */
.account-select {
width: auto;
min-width: 92px;
height: auto;
padding: 2px 8px;
margin: 0 0 0 4px;
font-size: 17px;
vertical-align: middle;
}
.add-account-btn {
height: auto;
padding: 1px 9px;
margin: 0 0 0 6px;
font-size: 17px;
line-height: 1.4;
vertical-align: middle;
border: 2px solid #352e2b;
background: hsla(0, 0%, 100%, 0.05);
color: #ebdec2;
cursor: pointer;
transition: 0.3s;
}
.add-account-btn:hover {
background: hsla(0, 0%, 100%, 0.1);
color: #fff;
}
/* El formulario de añadir cuenta sale en bloque, debajo del nombre. */
.add-account-box {
display: block;
margin-top: 6px;
}
.add-account-input {
min-width: 150px;
}
.add-account-msg {
display: block;
margin-top: 4px;
}
/* Colores de calidad de objeto (enlaces de recompensas RAF, etc.). */
.q0 { color: #9d9d9d; }
.q1 { color: #ffffff; }
.q2 { color: #1eff00; }
.q3 { color: #0070dd; }
.q4 { color: #a335ee; }
.q5 { color: #ff8000; }
/* Colores de clase de WoW (nombre de personaje) */
.class-warrior { color: #c79c6e; }
.class-paladin { color: #f58cba; }
.class-hunter { color: #abd473; }
.class-rogue { color: #fff569; }
.class-priest { color: #ffffff; }
.class-death-knight { color: #c41f3b; }
.class-shaman { color: #0070de; }
.class-mage { color: #69ccf0; }
.class-warlock { color: #9482c9; }
.class-druid { color: #ff7d0a; }
.class-unknown { color: #f0b100; }
/* Logos en línea de las pasarelas de pago (lista de métodos en /d-points) */
.pay-inline-logo {
height: 18px;
width: auto;
vertical-align: middle;
margin: 0 2px;
}
/* Pasarelas de pago en /d-points: layout e iconos de los botones de método
(portado del tema original; los SVG no tienen tamaño intrínseco, así que se
dimensionan aquí para que el icono quede en línea con el texto como PayPal). */
.dnt-sidebar.dnt-methods {
margin-top: 5px;
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 5px;
}
.dnt-sidebar.dnt-methods .dnt-button-2 {
flex: 1 1 auto;
padding: 0 18px;
}
.dnt-sidebar.dnt-methods .dnt-button-2 img {
height: 22px;
width: auto;
vertical-align: middle;
margin-right: 6px;
}
/* ==== Verificación en 2 pasos (/security-2falogin) ==== */
.twofa-login-info { display: block; }
.twofa-login-preview {
float: right;
max-width: 370px;
margin-left: 24px;
margin-bottom: 8px;
height: auto;
border: 2px solid #352e2b;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}
.google-play-logo { height: 40px; width: 140px; vertical-align: middle; }
.apple-store-logo { height: 40px; width: 120px; vertical-align: middle; }
.toggle-password, .toggle-token { cursor: pointer; margin-left: -28px; color: #b1997f; transition: .3s; }
.toggle-password:hover, .toggle-token:hover { color: #fff; }
.copy-secret-container { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 6px; }
#secret-key { width: 240px; text-align: center; }
.copy-btn { cursor: pointer; }
#qr-code { display: block; margin: 0 auto; max-width: 220px; height: auto; background: #fff; padding: 8px; border-radius: 6px; }
@media screen and (max-width: 1024px) {
.twofa-login-info { display: flex; flex-direction: column-reverse; align-items: center; }
.twofa-login-preview { float: none; display: block; clear: both; margin: 10px auto 8px auto; max-width: 90vw; }
}
/* ==== Selector de forma de pago (PD / Stripe / SumUp) ==== */
.pay-method-select { margin: 10px auto 4px auto; max-width: 560px; }
.pay-method-options {
display: flex;
gap: 10px;
justify-content: center;
flex-wrap: wrap;
margin: 8px 0;
}
.pay-method-option {
flex: 1 1 150px;
min-width: 140px;
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
padding: 12px 10px;
cursor: pointer;
border: 2px solid #352e2b;
border-radius: 8px;
background: rgba(0, 0, 0, 0.25);
transition: border-color .25s, background .25s;
}
.pay-method-option:hover { border-color: #6b5a4e; }
.pay-method-option.selected {
border-color: #d79602;
background: rgba(215, 150, 2, 0.10);
}
.pay-method-option.disabled { cursor: not-allowed; opacity: .55; }
.pay-method-option input[type='radio'] { accent-color: #d79602; }
.pay-method-label { color: #ebdec2; font-weight: bold; }
.pay-method-sub { font-size: 13px; }
.pay-method-balance { margin-top: 2px; font-size: 13px; }
/* ==== Tienda (/store) ==== */
#store-list, #store-list ul { list-style: none; margin: 0; padding-left: 14px; }
#store-list ul { display: block !important; }
#store-list > li { margin: 4px 0; }
/* Ojo: como en el markup original, el <ul> anidado comparte clase con el <span>
que lo abre (store-subcat/store-sub-subcat), así que estas reglas van atadas a
`span` para no convertir la lista en inline-block ni teñirla al pasar el ratón. */
#store-list span.store-cat,
#store-list span.store-subcat,
#store-list span.store-sub-subcat {
display: inline-block !important;
cursor: pointer;
padding: 3px 0;
user-select: none;
}
#store-list span.store-cat:hover,
#store-list span.store-subcat:hover,
#store-list span.store-sub-subcat:hover { color: #fff; }
#store-list span.store-cat i,
#store-list span.store-subcat i,
#store-list span.store-sub-subcat i { transition: transform .2s; margin-right: 4px; }
/* Rejilla de objetos dentro de una hoja. El tema YA define .item-box, .item-name,
.item-img-box y .item-box hr igual que el original: no se redefinen aquí (hacerlo
con `#store-list ...` gana la cascada y descuadra el cuadro del ítem). Lo único
que hace falta es deshacer el `display:none` con el que el tema oculta .item-list
(el original la revelaba con jQuery; aquí la monta React) y reponer el hueco entre
cajas: el PHP dejaba espacios en blanco entre los inline-block y JSX no los emite,
así que se imita con column-gap (el vertical ya lo da el margin del tema). */
#store-list .item-list {
display: flex !important;
flex-wrap: wrap;
align-items: flex-start;
gap: 0 5px;
margin: 8px 0 8px 10px;
}
/* Mismo problema que con los inputs de arriba: el tema se diseñó para el
content-box del navegador, y el preflight de Tailwind mete border-box. Los
200px de `.item-box` son los del original, que con su padding y su borde
miden 214; con border-box se quedaban en 200. Se restaura SOLO en la tienda:
en send-gift el .item-box va con width:auto dentro de una rejilla de columnas
de 160px, y ahí el content-box sumaría el padding y la desbordaría. */
#store-list .item-box { box-sizing: content-box; }
/* El tema esconde #store-div y los <ul> anidados (`display:none`) porque el store
original los revelaba con jQuery (.show()/slideToggle()). Aquí la visibilidad la
decide React montándolos, así que hay que deshacer ese display:none del tema
(que se carga después y gana la cascada). */
#store-div { margin-top: 14px; display: block !important; }
/* Carrito: el tema ya trae .max-left-table2 (width 95% + border-spacing 0 8px, que
es lo que separa las filas), .icon-td, .width-50-td y .justified del original.
No se pisan: el `border-collapse` que había aquí anulaba ese border-spacing. */
/* Precios del carrito: se enseñan SIEMPRE las dos monedas (saldo PD/PV y euros)
y se apaga la que no se va a cobrar con el método elegido. Así el carrito no
presupone nada antes de elegir ni se contradice al pagar con tarjeta. */
/* Cantidad por línea del carrito. Va con `#cart-list` por especificidad, NO por
gusto: el tema define `input[type=number] { width: 290px }` y se carga el
último para ganar la cascada, así que un `.store-copies` a secas pierde y el
input sale de 290px, reventando la tabla. */
#cart-list input.store-copies {
width: 4em;
height: 24px;
text-align: center;
}
.store-price { display: block; transition: opacity .2s, color .2s; }
.store-price-eur { color: #ebdec2; }
.store-price-total { font-weight: bold; }
.store-price-off { opacity: .4; }
.store-price-off .dp-color,
.store-price-off .vp-color { color: inherit; }
/* Modal de resultado */
.modal-div {
position: fixed; inset: 0; z-index: 1000;
background: rgba(0, 0, 0, 0.6);
display: flex; align-items: center; justify-content: center;
}
/* Acotada al overlay a propósito: el tema trae su propia `.modal-content`
(hoja pegada al fondo, borde gris) para un `.modal` que aquí ya no usa
nadie. Como theme.css se importa el último, a igual especificidad ganaba
él y este bloque no pintaba nada. `.modal-div .modal-content` (0,2,0) le
gana al (0,1,0) del tema sin depender del orden de carga. */
.modal-div .modal-content {
position: relative;
background: #17110e;
border: 2px solid #d79602;
border-radius: 10px;
padding: 26px 30px;
max-width: 90vw; min-width: 260px;
text-align: center;
/* el tema las aplica vía su `.modal-content`; sin esto se cuelan */
left: auto; bottom: auto; width: auto;
margin: 0; transform: none; animation: none;
}
.modal-close {
position: absolute; top: 6px; right: 12px;
cursor: pointer; font-size: 22px; color: #b1997f;
}
.modal-close:hover { color: #fff; }
/* Novedades de la tienda (cabecera plegable) */
#store-news { cursor: pointer; user-select: none; }
#store-news-content { margin-top: 6px; }
#store-news-content ul { padding-left: 16px; }
#store-news-content li { margin: 4px 0; }
/* ─── El tema ns-ryu, AL FINAL ─────────────────────────────────────────────
* El orden importa y no es cosmético: el tema se diseñó contra los defaults
* del navegador y el preflight de Tailwind los pisa (box-sizing, alturas...).
* Antes se cargaba con un <link> al final del <head> justo para ganar la
* cascada; ahora entra por el build, así que este @import DEBE ir el último.
* Si sube de sitio, el preflight gana y el diseño se rompe.
*/
@import './theme.css';