- Nuevo modelo skeen.ticket.config (AbstractModel) con layout, datos de clinica y logo en ir.config_parameter; _mezclar() hace que layouts viejos hereden las secciones nuevas; _validar() rechaza valores imposibles y textos largos. - Endpoints GET/PUT /ticket_config, PUT /ticket_config/clinica, POST /ticket_config/reset (reset solo admin) con auditoria en skeen_config_audit. - Los datos de la clinica pasan de localStorage (cada caja imprimia distinto) a configuracion compartida en el servidor. - TicketDoc.tsx renderiza segun el diseno: ancho 58/80mm, fuente, tamano de letra, separador, mayusculas, orden de bloques y 29 secciones activables. - TicketDesigner.tsx: editor completo con vista previa en vivo, reorden de bloques, textos personalizables y carga de logo. - TicketPrint.tsx ahora es un wrapper de TicketDoc; ReciboPrint, EstadoCuentaPrint, RecetaPrint, CortePrint y ConteoPrint usan useClinicaPrint(). - _sale_to_dict expone telefono del paciente, medico que atendio y datos de paquete; pos_checkout devuelve recibido/cambio en MXN y USD para imprimirlos.
325 lines
8.7 KiB
CSS
325 lines
8.7 KiB
CSS
@import "tailwindcss";
|
||
@config "../tailwind.config.js";
|
||
@import "./styles/fonts.css";
|
||
|
||
/* =========================================================
|
||
Tema SKEEN Derma Experts (default)
|
||
========================================================= */
|
||
:root,
|
||
[data-theme="skeen"] {
|
||
/* Paleta */
|
||
--color-coral: #EDA588;
|
||
--color-coral-hover: #d98b6c;
|
||
--color-mint: #CAE2C1;
|
||
--color-lilac: #C7BCDD;
|
||
--color-sky: #A4CCE2;
|
||
--color-dark: #1A1A1A;
|
||
--color-charcoal: #2D2D2D;
|
||
--color-gray: #6B6B6B;
|
||
--color-light: #F8F6F4;
|
||
--color-white: #FFFFFF;
|
||
|
||
/* Semántico */
|
||
--text: var(--color-charcoal);
|
||
--text-muted: var(--color-gray);
|
||
--text-heading: var(--color-dark);
|
||
--text-inverse: var(--color-white);
|
||
--bg: var(--color-light);
|
||
--surface: var(--color-white);
|
||
--surface-elevated: var(--color-white);
|
||
--border: rgba(26, 26, 26, 0.08);
|
||
--border-strong: #E5E0DC;
|
||
--accent: var(--color-coral);
|
||
--accent-hover: var(--color-coral-hover);
|
||
--accent-bg: rgba(237, 165, 136, 0.12);
|
||
--success: var(--color-mint);
|
||
--success-text: var(--color-dark);
|
||
--warning: #FEF3C7;
|
||
--warning-text: #92400E;
|
||
|
||
--font-sans: 'Sans Essential', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
--font-display: 'Carefree Serif', Georgia, serif;
|
||
--font-heading: 'TT Hoves Pro', 'Sans Essential', system-ui, sans-serif;
|
||
--font-mono: 'JetBrains Mono', monospace;
|
||
|
||
--sidebar-bg: var(--color-dark);
|
||
--sidebar-text: rgba(255, 255, 255, 0.7);
|
||
--sidebar-text-active: var(--color-white);
|
||
--sidebar-active-bg: var(--color-coral);
|
||
--header-bg: rgba(255, 255, 255, 0.8);
|
||
--logo: '/skeen-brand/logos/Logo%20Completo%20Blanco.png';
|
||
}
|
||
|
||
/* =========================================================
|
||
Tema HomeNest
|
||
========================================================= */
|
||
[data-theme="homenest"] {
|
||
/* Paleta */
|
||
--color-coral: #8B5E3C;
|
||
--color-coral-hover: #6F4B30;
|
||
--color-mint: #D9F99D;
|
||
--color-lilac: #F3E2B3;
|
||
--color-sky: #E9D5B7;
|
||
--color-dark: #3E2C1C;
|
||
--color-charcoal: #5C4634;
|
||
--color-gray: #7A5C44;
|
||
--color-light: #FEF3C7;
|
||
--color-white: #FFF9E6;
|
||
|
||
/* Semántico */
|
||
--text: var(--color-dark);
|
||
--text-muted: var(--color-gray);
|
||
--text-heading: var(--color-dark);
|
||
--text-inverse: var(--color-light);
|
||
--bg: var(--color-light);
|
||
--surface: var(--color-white);
|
||
--surface-elevated: var(--color-white);
|
||
--border: var(--color-sky);
|
||
--border-strong: var(--color-sky);
|
||
--accent: var(--color-coral);
|
||
--accent-hover: var(--color-coral-hover);
|
||
--accent-bg: var(--color-lilac);
|
||
--success: var(--color-mint);
|
||
--success-text: var(--color-dark);
|
||
--warning: #FEF3C7;
|
||
--warning-text: var(--color-dark);
|
||
|
||
--font-sans: 'DM Sans', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
--font-display: 'Alike', Georgia, serif;
|
||
--font-heading: 'Alike', Georgia, serif;
|
||
--font-mono: 'JetBrains Mono', monospace;
|
||
|
||
--sidebar-bg: var(--color-white);
|
||
--sidebar-text: var(--color-gray);
|
||
--sidebar-text-active: var(--color-dark);
|
||
--sidebar-active-bg: var(--color-coral);
|
||
--header-bg: rgba(255, 249, 230, 0.8);
|
||
--logo: '/skeen-brand/logos/Logo%20Completo%20Negro.png';
|
||
}
|
||
|
||
/* =========================================================
|
||
Tema Clásico (legacy AdminLTE 2.x)
|
||
========================================================= */
|
||
[data-theme="clasico"] {
|
||
/* Paleta */
|
||
--color-coral: #1abc9c;
|
||
--color-coral-hover: #16a085;
|
||
--color-mint: #2ecc71;
|
||
--color-lilac: #d9edf7;
|
||
--color-sky: #3498db;
|
||
--color-dark: #333333;
|
||
--color-charcoal: #444444;
|
||
--color-gray: #777777;
|
||
--color-light: #ecf0f5;
|
||
--color-white: #FFFFFF;
|
||
|
||
/* Semántico */
|
||
--text: var(--color-charcoal);
|
||
--text-muted: var(--color-gray);
|
||
--text-heading: var(--color-dark);
|
||
--text-inverse: var(--color-white);
|
||
--bg: var(--color-light);
|
||
--surface: var(--color-white);
|
||
--surface-elevated: var(--color-white);
|
||
--border: #d2d6de;
|
||
--border-strong: #dddddd;
|
||
--accent: var(--color-coral);
|
||
--accent-hover: var(--color-coral-hover);
|
||
--accent-bg: rgba(26, 188, 156, 0.12);
|
||
--success: #2ecc71;
|
||
--success-text: var(--color-white);
|
||
--warning: #f39c12;
|
||
--warning-text: var(--color-white);
|
||
|
||
--font-sans: 'Source Sans Pro', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
--font-display: 'Source Sans Pro', Georgia, serif;
|
||
--font-heading: 'Source Sans Pro', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
--font-mono: 'JetBrains Mono', monospace;
|
||
|
||
--sidebar-bg: #3E454C;
|
||
--sidebar-text: #dbdee1;
|
||
--sidebar-text-active: var(--color-white);
|
||
--sidebar-active-bg: #394046;
|
||
--sidebar-accent: #BED4AD;
|
||
--sidebar-group-bg: #353b41;
|
||
--sidebar-group-text: #6c7884;
|
||
--header-bg: #BED4AD;
|
||
--logo-block: #b1cb9c;
|
||
--logo: '/skeen-brand/logos/Logo%20Completo%20Blanco.png';
|
||
}
|
||
|
||
/* AdminLTE: esquinas casi cuadradas y sombras mínimas */
|
||
[data-theme="clasico"] .rounded-3xl,
|
||
[data-theme="clasico"] .rounded-2xl,
|
||
[data-theme="clasico"] .rounded-xl {
|
||
border-radius: 3px;
|
||
}
|
||
|
||
[data-theme="clasico"] .rounded-lg {
|
||
border-radius: 2px;
|
||
}
|
||
|
||
[data-theme="clasico"] .shadow-card {
|
||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
|
||
}
|
||
|
||
[data-theme="clasico"] .shadow-soft,
|
||
[data-theme="clasico"] .shadow-sm {
|
||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
/* =========================================================
|
||
Base
|
||
========================================================= */
|
||
html {
|
||
font-family: var(--font-sans);
|
||
font-size: 16px;
|
||
line-height: 1.5;
|
||
color: var(--text);
|
||
background: var(--bg);
|
||
font-synthesis: none;
|
||
text-rendering: optimizeLegibility;
|
||
-webkit-font-smoothing: antialiased;
|
||
-moz-osx-font-smoothing: grayscale;
|
||
}
|
||
|
||
#root {
|
||
width: 100%;
|
||
max-width: 100%;
|
||
margin: 0;
|
||
text-align: left;
|
||
border: none;
|
||
min-height: 100svh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
margin: 0;
|
||
font-family: var(--font-sans);
|
||
color: var(--text);
|
||
background: var(--bg);
|
||
}
|
||
|
||
h1, h2, h3, h4, h5, h6 {
|
||
font-family: var(--font-heading);
|
||
font-weight: 700;
|
||
color: var(--text-heading);
|
||
letter-spacing: -0.02em;
|
||
margin: 0;
|
||
}
|
||
|
||
[data-theme="homenest"] h1,
|
||
[data-theme="homenest"] h2,
|
||
[data-theme="homenest"] h3,
|
||
[data-theme="homenest"] h4,
|
||
[data-theme="homenest"] h5,
|
||
[data-theme="homenest"] h6 {
|
||
font-weight: 400;
|
||
letter-spacing: -0.01em;
|
||
}
|
||
|
||
.font-display {
|
||
font-family: var(--font-display);
|
||
}
|
||
|
||
.font-mono {
|
||
font-family: var(--font-mono);
|
||
}
|
||
|
||
p {
|
||
margin: 0;
|
||
}
|
||
|
||
/* Scrollbar */
|
||
::-webkit-scrollbar {
|
||
width: 8px;
|
||
height: 8px;
|
||
}
|
||
::-webkit-scrollbar-track {
|
||
background: transparent;
|
||
}
|
||
::-webkit-scrollbar-thumb {
|
||
background: var(--color-coral);
|
||
opacity: 0.25;
|
||
border-radius: 4px;
|
||
}
|
||
::-webkit-scrollbar-thumb:hover {
|
||
opacity: 0.4;
|
||
}
|
||
|
||
/* Impresión del ticket POS y de la receta médica */
|
||
@media print {
|
||
body * {
|
||
visibility: hidden;
|
||
}
|
||
.print-ticket,
|
||
.print-ticket *,
|
||
.print-receta,
|
||
.print-receta *,
|
||
.print-agenda,
|
||
.print-agenda *,
|
||
.print-recibo,
|
||
.print-recibo * {
|
||
visibility: visible;
|
||
}
|
||
.print-ticket,
|
||
.print-receta,
|
||
.print-agenda,
|
||
.print-recibo {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
}
|
||
/* Ticket térmico: el ancho, la fuente y el tamaño los decide el diseño
|
||
guardado en Configuración › Tickets, que viajan como style en línea del
|
||
documento. Aquí solo se quitan adornos para el papel. */
|
||
.print-ticket {
|
||
width: auto;
|
||
border: none;
|
||
border-radius: 0;
|
||
padding: 0;
|
||
}
|
||
/* La agenda es un documento de varias páginas: mientras está abierta, el
|
||
modal deja de ser un overlay fijo (los elementos `fixed` se repiten en
|
||
cada página impresa y anclan el contenido a su caja centrada) y se libera
|
||
el ancho/alto del diálogo para que el documento fluya desde el inicio. */
|
||
body:has(.print-agenda, .print-recibo) .print-modal-overlay {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: auto;
|
||
bottom: auto;
|
||
display: block;
|
||
width: 100%;
|
||
padding: 0;
|
||
}
|
||
body:has(.print-agenda, .print-recibo) .print-modal-content {
|
||
max-width: none;
|
||
max-height: none;
|
||
border-radius: 0;
|
||
box-shadow: none;
|
||
}
|
||
body:has(.print-agenda, .print-recibo) .print-modal-body {
|
||
overflow: visible;
|
||
padding: 0;
|
||
}
|
||
body:has(.print-agenda, .print-recibo) .print-modal-header,
|
||
body:has(.print-agenda, .print-recibo) .print-modal-footer {
|
||
display: none;
|
||
}
|
||
/* El resto de la app queda oculto (visibility) pero seguiría ocupando su
|
||
altura y generaría páginas en blanco al final: se colapsa su caja. El
|
||
overlay no se recorta porque su bloque contenedor es la página. */
|
||
body:has(.print-agenda, .print-recibo) > #root {
|
||
height: 0 !important;
|
||
overflow: hidden !important;
|
||
}
|
||
.print-agenda,
|
||
.print-recibo {
|
||
position: static;
|
||
}
|
||
}
|