skin Activista, colores en todo y barra de unirse a un pub
Skin: uno solo en el movil, Activista, lo mas simple posible: letra del sistema, titulos en negrita sin mayusculas, bordes de 1px, sin sombras ni botones que se hunden; el principal con el color de resalte. Sale de Acampada (themes/Activista.css y styles/activista.css); fuera Acampada y OasisMobile del selector, la fuente Anton y las miniaturas. Quien tuviera otro skin pasa a Activista al abrir. Los colores se aplican siempre; rojo de texto que se lee en las paletas oscuras. Perfil de uso: Activismo por defecto en la config de serie. Pub: barra fija encima de la barra de abajo mientras se une y descarga la red, con la fase, el porcentaje y, si falla, por que (sin red o pub caido, pub sin copia, otro corte). Se pone al dia sin recargar (public/js/mobile_pub.js y /mobile/pub-status); sale al tocar unirse y, si no arranca nada, explica las causas habituales. Fuera la recarga cada 5s de la bienvenida y de Copias en el movil. backend.js pasa backupModel a fork_routes.js en la linea que lo monta. Actividad: fichas de filtro en rejilla de tres y botones de cada tarjeta en una fila. Enlaces web de 24px.
This commit is contained in:
parent
b277f8e1cf
commit
b84a8856dc
25 changed files with 702 additions and 371 deletions
|
|
@ -44,8 +44,9 @@ Dónde va cada cosa:
|
|||
|
||||
| Quiero... | Va en |
|
||||
|---|---|
|
||||
| Cambiar colores, tamaños, márgenes | `styles/mobile_ux.css` (los dos skins) o `hive_acampada.css` (solo Acampada) |
|
||||
| Cambiar la paleta de Acampada | Variables `--a26-*` de `themes/Acampada.css`; las elegibles, en `mobile_settings.js` |
|
||||
| Cambiar colores, tamaños, márgenes | `styles/mobile_ux.css` (piezas) o `styles/activista.css` (lanzador y barras) |
|
||||
| Cambiar los colores de serie o las paletas | Variables `--a26-*` de `themes/Activista.css`; las paletas, en `mobile_settings.js` |
|
||||
| La barra de unirse a un pub | `views/mobile_pubbar.js` y `public/js/mobile_pub.js` |
|
||||
| Otro HTML en una pantalla del dev | Función en `views/mobile_ui.js` + una línea en su vista |
|
||||
| Una pantalla nueva | Vista propia en `views/mobile_*.js` + ruta en `fork_routes.js` |
|
||||
| Algo en Ajustes del móvil | `views/mobile_settings.js` |
|
||||
|
|
@ -144,13 +145,20 @@ Aquí se puede hacer lo que haga falta.
|
|||
tarjetas, formularios). Se carga siempre en el móvil, antes del skin.
|
||||
- `src/client/assets/styles/mobile_ux.css`: márgenes, letra, botones y todas las
|
||||
piezas nuevas. Vale para los dos skins de móvil.
|
||||
- `src/client/assets/themes/Acampada.css` y `styles/hive_acampada.css`: el skin
|
||||
Acampada.
|
||||
- `src/client/assets/themes/Activista.css` y `styles/activista.css`: el skin
|
||||
Activista, el único del móvil (Acampada y el OasisMobile del dev se quitaron del
|
||||
selector el 20/10/2026). Lo más simple posible: letra del sistema, bordes finos y
|
||||
sin sombras. El skin quita lo que sobra; los colores los pone cada cual.
|
||||
- `src/views/mobile_pubbar.js` y `public/js/mobile_pub.js`: la barra fija de unirse a
|
||||
un pub (y de restaurar una copia), encima de la barra de abajo. Se pone al día sin
|
||||
recargar, preguntando a `/mobile/pub-status`; el estado sale de
|
||||
`backupModel.restoreStatus()`, que `backend.js` le pasa a `fork_routes.js` en la
|
||||
línea que lo monta.
|
||||
- `src/views/mobile_ui.js`: lo que se enchufa en vistas del dev.
|
||||
- `src/views/mobile_settings.js`: los seis accesos de arriba de Ajustes (identidad,
|
||||
perfil, portada, colores, comunidad y saludo) y los colores. Los colores se guardan
|
||||
en la config (`mobileColors`) y salen en `/mobile-colors.css`, la última hoja; son
|
||||
las variables `--a26-*` de Acampada, así que solo valen con ese skin.
|
||||
las variables `--a26-*` del skin Activista.
|
||||
- `src/views/mobile_modules_view.js`, `identities_view.js`: pantallas propias.
|
||||
- `src/views/hive_views.js`: lanzador y barras de arriba y abajo.
|
||||
- `src/views/mobile_icons.js`: los iconos.
|
||||
|
|
@ -172,10 +180,10 @@ Aquí se puede hacer lo que haga falta.
|
|||
Cambiar cómo se ve algo. Se busca la clase en el HTML (servidor local e inspector) y
|
||||
se escribe la regla en `mobile_ux.css`. Para los colores usad las variables `--ux-*`
|
||||
(`--ux-bg`, `--ux-fg`, `--ux-accent`, `--ux-muted`, `--ux-line`, `--ux-danger`), que
|
||||
tiran de Acampada si está y si no de la paleta de OasisMobile. Si la regla no gana,
|
||||
es que `mobile.css` o `Acampada.css` mandan con `!important` y selectores largos:
|
||||
tiran de las `--a26-*` del skin. Si la regla no gana,
|
||||
es que `mobile.css` o `Activista.css` mandan con `!important` y selectores largos:
|
||||
hay que subir la especificidad y poner `!important` también. Ojo con una trampa:
|
||||
`Acampada.css` quita el borde a todos los `div`, así que para ponérselo a uno hace
|
||||
`Activista.css` quita fondo, borde y sombra a todos los `div`, así que para ponérselo a uno hace
|
||||
falta `.main-column div.la-clase`.
|
||||
|
||||
Huecos de las barras del sistema: nada de `env(safe-area-inset-*)`. El contenedor de
|
||||
|
|
@ -305,7 +313,7 @@ líneas (20/10/2026, contra el `nodejs-project` de la APK 1.3.3). Por tamaño:
|
|||
- `backend/blobHandler.js` (190): limpiar los metadatos de las fotos también en
|
||||
Android. Es una función nuestra metida en su fichero; habría que proponérsela al dev.
|
||||
- `configs/oasis-config.json` (87) y `configs/config-manager.js` (18): la config de
|
||||
serie del móvil (tema Acampada, workflow acampada, barra de abajo).
|
||||
serie del móvil (skin Activista, perfil Activismo, barra de abajo).
|
||||
- `views/main_views.js` (64), `settings_view.js` (33), `welcome_view.js` (20),
|
||||
`tribes_view.js` (9), `vote_view.js` (7): enganches a `mobile_ui.js` y el orden de
|
||||
carga de las hojas. Es lo que la guía permite, pero hay que revisarlo en cada versión.
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ table.tight td { padding: 1.1mm 2mm; }
|
|||
<rect x="0" y="0" width="330" height="34" rx="6" fill="#f1f4f5" stroke="#0b0b0b"/><text x="12" y="22">1 · style.css y mobile.css (tuyas)</text>
|
||||
<rect x="0" y="40" width="330" height="34" rx="6" fill="#e2fbff" stroke="#0b0b0b"/><text x="12" y="62">2 · mobile_base.css: maqueta de la rama</text>
|
||||
<rect x="0" y="80" width="330" height="34" rx="6" fill="#fff" stroke="#0b0b0b"/><text x="12" y="102">3 · skin: Acampada.css o tu OasisMobile.css</text>
|
||||
<rect x="0" y="120" width="330" height="34" rx="6" fill="#e2fbff" stroke="#0b0b0b"/><text x="12" y="142">4 · hive_acampada.css (solo con Acampada)</text>
|
||||
<rect x="0" y="120" width="330" height="34" rx="6" fill="#e2fbff" stroke="#0b0b0b"/><text x="12" y="142">4 · activista.css (solo con Acampada)</text>
|
||||
<rect x="0" y="160" width="330" height="34" rx="6" fill="#0b0b0b"/><text x="12" y="182" fill="#fff">5 · mobile_ux.css: piezas comunes, la última</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
|
|||
|
|
@ -15576,7 +15576,7 @@ const middleware = [
|
|||
await next();
|
||||
},
|
||||
// la rama movil: su router y su capa de backend (ver GUIA_DE_DESARROLLO.md)
|
||||
require('./fork_routes')({ checkMod, getViewerId, getConfig, saveConfig, isLoopbackRequest, sendErrorPage, about }),
|
||||
require('./fork_routes')({ checkMod, getViewerId, getConfig, saveConfig, isLoopbackRequest, sendErrorPage, about, backupModel }),
|
||||
routes,
|
||||
async (ctx) => {
|
||||
if (ctx.body != null || (ctx.method !== 'GET' && ctx.method !== 'HEAD')) return;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ require("../models/fork_workflows").register();
|
|||
|
||||
const isMobile = () => process.env.OASIS_MOBILE === '1';
|
||||
|
||||
module.exports = ({ checkMod, getViewerId, getConfig, saveConfig, isLoopbackRequest, sendErrorPage, about }) => {
|
||||
module.exports = ({ checkMod, getViewerId, getConfig, saveConfig, isLoopbackRequest, sendErrorPage, about, backupModel }) => {
|
||||
const pubBar = require('../views/mobile_pubbar');
|
||||
pubBar.setSource(backupModel);
|
||||
const mobileLayer = require('./mobile_layer')({ getViewerId, about });
|
||||
|
||||
const forkRouter = new koaRouter();
|
||||
|
|
@ -38,21 +40,29 @@ const mobileLayer = require('./mobile_layer')({ getViewerId, about });
|
|||
ctx.cookies.set('theme', theme, { httpOnly: true, sameSite: 'strict', secure: ctx.secure });
|
||||
ctx.redirect('/settings#theme');
|
||||
})
|
||||
// colores del movil (mobile_settings.js): se guardan en la config y el aspecto pasa
|
||||
// a Acampada, que es el tema que lee esas variables
|
||||
// colores del movil (mobile_settings.js): se guardan en la config
|
||||
.post('/settings/colors', koaBody(), async (ctx, next) => {
|
||||
if (!isMobile()) return next();
|
||||
const body = ctx.request.body || {};
|
||||
const cfg = getConfig();
|
||||
cfg.mobileColors = require('../views/mobile_settings').colorsFromBody(body);
|
||||
if ((cfg.themes || {}).current !== 'Acampada') {
|
||||
cfg.themes = { ...(cfg.themes || {}), current: 'Acampada' };
|
||||
ctx.cookies.set('theme', 'Acampada', { httpOnly: true, sameSite: 'strict', secure: ctx.secure });
|
||||
}
|
||||
saveConfig(cfg);
|
||||
const back = String(body.returnTo || '');
|
||||
ctx.redirect(/^\/(settings|welcome)(#[a-z-]+)?$/.test(back) ? back : '/settings#colors');
|
||||
})
|
||||
// barra de unirse a un pub (mobile_pubbar.js): el estado para el script, sin
|
||||
// recargar la pagina, y cerrar el aviso de terminado
|
||||
.get('/mobile/pub-status', async (ctx, next) => {
|
||||
if (!isMobile()) return next();
|
||||
ctx.set('Cache-Control', 'no-store');
|
||||
ctx.body = pubBar.status() || { kind: 'none', running: false };
|
||||
})
|
||||
.post('/mobile/pub-status/dismiss', koaBody(), async (ctx, next) => {
|
||||
if (!isMobile()) return next();
|
||||
pubBar.dismiss();
|
||||
const back = String(ctx.get('referer') || '').replace(/^https?:\/\/[^/]+/, '');
|
||||
ctx.redirect(/^\/[\w\-/?=&%.#]*$/.test(back) ? back : '/activity');
|
||||
})
|
||||
.get('/mobile-colors.css', async (ctx, next) => {
|
||||
if (!isMobile()) return next();
|
||||
ctx.type = 'text/css';
|
||||
|
|
|
|||
|
|
@ -31,8 +31,22 @@ module.exports = ({ getViewerId, about }) => {
|
|||
} catch (_) {}
|
||||
};
|
||||
|
||||
// un solo skin en el movil desde el 20/10/2026: quien venga de Acampada u
|
||||
// OasisMobile pasa a Activista (su config se conserva al actualizar la APK)
|
||||
let skinChecked = false;
|
||||
const checkSkin = () => {
|
||||
if (skinChecked) return;
|
||||
skinChecked = true;
|
||||
try {
|
||||
const { getConfig, saveConfig } = require('../configs/config-manager.js');
|
||||
const cfg = getConfig();
|
||||
if ((cfg.themes || {}).current !== 'Activista') { cfg.themes = { ...(cfg.themes || {}), current: 'Activista' }; saveConfig(cfg); }
|
||||
} catch (_) {}
|
||||
};
|
||||
|
||||
return async (ctx, next) => {
|
||||
if (!isMobile() || !isPage(ctx.path)) return next();
|
||||
checkSkin();
|
||||
global.__OASIS_HIVE_FILTER__ = (ctx.path === '/activity' && (ctx.query.hive === 'personal' || ctx.query.hive === 'community')) ? ctx.query.hive : '';
|
||||
// el lanzador ya no va en la portada: la portada es la actividad y los modulos
|
||||
// estan en la hoja de la pestaña Menu (docs/ESTUDIO_NAVEGACION.md)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,93 +0,0 @@
|
|||
Copyright 2020 The Anton Project Authors (https://github.com/googlefonts/AntonFont.git)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 57 KiB |
|
|
@ -1,9 +1,8 @@
|
|||
/* Lanzador, barras, tarjetas e identidades con el tema Acampada (rama movil).
|
||||
/* Lanzador, barras, tarjetas e identidades del skin Activista (rama movil).
|
||||
*
|
||||
* OasisMobile.css (cargado antes que themes/Acampada.css) esta pensado para fondo
|
||||
* oscuro; esta hoja va detras del tema, solo con Acampada, y cambia lo que alli
|
||||
* es amarillo sobre negro por negro sobre blanco con el cian neon de
|
||||
* acampada26s.net. Las variables --a26-* las define themes/Acampada.css. */
|
||||
* Va detras de themes/Activista.css y pinta las piezas propias de la rama con las
|
||||
* variables --a26-* (las de serie estan en el tema; Colores las cambia). Hasta el
|
||||
* 20/10/2026 era hive_acampada.css, del skin Acampada. */
|
||||
|
||||
body { background: var(--a26-bg) !important; }
|
||||
|
||||
|
|
@ -18,7 +17,7 @@ body { background: var(--a26-bg) !important; }
|
|||
.oasis-mobile-topbar .omt-menus .oasis-menu-btn {
|
||||
font-family: var(--a26-tit) !important;
|
||||
font-weight: 400 !important;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
font-size: 20px !important;
|
||||
letter-spacing: .02em;
|
||||
min-height: 44px !important;
|
||||
|
|
@ -27,11 +26,11 @@ body { background: var(--a26-bg) !important; }
|
|||
color: var(--a26-fg) !important;
|
||||
border: var(--a26-bd) !important;
|
||||
border-radius: var(--a26-radius) !important;
|
||||
box-shadow: 0 4px 0 var(--a26-fg) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.oasis-mobile-topbar .omt-menus .oasis-menu-btn span { color: var(--a26-fg) !important; }
|
||||
.oasis-mobile-topbar .omt-menus .oasis-menu-btn.active { background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; }
|
||||
.oasis-mobile-topbar .omt-menus .oasis-menu-btn:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--a26-fg) !important; }
|
||||
.oasis-mobile-topbar .omt-menus .oasis-menu-btn:active { box-shadow: none !important; }
|
||||
.oasis-mobile-topbar .omt-logo img, .oasis-mobile-topbar .omt-avatar img {
|
||||
border: var(--a26-bd) !important;
|
||||
border-radius: 50%;
|
||||
|
|
@ -62,15 +61,14 @@ body { background: var(--a26-bg) !important; }
|
|||
color: var(--a26-fg) !important;
|
||||
border: var(--a26-bd) !important;
|
||||
border-radius: var(--a26-radius) !important;
|
||||
box-shadow: 0 4px 0 var(--a26-fg) !important;
|
||||
box-shadow: none !important;
|
||||
font-size: 24px !important;
|
||||
transition: transform .12s ease-out, box-shadow .12s ease-out;
|
||||
}
|
||||
.ln-app:active .ln-ico, .ln-app:focus-visible .ln-ico {
|
||||
transform: translateY(3px);
|
||||
box-shadow: 0 1px 0 var(--a26-fg) !important;
|
||||
box-shadow: none !important;
|
||||
background: var(--a26-neon) !important;
|
||||
border-color: var(--a26-fg) !important; color: var(--a26-on-neon) !important;
|
||||
border-color: var(--a26-edge) !important; color: var(--a26-on-neon) !important;
|
||||
}
|
||||
.ln-app:hover, .ln-app:focus-visible { background: transparent !important; }
|
||||
.ln-lbl { color: var(--a26-fg) !important; font-size: 12px !important; font-weight: 600 !important; }
|
||||
|
|
@ -95,7 +93,7 @@ body { background: var(--a26-bg) !important; }
|
|||
}
|
||||
.oasis-bottombar a.bb-item.current .bb-ico { background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; }
|
||||
.oasis-bottombar a.bb-item.current .bb-lbl { color: var(--a26-fg) !important; }
|
||||
.oasis-bottombar .bb-badge { background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; border: 2px solid var(--a26-fg) !important; }
|
||||
.oasis-bottombar .bb-badge { background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; border: 1px solid var(--a26-edge) !important; }
|
||||
/* Nodos e Invitaciones: juntos y estrechos {
|
||||
background: var(--a26-bg) !important;
|
||||
border: var(--a26-bd-fino) !important;
|
||||
|
|
@ -110,7 +108,7 @@ body { background: var(--a26-bg) !important; }
|
|||
color: var(--a26-fg) !important;
|
||||
border: var(--a26-bd) !important;
|
||||
border-radius: var(--a26-radius) !important;
|
||||
box-shadow: 0 4px 0 var(--a26-fg) !important;
|
||||
box-shadow: none !important;
|
||||
font-family: var(--a26-txt) !important;
|
||||
text-transform: none;
|
||||
}
|
||||
|
|
@ -125,28 +123,28 @@ body { background: var(--a26-bg) !important; }
|
|||
.oasis-nav-list li a.current { background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; }
|
||||
|
||||
/* ---------- foro y chat: los colores de hive.css pensados para fondo negro ---------- */
|
||||
.forum-comment.level-1, .forum-comment.level-2, .forum-comment.level-3, .forum-comment.level-4 { border-left: 3px solid var(--a26-fg) !important; }
|
||||
.forum-comment.level-1, .forum-comment.level-2, .forum-comment.level-3, .forum-comment.level-4 { border-left: 1px solid var(--a26-edge) !important; }
|
||||
.forum-comment.highlighted-reply { background: var(--a26-tint) !important; border-left: 5px solid var(--a26-neon) !important; }
|
||||
.chat-message-form .filter-btn::before, .forum-send-btn::before { color: var(--a26-fg) !important; }
|
||||
|
||||
/* ---------- lo que mobile.css de upstream pinta en amarillo con !important ---------- */
|
||||
/* mobile.css va detras del tema, asi que estas reglas tienen que ir aqui */
|
||||
.create-button, button.create-button, a.create-button {
|
||||
background-color: var(--a26-fg) !important;
|
||||
border-color: var(--a26-fg) !important;
|
||||
color: var(--a26-bg) !important;
|
||||
background-color: var(--a26-neon) !important;
|
||||
border-color: var(--a26-neon) !important;
|
||||
color: var(--a26-on-neon) !important;
|
||||
}
|
||||
.filter-btn.active { background-color: var(--a26-neon) !important; border-color: var(--a26-fg) !important; color: var(--a26-on-neon) !important; }
|
||||
.filter-btn.active { background-color: var(--a26-neon) !important; border-color: var(--a26-neon) !important; color: var(--a26-on-neon) !important; }
|
||||
.peers-conn-actions button, .filter-box__button { background-color: var(--a26-bg) !important; color: var(--a26-fg) !important; }
|
||||
.oasis-id-copy { background: var(--a26-soft) !important; }
|
||||
.gov-overview tbody tr { border: var(--a26-bd-fino) !important; }
|
||||
button, input[type="submit"], input[type="button"], .filter-btn, .create-button { min-height: 48px !important; font-size: 18px !important; }
|
||||
button, input[type="submit"], input[type="button"], .filter-btn, .create-button { min-height: 44px !important; font-size: 16px !important; text-transform: none !important; }
|
||||
|
||||
/* aviso de bienvenida: el boton de empezar en negro y la X sin caja */
|
||||
/* aviso de bienvenida: el boton de empezar con el resalte y la X sin caja */
|
||||
.welcome-banner .welcome-banner-start {
|
||||
background: var(--a26-fg) !important;
|
||||
color: var(--a26-bg) !important;
|
||||
box-shadow: 0 4px 0 var(--a26-bg) !important;
|
||||
background: var(--a26-neon) !important;
|
||||
color: var(--a26-on-neon) !important;
|
||||
box-shadow: none !important;
|
||||
border: var(--a26-bd) !important;
|
||||
}
|
||||
.welcome-banner .welcome-banner-close-btn {
|
||||
|
|
@ -213,10 +211,10 @@ button:not([class]), input[type="submit"]:not([class]), input[type="button"]:not
|
|||
.identities .identity-actions button { width: 100%; }
|
||||
.identities .identity-legacy { text-align: center; text-decoration: underline; }
|
||||
.identities .identity-row { border: var(--a26-bd) !important; border-radius: var(--a26-radius) !important; background: var(--a26-bg) !important; }
|
||||
.identities .identity-name { font-family: var(--a26-tit) !important; font-weight: 400 !important; text-transform: uppercase; font-size: 22px !important; }
|
||||
.identities .identity-name { font-family: var(--a26-tit) !important; font-weight: 400 !important; text-transform: none; font-size: 22px !important; }
|
||||
.identities .identity-feed { color: var(--a26-muted) !important; }
|
||||
.identities .identity-active { background: var(--a26-neon) !important; border: var(--a26-bd-fino) !important; color: var(--a26-on-neon) !important; }
|
||||
.identities .identity-warn { color: #c4003b !important; }
|
||||
.identities .identity-warn { color: var(--a26-danger-text) !important; }
|
||||
|
||||
/* las barras de filtros de cada modulo: upstream las encoge (.75em) y les pone
|
||||
borde amarillo con selectores compuestos; aqui, del mismo tamaño que el resto */
|
||||
|
|
@ -224,10 +222,10 @@ button:not([class]), input[type="submit"]:not([class]), input[type="button"]:not
|
|||
.mode-buttons-row .create-button, .filters .create-button, .filter-group .create-button,
|
||||
.activity-sub-filter .create-button, .activity-filter-grid .create-button {
|
||||
border: var(--a26-bd) !important;
|
||||
border-color: var(--a26-fg) !important;
|
||||
background: var(--a26-fg) !important;
|
||||
color: var(--a26-bg) !important;
|
||||
font-size: 18px !important;
|
||||
border-color: var(--a26-neon) !important;
|
||||
background: var(--a26-neon) !important;
|
||||
color: var(--a26-on-neon) !important;
|
||||
font-size: 16px !important;
|
||||
padding: 8px 16px !important;
|
||||
min-height: 48px !important;
|
||||
border-radius: var(--a26-radius) !important;
|
||||
|
|
@ -259,7 +257,7 @@ button:not([class]), input[type="submit"]:not([class]), input[type="button"]:not
|
|||
background: var(--a26-bg) !important; color: var(--a26-fg) !important;
|
||||
border: var(--a26-bd-fino) !important; border-radius: 50% !important; box-shadow: none !important;
|
||||
}
|
||||
.btn-singleview.btn-delete { color: #c4003b !important; border-color: #c4003b !important; }
|
||||
.btn-singleview.btn-delete { color: var(--a26-danger-text) !important; border-color: var(--a26-danger-text) !important; }
|
||||
|
||||
/* barras de filtros: chips en fila que se reparten el ancho, no un boton por linea */
|
||||
.mode-buttons, .mode-buttons-row, .mode-buttons-cols, .tribe-mode-buttons, .ui-toolbar--filters, .filters {
|
||||
|
|
@ -275,7 +273,7 @@ button:not([class]), input[type="submit"]:not([class]), input[type="button"]:not
|
|||
width: auto !important; flex: 0 0 auto !important;
|
||||
min-height: 38px !important; height: auto !important;
|
||||
padding: 4px 12px !important; margin: 0 !important;
|
||||
font-size: 15px !important; box-shadow: 0 3px 0 var(--a26-fg) !important;
|
||||
font-size: 15px !important; box-shadow: none !important;
|
||||
border: var(--a26-bd-fino) !important;
|
||||
}
|
||||
.mode-buttons .create-button, .mode-buttons-row .create-button, .tribe-mode-buttons .create-button, .filters .create-button {
|
||||
|
|
@ -330,7 +328,7 @@ a.user-link { font-weight: 700 !important; text-decoration: underline !important
|
|||
}
|
||||
.pm-exposition-chip *, .card-chips-row > span * { color: var(--a26-bg) !important; }
|
||||
.pm-exposition-text { font-family: var(--a26-tit) !important; letter-spacing: .04em; font-size: 13px !important; }
|
||||
.content-actions .btn-singleview.btn-content, .content-actions a.btn-content { border-color: var(--a26-fg) !important; color: var(--a26-fg) !important; }
|
||||
.content-actions .btn-singleview.btn-content, .content-actions a.btn-content { border-color: var(--a26-edge) !important; color: var(--a26-fg) !important; }
|
||||
|
||||
/* opiniones y votos */
|
||||
.opinions-summary, .vote-btn, .score-btn {
|
||||
|
|
@ -342,13 +340,13 @@ a.user-link { font-weight: 700 !important; text-decoration: underline !important
|
|||
|
||||
/* tablas de detalle (fecha, estado, lugar...): filas claras, la etiqueta en gris */
|
||||
.main-column table, .main-column table tr, .main-column table td, .main-column table th, .main-column table tbody {
|
||||
background: var(--a26-bg) !important; color: var(--a26-fg) !important; border-color: var(--a26-fg) !important;
|
||||
background: var(--a26-bg) !important; color: var(--a26-fg) !important; border-color: var(--a26-edge) !important;
|
||||
}
|
||||
.main-column table { border: var(--a26-bd-fino) !important; border-radius: 10px !important; }
|
||||
.main-column table tr + tr td { border-top: 1px solid var(--a26-line) !important; }
|
||||
.main-column table td:first-child, .main-column table th, .main-column [class*="-info-label"] {
|
||||
color: var(--a26-muted) !important; font-weight: 700 !important; font-size: 13px !important;
|
||||
text-transform: uppercase; letter-spacing: .03em;
|
||||
text-transform: none; letter-spacing: .03em;
|
||||
}
|
||||
|
||||
/* perfil: los datos del habitante como lineas claras, sin cajas negras */
|
||||
|
|
@ -382,7 +380,7 @@ a.user-link { font-weight: 700 !important; text-decoration: underline !important
|
|||
padding: 4px 10px !important; font-weight: 700 !important; text-decoration: none !important;
|
||||
}
|
||||
.activity-chip.active { background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; }
|
||||
.activity-chip:hover { color: var(--a26-fg) !important; border-color: var(--a26-fg) !important; }
|
||||
.activity-chip:hover { color: var(--a26-fg) !important; border-color: var(--a26-edge) !important; }
|
||||
|
||||
/* ---------- fichas de filtro de 1.3.3 (OasisMobile.css las pinta en amarillo y gris) ---------- */
|
||||
/* mismo selector que alli: gana por ir detras */
|
||||
|
|
@ -402,11 +400,11 @@ a.user-link { font-weight: 700 !important; text-decoration: underline !important
|
|||
border-radius: var(--a26-radius) !important;
|
||||
background: var(--a26-bg) !important;
|
||||
color: var(--a26-fg) !important;
|
||||
box-shadow: 0 3px 0 var(--a26-fg) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.main-column :is(.tribe-mode-buttons, .mode-buttons, .mode-buttons-row, .filter-group) .filter-btn.active:not(.create-button) {
|
||||
background: var(--a26-neon) !important;
|
||||
border-color: var(--a26-fg) !important;
|
||||
border-color: var(--a26-edge) !important;
|
||||
color: var(--a26-on-neon) !important;
|
||||
}
|
||||
.main-column :is(.tribe-mode-buttons, .mode-buttons, .mode-buttons-row, .filter-group) .create-button { min-height: 48px !important; }
|
||||
|
|
@ -442,7 +440,7 @@ img.inhabitant-photo-details { border: var(--a26-bd) !important; }
|
|||
.welcome-action { color: var(--a26-fg) !important; }
|
||||
label.welcome-ux-option {
|
||||
background: var(--a26-bg) !important; border: var(--a26-bd-fino) !important;
|
||||
border-radius: var(--a26-radius) !important; box-shadow: 0 4px 0 var(--a26-fg) !important;
|
||||
border-radius: var(--a26-radius) !important; box-shadow: none !important;
|
||||
}
|
||||
label.welcome-ux-option:has(input:checked) { background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; }
|
||||
|
||||
|
|
@ -464,7 +462,7 @@ label.welcome-ux-option:has(input:checked) { background: var(--a26-neon) !import
|
|||
font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", sans-serif !important;
|
||||
text-transform: none !important; letter-spacing: 0 !important;
|
||||
background: var(--a26-bg) !important; color: var(--a26-fg) !important;
|
||||
border: 1px solid var(--a26-fg) !important; border-radius: 10px !important; box-shadow: none !important;
|
||||
border: 1px solid var(--a26-edge) !important; border-radius: 10px !important; box-shadow: none !important;
|
||||
}
|
||||
/* el 📌 va en la esquina: el texto deja su hueco (el padding general de la burbuja lo pisaba) */
|
||||
.chat-bubble-row .chat-message.chat-has-pin-toggle { position: relative !important; padding-right: 44px !important; }
|
||||
|
|
@ -476,15 +474,15 @@ label.welcome-ux-option:has(input:checked) { background: var(--a26-neon) !import
|
|||
.skin-card {
|
||||
background: var(--a26-bg) !important; color: var(--a26-fg) !important;
|
||||
border: var(--a26-bd) !important; border-radius: var(--a26-radius) !important;
|
||||
box-shadow: 0 5px 0 var(--a26-fg) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.skin-card .skin-shot { border: var(--a26-bd-fino); }
|
||||
.skin-card .skin-name {
|
||||
font-family: var(--a26-tit) !important; font-weight: 400 !important;
|
||||
text-transform: uppercase; letter-spacing: .02em; font-size: 21px !important;
|
||||
text-transform: none; letter-spacing: .02em; font-size: 21px !important;
|
||||
}
|
||||
.skin-card.is-current { background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; border: var(--a26-bd) !important; }
|
||||
.skin-card:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--a26-fg) !important; background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; }
|
||||
.skin-card:active { box-shadow: none !important; background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; }
|
||||
|
||||
/* ---------- letra y botones mas grandes, para leer sin gafas ---------- */
|
||||
body { font-size: 18px; }
|
||||
|
|
@ -518,3 +516,6 @@ input, textarea, select { font-size: 18px !important; min-height: 50px; }
|
|||
/* el plegable de mensajes anteriores del buzon: gris claro sobre blanco */
|
||||
summary.pm-thread-toggle { color: var(--a26-muted) !important; }
|
||||
.pm-thread-icon { font-size: 12px !important; }
|
||||
|
||||
/* fichas de la actividad y de filtros: mobile.css del dev las pone en mayusculas */
|
||||
.activity-chip, a.activity-chip, .filter-btn, a.filter-btn { text-transform: none !important; }
|
||||
|
|
@ -157,7 +157,7 @@ body { padding-top: 74px; background: #121212; }
|
|||
min-height: 48px; padding: 0 var(--space-3);
|
||||
cursor: pointer;
|
||||
color: #FFD700; font-weight: bold;
|
||||
text-transform: uppercase; letter-spacing: .04em;
|
||||
text-transform: none; letter-spacing: .04em;
|
||||
font-size: var(--fs-caption);
|
||||
}
|
||||
.oasis-nav-header .nav-text { flex: 1 1 auto; }
|
||||
|
|
@ -218,7 +218,7 @@ body { overscroll-behavior: none; }
|
|||
|
||||
.bb-manage { margin: 8px 0 16px; }
|
||||
.bb-manage h3, .bb-manage-add h3 {
|
||||
font-size: 13px; text-transform: uppercase; letter-spacing: .05em;
|
||||
font-size: 13px; text-transform: none; letter-spacing: .05em;
|
||||
color: #FFD700; margin: 14px 0 8px;
|
||||
}
|
||||
.bb-manage-list { display: flex; flex-direction: column; gap: 8px; }
|
||||
|
|
@ -246,7 +246,7 @@ body { overscroll-behavior: none; }
|
|||
.ln-group + .ln-group { margin-top: 20px; }
|
||||
.ln-title {
|
||||
margin: 0 2px 10px; padding: 0; border: 0;
|
||||
font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
|
||||
font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: none;
|
||||
color: var(--c-muted);
|
||||
}
|
||||
.ln-grid {
|
||||
|
|
@ -377,7 +377,7 @@ button, input[type="submit"], input[type="button"],
|
|||
color: var(--c-muted, #8c8c8c);
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: .03em;
|
||||
margin-bottom: 2px;
|
||||
padding-bottom: 0;
|
||||
|
|
@ -395,7 +395,7 @@ button, input[type="submit"], input[type="button"],
|
|||
color: var(--c-muted, #8c8c8c);
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: .03em;
|
||||
margin-bottom: 1px;
|
||||
white-space: nowrap;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
/* Piezas de usabilidad de la rama movil, para los dos skins (Acampada y OasisMobile).
|
||||
/* Piezas de usabilidad de la rama movil.
|
||||
*
|
||||
* Va la ultima, detras del skin. Los colores salen de las variables de
|
||||
* Acampada (--a26-*) si el tema las define y, si no, de la paleta oscura con oro
|
||||
* de OasisMobile; asi cada pieza nueva se ve bien en los dos sin duplicarla.
|
||||
* Va detras del skin (Activista, el unico del movil desde el 20/10/2026) y antes de
|
||||
* /mobile-colors.css. Los colores salen de las variables --a26-* a traves de las
|
||||
* --ux-*; los valores de reserva son los del OasisMobile.css del dev, por si algun
|
||||
* dia se carga sin skin.
|
||||
*
|
||||
* Letra: Anton (--ux-title) solo para titulos y para el boton principal de cada
|
||||
* pantalla; todo lo demas (fichas, botones secundarios, etiquetas) en la letra del
|
||||
* sistema en negrita. Antes habia Anton en botones, fichas, cabeceras de tabla y
|
||||
* pestañas, y la pantalla parecia un cartel.
|
||||
*
|
||||
* Espacios: rejilla de 4/8. Zonas tactiles de 44px como minimo. */
|
||||
* Letra del sistema en todo; los titulos en negrita. Espacios: rejilla de 4/8.
|
||||
* Zonas tactiles de 44px como minimo; enlaces dentro del texto, 24px. */
|
||||
|
||||
:root {
|
||||
--ux-bg: var(--a26-bg, #121212);
|
||||
|
|
@ -18,7 +15,7 @@
|
|||
--ux-on-accent: var(--a26-on-neon, #000);
|
||||
--ux-soft: var(--a26-soft, #1e1e1e);
|
||||
--ux-muted: var(--a26-muted, #a8a8a8);
|
||||
--ux-line: var(--a26-fg, #3a3a3a);
|
||||
--ux-line: var(--a26-edge, #3a3a3a);
|
||||
--ux-radius: var(--a26-radius, 12px);
|
||||
--ux-title: var(--a26-tit, inherit);
|
||||
--ux-text: var(--a26-txt, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
|
||||
|
|
@ -39,7 +36,7 @@
|
|||
}
|
||||
.main-column :is(.tribe-mode-buttons, .mode-buttons, .mode-buttons-row, .filter-group, .filters) .filter-btn:not(.create-button) {
|
||||
font-size: 15px !important;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
}
|
||||
/* los formularios de cada modulo (crear tribu, votacion, sala...): etiquetas como
|
||||
texto, no como titulos; el h2 de la pregunta de una votacion era Anton de 28px */
|
||||
|
|
@ -144,19 +141,19 @@
|
|||
.main-column a.tribe-row {
|
||||
display: flex !important; flex-wrap: nowrap !important; align-items: center; gap: 12px; width: auto !important;
|
||||
padding: 10px 12px !important; min-height: 72px;
|
||||
border: 2px solid var(--ux-line) !important; border-radius: var(--ux-radius) !important;
|
||||
border: 1px solid var(--ux-line) !important; border-radius: var(--ux-radius) !important;
|
||||
background: var(--ux-bg) !important; color: var(--ux-fg) !important; text-decoration: none !important;
|
||||
}
|
||||
.main-column a.tribe-row:active { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; }
|
||||
.tribe-row .tribe-row-thumb {
|
||||
flex: 0 0 52px; width: 52px !important; height: 52px !important; border-radius: 10px !important;
|
||||
object-fit: cover; border: 2px solid var(--ux-line) !important; margin: 0 !important;
|
||||
object-fit: cover; border: 1px solid var(--ux-line) !important; margin: 0 !important;
|
||||
}
|
||||
.tribe-row .tribe-row-icon { padding: 11px; background: var(--ux-soft); }
|
||||
.tribe-row .tribe-row-text { flex: 1 1 0; min-width: 0; overflow: hidden; display: flex; flex-direction: column; gap: 2px; }
|
||||
.tribe-row .tribe-row-text > span { display: block; max-width: 100%; margin: 0 !important; padding: 0 !important; line-height: 1.3; }
|
||||
.tribe-row .tribe-row-title {
|
||||
font-family: var(--ux-title) !important; font-size: 21px; line-height: 1.1; text-transform: uppercase;
|
||||
font-family: var(--ux-title) !important; font-size: 21px; line-height: 1.1; text-transform: none;
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
}
|
||||
.tribe-row .tribe-row-facts { font-size: 13px; font-weight: 700; color: var(--ux-muted); }
|
||||
|
|
@ -170,7 +167,7 @@
|
|||
.vote-bar-count { font-weight: 700; font-size: 15px; min-width: 2ch; text-align: right; }
|
||||
.vote-bar-meter {
|
||||
grid-column: 1 / -1; width: 100%; height: 12px; appearance: none; -webkit-appearance: none;
|
||||
border: 2px solid var(--ux-line); border-radius: 8px; overflow: hidden; background: var(--ux-soft);
|
||||
border: 1px solid var(--ux-line); border-radius: 8px; overflow: hidden; background: var(--ux-soft);
|
||||
}
|
||||
.vote-bar-meter::-webkit-progress-bar { background: var(--ux-soft); }
|
||||
.vote-bar-meter::-webkit-progress-value { background: var(--ux-fg); }
|
||||
|
|
@ -189,15 +186,15 @@
|
|||
width: 100% !important; min-height: 52px !important; margin: 0 !important;
|
||||
font-family: var(--ux-text) !important; font-weight: 700 !important; font-size: 16px !important;
|
||||
}
|
||||
.main-column .vote-buttons-row-single button[value="YES"], .main-column .vote-buttons-row-single button[value="GREEN"] { border-color: var(--ux-ok) !important; box-shadow: 0 4px 0 var(--ux-ok) !important; }
|
||||
.main-column .vote-buttons-row-single button[value="NO"], .main-column .vote-buttons-row-single button[value="RED"] { border-color: var(--ux-danger) !important; box-shadow: 0 4px 0 var(--ux-danger) !important; }
|
||||
.main-column .vote-buttons-row-single button[value="YELLOW"] { border-color: var(--ux-warn) !important; box-shadow: 0 4px 0 var(--ux-warn) !important; }
|
||||
.main-column .vote-buttons-row-single button[value="YES"], .main-column .vote-buttons-row-single button[value="GREEN"] { border-color: var(--ux-ok) !important; box-shadow: none !important; }
|
||||
.main-column .vote-buttons-row-single button[value="NO"], .main-column .vote-buttons-row-single button[value="RED"] { border-color: var(--ux-danger) !important; box-shadow: none !important; }
|
||||
.main-column .vote-buttons-row-single button[value="YELLOW"] { border-color: var(--ux-warn) !important; box-shadow: none !important; }
|
||||
/* tipo de votacion: tarjetas de radio */
|
||||
.vote-kind { display: flex; flex-direction: column; gap: 10px; margin: 4px 0 18px; }
|
||||
.vote-kind-title { font-weight: 700; font-size: 15px; }
|
||||
.vote-kind-option {
|
||||
display: grid !important; grid-template-columns: auto 1fr; gap: 2px 12px; align-items: center;
|
||||
padding: 12px 14px; border: 2px solid var(--ux-line); border-radius: var(--ux-radius); cursor: pointer;
|
||||
padding: 12px 14px; border: 1px solid var(--ux-line); border-radius: var(--ux-radius); cursor: pointer;
|
||||
}
|
||||
.main-column .vote-kind-option input[type="radio"] { grid-row: 1 / span 2; width: 22px !important; height: 22px !important; min-height: 0 !important; margin: 0 !important; accent-color: var(--ux-fg); }
|
||||
.vote-kind-option:has(input:checked) { background: var(--ux-accent); color: var(--ux-on-accent); }
|
||||
|
|
@ -210,12 +207,12 @@
|
|||
.module-group { display: flex; flex-direction: column; gap: 8px; }
|
||||
.module-group-title {
|
||||
font-family: var(--ux-title) !important; font-weight: 400 !important; font-size: 20px !important;
|
||||
text-transform: uppercase; margin: 0 0 4px !important; padding-bottom: 4px; border-bottom: 3px solid var(--ux-line);
|
||||
text-transform: none; margin: 0 0 4px !important; padding-bottom: 4px; border-bottom: 1px solid var(--ux-line);
|
||||
}
|
||||
.main-column label.module-switch {
|
||||
display: grid !important; grid-template-columns: 40px minmax(0, 1fr) 52px; align-items: center; gap: 12px;
|
||||
padding: 10px 12px; min-height: 64px; cursor: pointer;
|
||||
border: 2px solid var(--ux-line); border-radius: var(--ux-radius);
|
||||
border: 1px solid var(--ux-line); border-radius: var(--ux-radius);
|
||||
font-family: var(--ux-text) !important; text-transform: none !important; letter-spacing: 0 !important;
|
||||
}
|
||||
.module-switch-ico { width: 40px; height: 40px; padding: 8px; border-radius: 10px; background: var(--ux-soft); color: var(--ux-fg); }
|
||||
|
|
@ -227,7 +224,7 @@
|
|||
.main-column label.module-switch input.switch-input[type="checkbox"] {
|
||||
appearance: none; -webkit-appearance: none; flex: 0 0 auto;
|
||||
width: 52px !important; height: 30px !important; min-height: 0 !important; margin: 0 !important; padding: 0 !important;
|
||||
border: 2px solid var(--ux-line) !important; border-radius: 16px !important; background: var(--ux-soft) !important;
|
||||
border: 1px solid var(--ux-line) !important; border-radius: 16px !important; background: var(--ux-soft) !important;
|
||||
position: relative; cursor: pointer; transition: background .15s ease-out;
|
||||
}
|
||||
.main-column label.module-switch input.switch-input[type="checkbox"]::after {
|
||||
|
|
@ -248,7 +245,7 @@
|
|||
.main-column .lang-pick .lang-chip, .lang-pick .lang-chip {
|
||||
width: 100% !important; min-height: 48px !important; margin: 0 !important; padding: 6px 10px !important;
|
||||
font-size: 16px !important; text-transform: none !important; box-shadow: none !important;
|
||||
border: 2px solid var(--ux-line) !important; background: var(--ux-bg) !important; color: var(--ux-fg) !important;
|
||||
border: 1px solid var(--ux-line) !important; background: var(--ux-bg) !important; color: var(--ux-fg) !important;
|
||||
}
|
||||
.main-column .lang-pick .lang-chip.is-current, .lang-pick .lang-chip.is-current { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; }
|
||||
|
||||
|
|
@ -341,10 +338,10 @@ body .main-content > .main-column { padding-left: 0 !important; padding-right: 0
|
|||
.tribe-tabs-strip::-webkit-scrollbar { display: none; }
|
||||
.main-column a.tribe-tab, .tribe-tabs-more > summary {
|
||||
flex: 0 0 auto; scroll-snap-align: start; display: inline-flex; align-items: center; justify-content: center;
|
||||
min-height: 40px; padding: 4px 14px; border: 2px solid var(--ux-line) !important; border-radius: 20px !important;
|
||||
min-height: 40px; padding: 4px 14px; border: 1px solid var(--ux-line) !important; border-radius: 20px !important;
|
||||
background: var(--ux-bg) !important; color: var(--ux-fg) !important; text-decoration: none !important;
|
||||
font-family: var(--ux-text) !important; font-weight: 700 !important; font-size: 14px !important; white-space: nowrap;
|
||||
text-transform: uppercase; letter-spacing: .02em;
|
||||
text-transform: none; letter-spacing: .02em;
|
||||
}
|
||||
.main-column a.tribe-tab.is-current { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; }
|
||||
.tribe-tabs-more > summary { list-style: none; cursor: pointer; margin-top: 2px; }
|
||||
|
|
@ -393,7 +390,7 @@ body .main-content > .main-column { padding-left: 0 !important; padding-right: 0
|
|||
.main-column :is(.tribe-mode-buttons, .mode-buttons, .mode-buttons-row, .filters, .forum-create-col) .create-button.create-button {
|
||||
width: 100% !important; min-height: 52px !important; margin: 4px 0 0 !important; padding: 8px 16px !important;
|
||||
font-family: var(--ux-title) !important; font-weight: 400 !important; font-size: 20px !important;
|
||||
letter-spacing: .02em !important; text-transform: uppercase;
|
||||
letter-spacing: .02em !important; text-transform: none;
|
||||
}
|
||||
|
||||
/* ---------- estados vacios: icono, texto centrado, sin cajas ---------- */
|
||||
|
|
@ -414,14 +411,14 @@ body .main-content > .main-column { padding-left: 0 !important; padding-right: 0
|
|||
/* ---------- el pie abajo del todo aunque la pagina sea corta ---------- */
|
||||
body .main-content { min-height: calc(100dvh - 300px); }
|
||||
.main-column .tribe-grid:has(> p:only-child), .main-column .filters, .main-column .tribe-mode-buttons { padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important; }
|
||||
.main-column :is(.tribe-mode-buttons, .mode-buttons, .mode-buttons-row, .filters, .forum-create-col) .create-button.create-button { box-shadow: 0 5px 0 var(--ux-accent) !important; }
|
||||
.main-column :is(.tribe-mode-buttons, .mode-buttons, .mode-buttons-row, .filters, .forum-create-col) .create-button.create-button { box-shadow: none !important; }
|
||||
|
||||
/* ---------- buzon: cada mensaje en pocas lineas ---------- */
|
||||
/* era una tabla de seis filas (De, Fecha, Para, Asunto, Tasa ECO, Cifrado) dentro de
|
||||
dos cajas: un aviso ocupaba una pantalla. Para es siempre una misma, el asunto ya
|
||||
es el titulo, la tasa ECO no se entiende y el cifrado es igual en todos */
|
||||
.main-column .pm-thread { border: 0 !important; padding: 0 !important; margin: 0 0 10px !important; background: transparent !important; }
|
||||
.main-column div.pm-card { padding: 12px !important; margin: 0 !important; border: 2px solid var(--ux-line) !important; border-radius: var(--ux-radius) !important; }
|
||||
.main-column div.pm-card { padding: 12px !important; margin: 0 !important; border: 1px solid var(--ux-line) !important; border-radius: var(--ux-radius) !important; }
|
||||
.main-column .pm-card .pm-info-table { display: flex !important; flex-wrap: wrap; align-items: center; gap: 4px 10px; border: 0 !important; margin: 0 0 6px !important; width: 100%; }
|
||||
.main-column .pm-card .pm-info-table tbody { display: contents !important; }
|
||||
.main-column .pm-card .pm-info-table tr { display: none !important; }
|
||||
|
|
@ -481,7 +478,7 @@ form.oasis-phone-state .oasis-phone-state-btn {
|
|||
.main-column .vote-bar > * { margin: 0 !important; }
|
||||
.main-column .vote-bar-meter { height: 12px !important; min-height: 0 !important; }
|
||||
.main-column .vote-bar-label { text-transform: lowercase; }
|
||||
.main-column .vote-bar-label::first-letter { text-transform: uppercase; }
|
||||
.main-column .vote-bar-label::first-letter { text-transform: none; }
|
||||
|
||||
/* personalizar la barra de abajo: una fila por atajo, como el resto de listas */
|
||||
.main-column .bb-manage-list, .main-column .bb-pick-grid { display: flex !important; flex-direction: column !important; gap: 8px !important; align-items: stretch !important; }
|
||||
|
|
@ -520,7 +517,7 @@ body > .welcome-banner { order: -1; margin-top: 10px !important; }
|
|||
margin: 0 !important; padding: 6px 8px !important; box-sizing: border-box;
|
||||
border: var(--a26-bd-fino, 2px solid var(--ux-line)) !important; border-radius: var(--ux-radius) !important;
|
||||
background: var(--ux-bg) !important; color: var(--ux-fg) !important; box-shadow: none !important;
|
||||
font-family: var(--ux-text) !important; font-weight: 700 !important; font-size: 15px !important; text-transform: uppercase; text-decoration: none !important;
|
||||
font-family: var(--ux-text) !important; font-weight: 700 !important; font-size: 15px !important; text-transform: none; text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* ---------- pestaña Menu y su hoja con todos los modulos ---------- */
|
||||
|
|
@ -538,34 +535,34 @@ body > .welcome-banner { order: -1; margin-top: 10px !important; }
|
|||
bottom: 0; max-height: 82vh; max-height: 82dvh; overflow-y: auto; overscroll-behavior: contain;
|
||||
padding: 8px 14px calc(18px + var(--inset-bottom));
|
||||
background: var(--ux-bg); color: var(--ux-fg);
|
||||
border-top: 3px solid var(--ux-line); border-radius: 22px 22px 0 0;
|
||||
border-top: 1px solid var(--ux-line); border-radius: 22px 22px 0 0;
|
||||
box-shadow: 0 -6px 24px rgba(0, 0, 0, .25);
|
||||
}
|
||||
.menu-sheet-head {
|
||||
position: sticky; top: -8px; z-index: 1; display: flex; align-items: center; justify-content: space-between;
|
||||
margin: 0 -14px 8px; padding: 12px 14px 10px; background: var(--ux-bg); border-bottom: 2px solid var(--ux-line);
|
||||
margin: 0 -14px 8px; padding: 12px 14px 10px; background: var(--ux-bg); border-bottom: 1px solid var(--ux-line);
|
||||
}
|
||||
.menu-sheet-head::before {
|
||||
content: ""; position: absolute; top: 4px; left: 50%; width: 44px; height: 5px; margin-left: -22px;
|
||||
border-radius: 3px; background: var(--ux-muted);
|
||||
}
|
||||
.menu-sheet-title { font-family: var(--ux-title); font-size: 26px; text-transform: uppercase; line-height: 1; }
|
||||
.menu-sheet-title { font-family: var(--ux-title); font-size: 26px; text-transform: none; line-height: 1; }
|
||||
.menu-sheet-close {
|
||||
display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; cursor: pointer;
|
||||
border: 2px solid var(--ux-line); border-radius: 50%; font-size: 20px; background: var(--ux-bg);
|
||||
border: 1px solid var(--ux-line); border-radius: 50%; font-size: 20px; background: var(--ux-bg);
|
||||
}
|
||||
.menu-sheet .launcher { margin: 0 !important; padding: 0 !important; }
|
||||
/* cinco pestañas: que quepan a 360px */
|
||||
.oasis-bottombar .bb-item { flex: 1 1 0 !important; min-width: 0 !important; }
|
||||
@media (max-width: 380px) { .oasis-bottombar .bb-lbl { font-size: 11px !important; } }
|
||||
.oasis-bottombar .menu-toggle:checked ~ div.menu-sheet { background: var(--ux-bg) !important; bottom: calc(66px + var(--inset-bottom)); border-radius: 22px 22px 0 0 !important; border: 0 !important; border-top: 3px solid var(--ux-line) !important; }
|
||||
.oasis-bottombar div.menu-sheet-head { background: var(--ux-bg) !important; border: 0 !important; border-bottom: 2px solid var(--ux-line) !important; }
|
||||
.oasis-bottombar .menu-toggle:checked ~ div.menu-sheet { background: var(--ux-bg) !important; bottom: calc(66px + var(--inset-bottom)); border-radius: 22px 22px 0 0 !important; border: 0 !important; border-top: 1px solid var(--ux-line) !important; }
|
||||
.oasis-bottombar div.menu-sheet-head { background: var(--ux-bg) !important; border: 0 !important; border-bottom: 1px solid var(--ux-line) !important; }
|
||||
.oasis-bottombar .menu-toggle:checked ~ .menu-sheet-backdrop { bottom: calc(66px + var(--inset-bottom)); }
|
||||
/* en la hoja todo tiene que caber sin deslizar: cinco iconos por fila y mas pequeños
|
||||
(con 20 modulos la rejilla del lanzador medía 1.200px para 690 de hoja) */
|
||||
.menu-sheet .launcher .ln-grid { display: grid !important; grid-template-columns: repeat(5, 1fr) !important; gap: 8px 2px !important; }
|
||||
.menu-sheet .launcher .ln-app { min-width: 0 !important; padding: 0 !important; gap: 4px !important; }
|
||||
.menu-sheet .launcher .ln-ico.has-svg { width: 48px !important; height: 48px !important; padding: 11px !important; box-shadow: 0 3px 0 var(--ux-line) !important; }
|
||||
.menu-sheet .launcher .ln-ico.has-svg { width: 48px !important; height: 48px !important; padding: 11px !important; box-shadow: none !important; }
|
||||
.menu-sheet .launcher .ln-lbl { font-size: 11px !important; line-height: 1.1 !important; }
|
||||
.menu-sheet .launcher .ln-title { font-size: 15px !important; margin: 0 0 6px !important; padding: 0 0 2px !important; border-bottom-width: 2px !important; }
|
||||
.menu-sheet .launcher .ln-group + .ln-group { margin-top: 10px !important; }
|
||||
|
|
@ -594,13 +591,13 @@ body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !imp
|
|||
.main-column button.ux-pick-card {
|
||||
display: flex !important; flex-direction: row; align-items: center; text-align: left;
|
||||
width: 100% !important; min-width: 0 !important; min-height: 64px !important; height: auto !important; margin: 0 0 10px !important; padding: 8px 12px 8px 8px !important;
|
||||
background: var(--ux-bg) !important; color: var(--ux-fg) !important; border: 2px solid var(--ux-line) !important; border-radius: 14px !important;
|
||||
box-shadow: 0 3px 0 var(--ux-line) !important; text-transform: none !important; font-family: inherit !important; cursor: pointer;
|
||||
background: var(--ux-bg) !important; color: var(--ux-fg) !important; border: 1px solid var(--ux-line) !important; border-radius: 14px !important;
|
||||
box-shadow: none !important; text-transform: none !important; font-family: inherit !important; cursor: pointer;
|
||||
}
|
||||
.main-column button.ux-pick-card.is-current { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; }
|
||||
.main-column .ux-pick-shot { display: block; flex: 0 0 76px; width: 76px; height: auto; border-radius: 8px; margin: 0 12px 0 0; border: 1px solid rgba(0, 0, 0, .2); }
|
||||
.main-column .ux-pick-label { flex: 1 1 auto; min-width: 0; text-align: left; font-size: 16px; font-weight: 700; line-height: 1.2; }
|
||||
.main-column .ux-pick-now { flex: 0 0 auto; margin-left: 8px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
|
||||
.main-column .ux-pick-now { flex: 0 0 auto; margin-left: 8px; font-size: 12px; font-weight: 700; text-transform: none; letter-spacing: .04em; }
|
||||
/* perfil de uso: sin miniatura, nombre y una linea de para que sirve */
|
||||
.main-column .ux-pick-text { flex: 1 1 auto; min-width: 0; display: block; text-align: left; }
|
||||
.main-column .ux-pick-text .ux-pick-label { display: block; }
|
||||
|
|
@ -624,9 +621,9 @@ body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !imp
|
|||
display: flex !important; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center;
|
||||
min-height: 104px; min-width: 0; padding: 12px 6px 10px !important; box-sizing: border-box; text-decoration: none !important;
|
||||
background: var(--ux-bg) !important; color: var(--ux-fg) !important;
|
||||
border: 2px solid var(--ux-line) !important; border-radius: 14px !important; box-shadow: 0 3px 0 var(--ux-line) !important;
|
||||
border: 1px solid var(--ux-line) !important; border-radius: 14px !important; box-shadow: none !important;
|
||||
}
|
||||
.main-column a.quick-tile:active { transform: translateY(3px); box-shadow: 0 0 0 var(--ux-line) !important; background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; }
|
||||
.main-column a.quick-tile:active { box-shadow: 0 0 0 var(--ux-line) !important; background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; }
|
||||
.main-column .quick-tile .quick-ico.has-svg { display: block; width: 30px; height: 30px; margin: 0 0 6px; }
|
||||
.main-column .quick-tile .quick-ico svg { width: 100%; height: 100%; }
|
||||
.main-column .quick-tile .quick-name { display: block; font-size: 14px; font-weight: 700; line-height: 1.15; }
|
||||
|
|
@ -635,7 +632,7 @@ body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !imp
|
|||
.main-column div.quick-links { display: block !important; margin: 0 !important; padding: 0 !important; }
|
||||
.main-column div.quick-links a { display: block !important; text-align: center; margin: 0 0 10px !important; }
|
||||
.main-column div.quick-identity { display: flex !important; align-items: center; margin: 0 0 14px !important; padding: 0 !important; }
|
||||
.main-column .quick-identity-avatar { width: 56px; height: 56px; border-radius: 50%; margin-right: 12px; border: 2px solid var(--ux-line); object-fit: cover; }
|
||||
.main-column .quick-identity-avatar { width: 56px; height: 56px; border-radius: 50%; margin-right: 12px; border: 1px solid var(--ux-line); object-fit: cover; }
|
||||
.main-column .quick-identity-name { font-size: 18px; font-weight: 700; }
|
||||
.main-column section#identity a.create-button, .main-column section#greeting a.create-button { display: block !important; text-align: center; }
|
||||
|
||||
|
|
@ -647,27 +644,80 @@ body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !imp
|
|||
.main-column button.pal-card {
|
||||
display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; align-items: center; width: 100% !important; min-width: 0 !important; min-height: 56px !important; height: auto !important;
|
||||
margin: 0 !important; padding: 8px 10px !important; text-align: left; text-transform: none !important; font-family: var(--ux-text) !important;
|
||||
background: var(--ux-bg) !important; color: var(--ux-fg) !important; border: 2px solid var(--ux-line) !important; border-radius: 14px !important; box-shadow: 0 3px 0 var(--ux-line) !important;
|
||||
background: var(--ux-bg) !important; color: var(--ux-fg) !important; border: 1px solid var(--ux-line) !important; border-radius: 14px !important; box-shadow: none !important;
|
||||
}
|
||||
.main-column button.pal-card.is-current { border-width: 3px !important; box-shadow: 0 0 0 3px var(--ux-accent), 0 3px 0 var(--ux-line) !important; }
|
||||
.main-column button.pal-card.is-current { border-width: 3px !important; box-shadow: 0 0 0 3px var(--ux-accent) !important; }
|
||||
.main-column button.pal-card { justify-content: flex-start !important; }
|
||||
.main-column .pal-card .pal-name { flex: 1 1 auto; min-width: 0; text-align: left; font-size: 15px; font-weight: 700; line-height: 1.15; }
|
||||
.main-column .pal-card .ux-pick-now { display: none; }
|
||||
.pal-swatch { display: inline-flex; flex: 0 0 auto; width: 42px; height: 30px; margin-right: 10px; border-radius: 8px; overflow: hidden; border: 2px solid var(--ux-line); }
|
||||
.pal-swatch { display: inline-flex; flex: 0 0 auto; width: 42px; height: 30px; margin-right: 10px; border-radius: 8px; overflow: hidden; border: 1px solid var(--ux-line); }
|
||||
.pal-swatch .pal-bg { flex: 2 1 0; }
|
||||
.pal-swatch .pal-fg { flex: 1 1 0; }
|
||||
.pal-swatch .pal-ac { flex: 1 1 0; }
|
||||
.main-column details.color-custom { margin: 4px 0 0 !important; padding: 0 !important; border: 2px solid var(--ux-line) !important; border-radius: 14px !important; background: var(--ux-bg) !important; }
|
||||
.main-column details.color-custom { margin: 4px 0 0 !important; padding: 0 !important; border: 1px solid var(--ux-line) !important; border-radius: 14px !important; background: var(--ux-bg) !important; }
|
||||
.main-column details.color-custom > summary { display: flex; align-items: center; min-height: 52px; padding: 8px 12px; font-weight: 700; cursor: pointer; list-style: none; }
|
||||
.main-column details.color-custom > summary::-webkit-details-marker { display: none; }
|
||||
.main-column details.color-custom > summary::after { content: "\25BE"; margin-left: auto; font-size: 18px; }
|
||||
.main-column details.color-custom[open] > summary::after { content: "\25B4"; }
|
||||
.main-column form.color-custom-form { padding: 4px 12px 14px !important; margin: 0 !important; border: 0 !important; background: transparent !important; box-shadow: none !important; }
|
||||
.main-column form.color-custom-form label.color-field { display: flex !important; align-items: center; justify-content: space-between; min-height: 52px; margin: 0 0 8px !important; }
|
||||
.main-column label.color-field input[type="color"] { width: 64px !important; height: 44px !important; padding: 2px !important; border: 2px solid var(--ux-line) !important; border-radius: 10px !important; background: var(--ux-bg) !important; }
|
||||
.main-column label.color-field input[type="color"] { width: 64px !important; height: 44px !important; padding: 2px !important; border: 1px solid var(--ux-line) !important; border-radius: 10px !important; background: var(--ux-bg) !important; }
|
||||
.main-column form.color-custom-form .create-button { width: 100% !important; margin-top: 6px !important; }
|
||||
.main-column .color-pick .welcome-action { margin-top: 4px !important; }
|
||||
|
||||
/* ---------- actividad (la portada): fichas en rejilla y tarjetas ordenadas ---------- */
|
||||
/* fichas de filtro: tres columnas iguales, texto centrado (antes cada una de su ancho y
|
||||
el texto pegado arriba) */
|
||||
.main-column div.activity-filter-chips:not(.activity-toolbar-row) {
|
||||
display: grid !important; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-gap: 8px;
|
||||
margin: 0 0 12px !important; padding: 0 !important;
|
||||
}
|
||||
.main-column div.activity-filter-chips:not(.activity-toolbar-row) a.activity-chip {
|
||||
display: flex !important; align-items: center; justify-content: center; text-align: center;
|
||||
width: auto !important; min-width: 0; min-height: 44px !important; margin: 0 !important; padding: 4px 6px !important;
|
||||
font-size: 14px !important; line-height: 1.15 !important; overflow-wrap: anywhere;
|
||||
}
|
||||
/* cabecera de cada tarjeta: los botones en una fila arriba a la derecha y la etiqueta
|
||||
(FEEDS, SALAS...) debajo a la izquierda; antes compartian fila y la X caia sola */
|
||||
.main-column div.card-header.activity-card-header { display: flex !important; flex-direction: column !important; align-items: stretch !important; padding: 0 !important; margin: 0 0 8px !important; }
|
||||
.main-column div.activity-card-header > div.content-actions { order: 1; display: flex !important; justify-content: flex-end !important; align-items: center; gap: 8px; width: 100% !important; margin: 0 0 8px !important; padding: 0 !important; }
|
||||
.main-column div.activity-card-header > div.card-chips-row { order: 2; display: flex !important; justify-content: flex-start !important; margin: 0 !important; padding: 0 !important; }
|
||||
/* la X de borrar, cerrada, mide lo que su boton (algo le daba todo el ancho) */
|
||||
.main-column div.content-actions > details.content-action-confirm:not([open]) { width: auto !important; flex: 0 0 auto !important; margin: 0 !important; }
|
||||
@supports not (inset: 0) {
|
||||
.main-column div.activity-card-header > div.content-actions > * { margin-left: 8px !important; }
|
||||
}
|
||||
|
||||
/* ---------- barra de unirse a un pub (mobile_pubbar.js) ---------- */
|
||||
/* fija encima de la barra de abajo, en todas las pantallas; el color de la franja de
|
||||
la izquierda dice el estado: resalte mientras va, verde al terminar, ambar si se
|
||||
unio pero sin descarga y rojo si fallo */
|
||||
/* el skin quita fondo, borde y sombra a todos los div: aqui con especificidad alta */
|
||||
nav.oasis-bottombar div.pub-bar, body div.pub-bar {
|
||||
position: fixed !important; left: 8px; right: 8px; bottom: calc(80px + var(--inset-bottom)); z-index: 90;
|
||||
display: flex; align-items: flex-start; padding: 10px 6px 10px 14px !important; margin: 0 !important; border-radius: 12px !important;
|
||||
background: var(--ux-bg) !important; color: var(--ux-fg) !important;
|
||||
border: 1px solid var(--ux-line) !important; border-left: 6px solid var(--ux-accent) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, .22) !important;
|
||||
}
|
||||
nav.oasis-bottombar div.pub-bar[hidden], body div.pub-bar[hidden] { display: none !important; }
|
||||
nav.oasis-bottombar div.pub-bar.is-done { border-left-color: var(--ux-ok) !important; }
|
||||
nav.oasis-bottombar div.pub-bar.is-warn { border-left-color: var(--ux-warn) !important; }
|
||||
nav.oasis-bottombar div.pub-bar.is-error { border-left-color: var(--ux-danger) !important; }
|
||||
nav.oasis-bottombar div.pub-bar div.pub-bar-body { flex: 1 1 auto; min-width: 0; padding: 0 !important; margin: 0 !important; background: transparent !important; box-shadow: none !important; border: 0 !important; }
|
||||
.pub-bar .pub-bar-text { margin: 0 !important; font-size: 15px; font-weight: 700; line-height: 1.35; }
|
||||
.pub-bar .pub-bar-hint { margin: 2px 0 0 !important; font-size: 13px; color: var(--ux-muted); }
|
||||
.pub-bar .pub-bar-hint:empty { display: none; }
|
||||
.pub-bar .pub-bar-meter { display: block; width: 100%; height: 6px; margin-top: 8px; accent-color: var(--ux-accent); }
|
||||
.pub-bar.is-done .pub-bar-meter, .pub-bar.is-warn .pub-bar-meter, .pub-bar.is-error .pub-bar-meter { display: none; }
|
||||
.pub-bar .pub-bar-close { margin: 0 !important; padding: 0 !important; border: 0 !important; background: none !important; }
|
||||
.pub-bar .pub-bar-close button { min-width: 44px; min-height: 44px !important; padding: 0 !important; margin: 0 !important; border: 0 !important; background: transparent !important; color: var(--ux-fg) !important; font-size: 18px !important; }
|
||||
.pub-bar[data-running="1"] .pub-bar-close { display: none; }
|
||||
/* que la barra no tape lo ultimo de la pagina */
|
||||
body.has-pub-bar { padding-bottom: calc(190px + var(--inset-bottom)) !important; }
|
||||
/* con el menu abierto, la barra se va */
|
||||
body:has(#oasis-menu-toggle:checked) .pub-bar { display: none !important; }
|
||||
|
||||
/* ---------- zonas tactiles (pruebas de usabilidad del 20/10) ---------- */
|
||||
/* en el Pixel 9 se midieron por debajo de 44px: logo y avatar de la barra de arriba
|
||||
(42), fichas de filtro (38), pasos de la bienvenida (33) y casillas del dev (16) */
|
||||
|
|
@ -687,6 +737,7 @@ body .oasis-mobile-topbar .omt-logo img, body .oasis-mobile-topbar .omt-avatar i
|
|||
.main-column .tribe-card-title > a { display: inline-block; padding: 6px 0; min-height: 44px; box-sizing: border-box; }
|
||||
.main-column a.user-link, .main-column a.tag-link { display: inline-block; min-height: 24px; line-height: 24px; }
|
||||
.main-column .message-text a { display: inline-block; min-height: 24px; line-height: 24px; }
|
||||
.main-column a[href^="http"] { display: inline-block; min-height: 24px; line-height: 24px; }
|
||||
.main-column summary.pm-thread-toggle { min-height: 44px; display: flex; align-items: center; }
|
||||
.main-column form label:has(> input[type="radio"]) { min-height: 44px; display: flex !important; align-items: center; }
|
||||
.main-column input[type="checkbox"]:not(.switch-input):not(.pref-pill-input), .main-column input[type="radio"] { width: 24px !important; height: 24px !important; }
|
||||
|
|
|
|||
|
|
@ -1,32 +1,31 @@
|
|||
/* Tema Acampada (rama movil): blanco, negro y cian neon, titulos en Anton.
|
||||
/* Skin Activista (rama movil): el unico del movil, lo mas simple posible.
|
||||
*
|
||||
* Los colores y las formas salen de acampada26s.net: bordes negros gruesos,
|
||||
* botones con sombra solida que se hunden al pulsar y titulos en mayusculas.
|
||||
* Letra del sistema, titulos en negrita sin mayusculas, bordes de 1px, sin sombras y
|
||||
* el boton principal relleno con el color de resalte. Los colores salen de las
|
||||
* variables --a26-* (el nombre viene del skin Acampada, que se quito el 20/10/2026):
|
||||
* aqui van los de serie y Colores en Ajustes los cambia (mobile_settings.js, hoja
|
||||
* /mobile-colors.css, que va la ultima).
|
||||
*
|
||||
* La maqueta de movil es styles/mobile_base.css, que main_views.js carga justo antes
|
||||
* con su propio <link> versionado (no con @import: se quedaba en la cache del
|
||||
* WebView); aqui solo se cambian colores, letra y formas encima. Por eso casi todo lleva
|
||||
* !important: la maqueta tambien lo usa. Las piezas propias de la rama
|
||||
* (panal, barras) se ajustan en styles/hive_acampada.css. */
|
||||
@font-face {
|
||||
font-family: "Anton";
|
||||
src: url("../fonts/Anton-Regular.ttf") format("truetype");
|
||||
font-display: swap;
|
||||
}
|
||||
* La maqueta de movil es styles/mobile_base.css, que main_views.js carga justo antes;
|
||||
* aqui solo se cambian colores, letra y formas encima. Por eso casi todo lleva
|
||||
* !important: la maqueta tambien lo usa. Las piezas propias de la rama (lanzador,
|
||||
* barras) se ajustan en styles/activista.css. */
|
||||
|
||||
:root {
|
||||
--a26-bg: #fff;
|
||||
--a26-fg: #000;
|
||||
--a26-fg: #111;
|
||||
--a26-neon: #00e5ff;
|
||||
--a26-soft: #f2f2f2;
|
||||
--a26-muted: #555;
|
||||
--a26-on-neon: #000;
|
||||
--a26-tint: #e5fcff;
|
||||
--a26-line: #ccc;
|
||||
--a26-bd: 3px solid var(--a26-fg);
|
||||
--a26-bd-fino: 2px solid var(--a26-fg);
|
||||
--a26-radius: 14px;
|
||||
--a26-tit: "Anton", Impact, "Arial Narrow", sans-serif;
|
||||
--a26-line: #d6d6d6;
|
||||
--a26-edge: #8a8a8a;
|
||||
--a26-danger-text: #c4003b;
|
||||
--a26-bd: 1px solid var(--a26-edge);
|
||||
--a26-bd-fino: 1px solid var(--a26-edge);
|
||||
--a26-radius: 12px;
|
||||
--a26-tit: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
||||
--a26-txt: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
||||
color-scheme: light;
|
||||
}
|
||||
|
|
@ -43,7 +42,7 @@ header, footer, .header, .main-content, .main-column, .sidebar-left, .sidebar-ri
|
|||
section, article, div, table, .profile {
|
||||
background-color: transparent !important;
|
||||
color: var(--a26-fg) !important;
|
||||
border-color: var(--a26-fg) !important;
|
||||
border-color: var(--a26-line) !important;
|
||||
}
|
||||
div { border: 0 !important; box-shadow: none !important; }
|
||||
|
||||
|
|
@ -52,25 +51,25 @@ span, p, li, td, th, label, small, strong, em, h4, h5, h6 { color: inherit !impo
|
|||
a { color: var(--a26-fg) !important; }
|
||||
a:hover, a:focus-visible { color: var(--a26-on-neon) !important; background-color: var(--a26-neon); }
|
||||
|
||||
/* --- titulos: Anton en mayusculas --- */
|
||||
/* --- titulos: negrita, sin mayusculas --- */
|
||||
h1, h2, h3, .card-label, .tags-header h2, .oasis-nav-header {
|
||||
font-family: var(--a26-tit) !important;
|
||||
font-weight: 400 !important;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .01em;
|
||||
line-height: 1.05 !important;
|
||||
font-weight: 700 !important;
|
||||
text-transform: none !important;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.2 !important;
|
||||
color: var(--a26-fg) !important;
|
||||
}
|
||||
h1 { font-size: 34px !important; }
|
||||
h2 { font-size: 28px !important; }
|
||||
h3 { font-size: 21px !important; }
|
||||
.card-label { font-size: 15px !important; }
|
||||
h1 { font-size: 26px !important; }
|
||||
h2 { font-size: 22px !important; }
|
||||
h3 { font-size: 18px !important; }
|
||||
.card-label { font-size: 14px !important; }
|
||||
|
||||
/* cabecera de cada modulo: titulo con raya gorda debajo, como los h2 de la web */
|
||||
/* cabecera de cada modulo: titulo y una raya fina debajo */
|
||||
.tags-header {
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
border-bottom: var(--a26-bd) !important;
|
||||
border-bottom: 1px solid var(--a26-line) !important;
|
||||
border-radius: 0 !important;
|
||||
padding: 0 0 8px !important;
|
||||
margin: 0 0 16px !important;
|
||||
|
|
@ -78,64 +77,61 @@ h3 { font-size: 21px !important; }
|
|||
}
|
||||
.tags-header p { color: var(--a26-muted) !important; font-size: 15px !important; margin: 4px 0 0 !important; }
|
||||
|
||||
/* --- tarjetas: recuadro negro, sin sombras difusas --- */
|
||||
/* --- tarjetas: borde fino, sin sombra --- */
|
||||
.main-column article, .main-column [class$="-card"], .main-column [class*="-card "],
|
||||
.main-column .card, .forum-comment, .feed-row {
|
||||
background: var(--a26-bg) !important;
|
||||
border: var(--a26-bd-fino) !important;
|
||||
border: 1px solid var(--a26-line) !important;
|
||||
border-radius: var(--a26-radius) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.main-column > section { border: 0 !important; padding: 0 !important; }
|
||||
|
||||
/* --- botones: los .bt de acampada --- */
|
||||
/* --- botones: contorno fino; el elegido y el principal, rellenos --- */
|
||||
button, input[type="submit"], input[type="button"],
|
||||
.filter-btn, .create-button, .buy-btn, .delete-btn,
|
||||
a.user-link, button.user-link, .date-link, .welcome-banner-start, .update-download-link {
|
||||
font-family: var(--a26-tit) !important;
|
||||
font-weight: 400 !important;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .02em;
|
||||
font-family: var(--a26-txt) !important;
|
||||
font-weight: 600 !important;
|
||||
text-transform: none !important;
|
||||
letter-spacing: 0;
|
||||
background: var(--a26-bg) !important;
|
||||
color: var(--a26-fg) !important;
|
||||
border: var(--a26-bd) !important;
|
||||
border-radius: var(--a26-radius) !important;
|
||||
box-shadow: 0 5px 0 var(--a26-fg) !important;
|
||||
box-shadow: none !important;
|
||||
text-decoration: none !important;
|
||||
transition: transform .12s ease-out, box-shadow .12s ease-out;
|
||||
}
|
||||
button, input[type="submit"], input[type="button"], .filter-btn, .create-button {
|
||||
min-height: 48px;
|
||||
min-height: 44px;
|
||||
padding: 8px 16px !important;
|
||||
font-size: 18px !important;
|
||||
font-size: 16px !important;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
button:active, input[type="submit"]:active, input[type="button"]:active,
|
||||
.filter-btn:active, .create-button:active, a.user-link:active {
|
||||
transform: translateY(4px);
|
||||
box-shadow: 0 1px 0 var(--a26-fg) !important;
|
||||
background: var(--a26-neon) !important; color: var(--a26-on-neon) !important;
|
||||
.filter-btn:active, a.user-link:active {
|
||||
background: var(--a26-soft) !important;
|
||||
}
|
||||
/* el boton elegido (filtros, pestañas): relleno cian */
|
||||
.filter-btn.active, .mode-buttons .filter-btn.active, .mode-buttons-row .filter-btn.active,
|
||||
.tribe-mode-buttons .filter-btn.active, .filters .filter-btn.active,
|
||||
.activity-filter-grid .filter-btn.active, .activity-sub-filter .filter-btn.active,
|
||||
.bank-range-tabs .filter-btn.active {
|
||||
background: var(--a26-neon) !important;
|
||||
border-color: var(--a26-fg) !important;
|
||||
border-color: var(--a26-neon) !important;
|
||||
color: var(--a26-on-neon) !important;
|
||||
}
|
||||
/* el boton de crear: negro, para que se vea primero */
|
||||
/* el principal de cada pantalla (crear, escribir): relleno con el resalte */
|
||||
.create-button, .mode-buttons .create-button, .mode-buttons-row .create-button,
|
||||
.tribe-mode-buttons .create-button, .filters .create-button {
|
||||
background: var(--a26-fg) !important;
|
||||
color: var(--a26-bg) !important;
|
||||
box-shadow: 0 5px 0 var(--a26-neon) !important;
|
||||
font-size: 18px !important;
|
||||
background: var(--a26-neon) !important;
|
||||
border-color: var(--a26-neon) !important;
|
||||
color: var(--a26-on-neon) !important;
|
||||
font-size: 16px !important;
|
||||
padding: 8px 16px !important;
|
||||
min-height: 48px !important;
|
||||
}
|
||||
.delete-btn { box-shadow: 0 5px 0 #e0004d !important; }
|
||||
.create-button:active { filter: brightness(.92); }
|
||||
.delete-btn { border-color: var(--a26-danger-text) !important; color: var(--a26-danger-text) !important; }
|
||||
|
||||
/* --- formularios --- */
|
||||
input, textarea, select {
|
||||
|
|
@ -148,33 +144,34 @@ input, textarea, select {
|
|||
min-height: 44px;
|
||||
}
|
||||
input:focus, textarea:focus, select:focus {
|
||||
outline: 3px solid var(--a26-neon) !important;
|
||||
outline: 2px solid var(--a26-neon) !important;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
input[type="checkbox"], input[type="radio"] { min-height: 0; accent-color: var(--a26-fg); }
|
||||
input[type="checkbox"], input[type="radio"] { min-height: 0; accent-color: var(--a26-neon); }
|
||||
|
||||
/* --- tablas --- */
|
||||
table { border: var(--a26-bd-fino) !important; border-radius: 10px; overflow: hidden; }
|
||||
table th { background: var(--a26-fg) !important; color: var(--a26-bg) !important; }
|
||||
table td { border-color: var(--a26-fg) !important; }
|
||||
table { border: 1px solid var(--a26-line) !important; border-radius: 10px; overflow: hidden; }
|
||||
table th { background: var(--a26-soft) !important; color: var(--a26-fg) !important; }
|
||||
table td { border-color: var(--a26-line) !important; }
|
||||
|
||||
/* --- avisos de upstream (bienvenida, actualizaciones) --- */
|
||||
.update-banner, .welcome-banner {
|
||||
background: var(--a26-neon) !important;
|
||||
color: var(--a26-on-neon) !important;
|
||||
border: var(--a26-bd) !important;
|
||||
border-radius: var(--a26-radius) !important;
|
||||
background: var(--a26-tint) !important;
|
||||
color: var(--a26-fg) !important;
|
||||
border: 0 !important;
|
||||
border-left: 4px solid var(--a26-neon) !important;
|
||||
border-radius: 10px !important;
|
||||
margin: 8px 10px !important;
|
||||
}
|
||||
.update-banner-link, .update-banner-text { color: var(--a26-on-neon) !important; }
|
||||
.update-banner-link, .update-banner-text { color: var(--a26-fg) !important; }
|
||||
.welcome-banner-close-btn {
|
||||
background: var(--a26-bg) !important;
|
||||
box-shadow: none !important;
|
||||
min-height: 40px; width: 40px; padding: 0 !important;
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
min-height: 44px; width: 44px; padding: 0 !important;
|
||||
}
|
||||
|
||||
/* --- colores sueltos de OasisMobile que se quedaban en amarillo o naranja --- */
|
||||
.avatar, .article img, .post-preview img { border-color: var(--a26-fg) !important; }
|
||||
.avatar, .article img, .post-preview img { border-color: var(--a26-line) !important; }
|
||||
.profile .name, .snh-invite-code, .stats-kpi-label, .stats-kpi-value, .carbon-bar-formula,
|
||||
a.hashtag, .chat-topic-title, .chat-topic-active .chat-topic-title,
|
||||
.chat-topic-meta, .chat-topic-last-author, .chat-workspace-details > .tribe-side .tribe-card-members {
|
||||
|
|
@ -186,13 +183,8 @@ a.hashtag { text-decoration: underline !important; }
|
|||
|
||||
/* --- pie --- */
|
||||
.oasis-footer, .oasis-footer * { color: var(--a26-muted) !important; background: transparent !important; }
|
||||
.oasis-footer { border-top: var(--a26-bd) !important; margin-top: 32px; }
|
||||
.oasis-footer { border-top: 1px solid var(--a26-line) !important; margin-top: 32px; }
|
||||
.oasis-footer a { text-decoration: underline !important; }
|
||||
|
||||
::-webkit-scrollbar-thumb { background-color: var(--a26-fg) !important; }
|
||||
::-webkit-scrollbar-thumb { background-color: var(--a26-edge) !important; }
|
||||
::-webkit-scrollbar-track { background-color: var(--a26-soft) !important; }
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
button, .filter-btn, .create-button { transition: none; }
|
||||
button:active, .filter-btn:active, .create-button:active { transform: none; }
|
||||
}
|
||||
|
|
@ -22,6 +22,21 @@ module.exports = {
|
|||
bbMenuClose: "Close",
|
||||
uxPickHint: "Tap one and it is saved. You can change it any time in Settings.",
|
||||
uxPickCurrent: "In use",
|
||||
pubBarJoining: "Joining the pub… it can take up to a minute. Keep the app open.",
|
||||
pubBarJoinFailed: "If you did not get into the pub, the usual reasons are: no connection (wifi or data), the pub is down, or the invite was already used. Try another pub from the list, or later.",
|
||||
pubBarDownload: "Downloading the network from {pub} ({tier})…",
|
||||
pubBarTierRecent: "the latest",
|
||||
pubBarTierFull: "everything before",
|
||||
pubBarRestore: "Saving to your phone: {pct}% · {n} messages",
|
||||
pubBarHint: "You can keep using the app meanwhile.",
|
||||
pubBarDone: "You are in {pub}: {n} messages downloaded.",
|
||||
pubBarErrNoSnap: "You joined {pub}, but it offers no copy to download at once. Posts will arrive little by little while the app is open.",
|
||||
pubBarErrNet: "Cannot reach {pub}. Check that you have Internet (wifi or data) and try again later; if it keeps failing, the pub may be down.",
|
||||
pubBarErrOther: "The download from {pub} stopped ({error}). You are in; the rest will arrive little by little.",
|
||||
pubBarClose: "Close",
|
||||
pubBarBackupRestore: "Restoring your backup: {pct}% · {n} messages",
|
||||
pubBarBackupDone: "Backup restored: {n} messages.",
|
||||
pubBarBackupErr: "The backup could not be restored: {error}. Check the file and the password.",
|
||||
quickTitle: "The basics",
|
||||
quickHint: "What you chose when you started, one tap away.",
|
||||
quick_identity: "Identity",
|
||||
|
|
@ -37,7 +52,6 @@ module.exports = {
|
|||
quickWriteGreeting: "Write a greeting",
|
||||
welcomeHintColors: "Background, text and highlight colour of the app.",
|
||||
colorsHint: "Tap a palette and it is applied.",
|
||||
colorsSkinNote: "Colours go with the Acampada look; choosing one switches to it.",
|
||||
colorsCustom: "Your own",
|
||||
colorsBg: "Background",
|
||||
colorsFg: "Text",
|
||||
|
|
@ -45,7 +59,7 @@ module.exports = {
|
|||
colorsApply: "Apply",
|
||||
colorsFixed: "The text could not be read on that background, so it was set to black or white.",
|
||||
colorsKeep: "Keep these",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "Light",
|
||||
palette_noche: "Night",
|
||||
palette_oro: "Gold",
|
||||
palette_bosque: "Forest",
|
||||
|
|
@ -144,6 +158,21 @@ module.exports = {
|
|||
bbMenuClose: "Cerrar",
|
||||
uxPickHint: "Toca uno y queda guardado. Puedes cambiarlo cuando quieras en Ajustes.",
|
||||
uxPickCurrent: "En uso",
|
||||
pubBarJoining: "Uniéndote al pub… puede tardar hasta un minuto. No cierres la app.",
|
||||
pubBarJoinFailed: "Si no has entrado en el pub, lo más habitual es: no hay conexión (wifi o datos), el pub está caído o la invitación ya se ha usado. Prueba con otro pub de la lista o más tarde.",
|
||||
pubBarDownload: "Descargando la red de {pub} ({tier})…",
|
||||
pubBarTierRecent: "lo más reciente",
|
||||
pubBarTierFull: "todo lo anterior",
|
||||
pubBarRestore: "Guardando en tu móvil: {pct} % · {n} mensajes",
|
||||
pubBarHint: "Puedes seguir usando la app mientras tanto.",
|
||||
pubBarDone: "Ya estás en {pub}: {n} mensajes descargados.",
|
||||
pubBarErrNoSnap: "Te has unido a {pub}, pero no ofrece una copia para descargar de golpe. Lo que publique la gente irá llegando poco a poco mientras la app esté abierta.",
|
||||
pubBarErrNet: "No se puede conectar con {pub}. Comprueba que tienes Internet (wifi o datos) y vuelve a probar en un rato; si sigue igual, el pub puede estar caído.",
|
||||
pubBarErrOther: "La descarga desde {pub} se ha cortado ({error}). Ya estás dentro; lo demás llegará poco a poco.",
|
||||
pubBarClose: "Cerrar",
|
||||
pubBarBackupRestore: "Restaurando tu copia: {pct} % · {n} mensajes",
|
||||
pubBarBackupDone: "Copia restaurada: {n} mensajes.",
|
||||
pubBarBackupErr: "No se ha podido restaurar la copia: {error}. Revisa el archivo y la contraseña.",
|
||||
quickTitle: "Lo básico",
|
||||
quickHint: "Lo que elegiste al empezar, a un toque.",
|
||||
quick_identity: "Identidad",
|
||||
|
|
@ -159,7 +188,6 @@ module.exports = {
|
|||
quickWriteGreeting: "Escribir el saludo",
|
||||
welcomeHintColors: "Fondo, texto y color de resalte de la app.",
|
||||
colorsHint: "Toca una paleta y se aplica.",
|
||||
colorsSkinNote: "Los colores van con el aspecto Acampada; al elegir uno se pasa a ese aspecto.",
|
||||
colorsCustom: "A tu gusto",
|
||||
colorsBg: "Fondo",
|
||||
colorsFg: "Texto",
|
||||
|
|
@ -167,7 +195,7 @@ module.exports = {
|
|||
colorsApply: "Aplicar",
|
||||
colorsFixed: "El texto no se leía sobre ese fondo, así que se ha puesto en negro o blanco.",
|
||||
colorsKeep: "Dejar estos",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "Claro",
|
||||
palette_noche: "Noche",
|
||||
palette_oro: "Oro",
|
||||
palette_bosque: "Bosque",
|
||||
|
|
@ -272,6 +300,21 @@ module.exports = {
|
|||
bbMenuClose: "Fermer",
|
||||
uxPickHint: "Touchez-en un et c'est enregistré. Vous pouvez le changer à tout moment dans les Paramètres.",
|
||||
uxPickCurrent: "Actuel",
|
||||
pubBarJoining: "Connexion au pub… cela peut prendre jusqu'à une minute. Gardez l'app ouverte.",
|
||||
pubBarJoinFailed: "Si vous n'êtes pas entré dans le pub, c'est souvent : pas de connexion (wifi ou données), pub hors service, ou invitation déjà utilisée. Essayez un autre pub de la liste, ou plus tard.",
|
||||
pubBarDownload: "Téléchargement du réseau depuis {pub} ({tier})…",
|
||||
pubBarTierRecent: "le plus récent",
|
||||
pubBarTierFull: "tout le reste",
|
||||
pubBarRestore: "Enregistrement sur votre téléphone : {pct} % · {n} messages",
|
||||
pubBarHint: "Vous pouvez continuer à utiliser l'app.",
|
||||
pubBarDone: "Vous êtes dans {pub} : {n} messages téléchargés.",
|
||||
pubBarErrNoSnap: "Vous avez rejoint {pub}, mais il ne propose pas de copie à télécharger d'un coup. Les publications arriveront peu à peu tant que l'app est ouverte.",
|
||||
pubBarErrNet: "Impossible de joindre {pub}. Vérifiez votre connexion (wifi ou données) et réessayez plus tard ; si cela continue, le pub est peut-être hors service.",
|
||||
pubBarErrOther: "Le téléchargement depuis {pub} s'est interrompu ({error}). Vous êtes dedans ; le reste arrivera peu à peu.",
|
||||
pubBarClose: "Fermer",
|
||||
pubBarBackupRestore: "Restauration de votre sauvegarde : {pct} % · {n} messages",
|
||||
pubBarBackupDone: "Sauvegarde restaurée : {n} messages.",
|
||||
pubBarBackupErr: "Impossible de restaurer la sauvegarde : {error}. Vérifiez le fichier et le mot de passe.",
|
||||
quickTitle: "L'essentiel",
|
||||
quickHint: "Ce que vous avez choisi au début, à portée de doigt.",
|
||||
quick_identity: "Identité",
|
||||
|
|
@ -287,7 +330,6 @@ module.exports = {
|
|||
quickWriteGreeting: "Écrire un salut",
|
||||
welcomeHintColors: "Fond, texte et couleur d'accent de l'application.",
|
||||
colorsHint: "Touchez une palette et elle s'applique.",
|
||||
colorsSkinNote: "Les couleurs vont avec l'aspect Acampada ; en choisir une passe à cet aspect.",
|
||||
colorsCustom: "À votre goût",
|
||||
colorsBg: "Fond",
|
||||
colorsFg: "Texte",
|
||||
|
|
@ -295,7 +337,7 @@ module.exports = {
|
|||
colorsApply: "Appliquer",
|
||||
colorsFixed: "Le texte n'était pas lisible sur ce fond, il a été mis en noir ou en blanc.",
|
||||
colorsKeep: "Garder celles-ci",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "Clair",
|
||||
palette_noche: "Nuit",
|
||||
palette_oro: "Or",
|
||||
palette_bosque: "Forêt",
|
||||
|
|
@ -394,6 +436,21 @@ module.exports = {
|
|||
bbMenuClose: "Itxi",
|
||||
uxPickHint: "Bat ukitu eta gordeta geratzen da. Nahi duzunean alda dezakezu Ezarpenetan.",
|
||||
uxPickCurrent: "Erabiltzen",
|
||||
pubBarJoining: "Pubera sartzen… minutu bat arte iraun dezake. Ez itxi aplikazioa.",
|
||||
pubBarJoinFailed: "Pubean sartu ez bazara, ohikoena hau da: ez dago konexiorik (wifia edo datuak), puba eroria dago edo gonbidapena erabilita dago. Saiatu zerrendako beste pub batekin edo geroago.",
|
||||
pubBarDownload: "{pub}-ren sarea deskargatzen ({tier})…",
|
||||
pubBarTierRecent: "berriena",
|
||||
pubBarTierFull: "aurreko guztia",
|
||||
pubBarRestore: "Mugikorrean gordetzen: % {pct} · {n} mezu",
|
||||
pubBarHint: "Bitartean aplikazioa erabiltzen jarrai dezakezu.",
|
||||
pubBarDone: "{pub}-n zaude: {n} mezu deskargatuta.",
|
||||
pubBarErrNoSnap: "{pub}-ra batu zara, baina ez du kopiarik eskaintzen behin betiko deskargatzeko. Jendeak argitaratzen duena pixkanaka iritsiko da aplikazioa irekita dagoen bitartean.",
|
||||
pubBarErrNet: "Ezin da {pub}-rekin konektatu. Egiaztatu Interneta duzula (wifia edo datuak) eta saiatu berriro geroago; berdin jarraitzen badu, puba eroria egon daiteke.",
|
||||
pubBarErrOther: "{pub}-tik deskarga eten da ({error}). Barruan zaude; gainerakoa pixkanaka iritsiko da.",
|
||||
pubBarClose: "Itxi",
|
||||
pubBarBackupRestore: "Zure kopia leheneratzen: % {pct} · {n} mezu",
|
||||
pubBarBackupDone: "Kopia leheneratuta: {n} mezu.",
|
||||
pubBarBackupErr: "Ezin izan da kopia leheneratu: {error}. Begiratu fitxategia eta pasahitza.",
|
||||
quickTitle: "Oinarrizkoa",
|
||||
quickHint: "Hasieran aukeratu zenuena, ukitu batera.",
|
||||
quick_identity: "Nortasuna",
|
||||
|
|
@ -409,7 +466,6 @@ module.exports = {
|
|||
quickWriteGreeting: "Agurra idatzi",
|
||||
welcomeHintColors: "Aplikazioaren hondoa, testua eta nabarmentze-kolorea.",
|
||||
colorsHint: "Ukitu paleta bat eta aplikatzen da.",
|
||||
colorsSkinNote: "Koloreak Acampada itxurarekin doaz; bat aukeratzean itxura horretara pasatzen da.",
|
||||
colorsCustom: "Zure gustura",
|
||||
colorsBg: "Hondoa",
|
||||
colorsFg: "Testua",
|
||||
|
|
@ -417,7 +473,7 @@ module.exports = {
|
|||
colorsApply: "Aplikatu",
|
||||
colorsFixed: "Testua ez zen irakurtzen hondo horretan, beltzez edo zuriz jarri da.",
|
||||
colorsKeep: "Hauek utzi",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "Argia",
|
||||
palette_noche: "Gaua",
|
||||
palette_oro: "Urrea",
|
||||
palette_bosque: "Basoa",
|
||||
|
|
@ -516,6 +572,21 @@ module.exports = {
|
|||
bbMenuClose: "Schließen",
|
||||
uxPickHint: "Tippe eins an und es ist gespeichert. Du kannst es jederzeit in den Einstellungen ändern.",
|
||||
uxPickCurrent: "Aktiv",
|
||||
pubBarJoining: "Beitritt zum Pub… das kann bis zu einer Minute dauern. Lass die App offen.",
|
||||
pubBarJoinFailed: "Wenn du nicht in den Pub gekommen bist, liegt es meist daran: keine Verbindung (WLAN oder Daten), der Pub ist down oder die Einladung wurde schon benutzt. Probier einen anderen Pub aus der Liste oder später.",
|
||||
pubBarDownload: "Netzwerk wird von {pub} geladen ({tier})…",
|
||||
pubBarTierRecent: "das Neueste",
|
||||
pubBarTierFull: "alles davor",
|
||||
pubBarRestore: "Wird auf dein Handy gespeichert: {pct} % · {n} Nachrichten",
|
||||
pubBarHint: "Du kannst die App solange weiter benutzen.",
|
||||
pubBarDone: "Du bist in {pub}: {n} Nachrichten geladen.",
|
||||
pubBarErrNoSnap: "Du bist {pub} beigetreten, aber es bietet keine Kopie zum Herunterladen. Beiträge kommen nach und nach, solange die App offen ist.",
|
||||
pubBarErrNet: "{pub} ist nicht erreichbar. Prüfe deine Internetverbindung (WLAN oder Daten) und versuch es später; wenn es so bleibt, ist der Pub vielleicht down.",
|
||||
pubBarErrOther: "Der Download von {pub} wurde unterbrochen ({error}). Du bist drin; der Rest kommt nach und nach.",
|
||||
pubBarClose: "Schließen",
|
||||
pubBarBackupRestore: "Sicherung wird wiederhergestellt: {pct} % · {n} Nachrichten",
|
||||
pubBarBackupDone: "Sicherung wiederhergestellt: {n} Nachrichten.",
|
||||
pubBarBackupErr: "Die Sicherung konnte nicht wiederhergestellt werden: {error}. Prüfe Datei und Passwort.",
|
||||
quickTitle: "Das Wichtigste",
|
||||
quickHint: "Was du am Anfang gewählt hast, mit einem Tipp.",
|
||||
quick_identity: "Identität",
|
||||
|
|
@ -531,7 +602,6 @@ module.exports = {
|
|||
quickWriteGreeting: "Gruß schreiben",
|
||||
welcomeHintColors: "Hintergrund, Text und Akzentfarbe der App.",
|
||||
colorsHint: "Tippe auf eine Palette und sie wird angewendet.",
|
||||
colorsSkinNote: "Die Farben gehören zum Acampada-Design; mit einer Auswahl wechselst du dorthin.",
|
||||
colorsCustom: "Eigene",
|
||||
colorsBg: "Hintergrund",
|
||||
colorsFg: "Text",
|
||||
|
|
@ -539,7 +609,7 @@ module.exports = {
|
|||
colorsApply: "Anwenden",
|
||||
colorsFixed: "Der Text war auf diesem Hintergrund nicht lesbar, daher wurde er schwarz oder weiß gesetzt.",
|
||||
colorsKeep: "Diese behalten",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "Hell",
|
||||
palette_noche: "Nacht",
|
||||
palette_oro: "Gold",
|
||||
palette_bosque: "Wald",
|
||||
|
|
@ -638,6 +708,21 @@ module.exports = {
|
|||
bbMenuClose: "Chiudi",
|
||||
uxPickHint: "Toccane uno ed è salvato. Puoi cambiarlo quando vuoi nelle Impostazioni.",
|
||||
uxPickCurrent: "In uso",
|
||||
pubBarJoining: "Ti stai unendo al pub… può volerci fino a un minuto. Tieni l'app aperta.",
|
||||
pubBarJoinFailed: "Se non sei entrato nel pub, di solito è perché: non c'è connessione (wifi o dati), il pub è giù o l'invito è già stato usato. Prova un altro pub della lista, o più tardi.",
|
||||
pubBarDownload: "Scaricamento della rete da {pub} ({tier})…",
|
||||
pubBarTierRecent: "il più recente",
|
||||
pubBarTierFull: "tutto il resto",
|
||||
pubBarRestore: "Salvataggio sul telefono: {pct} % · {n} messaggi",
|
||||
pubBarHint: "Puoi continuare a usare l'app nel frattempo.",
|
||||
pubBarDone: "Sei in {pub}: {n} messaggi scaricati.",
|
||||
pubBarErrNoSnap: "Ti sei unito a {pub}, ma non offre una copia da scaricare in un colpo. I post arriveranno poco a poco mentre l'app è aperta.",
|
||||
pubBarErrNet: "Impossibile raggiungere {pub}. Controlla di avere Internet (wifi o dati) e riprova più tardi; se continua, il pub potrebbe essere giù.",
|
||||
pubBarErrOther: "Lo scaricamento da {pub} si è interrotto ({error}). Sei dentro; il resto arriverà poco a poco.",
|
||||
pubBarClose: "Chiudi",
|
||||
pubBarBackupRestore: "Ripristino del backup: {pct} % · {n} messaggi",
|
||||
pubBarBackupDone: "Backup ripristinato: {n} messaggi.",
|
||||
pubBarBackupErr: "Impossibile ripristinare il backup: {error}. Controlla file e password.",
|
||||
quickTitle: "L'essenziale",
|
||||
quickHint: "Quello che hai scelto all'inizio, a portata di tocco.",
|
||||
quick_identity: "Identità",
|
||||
|
|
@ -653,7 +738,6 @@ module.exports = {
|
|||
quickWriteGreeting: "Scrivi un saluto",
|
||||
welcomeHintColors: "Sfondo, testo e colore di risalto dell'app.",
|
||||
colorsHint: "Tocca una tavolozza e viene applicata.",
|
||||
colorsSkinNote: "I colori vanno con l'aspetto Acampada; sceglierne uno passa a quell'aspetto.",
|
||||
colorsCustom: "A modo tuo",
|
||||
colorsBg: "Sfondo",
|
||||
colorsFg: "Testo",
|
||||
|
|
@ -661,7 +745,7 @@ module.exports = {
|
|||
colorsApply: "Applica",
|
||||
colorsFixed: "Il testo non si leggeva su quello sfondo, quindi è stato messo nero o bianco.",
|
||||
colorsKeep: "Tieni questi",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "Chiaro",
|
||||
palette_noche: "Notte",
|
||||
palette_oro: "Oro",
|
||||
palette_bosque: "Bosco",
|
||||
|
|
@ -760,6 +844,21 @@ module.exports = {
|
|||
bbMenuClose: "Fechar",
|
||||
uxPickHint: "Toque num e fica guardado. Pode mudá-lo quando quiser nas Definições.",
|
||||
uxPickCurrent: "Em uso",
|
||||
pubBarJoining: "A entrar no pub… pode demorar até um minuto. Não feche a app.",
|
||||
pubBarJoinFailed: "Se não entrou no pub, o mais habitual é: não há ligação (wifi ou dados), o pub está em baixo ou o convite já foi usado. Tente outro pub da lista, ou mais tarde.",
|
||||
pubBarDownload: "A descarregar a rede de {pub} ({tier})…",
|
||||
pubBarTierRecent: "o mais recente",
|
||||
pubBarTierFull: "tudo o anterior",
|
||||
pubBarRestore: "A guardar no telemóvel: {pct} % · {n} mensagens",
|
||||
pubBarHint: "Pode continuar a usar a app entretanto.",
|
||||
pubBarDone: "Está em {pub}: {n} mensagens descarregadas.",
|
||||
pubBarErrNoSnap: "Entrou em {pub}, mas não oferece uma cópia para descarregar de uma vez. As publicações vão chegando aos poucos enquanto a app estiver aberta.",
|
||||
pubBarErrNet: "Não é possível ligar a {pub}. Verifique se tem Internet (wifi ou dados) e tente mais tarde; se continuar, o pub pode estar em baixo.",
|
||||
pubBarErrOther: "A descarga de {pub} parou ({error}). Já está dentro; o resto chegará aos poucos.",
|
||||
pubBarClose: "Fechar",
|
||||
pubBarBackupRestore: "A restaurar a cópia: {pct} % · {n} mensagens",
|
||||
pubBarBackupDone: "Cópia restaurada: {n} mensagens.",
|
||||
pubBarBackupErr: "Não foi possível restaurar a cópia: {error}. Verifique o ficheiro e a palavra-passe.",
|
||||
quickTitle: "O essencial",
|
||||
quickHint: "O que escolheu ao começar, a um toque.",
|
||||
quick_identity: "Identidade",
|
||||
|
|
@ -775,7 +874,6 @@ module.exports = {
|
|||
quickWriteGreeting: "Escrever a saudação",
|
||||
welcomeHintColors: "Fundo, texto e cor de destaque da app.",
|
||||
colorsHint: "Toque numa paleta e ela aplica-se.",
|
||||
colorsSkinNote: "As cores vão com o aspeto Acampada; escolher uma passa para esse aspeto.",
|
||||
colorsCustom: "À sua maneira",
|
||||
colorsBg: "Fundo",
|
||||
colorsFg: "Texto",
|
||||
|
|
@ -783,7 +881,7 @@ module.exports = {
|
|||
colorsApply: "Aplicar",
|
||||
colorsFixed: "O texto não se lia nesse fundo, por isso ficou preto ou branco.",
|
||||
colorsKeep: "Manter estas",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "Claro",
|
||||
palette_noche: "Noite",
|
||||
palette_oro: "Ouro",
|
||||
palette_bosque: "Floresta",
|
||||
|
|
@ -882,6 +980,21 @@ module.exports = {
|
|||
bbMenuClose: "关闭",
|
||||
uxPickHint: "点一下即保存。随时可以在设置中更改。",
|
||||
uxPickCurrent: "使用中",
|
||||
pubBarJoining: "正在加入 pub……最多可能需要一分钟。请不要关闭应用。",
|
||||
pubBarJoinFailed: "如果没有进入 pub,常见原因是:没有网络(wifi 或流量)、pub 已停止服务,或邀请已被使用。请尝试列表中的其他 pub,或稍后再试。",
|
||||
pubBarDownload: "正在从 {pub} 下载网络({tier})……",
|
||||
pubBarTierRecent: "最新内容",
|
||||
pubBarTierFull: "之前的全部",
|
||||
pubBarRestore: "正在保存到手机:{pct}% · {n} 条消息",
|
||||
pubBarHint: "在此期间你可以继续使用应用。",
|
||||
pubBarDone: "你已加入 {pub}:已下载 {n} 条消息。",
|
||||
pubBarErrNoSnap: "你已加入 {pub},但它不提供可一次下载的副本。应用打开时,内容会陆续到达。",
|
||||
pubBarErrNet: "无法连接 {pub}。请检查网络(wifi 或流量),稍后再试;如果仍然失败,pub 可能已停止服务。",
|
||||
pubBarErrOther: "从 {pub} 的下载中断了({error})。你已加入,其余内容会陆续到达。",
|
||||
pubBarClose: "关闭",
|
||||
pubBarBackupRestore: "正在恢复备份:{pct}% · {n} 条消息",
|
||||
pubBarBackupDone: "备份已恢复:{n} 条消息。",
|
||||
pubBarBackupErr: "无法恢复备份:{error}。请检查文件和密码。",
|
||||
quickTitle: "基本设置",
|
||||
quickHint: "开始时的选择,一点即达。",
|
||||
quick_identity: "身份",
|
||||
|
|
@ -897,7 +1010,6 @@ module.exports = {
|
|||
quickWriteGreeting: "写问候",
|
||||
welcomeHintColors: "应用的背景、文字和强调色。",
|
||||
colorsHint: "点一个配色即可应用。",
|
||||
colorsSkinNote: "颜色配合 Acampada 外观;选择后会切换到该外观。",
|
||||
colorsCustom: "自定义",
|
||||
colorsBg: "背景",
|
||||
colorsFg: "文字",
|
||||
|
|
@ -905,7 +1017,7 @@ module.exports = {
|
|||
colorsApply: "应用",
|
||||
colorsFixed: "文字在该背景上看不清,已改为黑色或白色。",
|
||||
colorsKeep: "保留这些",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "浅色",
|
||||
palette_noche: "夜晚",
|
||||
palette_oro: "金色",
|
||||
palette_bosque: "森林",
|
||||
|
|
@ -1004,6 +1116,21 @@ module.exports = {
|
|||
bbMenuClose: "إغلاق",
|
||||
uxPickHint: "المس واحدًا ويُحفظ. يمكنك تغييره في أي وقت من الإعدادات.",
|
||||
uxPickCurrent: "قيد الاستخدام",
|
||||
pubBarJoining: "جارٍ الانضمام إلى الـ pub… قد يستغرق ذلك دقيقة. أبقِ التطبيق مفتوحًا.",
|
||||
pubBarJoinFailed: "إن لم تدخل إلى الـ pub، فالأسباب المعتادة: لا يوجد اتصال (واي فاي أو بيانات)، أو الـ pub متوقف، أو الدعوة استُخدمت من قبل. جرّب pub آخر من القائمة أو لاحقًا.",
|
||||
pubBarDownload: "جارٍ تنزيل الشبكة من {pub} ({tier})…",
|
||||
pubBarTierRecent: "الأحدث",
|
||||
pubBarTierFull: "كل ما سبق",
|
||||
pubBarRestore: "جارٍ الحفظ على هاتفك: {pct}% · {n} رسالة",
|
||||
pubBarHint: "يمكنك متابعة استخدام التطبيق في هذه الأثناء.",
|
||||
pubBarDone: "أنت في {pub}: تم تنزيل {n} رسالة.",
|
||||
pubBarErrNoSnap: "انضممت إلى {pub}، لكنه لا يقدم نسخة للتنزيل دفعة واحدة. ستصل المنشورات تدريجيًا ما دام التطبيق مفتوحًا.",
|
||||
pubBarErrNet: "تعذّر الاتصال بـ {pub}. تحقق من اتصالك بالإنترنت (واي فاي أو بيانات) وحاول لاحقًا؛ إن استمر الأمر فقد يكون الـ pub متوقفًا.",
|
||||
pubBarErrOther: "توقف التنزيل من {pub} ({error}). أنت منضم؛ وسيصل الباقي تدريجيًا.",
|
||||
pubBarClose: "إغلاق",
|
||||
pubBarBackupRestore: "جارٍ استعادة النسخة الاحتياطية: {pct}% · {n} رسالة",
|
||||
pubBarBackupDone: "تمت استعادة النسخة: {n} رسالة.",
|
||||
pubBarBackupErr: "تعذّرت استعادة النسخة: {error}. تحقق من الملف وكلمة المرور.",
|
||||
quickTitle: "الأساسيات",
|
||||
quickHint: "ما اخترته في البداية، بلمسة واحدة.",
|
||||
quick_identity: "الهوية",
|
||||
|
|
@ -1019,7 +1146,6 @@ module.exports = {
|
|||
quickWriteGreeting: "كتابة التحية",
|
||||
welcomeHintColors: "لون الخلفية والنص والتمييز في التطبيق.",
|
||||
colorsHint: "المس لوحة ألوان فتُطبَّق.",
|
||||
colorsSkinNote: "الألوان تأتي مع مظهر Acampada؛ اختيار لون ينقلك إليه.",
|
||||
colorsCustom: "على ذوقك",
|
||||
colorsBg: "الخلفية",
|
||||
colorsFg: "النص",
|
||||
|
|
@ -1027,7 +1153,7 @@ module.exports = {
|
|||
colorsApply: "تطبيق",
|
||||
colorsFixed: "لم يكن النص مقروءًا على تلك الخلفية، فجُعل أسود أو أبيض.",
|
||||
colorsKeep: "الإبقاء على هذه",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "فاتح",
|
||||
palette_noche: "ليل",
|
||||
palette_oro: "ذهب",
|
||||
palette_bosque: "غابة",
|
||||
|
|
@ -1126,6 +1252,21 @@ module.exports = {
|
|||
bbMenuClose: "बंद करें",
|
||||
uxPickHint: "एक पर टैप करें और वह सेव हो जाएगा। सेटिंग्स में इसे कभी भी बदल सकते हैं।",
|
||||
uxPickCurrent: "चालू",
|
||||
pubBarJoining: "pub से जुड़ रहे हैं… इसमें एक मिनट तक लग सकता है। ऐप खुला रखें।",
|
||||
pubBarJoinFailed: "अगर आप pub में नहीं जा पाए, तो आम वजहें हैं: कनेक्शन नहीं है (वाई-फ़ाई या डेटा), pub बंद है, या निमंत्रण पहले ही इस्तेमाल हो चुका है। सूची से कोई दूसरा pub आज़माएँ, या बाद में।",
|
||||
pubBarDownload: "{pub} से नेटवर्क डाउनलोड हो रहा है ({tier})…",
|
||||
pubBarTierRecent: "सबसे नया",
|
||||
pubBarTierFull: "पहले का सब कुछ",
|
||||
pubBarRestore: "आपके फ़ोन में सहेजा जा रहा है: {pct}% · {n} संदेश",
|
||||
pubBarHint: "इस बीच आप ऐप का उपयोग जारी रख सकते हैं।",
|
||||
pubBarDone: "आप {pub} में हैं: {n} संदेश डाउनलोड हुए।",
|
||||
pubBarErrNoSnap: "आप {pub} से जुड़ गए, पर यह एक बार में डाउनलोड करने के लिए कॉपी नहीं देता। ऐप खुला रहने पर पोस्ट धीरे-धीरे आएँगी।",
|
||||
pubBarErrNet: "{pub} से जुड़ नहीं पा रहे। जाँचें कि इंटरनेट (वाई-फ़ाई या डेटा) है और बाद में फिर कोशिश करें; अगर ऐसा ही रहे तो pub बंद हो सकता है।",
|
||||
pubBarErrOther: "{pub} से डाउनलोड रुक गया ({error})। आप जुड़ चुके हैं; बाकी धीरे-धीरे आएगा।",
|
||||
pubBarClose: "बंद करें",
|
||||
pubBarBackupRestore: "आपका बैकअप बहाल हो रहा है: {pct}% · {n} संदेश",
|
||||
pubBarBackupDone: "बैकअप बहाल हुआ: {n} संदेश।",
|
||||
pubBarBackupErr: "बैकअप बहाल नहीं हो सका: {error}। फ़ाइल और पासवर्ड जाँचें।",
|
||||
quickTitle: "मूल बातें",
|
||||
quickHint: "शुरुआत में जो चुना था, एक टैप पर।",
|
||||
quick_identity: "पहचान",
|
||||
|
|
@ -1141,7 +1282,6 @@ module.exports = {
|
|||
quickWriteGreeting: "अभिवादन लिखें",
|
||||
welcomeHintColors: "ऐप का पृष्ठभूमि, टेक्स्ट और हाइलाइट रंग।",
|
||||
colorsHint: "किसी पैलेट पर टैप करें और वह लागू हो जाएगा।",
|
||||
colorsSkinNote: "रंग Acampada रूप के साथ चलते हैं; कोई चुनने पर वही रूप लग जाता है।",
|
||||
colorsCustom: "अपनी पसंद",
|
||||
colorsBg: "पृष्ठभूमि",
|
||||
colorsFg: "टेक्स्ट",
|
||||
|
|
@ -1149,7 +1289,7 @@ module.exports = {
|
|||
colorsApply: "लागू करें",
|
||||
colorsFixed: "उस पृष्ठभूमि पर टेक्स्ट पढ़ा नहीं जा रहा था, इसलिए काला या सफ़ेद कर दिया गया।",
|
||||
colorsKeep: "इन्हें रखें",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "हल्का",
|
||||
palette_noche: "रात",
|
||||
palette_oro: "सोना",
|
||||
palette_bosque: "जंगल",
|
||||
|
|
@ -1248,6 +1388,21 @@ module.exports = {
|
|||
bbMenuClose: "Закрыть",
|
||||
uxPickHint: "Нажмите на вариант, и он сохранится. Изменить можно в любой момент в Настройках.",
|
||||
uxPickCurrent: "Сейчас",
|
||||
pubBarJoining: "Подключение к пабу… это может занять до минуты. Не закрывайте приложение.",
|
||||
pubBarJoinFailed: "Если не удалось войти в паб, обычно причина такая: нет связи (wifi или мобильные данные), паб недоступен или приглашение уже использовано. Попробуйте другой паб из списка или позже.",
|
||||
pubBarDownload: "Загрузка сети с {pub} ({tier})…",
|
||||
pubBarTierRecent: "самое новое",
|
||||
pubBarTierFull: "всё остальное",
|
||||
pubBarRestore: "Сохранение на телефон: {pct} % · {n} сообщений",
|
||||
pubBarHint: "Пока можно пользоваться приложением.",
|
||||
pubBarDone: "Вы в {pub}: загружено {n} сообщений.",
|
||||
pubBarErrNoSnap: "Вы присоединились к {pub}, но он не даёт копию для загрузки целиком. Публикации будут приходить постепенно, пока приложение открыто.",
|
||||
pubBarErrNet: "Не удаётся связаться с {pub}. Проверьте интернет (wifi или мобильные данные) и попробуйте позже; если не получится, паб может быть недоступен.",
|
||||
pubBarErrOther: "Загрузка с {pub} прервалась ({error}). Вы уже внутри; остальное придёт постепенно.",
|
||||
pubBarClose: "Закрыть",
|
||||
pubBarBackupRestore: "Восстановление резервной копии: {pct} % · {n} сообщений",
|
||||
pubBarBackupDone: "Копия восстановлена: {n} сообщений.",
|
||||
pubBarBackupErr: "Не удалось восстановить копию: {error}. Проверьте файл и пароль.",
|
||||
quickTitle: "Основное",
|
||||
quickHint: "То, что вы выбрали в начале, в одно касание.",
|
||||
quick_identity: "Личность",
|
||||
|
|
@ -1263,7 +1418,6 @@ module.exports = {
|
|||
quickWriteGreeting: "Написать приветствие",
|
||||
welcomeHintColors: "Фон, текст и цвет выделения в приложении.",
|
||||
colorsHint: "Нажмите на палитру, и она применится.",
|
||||
colorsSkinNote: "Цвета идут с оформлением Acampada; при выборе включается оно.",
|
||||
colorsCustom: "Свои",
|
||||
colorsBg: "Фон",
|
||||
colorsFg: "Текст",
|
||||
|
|
@ -1271,7 +1425,7 @@ module.exports = {
|
|||
colorsApply: "Применить",
|
||||
colorsFixed: "Текст не читался на этом фоне, поэтому он стал чёрным или белым.",
|
||||
colorsKeep: "Оставить эти",
|
||||
palette_acampada: "Acampada",
|
||||
palette_acampada: "Светлая",
|
||||
palette_noche: "Ночь",
|
||||
palette_oro: "Золото",
|
||||
palette_bosque: "Лес",
|
||||
|
|
|
|||
72
src/client/public/js/mobile_pub.js
Normal file
72
src/client/public/js/mobile_pub.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// Barra de unirse a un pub (ver views/mobile_pubbar.js). Sin este script la barra se
|
||||
// ve igual al cargar cada pagina; con el, se pone al dia sola y sale nada mas tocar
|
||||
// "unirse", sin recargar la pagina.
|
||||
(function () {
|
||||
var bar = document.getElementById('pub-bar');
|
||||
if (!bar || !window.fetch) return;
|
||||
var text = bar.querySelector('.pub-bar-text');
|
||||
var hint = bar.querySelector('.pub-bar-hint');
|
||||
var meter = bar.querySelector('.pub-bar-meter');
|
||||
var timer = null;
|
||||
|
||||
function show(s) {
|
||||
if (!s || s.kind === 'none') { bar.hidden = true; document.body.classList.remove('has-pub-bar'); return; }
|
||||
bar.hidden = false;
|
||||
document.body.classList.add('has-pub-bar');
|
||||
bar.className = 'pub-bar is-' + s.kind;
|
||||
bar.setAttribute('data-running', s.running ? '1' : '0');
|
||||
text.textContent = s.text || '';
|
||||
hint.textContent = s.hint || '';
|
||||
if (s.pct == null) meter.removeAttribute('value'); else meter.value = s.pct;
|
||||
}
|
||||
|
||||
function poll() {
|
||||
fetch('/mobile/pub-status', { credentials: 'same-origin', cache: 'no-store' })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (s) {
|
||||
show(s);
|
||||
clearTimeout(timer);
|
||||
if (s && s.running) timer = setTimeout(poll, 2000);
|
||||
})
|
||||
.catch(function () { clearTimeout(timer); timer = setTimeout(poll, 5000); });
|
||||
}
|
||||
|
||||
if (!bar.hidden) document.body.classList.add('has-pub-bar');
|
||||
if (bar.getAttribute('data-running') === '1') timer = setTimeout(poll, 2000);
|
||||
|
||||
// despues de intentar unirse: si no ha arrancado ninguna descarga, explicar las
|
||||
// causas habituales (el aviso del dev a veces dice "codigo no valido" cuando lo
|
||||
// que pasa es que no hay red). Solo se mira nuestro estado, no la pagina del dev
|
||||
var tried = 0;
|
||||
try { tried = Number(sessionStorage.getItem('oasisPubJoin')) || 0; sessionStorage.removeItem('oasisPubJoin'); } catch (_) {}
|
||||
if (tried && Date.now() - tried < 3 * 60 * 1000 && bar.hidden) {
|
||||
fetch('/mobile/pub-status', { credentials: 'same-origin', cache: 'no-store' })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (s) {
|
||||
if (s && s.kind !== 'none') { show(s); if (s.running) timer = setTimeout(poll, 2000); return; }
|
||||
show({ kind: 'error', running: false, pct: null, text: bar.getAttribute('data-failed'), hint: '' });
|
||||
})
|
||||
.catch(function () {});
|
||||
}
|
||||
|
||||
// al tocar unirse (Invitaciones, bienvenida, Ajustes, importar pubs): la barra sale ya. El
|
||||
// dev tarda en contestar mientras conecta con el pub y la pantalla se quedaba quieta
|
||||
document.addEventListener('submit', function (e) {
|
||||
var f = e.target;
|
||||
var action = (f && f.getAttribute('action')) || '';
|
||||
var by = e.submitter && e.submitter.value;
|
||||
if (!/^\/(invites\/join|invites\/import-pubs|settings\/invite\/accept|welcome\/community)$/.test(action) || by === 'skip') return;
|
||||
// en la bienvenida, solo si hay algun pub marcado (sin e.submitter en WebView viejos)
|
||||
if (action === '/welcome/community' && !f.querySelector('input[name="pub"]:checked')) return;
|
||||
try { sessionStorage.setItem('oasisPubJoin', String(Date.now())); } catch (_) {}
|
||||
show({ kind: 'joining', running: true, pct: null, text: bar.getAttribute('data-joining'), hint: '' });
|
||||
});
|
||||
|
||||
// cerrar sin cambiar de pagina
|
||||
var close = bar.querySelector('.pub-bar-close');
|
||||
if (close) close.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
fetch(close.getAttribute('action'), { method: 'POST', credentials: 'same-origin' }).catch(function () {});
|
||||
show(null);
|
||||
});
|
||||
})();
|
||||
|
|
@ -1,39 +1,39 @@
|
|||
{
|
||||
"themes": {
|
||||
"current": "Acampada"
|
||||
"current": "Activista"
|
||||
},
|
||||
"ux": {
|
||||
"current": "blocks"
|
||||
},
|
||||
"modules": {
|
||||
"blogsMod": "on",
|
||||
"pollsMod": "off",
|
||||
"fediverseMod": "off",
|
||||
"pollsMod": "on",
|
||||
"fediverseMod": "on",
|
||||
"invitesMod": "on",
|
||||
"walletMod": "off",
|
||||
"devMod": "off",
|
||||
"cipherMod": "off",
|
||||
"bookmarksMod": "off",
|
||||
"cipherMod": "on",
|
||||
"bookmarksMod": "on",
|
||||
"videosMod": "on",
|
||||
"docsMod": "off",
|
||||
"audiosMod": "off",
|
||||
"tagsMod": "off",
|
||||
"docsMod": "on",
|
||||
"audiosMod": "on",
|
||||
"tagsMod": "on",
|
||||
"imagesMod": "on",
|
||||
"trendingMod": "off",
|
||||
"trendingMod": "on",
|
||||
"eventsMod": "on",
|
||||
"tasksMod": "off",
|
||||
"tasksMod": "on",
|
||||
"marketMod": "off",
|
||||
"votesMod": "on",
|
||||
"tribesMod": "on",
|
||||
"reportsMod": "off",
|
||||
"opinionsMod": "off",
|
||||
"reportsMod": "on",
|
||||
"opinionsMod": "on",
|
||||
"padsMod": "on",
|
||||
"calendarsMod": "off",
|
||||
"calendarsMod": "on",
|
||||
"transfersMod": "off",
|
||||
"feedMod": "on",
|
||||
"pixeliaMod": "off",
|
||||
"melodyMod": "off",
|
||||
"agendaMod": "off",
|
||||
"melodyMod": "on",
|
||||
"agendaMod": "on",
|
||||
"aiMod": "off",
|
||||
"aiNavMod": "off",
|
||||
"forumMod": "on",
|
||||
|
|
@ -41,28 +41,28 @@
|
|||
"housingMod": "off",
|
||||
"jobsMod": "off",
|
||||
"shopsMod": "off",
|
||||
"projectsMod": "off",
|
||||
"projectsMod": "on",
|
||||
"industryMod": "off",
|
||||
"bankingMod": "off",
|
||||
"schoolMod": "off",
|
||||
"schoolMod": "on",
|
||||
"parliamentMod": "on",
|
||||
"courtsMod": "off",
|
||||
"favoritesMod": "off",
|
||||
"logsMod": "off",
|
||||
"mapsMod": "off",
|
||||
"courtsMod": "on",
|
||||
"favoritesMod": "on",
|
||||
"logsMod": "on",
|
||||
"mapsMod": "on",
|
||||
"chatsMod": "on",
|
||||
"torrentsMod": "off",
|
||||
"filesMod": "off",
|
||||
"torrentsMod": "on",
|
||||
"filesMod": "on",
|
||||
"phoneMod": "on",
|
||||
"roomsMod": "on",
|
||||
"graphosMod": "off",
|
||||
"larpMod": "off",
|
||||
"graphosMod": "on",
|
||||
"larpMod": "on",
|
||||
"backupMod": "on",
|
||||
"campaignsMod": "off",
|
||||
"emergenciesMod": "off",
|
||||
"logisticsMod": "off",
|
||||
"mailingMod": "off",
|
||||
"podcastsMod": "off",
|
||||
"campaignsMod": "on",
|
||||
"emergenciesMod": "on",
|
||||
"logisticsMod": "on",
|
||||
"mailingMod": "on",
|
||||
"podcastsMod": "on",
|
||||
"wikiMod": "on"
|
||||
},
|
||||
"wallet": {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ const FORK_WORKFLOWS = [
|
|||
// una acampada: hablar (chats, telefono y salas de voz del dev), escribir juntos,
|
||||
// compartir lo que pasa y decidir (tribus = comisiones, parlamento y votaciones)
|
||||
key: 'acampada',
|
||||
theme: 'Acampada',
|
||||
theme: 'Activista',
|
||||
homePage: 'activity',
|
||||
modules: ['chats', 'phone', 'rooms', 'pads', 'forum', 'images', 'videos', 'wiki', 'blogs', 'feed', 'invites', 'backup',
|
||||
'tribes', 'parliament', 'votes', 'events']
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ const WORKFLOWS = [
|
|||
},
|
||||
{
|
||||
key: 'mobile',
|
||||
theme: 'Acampada',
|
||||
theme: 'OasisMobile',
|
||||
homePage: 'activity',
|
||||
modules: MOBILE_MODULES
|
||||
}
|
||||
|
|
@ -91,13 +91,9 @@ const WORKFLOWS = [
|
|||
const WORKFLOW_KEYS = WORKFLOWS.map(w => w.key);
|
||||
|
||||
const isMobile = () => process.env.OASIS_MOBILE === '1';
|
||||
// en el movil el workflow no toca el skin: se queda el que haya elegido cada cual
|
||||
// (Acampada u OasisMobile); si no hay ninguno de movil, Acampada
|
||||
const MOBILE_THEMES = ['Acampada', 'OasisMobile'];
|
||||
const mobileSkin = (cfg) => {
|
||||
const cur = cfg && cfg.themes && cfg.themes.current;
|
||||
return MOBILE_THEMES.includes(cur) ? cur : 'Acampada';
|
||||
};
|
||||
// en el movil el workflow no toca el skin: hay uno solo, Activista
|
||||
const MOBILE_THEMES = ['Activista'];
|
||||
const mobileSkin = () => 'Activista';
|
||||
const themeOf = (workflow, cfg) => (isMobile() ? mobileSkin(cfg) : workflow.theme);
|
||||
const sameTheme = (theme, workflow) => (isMobile() ? MOBILE_THEMES.includes(theme) : theme === workflow.theme);
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,8 @@ exports.backupView = async ({ type = "RECOVERY", options = null, restoreJob = nu
|
|||
div({ class: "div-center backup-wrap" }, body)
|
||||
)
|
||||
);
|
||||
return restoreJob && restoreJob.running ? html.replace('</head>', '<meta http-equiv="refresh" content="5"></head>') : html;
|
||||
// movil: sin recargar cada 5s; la barra del pub (mobile_pubbar.js) se pone al dia sola
|
||||
return restoreJob && restoreJob.running && !require('./mobile_ui').isMobile() ? html.replace('</head>', '<meta http-equiv="refresh" content="5"></head>') : html;
|
||||
};
|
||||
|
||||
exports.renderRestoreStatus = renderRestoreStatus;
|
||||
|
|
|
|||
|
|
@ -132,7 +132,10 @@ module.exports = ({ i18n }) => {
|
|||
renderHiveNav()
|
||||
),
|
||||
// atras cierra la hoja (sin este script el menu funciona igual)
|
||||
script({ src: '/js/mobile_menu.js', defer: 'defer' })
|
||||
script({ src: '/js/mobile_menu.js', defer: 'defer' }),
|
||||
// unirse a un pub: barra fija encima de esta, al dia sin recargar (mobile_pubbar.js)
|
||||
require('./mobile_pubbar').pubBar(),
|
||||
script({ src: '/js/mobile_pub.js', defer: 'defer' })
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -441,17 +441,18 @@ exports.CONTENT_FAV_KIND = CONTENT_FAV_KIND;
|
|||
exports.CONTENT_SPREADABLE = CONTENT_SPREADABLE;
|
||||
exports.CONTENT_TORRENTABLE = CONTENT_TORRENTABLE;
|
||||
exports.contentDeleteAction = contentDeleteAction;
|
||||
exports.THEMES = [['Acampada', 'Acampada'], ['Dark-SNH', 'Dark-SNH'], ['Clear-SNH', 'Clear-SNH'], ['Purple-SNH', 'Purple-SNH'], ['Matrix-SNH', 'Matrix-SNH'], ['OasisMobile', 'Oasis-Mobile']];
|
||||
// los dos skins de movil; los de escritorio no estan pensados para la maqueta del movil
|
||||
exports.MOBILE_THEMES = [['Acampada', 'Acampada'], ['OasisMobile', 'Oasis Mobile']];
|
||||
exports.THEMES = [['Activista', 'Activista'], ['Dark-SNH', 'Dark-SNH'], ['Clear-SNH', 'Clear-SNH'], ['Purple-SNH', 'Purple-SNH'], ['Matrix-SNH', 'Matrix-SNH'], ['OasisMobile', 'Oasis-Mobile']];
|
||||
// el skin del movil (uno solo desde el 20/10/2026); los de escritorio no estan pensados
|
||||
// para la maqueta del movil
|
||||
exports.MOBILE_THEMES = [['Activista', 'Activista']];
|
||||
exports.WIZARD_THEMES = process.env.OASIS_MOBILE === '1'
|
||||
? exports.MOBILE_THEMES
|
||||
: exports.THEMES.filter(([value]) => value !== 'OasisMobile' && value !== 'Acampada');
|
||||
// en el movil la maqueta de la rama (styles/mobile_base.css) va antes de cualquier skin;
|
||||
// encima, Acampada.css o el OasisMobile.css del dev. hive_acampada.css va detras del
|
||||
// tema Acampada: pinta lanzador, barras y tarjetas.
|
||||
const acampadaBase = () => process.env.OASIS_MOBILE === '1' ? link({ rel: "stylesheet", href: `/assets/styles/mobile_base.css?v=${assetVersion()}` }) : null;
|
||||
const acampadaLink = (theme) => theme === 'Acampada' ? link({ rel: "stylesheet", href: `/assets/styles/hive_acampada.css?v=${assetVersion()}` }) : null;
|
||||
: exports.THEMES.filter(([value]) => value !== 'OasisMobile' && value !== 'Activista');
|
||||
// en el movil la maqueta de la rama (styles/mobile_base.css) va antes del skin;
|
||||
// encima, themes/Activista.css y detras styles/activista.css, que pinta lanzador,
|
||||
// barras y tarjetas.
|
||||
const mobileBase = () => process.env.OASIS_MOBILE === '1' ? link({ rel: "stylesheet", href: `/assets/styles/mobile_base.css?v=${assetVersion()}` }) : null;
|
||||
const skinLink = (theme) => theme === 'Activista' ? link({ rel: "stylesheet", href: `/assets/styles/activista.css?v=${assetVersion()}` }) : null;
|
||||
|
||||
const renderDocumentActions = (kind, id, leadingNodes = []) => {
|
||||
const base = id ? `/${kind}/${encodeURIComponent(id)}` : `/${kind}`;
|
||||
|
|
@ -2007,7 +2008,7 @@ const template = (titlePrefix, ...elements) => {
|
|||
// movil: el tema va DESPUES de mobile.css para ganar por cascada sin !important;
|
||||
// escritorio: orden original de epsylon
|
||||
...(process.env.OASIS_MOBILE === '1'
|
||||
? [ link({ rel: "stylesheet", href: `/assets/styles/mobile.css?v=${assetVersion()}` }), acampadaBase(theme), themeLink, acampadaLink(theme) ]
|
||||
? [ link({ rel: "stylesheet", href: `/assets/styles/mobile.css?v=${assetVersion()}` }), mobileBase(theme), themeLink, skinLink(theme) ]
|
||||
: [ themeLink, link({ rel: "stylesheet", href: `/assets/styles/mobile.css?v=${assetVersion()}`, media: "(max-width: 768px)" }) ]),
|
||||
process.env.OASIS_MOBILE === '1' ? link({ rel: "stylesheet", href: `/assets/styles/mobile_ux.css?v=${assetVersion()}` }) : null,
|
||||
process.env.OASIS_MOBILE === '1' ? require('./mobile_ui').colorsLink() : null,
|
||||
|
|
@ -2396,7 +2397,7 @@ exports.ainavHomeView = ({ recentTags = [] } = {}) => {
|
|||
// movil: el tema va DESPUES de mobile.css para ganar por cascada sin !important;
|
||||
// escritorio: orden original de epsylon
|
||||
...(process.env.OASIS_MOBILE === '1'
|
||||
? [ link({ rel: "stylesheet", href: `/assets/styles/mobile.css?v=${assetVersion()}` }), acampadaBase(theme), link({ rel: "stylesheet", href: `/assets/themes/${theme}.css?v=${assetVersion()}` }), acampadaLink(theme) ]
|
||||
? [ link({ rel: "stylesheet", href: `/assets/styles/mobile.css?v=${assetVersion()}` }), mobileBase(theme), link({ rel: "stylesheet", href: `/assets/themes/${theme}.css?v=${assetVersion()}` }), skinLink(theme) ]
|
||||
: [ link({ rel: "stylesheet", href: `/assets/themes/${theme}.css?v=${assetVersion()}` }), link({ rel: "stylesheet", href: `/assets/styles/mobile.css?v=${assetVersion()}`, media: "(max-width: 768px)" }) ]),
|
||||
process.env.OASIS_MOBILE === '1' ? link({ rel: "stylesheet", href: `/assets/styles/mobile_ux.css?v=${assetVersion()}` }) : null,
|
||||
process.env.OASIS_MOBILE === '1' ? require('./mobile_ui').colorsLink() : null,
|
||||
|
|
|
|||
120
src/views/mobile_pubbar.js
Normal file
120
src/views/mobile_pubbar.js
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
"use strict";
|
||||
// Barra de "uniendote a un pub" (rama movil).
|
||||
//
|
||||
// Al unirse a un pub, el dev acepta la invitacion y arranca una descarga de la red
|
||||
// desde el pub (backupModel.startBootstrap: bajar la copia y guardarla en el movil).
|
||||
// Su pantalla de bienvenida lo enseñaba recargandose entera cada 5 segundos y, si
|
||||
// fallaba, solo decia el error en ingles. Aqui va una barra fija encima de la barra
|
||||
// de abajo, en todas las pantallas, que dice en claro que esta pasando y por que
|
||||
// falla. La pinta hive_views.js (la barra de abajo es nuestra) y la mantiene al dia
|
||||
// public/js/mobile_pub.js preguntando a /mobile/pub-status, sin recargar.
|
||||
//
|
||||
// El estado lo lee de backupModel.restoreStatus(), que le pasa fork_routes.js al
|
||||
// montarse (es una funcion del dev; no se cambia nada suyo).
|
||||
|
||||
const { button, div, form, p, progress, span } = require("../server/node_modules/hyperaxe");
|
||||
|
||||
const t = () => require("./main_views").i18n;
|
||||
|
||||
let source = null;
|
||||
const setSource = (backupModel) => { source = backupModel; };
|
||||
|
||||
// lo terminado se enseña un rato y se puede cerrar
|
||||
const SHOW_DONE_MS = 15 * 60 * 1000;
|
||||
let dismissedAt = null;
|
||||
const dismiss = () => { const j = source && source.restoreStatus(); dismissedAt = j && j.finishedAt; };
|
||||
|
||||
// "net:pub.example.org:8008~shs:..." -> "pub.example.org"
|
||||
const hostOf = (address) => {
|
||||
const m = String(address || "").match(/^[a-z]+:([^:~]+)(?::\d+)?/i);
|
||||
return m ? m[1] : String(address || "").slice(0, 40);
|
||||
};
|
||||
|
||||
const errorKind = (err) => {
|
||||
const e = String(err || "");
|
||||
if (/snapshot not available/i.test(e)) return "nosnap";
|
||||
if (/ECONNREFUSED|ETIMEDOUT|ENOTFOUND|EHOSTUNREACH|ENETUNREACH|EAI_AGAIN|timed? ?out|socket|connect/i.test(e)) return "net";
|
||||
return "other";
|
||||
};
|
||||
|
||||
const fill = (s, vars) => String(s || "").replace(/\{(\w+)\}/g, (_, k) => (vars[k] != null ? String(vars[k]) : ""));
|
||||
const num = (n) => Number(n || 0).toLocaleString("es-ES");
|
||||
|
||||
// el estado, ya en palabras: { kind, text, hint, pct, running }
|
||||
const status = () => {
|
||||
const job = source && typeof source.restoreStatus === "function" ? source.restoreStatus() : null;
|
||||
if (!job) return null;
|
||||
const i18n = t();
|
||||
if (job.source !== "snapshot") return backupStatus(job, i18n);
|
||||
const pub = hostOf(job.address);
|
||||
const pr = job.progress || {};
|
||||
if (job.running) {
|
||||
const pct = Math.max(0, Math.min(100, Number(pr.percent) || 0));
|
||||
if (job.phase === "restore") {
|
||||
return { kind: "restore", running: true, pct,
|
||||
text: fill(i18n.pubBarRestore || "Saving to your phone: {pct}% · {n} messages", { pct: Math.round(pct), n: num(pr.messages) }),
|
||||
hint: i18n.pubBarHint || "You can keep using the app meanwhile." };
|
||||
}
|
||||
const tier = job.tier === "full" ? (i18n.pubBarTierFull || "everything before") : (i18n.pubBarTierRecent || "the latest");
|
||||
return { kind: "download", running: true, pct: null,
|
||||
text: fill(i18n.pubBarDownload || "Downloading the network from {pub} ({tier})…", { pub, tier }),
|
||||
hint: i18n.pubBarHint || "You can keep using the app meanwhile." };
|
||||
}
|
||||
if (job.finishedAt && job.finishedAt === dismissedAt) return null;
|
||||
if (job.finishedAt && Date.now() - Date.parse(job.finishedAt) > SHOW_DONE_MS) return null;
|
||||
if (job.error) {
|
||||
const k = errorKind(job.error);
|
||||
const key = { nosnap: "pubBarErrNoSnap", net: "pubBarErrNet", other: "pubBarErrOther" }[k];
|
||||
const fallback = {
|
||||
nosnap: "You joined {pub}, but it offers no copy to download at once. Posts will arrive little by little while the app is open.",
|
||||
net: "Cannot reach {pub}. Check that you have Internet (wifi or data) and try again later; if it keeps failing, the pub may be down.",
|
||||
other: "The download from {pub} stopped ({error}). You are in; the rest will arrive little by little."
|
||||
}[k];
|
||||
return { kind: k === "nosnap" ? "warn" : "error", running: false, pct: null,
|
||||
text: fill(i18n[key] || fallback, { pub, error: String(job.error).slice(0, 80) }), hint: "" };
|
||||
}
|
||||
const r = job.result || {};
|
||||
return { kind: "done", running: false, pct: 100,
|
||||
text: fill(i18n.pubBarDone || "You are in {pub}: {n} messages downloaded.", { pub, n: num(r.messages) }), hint: "" };
|
||||
};
|
||||
|
||||
// restaurar una copia desde archivo (pantalla de Copias): la misma barra
|
||||
const backupStatus = (job, i18n) => {
|
||||
const pr = job.progress || {};
|
||||
if (job.running) {
|
||||
const pct = Math.max(0, Math.min(100, Number(pr.percent) || 0));
|
||||
return { kind: "restore", running: true, pct,
|
||||
text: fill(i18n.pubBarBackupRestore || "Restoring your backup: {pct}% · {n} messages", { pct: Math.round(pct), n: num(pr.messages) }),
|
||||
hint: i18n.pubBarHint || "You can keep using the app meanwhile." };
|
||||
}
|
||||
if (job.finishedAt && job.finishedAt === dismissedAt) return null;
|
||||
if (job.finishedAt && Date.now() - Date.parse(job.finishedAt) > SHOW_DONE_MS) return null;
|
||||
if (job.error) return { kind: "error", running: false, pct: null, hint: "",
|
||||
text: fill(i18n.pubBarBackupErr || "The backup could not be restored: {error}. Check the file and the password.", { error: String(job.error).slice(0, 80) }) };
|
||||
return { kind: "done", running: false, pct: 100, hint: "",
|
||||
text: fill(i18n.pubBarBackupDone || "Backup restored: {n} messages.", { n: num((job.result || {}).messages) }) };
|
||||
};
|
||||
|
||||
// la barra; siempre se pinta (oculta si no hay nada) para que el script la enseñe
|
||||
// al tocar "unirse", antes de que conteste el dev
|
||||
const pubBar = () => {
|
||||
const i18n = t();
|
||||
const s = status();
|
||||
return div({
|
||||
id: "pub-bar", class: `pub-bar${s ? ` is-${s.kind}` : ""}`, role: "status", "aria-live": "polite",
|
||||
"data-running": s && s.running ? "1" : "0",
|
||||
"data-joining": i18n.pubBarJoining || "Joining the pub… it can take up to a minute. Keep the app open.",
|
||||
"data-failed": i18n.pubBarJoinFailed || "If you did not get into the pub, the usual reasons are: no connection (wifi or data), the pub is down, or the invite was already used. Try another pub from the list, or later.",
|
||||
...(s ? {} : { hidden: true })
|
||||
},
|
||||
div({ class: "pub-bar-body" },
|
||||
p({ class: "pub-bar-text" }, s ? s.text : ""),
|
||||
p({ class: "pub-bar-hint" }, s ? s.hint : ""),
|
||||
progress({ class: "pub-bar-meter", max: "100", ...(s && s.pct != null ? { value: String(s.pct) } : {}) })
|
||||
),
|
||||
form({ method: "POST", action: "/mobile/pub-status/dismiss", class: "pub-bar-close" },
|
||||
button({ type: "submit", "aria-label": i18n.pubBarClose || "Close" }, "✕"))
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = { setSource, status, dismiss, pubBar, errorKind, hostOf };
|
||||
|
|
@ -10,8 +10,8 @@
|
|||
// /feed/create): no se reenvia nada a sus rutas ni se toca lo que contestan. Colores
|
||||
// es propio: /settings/colors y la hoja /mobile-colors.css, que va la ultima.
|
||||
//
|
||||
// Los colores son las variables --a26-* del tema Acampada; por eso al elegir colores
|
||||
// el aspecto pasa a Acampada (OasisMobile.css es del dev y lleva los suyos fijos).
|
||||
// Los colores son las variables --a26-* del skin Activista, el unico del movil: el
|
||||
// skin quita lo que sobra y los colores lo dejan a gusto de cada cual.
|
||||
|
||||
const crypto = require("crypto");
|
||||
const { a, button, details, div, form, img, input, label, p, section, span, summary, h2 } = require("../server/node_modules/hyperaxe");
|
||||
|
|
@ -22,7 +22,7 @@ const cfgNow = () => { try { return require("../configs/config-manager.js").getC
|
|||
|
||||
// ---------- colores ----------
|
||||
|
||||
// [clave, fondo, texto, acento]; la primera es la de Acampada tal cual
|
||||
// [clave, fondo, texto, acento]; la primera es la de serie
|
||||
const PALETTES = [
|
||||
["acampada", "#ffffff", "#000000", "#00e5ff"],
|
||||
["noche", "#101114", "#f2f2f2", "#00e5ff"],
|
||||
|
|
@ -47,7 +47,7 @@ const contrast = (x, y) => { const p = lum(x), q = lum(y); return (Math.max(p, q
|
|||
// negro o blanco, el que mas se lea encima
|
||||
const readableOn = (hex) => contrast(hex, "#000000") >= contrast(hex, "#ffffff") ? "#000000" : "#ffffff";
|
||||
|
||||
// lo guardado, ya comprobado; sin nada guardado, Acampada
|
||||
// lo guardado, ya comprobado; sin nada guardado, la de serie
|
||||
const colorState = (cfg) => {
|
||||
const c = (cfg || cfgNow()).mobileColors;
|
||||
if (!c || typeof c !== "object" || ![c.bg, c.fg, c.accent].every(v => HEX.test(String(v || "")))) {
|
||||
|
|
@ -79,15 +79,16 @@ const PREVIEW_CSS = PALETTES.map(([k, bg, fg, ac]) =>
|
|||
// muestras de las paletas (la CSP no deja estilos en linea)
|
||||
const colorsCss = (cfg) => {
|
||||
const c = colorState(cfg);
|
||||
// solo con Acampada: OasisMobile.css es del dev y lleva su paleta fija
|
||||
const onAcampada = ((cfg || cfgNow()).themes || {}).current === "Acampada";
|
||||
const vars = c.chosen && onAcampada ? [
|
||||
const vars = c.chosen ? [
|
||||
`--a26-bg:${c.bg}`, `--a26-fg:${c.fg}`, `--a26-neon:${c.accent}`,
|
||||
`--a26-on-neon:${readableOn(c.accent)}`,
|
||||
`--a26-soft:${mix(c.bg, c.fg, 0.06)}`,
|
||||
`--a26-muted:${mix(c.fg, c.bg, 0.35)}`,
|
||||
`--a26-tint:${mix(c.bg, c.accent, 0.2)}`,
|
||||
`--a26-line:${mix(c.bg, c.fg, 0.25)}`,
|
||||
`--a26-line:${mix(c.bg, c.fg, 0.18)}`,
|
||||
`--a26-edge:${mix(c.bg, c.fg, 0.5)}`,
|
||||
// rojo de texto (borrar): el de serie si se lee sobre el fondo; si no, uno claro
|
||||
`--a26-danger-text:${contrast(c.bg, "#c4003b") >= 4.5 ? "#c4003b" : "#ff6b86"}`,
|
||||
`color-scheme:${lum(c.bg) < 0.2 ? "dark" : "light"}`
|
||||
] : [];
|
||||
const custom = `.pal-custom .pal-bg{background:${c.bg}!important}.pal-custom .pal-fg{background:${c.fg}!important}.pal-custom .pal-ac{background:${c.accent}!important}`;
|
||||
|
|
@ -104,12 +105,10 @@ const colorsPick = (returnTo, withKeep) => {
|
|||
const i18n = t();
|
||||
const c = colorState();
|
||||
const cur = c.chosen ? c.preset : DEFAULT[0];
|
||||
const theme = (cfgNow().themes || {}).current;
|
||||
return div({ class: "color-pick" },
|
||||
form({ method: "POST", action: "/settings/colors", class: "ux-pick" },
|
||||
input({ type: "hidden", name: "returnTo", value: returnTo }),
|
||||
p({ class: "ux-pick-hint" }, i18n.colorsHint || "Tap a palette and it is applied."),
|
||||
theme && theme !== "Acampada" ? p({ class: "form-hint" }, i18n.colorsSkinNote || "Colours go with the Acampada look; choosing one switches to it.") : null,
|
||||
div({ class: "pal-grid" },
|
||||
...PALETTES.map(([k]) => button(Object.assign({ type: "submit", name: "preset", value: k, class: k === cur ? "pal-card is-current" : "pal-card" }, k === cur ? { "aria-current": "true" } : {}),
|
||||
swatch(k),
|
||||
|
|
@ -220,7 +219,7 @@ const greetingSection = () => {
|
|||
|
||||
// recibe las secciones de settings_view (pestaña Oasis) y devuelve la lista del movil:
|
||||
// la rejilla arriba, los bloques nuevos metidos en su sitio y el orden de los accesos
|
||||
const ORDER = ["quick", "update", "language", "identity", "workflows", "ux", "colors", "theme", "community", "greeting", "home-page"];
|
||||
const ORDER = ["quick", "update", "language", "identity", "workflows", "ux", "colors", "community", "greeting", "home-page"];
|
||||
const withQuick = (parts) => {
|
||||
const cfg = cfgNow();
|
||||
const mods = cfg.modules || {};
|
||||
|
|
@ -230,7 +229,8 @@ const withQuick = (parts) => {
|
|||
mods.invitesMod !== "off" ? communitySection() : null,
|
||||
mods.feedMod !== "off" ? greetingSection() : null
|
||||
].filter(Boolean);
|
||||
const list = parts.filter(Boolean).concat(extra);
|
||||
// el selector de skin no va: en el movil hay uno solo (Activista)
|
||||
const list = parts.filter(el => el && el.id !== "theme").concat(extra);
|
||||
const ids = list.map(el => el && el.id);
|
||||
list.push(quickGrid(cfg, ids));
|
||||
const rank = (el) => { const i = ORDER.indexOf(el && el.id); return i === -1 ? ORDER.length : i; };
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ const uxPick = (action, cfg, withHint) => {
|
|||
};
|
||||
|
||||
// perfil de uso (workflow): igual, un boton por opcion con una linea de para que
|
||||
// sirve. Activismo y Acampada primero; el resto en el orden del dev
|
||||
// sirve. Activismo (el de serie) y Acampada primero; el resto en el orden del dev
|
||||
const WORKFLOW_FIRST = ['activists', 'acampada'];
|
||||
const workflowPick = (action, current, keys, withHint) => {
|
||||
const i18n = t();
|
||||
|
|
|
|||
|
|
@ -149,5 +149,6 @@ exports.welcomeView = async (status, profile = {}) => {
|
|||
button({ type: "submit", class: "welcome-skip-btn" }, i18n.welcomeSkip)))
|
||||
: null
|
||||
)
|
||||
return status.bootstrap && status.bootstrap.running ? html.replace('</head>', '<meta http-equiv="refresh" content="5"></head>') : html
|
||||
// movil: sin recargar cada 5s; la barra del pub (mobile_pubbar.js) se pone al dia sola
|
||||
return status.bootstrap && status.bootstrap.running && !mobileUi.isMobile() ? html.replace('</head>', '<meta http-equiv="refresh" content="5"></head>') : html
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue