/* =====================================================================
   DESIGN SYSTEM DEL BACKOFFICE — portado 1:1 de Utilidades/diseno-backoffice-v2
   Los tokens mapean directamente al MudTheme (Shared/Theme/EcommerceTheme.cs).
   ===================================================================== */
:root {
  --palette-primary: #ec3013;
  --palette-secondary: #201e1d;
  --palette-tertiary: #6b6764;
  --palette-success: #1f7a33;
  --palette-info: #1a6fa8;
  --palette-warning: #b57400;
  --palette-error: #b3261e;
  --palette-background: #f3f2f2;
  --palette-surface: #ffffff;
  --palette-appbar: #ffffff;
  --palette-drawer: #ffffff;
  --palette-text-primary: #201e1d;
  --palette-text-secondary: #6b6764;
  --palette-text-disabled: #a3a09d;
  --palette-divider: #dcd9d6;
  --palette-action-default: #201e1d;
  --palette-action-disabled: #a3a09d;
  /* derivados (tintes de los anteriores, no colores nuevos) */
  --tint-primary: rgba(236, 48, 19, 0.08);
  --tint-hover: rgba(32, 30, 29, 0.05);
  --tint-success: rgba(31, 122, 51, 0.12);
  --tint-warning: rgba(181, 116, 0, 0.12);
  --tint-error: rgba(179, 38, 30, 0.10);
  --tint-info: rgba(26, 111, 168, 0.12);
  --radius: 0px; --radius-sm: 0px; --radius-lg: 0px;
  /* Alto del editor con indice, y de su indice al lado. */
  --mdedit-h: clamp(280px, calc(100dvh - 320px), 820px);
  --elevation-0: none;
  --elevation-1: 0 1px 2px rgba(32, 30, 29, 0.10);
  --elevation-2: 0 8px 32px rgba(32, 30, 29, 0.22);
}
[data-theme="dark"] {
  --palette-primary: #ff5a3c;
  --palette-secondary: #f3f2f2;
  --palette-tertiary: #b0aca9;
  --palette-success: #57b374;
  --palette-info: #5aa9dd;
  --palette-warning: #e0a63f;
  --palette-error: #e57373;
  --palette-background: #161514;
  --palette-surface: #201e1d;
  --palette-appbar: #201e1d;
  --palette-drawer: #1b1a19;
  --palette-text-primary: #f3f2f2;
  --palette-text-secondary: #b0aca9;
  --palette-text-disabled: #6b6764;
  --palette-divider: #3a3735;
  --palette-action-default: #f3f2f2;
  --palette-action-disabled: #6b6764;
  --tint-primary: rgba(255, 90, 60, 0.14);
  --tint-hover: rgba(243, 242, 242, 0.06);
  --tint-success: rgba(87, 179, 116, 0.16);
  --tint-warning: rgba(224, 166, 63, 0.16);
  --tint-error: rgba(229, 115, 115, 0.14);
  --tint-info: rgba(90, 169, 221, 0.16);
  --elevation-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --elevation-2: 0 8px 32px rgba(0, 0, 0, 0.6);
}
* { box-sizing: border-box }
html, body { margin: 0; padding: 0 }
body { background: var(--palette-background); color: var(--palette-text-primary); font-family: 'Archivo', sans-serif; font-size: 15px; line-height: 1.5 }
a { color: var(--palette-info); text-decoration: none }
a:hover { text-decoration: underline; color: var(--palette-primary) }
::selection { background: var(--tint-primary) }
:focus-visible { outline: 2px solid var(--palette-primary); outline-offset: 2px }
.msr { font-family: 'Material Symbols Outlined'; font-weight: normal; font-style: normal; font-size: 20px; line-height: 1; display: inline-block; flex: none; user-select: none; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20 }
/* ============ TIPOGRAFÍA — roles MudBlazor ============ */
.typo-h1 { font-size: 40px; font-weight: 700; line-height: 1.15; letter-spacing: -0.02em; margin: 0 }
.typo-h2 { font-size: 32px; font-weight: 700; line-height: 1.2; letter-spacing: -0.01em; margin: 0 }
.typo-h3 { font-size: 28px; font-weight: 700; line-height: 1.2; letter-spacing: -0.01em; margin: 0 }
.typo-h4 { font-size: 24px; font-weight: 600; line-height: 1.25; letter-spacing: 0; margin: 0 }
.typo-h5 { font-size: 20px; font-weight: 600; line-height: 1.3; letter-spacing: 0; margin: 0 }
.typo-h6 { font-size: 17px; font-weight: 600; line-height: 1.35; letter-spacing: 0; margin: 0 }
.typo-subtitle1 { font-size: 15px; font-weight: 600; line-height: 1.4; letter-spacing: 0 }
.typo-subtitle2 { font-size: 13px; font-weight: 600; line-height: 1.4; letter-spacing: 0.01em }
.typo-body1 { font-size: 15px; font-weight: 400; line-height: 1.5; letter-spacing: 0 }
.typo-body2 { font-size: 13px; font-weight: 400; line-height: 1.45; letter-spacing: 0 }
.typo-button { font-size: 13px; font-weight: 600; line-height: 1; letter-spacing: 0.03em }
.typo-caption { font-size: 12px; font-weight: 400; line-height: 1.35; letter-spacing: 0.01em }
.typo-overline { font-size: 11px; font-weight: 600; line-height: 1.3; letter-spacing: 0.08em; text-transform: uppercase }
.text-secondary { color: var(--palette-text-secondary) }
/* ============ LAYOUT ============ */
/* dvh y no vh: en iOS `100vh` mide la ventana como si la barra del navegador no
   existiera, asi que el fondo del area con scroll queda debajo de esa barra y lo
   que se ancle ahi solo aparece cuando el usuario la colapsa scrolleando. `dvh`
   sigue el alto que de verdad se ve. Se deja vh antes como respaldo. */
.layout { display: flex; height: 100vh; height: 100dvh; overflow: hidden }
.drawer { width: 248px; flex: none; background: var(--palette-drawer); border-right: 1px solid var(--palette-divider); display: flex; flex-direction: column; transition: width .15s ease }
.drawer--collapsed { width: 64px }
.drawer__brand { display: flex; align-items: center; gap: 12px; height: 56px; padding: 0 16px; border-bottom: 2px solid var(--palette-text-primary); flex: none; overflow: hidden }
.drawer__logo { width: 28px; height: 28px; flex: none; background: var(--palette-primary); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 15px }
.drawer__nav { flex: 1; padding: 8px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px }
.drawer__footer { padding: 12px 16px; border-top: 1px solid var(--palette-divider); color: var(--palette-text-disabled); white-space: nowrap; overflow: hidden }
.nav-link { display: flex; align-items: center; gap: 12px; padding: 8px 12px; color: var(--palette-text-primary); cursor: pointer; border: none; background: none; width: 100%; text-align: left; font-family: inherit; font-size: 14px; font-weight: 500; white-space: nowrap; overflow: hidden }
.nav-link:hover { background: var(--tint-hover) }
.nav-link:active { background: var(--tint-primary) }
.nav-link--active { background: var(--tint-primary); color: var(--palette-primary); box-shadow: inset 2px 0 0 var(--palette-primary) }
.nav-link--child { padding-left: 44px }
.drawer--collapsed .nav-link { justify-content: center; padding: 8px }
.drawer--collapsed .nav-link__label, .drawer--collapsed .nav-link__chev, .drawer--collapsed .drawer__brandname, .drawer--collapsed .nav-group__tag { display: none }
.drawer--collapsed .nav-link--child { padding-left: 8px }
.nav-link__label { flex: 1 }
.nav-group__tag { font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; padding: 2px 6px; background: var(--tint-hover); color: var(--palette-text-secondary); border: 1px solid var(--palette-divider) }
.main { flex: 1; display: flex; flex-direction: column; min-width: 0 }
.appbar { height: 56px; flex: none; display: flex; align-items: center; gap: 8px; padding: 0 16px; background: var(--palette-appbar); border-bottom: 2px solid var(--palette-text-primary) }
.appbar__spacer { flex: 1 }
.appbar__search { display: flex; align-items: center; gap: 8px; width: 320px; height: 36px; padding: 0 12px; border: 1px solid var(--palette-divider); background: var(--palette-background); color: var(--palette-text-secondary) }
.appbar__search:focus-within { border-color: var(--palette-primary) }
.appbar__search input { border: none; background: none; outline: none; flex: 1; font-family: inherit; font-size: 14px; color: var(--palette-text-primary) }
.appbar__vdiv { width: 1px; height: 24px; background: var(--palette-divider); margin: 0 4px }
.content { flex: 1; overflow-y: auto; padding: 24px }
.content__inner { max-width: 1200px; margin: 0 }
/* ============ BOTONES (labels flush-left) ============ */
.btn { display: inline-flex; align-items: center; justify-content: flex-start; text-align: left; white-space: nowrap; gap: 8px; height: 36px; padding: 0 16px; border: 1px solid transparent; background: none; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: 600; letter-spacing: 0.03em; color: var(--palette-action-default) }
.btn .msr { font-size: 18px }
.btn--primary { background: var(--palette-primary); color: #ffffff; border-color: var(--palette-primary) }
.btn--primary:hover { background: var(--palette-secondary); border-color: var(--palette-secondary) }
[data-theme="dark"] .btn--primary { color: #161514 }
[data-theme="dark"] .btn--primary:hover { color: var(--palette-background) }
.btn--primary:active { background: var(--palette-primary); opacity: .85 }
.btn--outlined { border-color: var(--palette-text-primary) }
.btn--outlined:hover { background: var(--tint-hover) }
.btn--outlined:active { background: var(--tint-primary) }
.btn--text:hover { background: var(--tint-hover) }
.btn--danger { background: var(--palette-error); color: #fff; border-color: var(--palette-error) }
.btn--danger:hover { opacity: .85 }
.btn:disabled { opacity: .45; cursor: default; pointer-events: none }
.btn--loading { pointer-events: none }
.icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border: none; background: none; cursor: pointer; color: var(--palette-action-default) }
.icon-btn:hover { background: var(--tint-hover) }
.icon-btn:active { background: var(--tint-primary); color: var(--palette-primary) }
.icon-btn:disabled { color: var(--palette-action-disabled); cursor: default; pointer-events: none }
.icon-btn--sm { width: 28px; height: 28px }
.icon-btn--sm .msr { font-size: 18px }
.spinner { width: 16px; height: 16px; border: 2px solid rgba(255, 255, 255, .35); border-top-color: #fff; border-radius: 50%; animation: om-spin .7s linear infinite }
/* ============ CHIPS / TAGS ============ */
.chip { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px; font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; border: 1px solid transparent; white-space: nowrap; background: none; font-family: inherit; color: inherit }
.chip--success { background: var(--tint-success); color: var(--palette-success); border-color: var(--palette-success) }
.chip--neutral { background: var(--tint-hover); color: var(--palette-text-secondary); border-color: var(--palette-divider) }
.chip--error { background: var(--tint-error); color: var(--palette-error); border-color: var(--palette-error) }
.chip--warning { background: var(--tint-warning); color: var(--palette-warning); border-color: var(--palette-warning) }
.chip--info { background: var(--tint-info); color: var(--palette-info); border-color: var(--palette-info) }
.chip--outline { border-color: var(--palette-divider); color: var(--palette-text-primary) }
/* ============ FORMULARIOS ============ */
.field { display: flex; flex-direction: column; gap: 4px; min-width: 0 }
.field__label { font-size: 12px; font-weight: 600; letter-spacing: 0.02em; color: var(--palette-text-secondary) }
.field__helper { font-size: 12px; color: var(--palette-text-secondary) }
.field--error .input, .field--error .select { border-color: var(--palette-error) }
.field--error .field__helper, .field--error .field__label { color: var(--palette-error) }
.input, .select, .textarea { height: 36px; padding: 0 12px; border: 1px solid var(--palette-divider); background: var(--palette-surface); color: var(--palette-text-primary); font-family: inherit; font-size: 14px; width: 100% }
.textarea { height: auto; padding: 8px 12px; resize: vertical; line-height: 1.5 }
.textarea--code { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px }
.textarea--tall { min-height: 60vh; resize: vertical }
.field__label-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 24px }
/* ============ DESLIZADOR ============
   Para un numero con los dos extremos conocidos. Los extremos van en palabras
   debajo de la barra: un 0 y un 1 sueltos no dicen hacia donde suena cada lado.
   Sin valor puesto se apaga el pulgar y se lee el texto de vacio en lugar del
   numero, porque mostrar uno haria creer que alguien lo eligio. */
.slider__readout { display: inline-flex; align-items: center; gap: 6px }
.slider__value { font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--palette-text-primary) }
.slider__clear { border: 0; background: none; padding: 0; width: 16px; height: 16px; line-height: 1; font-size: 11px; font-family: inherit; color: var(--palette-text-secondary); cursor: pointer }
.slider__clear:hover { color: var(--palette-primary) }
.slider__ends { display: flex; justify-content: space-between; gap: 8px; font-size: 11px; color: var(--palette-text-secondary) }
.slider__input { appearance: none; -webkit-appearance: none; width: 100%; height: 18px; margin: 0; background: none; cursor: pointer }
.slider__input::-webkit-slider-runnable-track { height: 2px; background: var(--palette-divider) }
.slider__input::-moz-range-track { height: 2px; background: var(--palette-divider) }
.slider__input::-webkit-slider-thumb { appearance: none; -webkit-appearance: none; width: 12px; height: 12px; margin-top: -5px; background: var(--palette-primary) }
.slider__input::-moz-range-thumb { width: 12px; height: 12px; border: 0; border-radius: 0; background: var(--palette-primary) }
.slider__input:focus-visible { outline: 2px solid var(--palette-primary); outline-offset: 2px }
.slider--unset .slider__value { font-weight: 400; color: var(--palette-text-disabled) }
.slider--unset .slider__input::-webkit-slider-thumb { background: var(--palette-text-disabled) }
.slider--unset .slider__input::-moz-range-thumb { background: var(--palette-text-disabled) }
/* Resaltado de variables: un espejo detras del textarea que pinta solo los
   fondos. El texto que se ve sigue siendo el del textarea, asi que la
   seleccion, el cursor, el corrector y los acentos siguen funcionando igual
   que siempre; con el texto en transparente se rompen los cuatro.
   Los dos comparten tipografia, padding, borde y wrapping desde aca: si algo
   difiere, los recuadros quedan corridos respecto a las palabras. */
.tokenbox { position: relative }
.tokenbox > .textarea { position: relative; z-index: 1; background: transparent }
.tokenbox__mirror { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; color: transparent; background: var(--palette-surface); border: 1px solid transparent; padding: 8px 12px; font-family: inherit; font-size: 14px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: break-word; word-break: break-word }
.tokenbox__mirror--code { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px }
/* El color del subrayado es propio, asi que se ve aunque el texto no. */
.tokenbox__hit { background: var(--tint-success) }
.tokenbox__miss { background: var(--tint-warning); text-decoration: underline wavy var(--palette-error) }
/* El ancla del indice: sin tamano para no mover el texto, y alineada arriba
   para que su borde superior sea el de la linea y no el de la base. */
.tokenbox__anchor { display: inline-block; width: 0; height: 0; vertical-align: top }
.tokenbar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px }
.tokenbar__chip { display: inline-flex; align-items: center; gap: 4px; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; line-height: 1; padding: 5px 10px; border: 1px solid var(--palette-divider); border-radius: 999px; background: var(--palette-surface); color: var(--palette-text-secondary); cursor: pointer }
.tokenbar__chip:hover { border-color: var(--palette-primary); background: var(--tint-hover); color: var(--palette-primary) }
.tokenbar__chip:active { background: var(--tint-primary) }
.tokenbar__chip[disabled] { cursor: default; opacity: 0.5 }
.tokenbar__plus { font-weight: 700; opacity: 0.6 }
.tokenbar__required { color: var(--palette-error) }
/* Editor con indice: el prompt a la derecha, sus encabezados markdown a la
   izquierda. Las anclas a las que salta viven en el espejo de variables, que
   es el unico que esta pegado al texto linea por linea.
   Con indice el editor scrollea por dentro en vez de estirar el dialogo: asi
   el indice no se va de pantalla, y a la ultima seccion se puede llegar aunque
   abajo de ella no quede nada. De ahi que --paged apague el autogrow. */
/* El relleno de abajo es lo que deja llegar arriba a la ultima seccion: sin el,
   tocarla en el indice no mueve nada porque debajo de ella no queda texto que
   scrollear. El espejo lleva el mismo, o deja de poder seguir al texto. */
.textarea--paged { height: var(--mdedit-h); min-height: 0; overflow-y: auto; padding-bottom: calc(var(--mdedit-h) - 40px) }
.tokenbox__mirror--paged { padding-bottom: calc(var(--mdedit-h) - 40px) }
.mdedit { display: grid; grid-template-columns: 172px minmax(0, 1fr); gap: 20px; align-items: start }
.mdedit__index { display: flex; flex-direction: column; min-width: 0; max-height: var(--mdedit-h); overflow-y: auto; overscroll-behavior: contain; border-left: 1px solid var(--palette-divider) }
.mdedit__index-label { flex: none; font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--palette-text-secondary); padding: 2px 8px 8px 12px }
.mdedit__item { display: block; flex: none; width: 100%; min-width: 0; text-align: left; font-family: inherit; font-size: 13px; line-height: 1.35; color: var(--palette-text-secondary); background: none; border: none; border-left: 2px solid transparent; margin-left: -1px; padding: 5px 8px 5px 11px; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
/* La jerarquia se lee en la sangria, no en el color: un gris mas claro para el
   tercer nivel cae abajo del contraste que necesita un texto de 13px. */
.mdedit__item--0 { color: var(--palette-text-primary); font-weight: 600 }
.mdedit__item--1 { padding-left: 23px }
.mdedit__item--2 { padding-left: 35px }
.mdedit__item:hover { background: var(--tint-hover); color: var(--palette-text-primary) }
.mdedit__item:focus-visible { outline: 2px solid var(--palette-primary); outline-offset: -2px }
.mdedit__item.is-current { color: var(--palette-primary); border-left-color: var(--palette-primary); background: var(--tint-primary); font-weight: 600 }
/* Angosto: el indice pasa a ser una tira arriba del editor. Una columna de 172
   pixeles al lado de un textarea a pantalla completa deja el prompt en la mitad. */
@media (max-width:600px) {
  :root { --mdedit-h: clamp(240px, calc(100dvh - 360px), 820px) }
  .mdedit { grid-template-columns: minmax(0, 1fr); gap: 0 }
  .mdedit__index { flex-direction: row; max-height: none; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; border-left: none; border-bottom: 1px solid var(--palette-divider); margin-bottom: 12px }
  .mdedit__index-label { display: none }
  .mdedit__item { width: auto; flex: none; max-width: 180px; border-left: none; border-bottom: 2px solid transparent; margin-left: 0; padding: 8px 12px }
  .mdedit__item--1, .mdedit__item--2 { padding-left: 12px }
  .mdedit__item.is-current { border-left-color: transparent; border-bottom-color: var(--palette-primary) }
  /* A pantalla completa el editor se estira hasta el pie en vez de medir un alto
     fijo: la barra de variables cambia de alto segun cuantas haya declaradas, y
     cualquier numero constante deja un hueco debajo del boton o desborda. */
  .dialog:has(.mdedit) { display: flex; flex-direction: column }
  .dialog:has(.mdedit) .dialog__body { flex: 1; min-height: 0; display: flex; flex-direction: column }
  .dialog:has(.mdedit) .mdedit { flex: 1; min-height: 0; grid-template-rows: auto minmax(0, 1fr) }
  .dialog:has(.mdedit) .mdedit__text { display: flex; flex-direction: column; min-height: 0 }
  .dialog:has(.mdedit) .tokenbox { flex: 1; min-height: 0 }
  .dialog:has(.mdedit) .textarea--paged { height: 100%; padding-bottom: calc(100dvh - 200px) }
  .dialog:has(.mdedit) .tokenbox__mirror--paged { padding-bottom: calc(100dvh - 200px) }
}
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--palette-text-secondary) }
.input:focus, .select:focus, .textarea:focus { border-color: var(--palette-primary); outline: none }
.input:disabled, .select:disabled { background: var(--palette-background); color: var(--palette-text-disabled); border-color: var(--palette-divider) }
/* En pantallas tactiles el texto sube a 16px. Por debajo de eso iOS hace zoom solo
   al enfocar el campo, y con la pagina ampliada todo queda mas ancho que la
   pantalla: se corta el contenido y aparece scroll horizontal del que cuesta
   salir. La condicion es el tipo de puntero y no el ancho porque el zoom lo
   dispara el dispositivo, no el tamano de la ventana. */
@media (pointer: coarse) {
  .input, .select, .textarea { font-size: 16px }
  .tokenbox__mirror { font-size: 16px }
}
.select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--palette-text-secondary) 50%), linear-gradient(135deg, var(--palette-text-secondary) 50%, transparent 50%); background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%; background-size: 5px 5px; background-repeat: no-repeat; padding-right: 32px; cursor: pointer }
/* multiselect buscable de los filtros */
.msel { position: relative; display: inline-block }
.msel__trigger { display: flex; align-items: center; gap: 8px; height: 36px; width: 100%; padding: 0 10px 0 12px; border: 1px solid var(--palette-divider); background: var(--palette-surface); color: var(--palette-text-primary); font-family: inherit; font-size: 14px; cursor: pointer; text-align: left }
.msel__trigger:hover { border-color: var(--palette-text-secondary) }
.msel__trigger:disabled { background: var(--palette-background); color: var(--palette-text-disabled); cursor: default }
.msel__trigger--on { border-color: var(--palette-primary); background: var(--tint-primary) }
.msel__value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.msel__count { flex: none; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: var(--palette-primary); color: #fff; font-size: 12px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center }
.msel__panel { position: absolute; z-index: 41; top: calc(100% + 4px); left: 0; min-width: 100%; width: max-content; max-width: 320px; background: var(--palette-surface); border: 1px solid var(--palette-text-primary); box-shadow: var(--elevation-2) }
.msel__search { display: flex; align-items: center; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--palette-divider) }
.msel__input { flex: 1; min-width: 0; border: none; background: none; outline: none; font-family: inherit; font-size: 14px; color: var(--palette-text-primary) }
.msel__clearsearch { display: inline-flex; border: none; background: none; cursor: pointer; color: var(--palette-text-secondary); padding: 0 }
.msel__list { max-height: 280px; overflow-y: auto; padding: 4px 0 }
.msel__opt { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 12px; border: none; background: none; cursor: pointer; font-family: inherit; font-size: 14px; color: var(--palette-text-primary); text-align: left }
.msel__opt:hover { background: var(--tint-hover) }
.msel__opt--sel { background: var(--tint-primary) }
.msel__box { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; flex: none; border: 1px solid var(--palette-text-secondary); color: var(--palette-primary) }
.msel__opt--sel .msel__box { border-color: var(--palette-primary) }
.msel__opt--all { color: var(--palette-primary) }
.msel__box--part { border-color: var(--palette-primary) }
.msel__sep { height: 1px; background: var(--palette-divider); margin: 4px 0 }
.msel__opttext { flex: 1; min-width: 0; overflow-wrap: anywhere }
.msel__empty { padding: 12px }
.msel__foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; border-top: 1px solid var(--palette-divider) }
.msel__link { display: inline-flex; align-items: center; gap: 4px; border: none; background: none; cursor: pointer; font-family: inherit; font-size: 12px; font-weight: 600; color: var(--palette-primary); padding: 0 }
.input-group { display: flex; align-items: stretch }
.input-group__prefix { display: flex; align-items: center; padding: 0 12px; border: 1px solid var(--palette-divider); border-right: none; background: var(--palette-background); color: var(--palette-text-secondary); font-size: 13px; white-space: nowrap }
.checkline { display: flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; user-select: none }
.checkline input { width: 16px; height: 16px; accent-color: var(--palette-primary); margin: 0 }
/* switch */
.switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; font-size: 14px }
.switch__input { position: absolute; opacity: 0; width: 0; height: 0 }
.switch__track { width: 36px; height: 20px; flex: none; background: var(--palette-text-disabled); position: relative; transition: background .15s }
.switch__track::after { content: ''; position: absolute; top: 3px; left: 3px; width: 14px; height: 14px; background: var(--palette-surface); transition: transform .15s }
.switch__input:checked + .switch__track { background: var(--palette-primary) }
.switch__input:checked + .switch__track::after { transform: translateX(16px) }
.switch__input:focus-visible + .switch__track { outline: 2px solid var(--palette-primary); outline-offset: 2px }
/* segmented */
.seg { display: inline-flex; border: 1px solid var(--palette-text-primary) }
.seg__opt { height: 28px; padding: 0 12px; border: none; background: none; cursor: pointer; font-family: inherit; font-size: 12px; font-weight: 600; letter-spacing: .03em; color: var(--palette-text-primary); display: inline-flex; align-items: center; gap: 6px }
.seg__opt:hover { background: var(--tint-hover) }
.seg__opt--active { background: var(--palette-text-primary); color: var(--palette-surface) }
/* ============ SUPERFICIES ============ */
.paper { background: var(--palette-surface); border: 1px solid var(--palette-divider); box-shadow: var(--elevation-0) }
.toolbar { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--palette-divider); flex-wrap: wrap }
.page-head { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 16px; flex-wrap: wrap }
.page-head__grow { flex: 1; min-width: 200px }
/* El grupo de acciones envuelve como una unidad y se mantiene a la derecha */
.page-head__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto }
@media (max-width:600px) { .page-head__actions { width: 100%; margin-left: 0 } .page-head__actions .btn { flex: 1 } }
.breadcrumbs { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--palette-text-secondary); margin-bottom: 8px }
.breadcrumbs a { color: var(--palette-text-secondary) }
.breadcrumbs a:hover { color: var(--palette-primary); text-decoration: none }
/* ============ TABLA ============ */
.table { width: 100%; border-collapse: collapse; min-width: 880px }
.table th { text-align: left; font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--palette-text-secondary); padding: 8px 16px; border-bottom: 2px solid var(--palette-text-primary); white-space: nowrap }
.table td { padding: 8px 16px; border-bottom: 1px solid var(--palette-divider); font-size: 13px; vertical-align: middle }
.table__row { height: 48px }
.table__row:hover { background: var(--tint-hover) }
.table__row--dim { opacity: .6 }
.table__num { text-align: right }
.table__actions { white-space: nowrap; text-align: right }
.th-sort { display: inline-flex; align-items: center; gap: 4px; border: none; background: none; padding: 0; font: inherit; font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--palette-text-secondary); cursor: pointer }
.th-sort:hover { color: var(--palette-text-primary) }
.th-sort .msr { font-size: 16px; opacity: .3; transition: opacity .1s }
.th-sort:hover .msr { opacity: .6 }
.th-sort--active { color: var(--palette-primary) }
.th-sort--active .msr { opacity: 1 }
th.table__num .th-sort { flex-direction: row-reverse }
.sort-picker { display: flex; align-items: center; gap: 8px }
@media (max-width:600px) { .sort-picker { width: 100% } }
.pagination { display: flex; align-items: center; gap: 8px; padding: 8px 16px; justify-content: flex-end; font-size: 13px; color: var(--palette-text-secondary); flex-wrap: wrap }
.pagination .select { width: auto; height: 28px; font-size: 13px }
/* ============ ESTADO VACÍO (patrón único) ============ */
.empty { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 48px 24px; color: var(--palette-text-secondary); max-width: 520px }
.empty .msr { font-size: 40px; color: var(--palette-text-disabled) }
.empty__title { font-size: 17px; font-weight: 600; line-height: 1.35; color: var(--palette-text-primary) }
.empty__text { font-size: 13px; line-height: 1.45; margin: 0 }
.empty__actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px }
.empty--sm { padding: 32px 16px }
.empty--sm .msr { font-size: 28px }
/* ============ ESTADO DE CARGA (skeleton único) ============ */
.skel { display: block; height: 12px; background: var(--palette-divider); background-image: linear-gradient(90deg, transparent 0%, var(--tint-hover) 50%, transparent 100%); background-size: 200% 100%; background-repeat: no-repeat; animation: om-shimmer 1.2s linear infinite }
@keyframes om-shimmer { from { background-position: 200% 0 } to { background-position: -200% 0 } }
.skel-row { display: flex; align-items: center; gap: 16px; padding: 18px 16px; border-bottom: 1px solid var(--palette-divider) }
.skel-row:last-child { border-bottom: none }
.skel-card { border: 1px solid var(--palette-divider); background: var(--palette-surface) }
.skel-card__photo { aspect-ratio: 1; background: var(--palette-background); border-bottom: 1px solid var(--palette-divider) }
.skel-card__body { padding: 12px; display: flex; flex-direction: column; gap: 8px }
.loading-bar { display: flex; align-items: center; gap: 8px; padding: 8px 16px; border-bottom: 1px solid var(--palette-divider); color: var(--palette-text-secondary); font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase }
.loading-bar .spinner { border-color: var(--palette-divider); border-top-color: var(--palette-primary); width: 14px; height: 14px }
/* celdas producto */
.prod-cell { display: flex; align-items: center; gap: 12px; min-width: 0 }
.prod-cell--link { width: 100%; border: none; background: none; font-family: inherit; text-align: left; cursor: pointer; padding: 8px 16px; margin: 0; color: inherit; white-space: nowrap }
a.prod-cell--link { text-decoration: none }
.prod-cell--link:hover .prod-cell__name { color: var(--palette-primary); text-decoration: underline }
.prod-cell--link:active { background: var(--tint-primary) }
.table td.table__cell--link { padding: 0 }
.table td.table__cell--link::before { display: none }
.thumb { width: 32px; height: 32px; flex: none; background: var(--palette-background); border: 1px solid var(--palette-divider); display: flex; align-items: center; justify-content: center; color: var(--palette-text-secondary) }
.price--old { color: var(--palette-text-disabled); text-decoration: line-through; margin-left: 6px; font-size: 12px }
.price--sale { color: var(--palette-primary); font-weight: 600 }
.stock-cell { display: flex; align-items: center; gap: 8px }
.stock--out { color: var(--palette-error); font-weight: 600 }
.stock--low { color: var(--palette-warning); font-weight: 600 }
/* ============ AVATARES / MENÚS ============ */
.avatar { width: 28px; height: 28px; flex: none; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; color: #fff; text-transform: uppercase }
.avatar--lg { width: 40px; height: 40px; font-size: 15px }
.tenant-btn { display: flex; align-items: center; gap: 10px; height: 40px; padding: 0 12px; border: 1px solid var(--palette-divider); background: none; cursor: pointer; font-family: inherit; color: var(--palette-text-primary); text-align: left }
.tenant-btn:hover { border-color: var(--palette-text-primary); background: var(--tint-hover) }
.tenant-btn__name { font-size: 13px; font-weight: 600; line-height: 1.2 }
.tenant-btn__domain { font-size: 11px; color: var(--palette-text-secondary); line-height: 1.2 }
.menu-backdrop { position: fixed; inset: 0; z-index: 40 }
.menu { position: fixed; z-index: 41; min-width: 260px; background: var(--palette-surface); border: 1px solid var(--palette-text-primary); box-shadow: var(--elevation-2); padding: 4px 0 }
.menu__item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 8px 16px; border: none; background: none; cursor: pointer; font-family: inherit; font-size: 14px; color: var(--palette-text-primary); text-align: left }
.menu__item:hover { background: var(--tint-hover) }
.menu__item:disabled { color: var(--palette-text-disabled); cursor: default }
.menu__item--active { background: var(--tint-primary) }
.menu__item--danger, .menu__item--danger .msr { color: var(--palette-error) }
.menu__item--danger:hover { background: var(--tint-error) }
/* Menú colgado de su botón, en vez de posicionado a mano contra la ventana. */
.menu-anchor { position: relative; display: inline-flex }
.menu--anchored { position: absolute; top: calc(100% + 4px); right: 0 }
.menu__divider { height: 1px; background: var(--palette-divider); margin: 4px 0 }
.menu__header { padding: 8px 16px 4px }
/* ============ TABS ============ */
.tabs { display: flex; gap: 0; border-bottom: 2px solid var(--palette-text-primary) }
.tab { height: 40px; padding: 0 20px; border: none; background: none; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: 600; letter-spacing: .03em; color: var(--palette-text-secondary); display: inline-flex; align-items: center; gap: 8px }
.tab:hover { background: var(--tint-hover); color: var(--palette-text-primary) }
.tab--active { color: var(--palette-primary); box-shadow: inset 0 -2px 0 var(--palette-primary) }
/* ============ DIALOG / SNACKBAR ============ */
.dialog-backdrop { position: fixed; inset: 0; background: rgba(22, 21, 20, .5); z-index: 50; display: flex; align-items: flex-start; justify-content: center; padding: 48px 16px; overflow-y: auto }
/* Catálogos abiertos DESDE otro modal: viven una capa arriba */
.dialog-backdrop--nested { z-index: 52 }
.dialog { background: var(--palette-surface); border: 1px solid var(--palette-text-primary); box-shadow: var(--elevation-2); width: 480px; max-width: 100% }
.dialog--lg { width: 720px }
/* El editor con indice pide mas ancho: el indice y su separacion se llevan casi
   200px de los 720, y al prompt le queda menos espacio del que tenia antes de
   tenerlo. Acotado a los dialogos que lo muestran, para no ensanchar el resto. */
.dialog--lg:has(.mdedit) { width: 880px; max-width: 100% }
.dialog__title { display: flex; align-items: center; gap: 12px; padding: 16px 24px; border-bottom: 2px solid var(--palette-text-primary) }
.dialog__title .typo-h6 { flex: 1 }
.dialog__body { padding: 24px }
.dialog__actions { display: flex; justify-content: flex-end; gap: 8px; padding: 16px 24px; border-top: 1px solid var(--palette-divider) }
.snackbar { position: fixed; left: 24px; bottom: 24px; z-index: 60; background: var(--palette-secondary); color: var(--palette-surface); padding: 12px 20px; display: flex; align-items: center; gap: 12px; box-shadow: var(--elevation-2); font-size: 14px }
[data-theme="dark"] .snackbar { background: #f3f2f2; color: #201e1d }
/* ============ EDITOR / IMÁGENES / GRID ============ */
.rte { border: 1px solid var(--palette-divider) }
.rte__toolbar { display: flex; align-items: center; gap: 2px; padding: 4px 8px; border-bottom: 1px solid var(--palette-divider); background: var(--palette-background); flex-wrap: wrap }
.rte__body { min-height: 160px; padding: 12px 16px; outline: none; font-size: 14px; line-height: 1.6; background: var(--palette-surface) }
.rte__body:focus { box-shadow: inset 0 0 0 1px var(--palette-primary) }
.img-row { display: flex; align-items: center; gap: 16px; padding: 12px 16px; border: 1px solid var(--palette-divider); background: var(--palette-surface) }
.img-row__thumb { width: 56px; height: 56px; flex: none; border: 1px solid var(--palette-divider); display: flex; align-items: center; justify-content: center; color: var(--palette-text-secondary) }
.img-row__grow { flex: 1; min-width: 0 }
.img-add { display: flex; align-items: center; gap: 12px; padding: 16px; border: 1px dashed var(--palette-text-secondary); background: none; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--palette-text-secondary); width: 100% }
.img-add:hover { border-color: var(--palette-primary); color: var(--palette-primary) }
.form-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 16px }
.col-12 { grid-column: span 12 } .col-6 { grid-column: span 6 } .col-4 { grid-column: span 4 } .col-3 { grid-column: span 3 } .col-8 { grid-column: span 8 }
/* ============ BREAKPOINTS MudBlazor: xs 0 · sm 600 · md 960 · lg 1280 · xl 1920 ============ */
.nav-backdrop { display: none }
@media (max-width:1280px) { .appbar__search { width: 240px } }
@media (max-width:960px) { .col-6, .col-4, .col-3, .col-8 { grid-column: span 12 } .appbar__search { width: 180px } .content { padding: 16px } .dialog--lg { width: 100% } }
@media (max-width:600px) {
  .drawer { position: fixed; top: 0; left: 0; bottom: 0; z-index: 46; width: 264px; transform: translateX(-100%); box-shadow: var(--elevation-2) }
  .drawer--collapsed { width: 264px }
  .drawer--collapsed .nav-link { justify-content: flex-start; padding: 12px }
  .drawer--collapsed .nav-link--child { padding-left: 44px }
  .drawer--collapsed .nav-link__label, .drawer--collapsed .nav-link__chev, .drawer--collapsed .drawer__brandname, .drawer--collapsed .nav-group__tag { display: inline }
  .drawer--mobile-open { transform: none }
  .nav-backdrop { display: block; position: fixed; inset: 0; background: rgba(22, 21, 20, .5); z-index: 45 }
  .nav-link { min-height: 48px }
  .appbar { padding: 0 8px; gap: 4px }
  .appbar__search { display: none }
  .appbar__search--mobile { display: flex; width: 100%; margin: 0 0 16px }
  .tenant-btn { padding: 0 8px; gap: 8px }
  .tenant-btn__domain { display: none }
  .tenant-btn__name { max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
  .content { padding: 12px }
  .icon-btn { width: 44px; height: 44px }
  .icon-btn--sm { width: 36px; height: 36px }
  .btn { height: 44px }
  .toolbar { padding: 12px; gap: 8px }
  .toolbar .field { width: 100% !important }
  .page-head { align-items: stretch; flex-direction: column; gap: 12px }
  .page-head .btn { width: 100% }
  .tabs { overflow-x: auto; scrollbar-width: none }
  .tab { padding: 0 16px; flex: none; height: 48px }
  .dialog-backdrop { padding: 0; align-items: stretch }
  .dialog, .dialog--lg { width: 100%; min-height: 100%; border: none }
  .dialog__body { padding: 16px }
  .dialog__title, .dialog__actions { padding: 12px 16px; position: sticky; background: var(--palette-surface); z-index: 1 }
  .dialog__title { top: 0 }
  .dialog__actions { bottom: 0 }
  .dialog__actions .btn { flex: 1 }
  /* El anclado se excluye: se posiciona contra su botón, no contra la ventana. */
  .menu:not(.menu--anchored) { left: 8px !important; right: 8px !important; width: auto !important; min-width: 0 }
  .menu--anchored { min-width: 240px }
  .snackbar { left: 12px; right: 12px; bottom: 12px }
  .stat { flex: 1 }
  /* Tabla densa → tarjetas apiladas */
  .table thead { display: none }
  .table { min-width: 0 }
  .table, .table tbody, .table tr, .table td { display: block; width: 100% }
  .prod-cell--link { white-space: normal }
  .table__row { height: auto; border-bottom: 2px solid var(--palette-divider); padding: 8px 0; position: relative }
  .table td { border: none; padding: 4px 12px; display: flex; align-items: center; gap: 8px }
  /* La etiqueta ocupa una columna fija para que los valores queden alineados entre
     filas, asi que tiene que poder partirse en dos lineas: varias pasan de 88px
     («Ultima actividad», «Herramientas esperadas») y sin esto se derraman sobre el valor.
     El white-space propio es obligatorio porque varias celdas traen nowrap y el
     pseudoelemento lo hereda. */
  .table td[data-label]::before { content: attr(data-label); flex: none; width: 88px; white-space: normal; overflow-wrap: anywhere; line-height: 1.3; font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--palette-text-secondary) }
  .table td.table__num { text-align: left }
  /* Ancho automatico, no el 100% que heredan todas las celdas al apilarse: siendo
     absoluta, una celda del ancho de la fila tapa el nombre del renglon y se come
     el tap que deberia abrir el detalle. Los botones se ven igual a la derecha; lo
     que cambia es que su caja deja de cubrir lo que hay debajo. El selector lleva
     el tipo porque `.table td` le gana en especificidad a la clase sola. */
  .table td.table__actions { justify-content: flex-end; position: absolute; top: 8px; right: 4px; padding: 0; width: auto }
  .prod-cell--link { padding-right: 44px }
  .pagination { justify-content: flex-start; padding: 12px }
}
.stat { display: flex; flex-direction: column; gap: 4px; padding: 16px 20px; border: 1px solid var(--palette-divider); background: var(--palette-surface); min-width: 160px }
.stat__num { font-size: 32px; font-weight: 700; line-height: 1.1 }
.section { margin-bottom: 24px }
.section__head { display: flex; align-items: center; gap: 12px; padding-bottom: 8px; margin-bottom: 12px; border-bottom: 2px solid var(--palette-text-primary) }
.section__head .msr { font-size: 20px; color: var(--palette-text-secondary) }
.kv-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; padding: 16px; border: 1px solid var(--palette-divider); background: var(--palette-surface) }
.kv { display: flex; flex-direction: column; gap: 2px; min-width: 0 }
.kv__k { font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--palette-text-secondary) }
.kv__v { font-size: 15px; font-weight: 500; overflow-wrap: anywhere }
.kv__copy { width: 22px; height: 22px; margin-left: 4px; vertical-align: text-bottom; opacity: 0; transition: opacity .15s }
.kv__copy .msr { font-size: 15px }
.kv:hover .kv__copy, .kv:focus-within .kv__copy { opacity: 1 }
@media (hover: none) { .kv__copy { opacity: 1 } }
.page-head__copy { vertical-align: middle; margin-left: 2px }
.totals { display: flex; flex-direction: column; gap: 4px; padding: 16px; border: 1px solid var(--palette-divider); background: var(--palette-surface); max-width: 360px; margin-left: auto }
.totals__row { display: flex; justify-content: space-between; gap: 16px; font-size: 14px }
.totals__row--total { border-top: 1px solid var(--palette-divider); margin-top: 8px; padding-top: 8px; font-size: 17px; font-weight: 700 }
/* Dentro de un diálogo la cuenta es el contenido, no un apéndice del costado: ocupa todo el ancho. */
.totals--flush { max-width: none; margin-left: 0 }
.mono { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px }
.date { cursor: help; text-decoration: underline dotted 1px; text-decoration-color: var(--palette-divider); text-underline-offset: 3px }
/* Celda con varias fechas del mismo asunto apiladas (la entrega estimada y la deseada
   de una orden). La etiqueta de cada línea es lo único que las distingue, así que se
   pinta siempre; --weak hunde la secundaria y --late marca la que incumple. */
.delivery { display: inline-flex; flex-direction: column; gap: 2px; align-items: flex-start }
.delivery__line { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap }
/* El ancho fijo alinea las fechas entre líneas: sin él «Deseada» las corre a la izquierda. */
.delivery__tag { flex: none; min-width: 54px; font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--palette-text-secondary) }
.delivery__line--weak .date { color: var(--palette-text-secondary) }
.delivery__line--late .date { color: var(--palette-error); font-weight: 600 }
.table--fit { min-width: 0; width: 100%; max-width: 100% }
.table--fit th, .table--fit td { padding-left: 8px; padding-right: 8px; white-space: normal; overflow-wrap: anywhere }
.table--fit th:first-child, .table--fit td:first-child { padding-left: 16px }
.table--fit th:last-child, .table--fit td:last-child { padding-right: 16px }
.table--fit .nowrap, .table--fit td[data-label="Fecha"], .table--fit td[data-label="Monto"], .table--fit td[data-label="Estado"], .table--fit .table__num { white-space: nowrap }
.table--fit .cell--truncate { max-width: 0; width: 24%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
.raw-btn { display: block; width: 100%; max-width: 100%; border: none; background: none; padding: 0; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; color: var(--palette-text-secondary); text-align: left; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: underline; text-decoration-color: var(--palette-divider) }
.raw-btn:hover { color: var(--palette-primary); text-decoration-color: currentColor }
.code-block { margin: 0; padding: 16px; background: var(--palette-background); border: 1px solid var(--palette-divider); font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 320px; overflow-y: auto }
.status-picker { display: flex; flex-direction: column; gap: 8px }
.status-opt { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border: 1px solid var(--palette-divider); background: var(--palette-surface); cursor: pointer; font-family: inherit; text-align: left; width: 100%; color: inherit }
.status-opt:hover { border-color: var(--palette-text-primary); background: var(--tint-hover) }
.status-opt--sel { border-color: var(--palette-primary); background: var(--tint-primary) }
/* ============ NUEVA ORDEN (stepper + selector de productos + carrito) ============ */
.stepper { display: flex; border: 1px solid var(--palette-divider); background: var(--palette-surface); margin-bottom: 24px; overflow-x: auto }
.step { display: flex; align-items: center; gap: 12px; padding: 16px 20px; flex: 1; min-width: 200px; border-right: 1px solid var(--palette-divider); background: none; font-family: inherit; text-align: left; cursor: pointer; color: var(--palette-text-secondary) }
.step:last-child { border-right: none }
.step:hover { background: var(--tint-hover) }
.step--active { color: var(--palette-text-primary); box-shadow: inset 0 -2px 0 var(--palette-primary) }
.step--todo { cursor: default; opacity: .6 }
.step__num { width: 28px; height: 28px; flex: none; display: flex; align-items: center; justify-content: center; border: 1px solid currentColor; font-size: 13px; font-weight: 700 }
.step--active .step__num { background: var(--palette-primary); border-color: var(--palette-primary); color: #fff }
[data-theme="dark"] .step--active .step__num { color: #161514 }
.step--done .step__num { background: var(--palette-text-primary); border-color: var(--palette-text-primary); color: var(--palette-surface) }
.new-order { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 24px; align-items: start }
@media (max-width:960px) { .new-order { grid-template-columns: minmax(0, 1fr) } }
.prod-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 16px }
.prod-card { display: flex; flex-direction: column; border: 1px solid var(--palette-divider); background: var(--palette-surface) }
.prod-card--out { opacity: .6 }
.prod-card__photo { position: relative; aspect-ratio: 1; border: none; border-bottom: 1px solid var(--palette-divider); background: var(--palette-background); display: flex; align-items: center; justify-content: center; color: var(--palette-text-disabled); cursor: pointer; width: 100%; padding: 0 }
.prod-card__photo:hover { color: var(--palette-primary) }
.prod-card__photo .msr { font-size: 48px }
.prod-card__badge { position: absolute; top: 8px; left: 8px }
.prod-card__zoom { position: absolute; bottom: 8px; right: 8px; display: flex; align-items: center; gap: 4px; padding: 2px 6px; background: var(--palette-surface); border: 1px solid var(--palette-divider); font-size: 11px; font-weight: 600; color: var(--palette-text-secondary) }
.prod-card__body { padding: 12px; display: flex; flex-direction: column; gap: 4px; flex: 1 }
.prod-card__name { border: none; background: none; padding: 0; font-family: inherit; font-size: 13px; font-weight: 600; line-height: 1.4; text-align: left; cursor: pointer; color: inherit }
.prod-card__name:hover { color: var(--palette-primary); text-decoration: underline }
.prod-card__foot { padding: 8px 12px; border-top: 1px solid var(--palette-divider); display: flex; align-items: center; gap: 8px }
.qty { display: flex; align-items: center; border: 1px solid var(--palette-divider) }
.qty__num { min-width: 32px; text-align: center; font-size: 13px; font-weight: 600 }
.cart { border: 1px solid var(--palette-divider); background: var(--palette-surface); position: sticky; top: 0 }
.cart__head { display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-bottom: 2px solid var(--palette-text-primary) }
.cart__body { padding: 8px 16px; max-height: 340px; overflow-y: auto }
.cart__item { display: flex; align-items: flex-start; gap: 8px; padding: 12px 0; border-bottom: 1px solid var(--palette-divider) }
.cart__item:last-child { border-bottom: none }
.cart__foot { padding: 16px; border-top: 1px solid var(--palette-divider); display: flex; flex-direction: column; gap: 4px }
/* Barra de accion del alta de orden.

   Solo existe en movil. Ahi la rejilla pasa a una columna y el resumen queda
   debajo del catalogo entero, asi que llegar al boton obligaba a recorrer todos
   los productos. Se queda pegada al borde inferior del area con scroll, que es
   .content y no la ventana. Como va en el flujo y no fija, no tapa el final de
   la pagina ni salta con el teclado del telefono.

   No sangra hasta el borde con margenes negativos: el padding de .content cambia
   entre breakpoints (16px y 12px), asi que cualquier valor fijo desborda a lo
   ancho en uno de los dos. Queda dentro del ancho de contenido, que ademas se lee
   como una barra flotante. */
.order-bar { display: none }
@media (max-width:960px) {
  .cart__actions { display: none }
  .order-bar { position: sticky; bottom: 0; z-index: 35; display: flex; align-items: center; gap: 12px;
               margin-top: 16px; padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
               background: var(--palette-surface); border: 2px solid var(--palette-text-primary);
               box-shadow: var(--elevation-2) }
  .order-bar__grow { flex: 1; min-width: 0 }
}
.photo-lg { aspect-ratio: 4/3; max-height: 280px; background: var(--palette-background); border: 1px solid var(--palette-divider); display: flex; align-items: center; justify-content: center; color: var(--palette-text-disabled) }
.peek-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px }
@media (max-width:600px) { .peek-grid { grid-template-columns: minmax(0, 1fr); gap: 16px } .photo-lg { max-height: 200px } }
.photo-lg .msr { font-size: 72px }
.thumbs { display: flex; gap: 8px; margin-top: 8px }
.thumb-sq { width: 56px; height: 56px; flex: none; border: 1px solid var(--palette-divider); background: var(--palette-background); display: flex; align-items: center; justify-content: center; color: var(--palette-text-secondary); cursor: pointer }
.thumb-sq--sel { border-color: var(--palette-primary); box-shadow: inset 0 0 0 1px var(--palette-primary) }
.radio-opt { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border: 1px solid var(--palette-divider); background: var(--palette-surface); cursor: pointer; font-family: inherit; text-align: left; width: 100%; color: inherit }
.radio-opt:hover { border-color: var(--palette-text-primary); background: var(--tint-hover) }
.radio-opt--sel { border-color: var(--palette-primary); background: var(--tint-primary) }
/* ============ SPLASH + LOGIN ============ */
.splash { height: 100vh; display: flex; flex-direction: column; justify-content: space-between; padding: 48px; background: var(--palette-background) }
.splash__mark { display: flex; align-items: center; gap: 16px }
.splash__logo { width: 56px; height: 56px; flex: none; background: var(--palette-primary); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 28px; font-weight: 700 }
.splash__bar { height: 4px; background: var(--palette-divider); overflow: hidden }
.splash__fill { height: 100%; background: var(--palette-primary); width: 0; animation: om-load 1.6s ease-out forwards }
@keyframes om-load { from { width: 0 } to { width: 100% } }
.auth { height: 100vh; display: grid; grid-template-columns: minmax(0, 1fr) 480px }
.auth__poster { background: var(--palette-primary); color: #fff; padding: 48px; display: flex; flex-direction: column; justify-content: space-between }
[data-theme="dark"] .auth__poster { color: #161514 }
.auth__form { background: var(--palette-surface); border-left: 2px solid var(--palette-text-primary); padding: 48px 40px; display: flex; flex-direction: column; justify-content: center; overflow-y: auto }
@media (max-width:960px) { .auth { grid-template-columns: minmax(0, 1fr) } .auth__poster { display: none } .auth__form { border-left: none; padding: 32px 24px } }
.auth__logo { width: 48px; height: 48px; background: #fff; color: var(--palette-primary); display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: 700 }
.auth__alert { display: flex; align-items: flex-start; gap: 12px; padding: 12px 16px; border: 1px solid var(--palette-error); background: var(--tint-error); color: var(--palette-error); margin-bottom: 16px }
.auth__alert--info { border-color: var(--palette-info); background: var(--tint-info); color: var(--palette-info) }
.auth__alert--warning { border-color: var(--palette-warning); background: var(--tint-warning); color: var(--palette-warning) }
.input-pw { position: relative; display: flex }
.input-pw .icon-btn { position: absolute; right: 0; top: 0; height: 36px; width: 36px }
/* ============ CASCADA DE COSTOS (reparto secuencial) ============ */
.wf { border: 1px solid var(--palette-divider); background: var(--palette-surface) }
.wf__note { display: flex; align-items: flex-start; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--palette-divider); background: var(--palette-background); color: var(--palette-text-secondary); font-size: 13px; line-height: 1.45 }
.wf__row { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--palette-divider) }
.wf__row:last-child { border-bottom: none }
.wf__row--void { opacity: .65 }
.wf__ord { display: flex; flex-direction: column; align-items: center; gap: 2px; flex: none }
.wf__ordnum { font-size: 13px; font-weight: 700; width: 24px; text-align: center }
.wf__grow { flex: 1; min-width: 0 }
.wf__math { font-size: 12px; color: var(--palette-text-secondary); line-height: 1.5; overflow-wrap: anywhere }
.wf__math b { color: var(--palette-text-primary); font-weight: 600 }
.wf__amt { font-size: 15px; font-weight: 600; white-space: nowrap; text-align: right }
.wf__amt--void { text-decoration: line-through; color: var(--palette-text-disabled) }
.wf__base { display: flex; justify-content: space-between; gap: 16px; padding: 12px 16px; border-top: 2px solid var(--palette-text-primary); font-weight: 700 }
/* ============ EDITOR DEL FLUJO DE ÓRDENES (mapa de etapas) ============ */
.flow { display: flex; flex-direction: column }
.flow__item { display: flex; gap: 14px }
.flow__rail { display: flex; flex-direction: column; align-items: center; width: 20px; flex: none }
.flow__rail .flow__dot { margin-top: 18px; box-shadow: 0 0 0 3px var(--tint-hover) }
.flow__dot { width: 13px; height: 13px; border-radius: 50%; flex: none }
.flow__line { width: 2px; flex: 1; background: var(--palette-divider); margin: 6px 0 }
.flow__card { flex: 1; min-width: 0; border: 1px solid var(--palette-divider); border-left: 4px solid var(--palette-divider); background: var(--palette-surface); padding: 12px 16px; margin-bottom: 14px }
.flow__head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap }
.flow__code { font-family: ui-monospace, monospace; font-size: 12px; color: var(--palette-text-secondary); background: var(--palette-background); border: 1px solid var(--palette-divider); padding: 1px 6px }
.flow__spacer { flex: 1 }
.flow__badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px }
.flow__badges:empty { display: none }
.flow__next { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--palette-divider) }
.flow__arrow { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; padding: 2px 8px; border: 1px solid currentColor }
.flow__swatch { width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--palette-divider); cursor: pointer; padding: 0 }
.flow__swatch--sel { border-color: var(--palette-text-primary); outline: 2px solid var(--palette-text-primary); outline-offset: 2px }
.flow__iconpick { display: flex; flex-wrap: wrap; gap: 6px }
.flow__iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border: 1px solid var(--palette-divider); background: var(--palette-surface); cursor: pointer; color: inherit }
.flow__iconbtn:hover { border-color: var(--palette-text-primary) }
.flow__iconbtn--sel { border-color: var(--palette-primary); background: var(--tint-primary); color: var(--palette-primary) }
.stage { display: flex; border: 1px solid var(--palette-divider); background: var(--palette-surface); margin-bottom: 24px; overflow-x: auto }
.stage__s { display: flex; align-items: center; gap: 10px; padding: 14px 18px; flex: 1; min-width: 170px; border-right: 1px solid var(--palette-divider); color: var(--palette-text-disabled) }
.stage__s:last-child { border-right: none }
.stage__s--done { color: var(--palette-text-secondary) }
.stage__s--now { color: var(--palette-text-primary); box-shadow: inset 0 -2px 0 var(--palette-primary) }
.stage__s--void { color: var(--palette-error) }
.stage__dot { width: 10px; height: 10px; flex: none; border: 1px solid currentColor }
.stage__s--done .stage__dot, .stage__s--now .stage__dot { background: currentColor }
.stage__s--now .stage__dot { background: var(--palette-primary); border-color: var(--palette-primary) }
.ro { display: block; font-size: 15px; font-weight: 500; padding: 7px 0; border-bottom: 1px solid var(--palette-divider); overflow-wrap: anywhere }
.calc { background: var(--palette-background); border: 1px solid var(--palette-divider); padding: 2px 6px; font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--palette-text-secondary); white-space: nowrap }
.money { font-variant-numeric: tabular-nums; white-space: nowrap }
.neg { color: var(--palette-error) }
/* Iconos de canal: heredan el color del texto que acompanan, para leerse en ambos temas. */
.chan { display: inline-flex; align-items: center; color: var(--palette-text-secondary); vertical-align: middle }
.chan svg { display: block }
.chans { display: inline-flex; align-items: center; gap: 4px; vertical-align: middle }

/* Sugerencias de cliente.

   La lista va absoluta sobre el contenido y nunca en el flujo: si empujara, en el
   celular el formulario entero saltaria a cada tecla. El alto se topa contra el
   viewport porque con el teclado abierto queda media pantalla, y un alto fijo en
   pixeles se saldria de vista. */
.sugg { position: relative; min-width: 0 }
.sugg__pop { position: absolute; top: 100%; left: 0; right: 0; z-index: 30; margin-top: 4px; max-height: min(240px, 40vh); overflow-y: auto; background: var(--palette-surface); border: 1px solid var(--palette-text-primary); box-shadow: var(--elevation-2) }
.sugg__row { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 10px; border: none; border-bottom: 1px solid var(--palette-divider); background: none; cursor: pointer; font-family: inherit; text-align: left; color: inherit }
.sugg__row:last-child { border-bottom: none }
.sugg__row:hover { background: var(--tint-hover) }
.sugg__thumb { width: 32px; height: 32px; flex: none; font-size: 12px }
.sugg__grow { flex: 1; min-width: 0 }
.sugg__desc { font-size: 12px; color: var(--palette-text-secondary); line-height: 1.4; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.sugg__note { padding: 10px; font-size: 13px; color: var(--palette-text-secondary) }
/* Se abre hacia arriba cuando abajo no cabe. Cual de los dos lados sirve depende
   de donde quedo el campo en la pantalla, que en el telefono cambia al abrirse el
   teclado, asi que lo decide js midiendo y no una media query. */
.sugg__pop--up { top: auto; bottom: 100%; margin-top: 0; margin-bottom: 4px }
.pos { color: var(--palette-success) }
.dual { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; align-items: end }
.dual__out { display: flex; flex-direction: column; gap: 4px }
.dual__val { height: 36px; display: flex; align-items: center; padding: 0 12px; border: 1px solid var(--palette-divider); background: var(--palette-background); font-weight: 600; font-variant-numeric: tabular-nums }
.cascade { display: flex; flex-direction: column; border: 1px solid var(--palette-divider); background: var(--palette-surface) }
.cascade__r { display: flex; align-items: center; gap: 16px; padding: 14px 16px; border-bottom: 1px solid var(--palette-divider) }
.cascade__r:last-child { border-bottom: none }
.cascade__r--sum { border-top: 2px solid var(--palette-text-primary); background: var(--palette-background) }
.cascade__lbl { flex: 1; min-width: 0 }
.cascade__bar { width: 120px; height: 8px; flex: none; background: var(--palette-divider) }
.cascade__fill { height: 100%; display: block }
.cascade__amt { width: 132px; text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap }
.layer-row { display: flex; align-items: center; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--palette-divider) }
.layer-row:last-child { border-bottom: none }
.layer-row--spent { opacity: .55 }
.layer-bar { width: 88px; height: 6px; flex: none; background: var(--palette-divider) }
.layer-bar span { display: block; height: 100%; background: var(--palette-primary) }
/* ============ SELECTOR DE PRODUCTO (reutilizable) ============ */
.ppick { border: 1px solid var(--palette-divider); background: var(--palette-surface) }
.ppick__search { display: flex; align-items: center; gap: 8px; padding: 0 12px; height: 40px; border-bottom: 1px solid var(--palette-divider); background: var(--palette-background); color: var(--palette-text-secondary) }
.ppick__search input { flex: 1; border: none; background: none; outline: none; font-family: inherit; font-size: 14px; color: var(--palette-text-primary) }
.ppick__list { max-height: 236px; overflow-y: auto }
.ppick__row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 12px; border: none; border-bottom: 1px solid var(--palette-divider); background: none; cursor: pointer; font-family: inherit; text-align: left; color: inherit }
.ppick__row:last-child { border-bottom: none }
.ppick__row:hover { background: var(--tint-hover) }
.ppick__row--sel { background: var(--tint-primary); box-shadow: inset 2px 0 0 var(--palette-primary) }
.ppick__thumb { width: 44px; height: 44px; flex: none; background: var(--palette-background); border: 1px solid var(--palette-divider); display: flex; align-items: center; justify-content: center; color: var(--palette-text-secondary) }
.ppick__grow { flex: 1; min-width: 0 }
.ppick__desc { font-size: 12px; color: var(--palette-text-secondary); line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden }
.ppick__right { text-align: right; flex: none }
.cat-row { display: flex; align-items: center; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--palette-divider) }
.cat-row:last-child { border-bottom: none }
.cat-row--off { opacity: .55 }
.field__row { display: flex; align-items: flex-end; gap: 8px }
.field__row .field { flex: 1; min-width: 0 }
.qcap { display: grid; grid-template-columns: 180px minmax(0, 1fr) 140px 150px auto; gap: 8px; align-items: end; padding: 12px 16px; border: 1px solid var(--palette-text-primary); background: var(--palette-surface); margin-bottom: 16px }
@media (max-width:960px) { .qcap { grid-template-columns: minmax(0, 1fr) } .dual { grid-template-columns: minmax(0, 1fr) } }
.pos-cell { display: flex; align-items: center; gap: 4px }
.pos-cell__num { width: 24px; text-align: center; font-weight: 600 }
.kwchips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 6px 8px; border: 1px solid var(--palette-divider); background: var(--palette-surface) }
.kwchips input { border: none; outline: none; background: none; font-family: inherit; font-size: 13px; flex: 1; min-width: 120px; color: var(--palette-text-primary) }
.kwchip { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 4px 0 8px; background: var(--tint-hover); border: 1px solid var(--palette-divider); font-size: 12px }
.kwchip .msr { font-size: 14px; cursor: pointer }
.kwchip .msr:hover { color: var(--palette-error) }
.ogslot { width: 200px; height: 104px; border: 1px dashed var(--palette-text-secondary); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; color: var(--palette-text-secondary); font-size: 12px; cursor: pointer }
.ogslot:hover { border-color: var(--palette-primary); color: var(--palette-primary) }
@keyframes om-spin { to { transform: rotate(360deg) } }

/* Recetario de promociones: las formas que se pueden armar, como tarjetas elegibles. */
.recipe-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 8px; margin-bottom: 16px }
.recipe { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 12px; text-align: left; border: 1px solid var(--palette-divider); background: var(--palette-surface); cursor: pointer; font-family: inherit; color: var(--palette-text-primary) }
.recipe:hover { border-color: var(--palette-text-primary); background: var(--tint-hover) }
.recipe--on { border-color: var(--palette-primary); background: var(--tint-primary) }
.recipe .msr { color: var(--palette-text-secondary) }
.recipe--on .msr { color: var(--palette-primary) }

/* Fila de chips que se pueden quitar: los productos de una promoción. */
.chips { display: flex; flex-wrap: wrap; gap: 6px }

/* Revelar opciones que casi nadie toca, sin gastarles sitio a las que sí. */
.link-button { display: inline-flex; align-items: center; gap: 4px; margin: 12px 0; padding: 0; border: none; background: none; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--palette-primary); cursor: pointer }
.link-button:hover { text-decoration: underline }

/* Pie del buscador de productos: traer la página siguiente sin salir de la lista. */
.ppick__more { display: flex; align-items: center; justify-content: center; gap: 4px; width: 100%; padding: 10px; border: none; border-top: 1px solid var(--palette-divider); background: none; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--palette-primary); cursor: pointer }
.ppick__more:hover:not(:disabled) { background: var(--tint-hover) }
.ppick__more:disabled { color: var(--palette-text-secondary); cursor: default }

/* Archivos que un nodo manda al entrar: la lista del editor. */
.attach { display: flex; align-items: center; gap: 8px; padding: 8px; border: 1px solid var(--palette-divider); background: var(--palette-surface); margin-bottom: 6px }
.attach__grow { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px }
.attach__name { font-size: 12px; font-weight: 600; color: var(--palette-text-primary); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.attach__name:hover { text-decoration: underline }
.attach__caption { border: 1px solid var(--palette-divider); background: none; font-family: inherit; font-size: 12px; padding: 4px 6px; color: var(--palette-text-primary) }
.attach__caption:focus { outline: none; border-color: var(--palette-primary) }
.attach__add { display: inline-flex; align-items: center; gap: 4px; padding: 6px 10px; border: 1px dashed var(--palette-text-secondary); font-size: 12px; font-weight: 600; color: var(--palette-text-secondary); cursor: pointer }
.attach__add:hover { border-color: var(--palette-primary); color: var(--palette-primary) }

/* Un documento adjunto en el chat de pruebas: no es una foto, no se pinta como una. */
.msg__doc { display: inline-flex; align-items: center; gap: 6px; padding: 8px 10px; border: 1px solid var(--palette-divider); background: var(--palette-surface); font-size: 13px; color: var(--palette-text-primary); text-decoration: none }
.msg__doc:hover { border-color: var(--palette-primary) }
.msg__caption { display: block; color: var(--palette-text-secondary) }

/* ============ MENSAJERÍA (lista + hilo, dos paneles) ============
   Se lee como un mensajero: los hilos a la izquierda, el abierto a la derecha,
   sin diálogo de por medio. Quien atiende salta entre clientes sin perder de
   vista la cola, que es lo que hacía lenta la versión de tabla + modal. */

/* Ocupa lo que queda de ventana: menos el appbar (56px) y el padding vertical
   de .content, que cambia con el breakpoint y por eso es una variable. Así no
   hay dos barras de scroll compitiendo: cada panel corre por su cuenta. */
.msgr { --msgr-chrome: 104px;
        display: grid; grid-template-columns: 340px minmax(0, 1fr);
        height: calc(100vh - var(--msgr-chrome)); height: calc(100dvh - var(--msgr-chrome));
        min-height: 420px; background: var(--palette-surface);
        border: 1px solid var(--palette-divider); overflow: hidden }
.msgr__aside { display: flex; flex-direction: column; min-width: 0; min-height: 0; border-right: 1px solid var(--palette-divider) }
.msgr__main { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--palette-background) }
.msgr__head { flex: none; display: flex; align-items: center; gap: 8px; height: 52px; padding: 0 8px 0 16px; border-bottom: 2px solid var(--palette-text-primary) }
.msgr__head-grow { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 8px }
.msgr__count { flex: none; font-size: 11px; font-weight: 600; letter-spacing: .06em; color: var(--palette-text-secondary); font-variant-numeric: tabular-nums }
.msgr__filters { flex: none; display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--palette-divider) }
.msgr__filters-row { display: flex; align-items: center; gap: 8px }
.msgr__filters-row .field { flex: 1; min-width: 0 }
.msgr__list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain }

/* Una fila es el hilo entero de un cliente: quién, qué se dijo al final y cuándo. */
.msgr__row { display: flex; align-items: flex-start; gap: 12px; width: 100%; padding: 12px 16px; border: none; border-bottom: 1px solid var(--palette-divider); background: none; font-family: inherit; color: inherit; text-align: left; cursor: pointer }
.msgr__row:hover { background: var(--tint-hover) }
.msgr__row:focus-visible { outline: 2px solid var(--palette-primary); outline-offset: -2px }
.msgr__row--on, .msgr__row--on:hover { background: var(--tint-primary); box-shadow: inset 2px 0 0 var(--palette-primary) }
.msgr__row--on .msgr__row-name { color: var(--palette-primary) }
.msgr__row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px }
.msgr__row-top { display: flex; align-items: baseline; gap: 8px }
.msgr__row-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.msgr__row-when { flex: none; color: var(--palette-text-secondary); font-variant-numeric: tabular-nums }
.msgr__row-bottom { display: flex; align-items: center; gap: 6px; min-width: 0; color: var(--palette-text-secondary) }
.msgr__row-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
/* El canal solo se dice cuando hay más de uno: repetirlo en cada fila de una
   cuenta con un solo canal es ruido que empuja al adelanto del mensaje. */
.msgr__row-chan { flex: none; padding: 0 4px; border: 1px solid var(--palette-divider); font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase }
.msgr__more { display: flex; justify-content: center; padding: 16px }
/* .avatar fija el texto en blanco y en oscuro su fondo es claro: las iniciales
   desaparecen. Acá el texto es el de la superficie, que se invierte con el tema. */
.msgr .avatar, .thread .avatar { color: var(--palette-surface) }
.msgr__busy .msr { animation: om-spin .8s linear infinite }

/* ---- El hilo ---- */
.thread { display: flex; flex-direction: column; min-width: 0; height: 100% }
.thread__head { flex: none; display: flex; align-items: center; flex-wrap: wrap; gap: 12px; min-height: 52px; padding: 8px 8px 8px 16px; border-bottom: 2px solid var(--palette-text-primary); background: var(--palette-surface) }
/* Base propia y no cero: cuando el ancho no alcanza, lo que sobra baja de linea
   en vez de estrujar el nombre del cliente hasta dejarlo en dos letras. */
.thread__who { flex: 1 1 160px; min-width: 0 }
.thread__head .chip { min-width: 0; overflow: hidden }
.thread__head > .icon-btn:last-child { margin-left: auto }
.thread__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
/* En una linea con puntos suspensivos: partido, el teléfono y el canal se comen
   media pantalla del teléfono antes de que empiece el hilo. */
.thread__sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.thread__back { display: none }
.thread__blank { flex: 1; display: flex; align-items: center; justify-content: center; padding: 24px }

/* Invertido por CSS: los mensajes llegan del más nuevo al más viejo, y así se
   pintan en orden y la vista arranca abajo, que es donde se empieza a leer. */
.thread__body { flex: 1; min-height: 0; display: flex; flex-direction: column-reverse; gap: 10px; padding: 20px 24px; overflow-y: auto; overscroll-behavior: contain; background: var(--palette-background) }
.thread__row { display: flex }
.thread__row--ours { justify-content: flex-end }
/* Cinco burbujas seguidas de la misma persona son una intervención, no cinco.
   El margen va abajo y no arriba: con el contenedor invertido, el borde de abajo
   de un mensaje es el que da contra el siguiente de la misma tanda. */
.thread__row--tight { margin-bottom: -6px }
.thread__stack { display: flex; flex-direction: column; gap: 3px; min-width: 0; max-width: min(72%, 560px) }
.thread__row--ours .thread__stack { align-items: flex-end }
.thread__bubble { display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: 8px 12px; border: 1px solid var(--palette-divider); background: var(--palette-surface); box-shadow: var(--elevation-1) }
/* Lo nuestro va en sólido y lo del cliente en papel: el lado ya lo dice, pero
   el peso lo dice también para quien recorre el hilo de un vistazo. */
.thread__bubble--ours { border-color: var(--palette-secondary); background: var(--palette-secondary); color: var(--palette-surface) }
.thread__bubble--ours ::selection { background: var(--palette-primary); color: #fff }
.thread__text { white-space: pre-wrap; overflow-wrap: anywhere }
/* Una reacción es un emoji y nada más: a tamaño de texto no se distingue. */
.thread__text--emoji { font-size: 30px; line-height: 1.1 }
.thread__quote { display: flex; flex-direction: column; gap: 2px; padding: 2px 0 2px 10px; border-left: 1px solid currentColor; opacity: .72 }
.thread__quote-who { font-weight: 600 }
/* La hora va fuera de la burbuja: dentro de la sólida tendría que ser un gris
   que no contrasta con el negro, y aquí hereda el secundario del sistema. */
.thread__meta { display: flex; align-items: center; gap: 4px; font-size: 11px; line-height: 1.2; color: var(--palette-text-secondary); font-variant-numeric: tabular-nums }
.thread__tick--read { color: var(--palette-primary) }
.thread__tick--failed { color: var(--palette-error) }
/* Mensajes automáticos: la vista previa usa la misma burbuja del chat, sobre su mismo fondo. */
.automsg__preview { padding: 16px; border: 1px solid var(--palette-divider); background: var(--palette-background) }
.automsg__excerpt { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; max-width: 60ch }
.automsg__file { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px }
.automsg__replies { display: flex; flex-direction: column; gap: 4px }
.automsg__reply { padding: 6px 12px; border: 1px solid var(--palette-divider); background: var(--palette-surface); color: var(--palette-secondary); text-align: center }
.thread__day { display: flex; align-items: center; gap: 12px; margin: 6px 0 }
.thread__day::before, .thread__day::after { content: ''; flex: 1; height: 1px; background: var(--palette-divider) }
.thread__day span { flex: none; font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--palette-text-secondary) }
.thread__note { align-self: center; max-width: 80%; padding: 4px 12px; border: 1px solid var(--palette-divider); background: var(--palette-surface); color: var(--palette-text-secondary); text-align: center }
.thread__media img { display: block; max-width: 280px; max-height: 280px; border: 1px solid var(--palette-divider); cursor: zoom-in }
.thread__media audio { width: 260px; max-width: 100% }
.thread__media video { display: block; max-width: 300px; max-height: 300px }
.thread__file { display: inline-flex; align-items: center; gap: 8px; padding: 6px 8px; border: 1px solid currentColor; color: inherit; text-decoration: none }
.thread__file:hover { color: inherit; text-decoration: underline }
.thread__file-name { overflow-wrap: anywhere }
.thread__pending { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; opacity: .7 }
.thread__more { display: flex; justify-content: center; padding: 8px 0 4px }
.thread__foot { flex: none; display: flex; align-items: center; gap: 8px; padding: 8px 16px; border-top: 1px solid var(--palette-divider); background: var(--palette-surface); color: var(--palette-text-secondary) }

/* La caja de respuesta. Ocupa el sitio del pie de solo lectura que habia antes. */
/* La franja de traspaso, arriba de la caja de escribir. */
.handover { flex: none; display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-top: 1px solid var(--palette-divider); background: var(--palette-background) }
.handover--alert { border-left: 3px solid var(--palette-error) }
.handover--alert .msr, .handover--alert > .material-symbols-rounded { color: var(--palette-error) }
.handover__grow { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0 }
.handover__past { flex: none; padding: 6px 14px; border-top: 1px solid var(--palette-divider); background: var(--palette-surface) }

/* El aviso de que una conversacion espera a una persona: es lo unico rojo de la lista. */
.msgr__row-alert { color: var(--palette-error) }
/* Lo que espera respuesta se lee como un correo sin abrir: texto más oscuro, hora
   de color y un punto. Solo late lo que pidió a una persona, que son pocos. */
.msgr__row--waiting .msgr__row-bottom { color: var(--palette-text-primary) }
.msgr__row--waiting .msgr__row-when { color: var(--palette-text-primary); font-weight: 600 }
.msgr__row-dot { flex: none; align-self: center; width: 8px; height: 8px; border-radius: 50%; background: var(--palette-primary) }
.msgr__row--urgent { background: color-mix(in srgb, var(--palette-error) 6%, transparent) }
.msgr__row--urgent:hover { background: color-mix(in srgb, var(--palette-error) 10%, transparent) }
.msgr__row--urgent.msgr__row--on { background: var(--tint-primary) }
.msgr__row--urgent .msgr__row-when { color: var(--palette-error) }
.msgr__row--urgent .msgr__row-dot { background: var(--palette-error); animation: msgr-halo 2.4s ease-out infinite }
@keyframes msgr-halo {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--palette-error) 45%, transparent) }
  70%, 100% { box-shadow: 0 0 0 6px transparent }
}

.composer { flex: none; display: flex; flex-direction: column; gap: 6px; padding: 8px 12px; border-top: 1px solid var(--palette-divider); background: var(--palette-surface) }
.composer__row { display: flex; align-items: flex-end; gap: 4px }
/* Crece con lo que se escribe hasta un tope, y a partir de ahi hace scroll: una respuesta larga
   no puede comerse el hilo que se esta contestando. */
.composer__text { flex: 1; min-height: 38px; max-height: 140px; padding: 9px 12px; border: 1px solid var(--palette-divider); border-radius: 19px; background: var(--palette-background); color: var(--palette-text-primary); font: inherit; resize: none; outline: none; field-sizing: content }
.composer__text:focus { border-color: var(--palette-primary) }
.composer__text:disabled { opacity: .6 }
/* El input real no se ve: lo dispara la etiqueta, que es lo que se puede estilar. */
.composer__pick { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px; border-radius: 50%; cursor: pointer; color: var(--palette-text-secondary) }
.composer__pick:hover { background: var(--palette-action-hover); color: var(--palette-text-primary) }
.composer__pick input { display: none }
.composer__note { display: flex; align-items: center; gap: 8px; padding: 6px 4px; color: var(--palette-text-secondary) }
.composer__note--bad { color: var(--palette-error) }
.composer__clip { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 8px; background: var(--palette-background) }
.composer__clip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 50% }
.composer__rec { flex: 1; display: flex; align-items: center; gap: 8px; padding-left: 8px; color: var(--palette-error) }
.composer__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--palette-error); animation: composer-pulse 1.1s ease-in-out infinite }
@keyframes composer-pulse { 50% { opacity: .25 } }
/* Al cambiar de hilo el cuerpo se remonta y entra: es el único movimiento de la
   pantalla, y es el que dice que lo de abajo ya es otra conversación. */
.thread__body { animation: msgr-rise .22s cubic-bezier(.16, 1, .3, 1) both }
@keyframes msgr-rise { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: none } }

/* Las barras de scroll son parte del diseño: las de fábrica no son de nadie. */
.msgr__list, .thread__body { scrollbar-width: thin; scrollbar-color: var(--palette-divider) transparent }
.msgr__list::-webkit-scrollbar, .thread__body::-webkit-scrollbar { width: 10px }
.msgr__list::-webkit-scrollbar-track, .thread__body::-webkit-scrollbar-track { background: transparent }
.msgr__list::-webkit-scrollbar-thumb, .thread__body::-webkit-scrollbar-thumb { background: var(--palette-divider); border: 3px solid transparent; background-clip: content-box }
.msgr__list::-webkit-scrollbar-thumb:hover, .thread__body::-webkit-scrollbar-thumb:hover { background: var(--palette-text-disabled); background-clip: content-box }

@media (max-width:1280px) { .msgr { grid-template-columns: 300px minmax(0, 1fr) } }
/* De dos paneles a uno: se ve la lista, o se ve el hilo con una flecha para volver. */
@media (max-width:960px) {
  .msgr { --msgr-chrome: 88px; grid-template-columns: minmax(0, 1fr) }
  .msgr__aside { border-right: none }
  .msgr--open .msgr__aside { display: none }
  .msgr:not(.msgr--open) .msgr__main { display: none }
  .thread__back { display: inline-flex }
  /* De los dos que sobran en la cabecera, el que baja es el anuncio: recargar es
     la acción de la pantalla y se queda arriba, a la mano. */
  .thread__head .chip { order: 1 }
}
@media (max-width:600px) {
  .msgr { --msgr-chrome: 80px }
  .msgr__row { padding: 12px }
  /* .appbar__search se esconde en movil para sacarlo de la barra superior. Aca
     el buscador es del panel, no de la barra, y sin el no hay como encontrar un
     hilo en una cuenta con cientos. */
  .msgr__filters .appbar__search { display: flex }
  .thread__body { padding: 16px 12px }
  .thread__stack { max-width: 86% }
  .thread__media img, .thread__media video { max-width: 220px; max-height: 220px }
}
@media (prefers-reduced-motion: reduce) {
  .thread__body { animation: none }
  .msgr__row-dot { animation: none }
  .msgr__busy .msr { animation: none }
}

/* La foto a tamaño completo, encima de todo. Se cierra tocando donde sea: es lo
   que espera cualquiera que haya abierto una imagen en un chat. */
.lightbox { position: fixed; inset: 0; z-index: 1400; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 24px; background: rgba(22, 21, 20, .88); cursor: zoom-out }
.lightbox img { max-width: 92vw; max-height: 82vh; object-fit: contain; cursor: default }
.lightbox__bar { display: flex; align-items: center; gap: 16px; padding: 8px 12px; background: var(--palette-surface); border: 1px solid var(--palette-text-primary); color: var(--palette-text-primary); cursor: default }
.lightbox__bar a { color: var(--palette-text-primary); text-decoration: underline; text-underline-offset: 3px }
.lightbox__bar a:hover { color: var(--palette-primary) }

/* El calendario de una opción de entrega se edita como frases dentro de su tarjeta, no en una
   ventana: las reglas crecen hacia abajo, cada una se lee completa y se acomoda sola cuando el
   ancho no alcanza. La tabla que había antes se deformaba al agregar reglas. */
.cal { border-top: 1px solid var(--palette-divider); margin-top: 16px; padding-top: 8px }
.cal__label { color: var(--palette-text-secondary); margin: 20px 0 8px }
.cal__say { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px }
.cal__say .field { flex: 0 0 auto }
.cal__note { margin-top: 4px }

/* Cada palabra viaja pegada a su campo: al no caber, la frase parte entre pares y no entre una
   etiqueta y el control que nombra. */
.cal__pair { display: inline-flex; align-items: center; gap: 8px }
.cal__pair .field { flex: 0 0 auto }
.cal__reason { flex: 1; min-width: 170px; max-width: 320px }

/* La regla de un día: colgada de una línea para que se lea como un bloque aparte sin ser otra
   tarjeta dentro de la tarjeta. */
.cal__rule { border-left: 1px solid var(--palette-divider); padding-left: 14px; margin: 16px 0 }
.cal__rule .cal__say:last-child { margin-bottom: 0 }

/* Lo que promete la configuración cada día de la semana, mientras se edita. */
.cal__preview { border-top: 1px solid var(--palette-divider); margin-top: 20px; padding-top: 4px }
.cal__week { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(430px, 100%), 1fr)); gap: 2px 32px }
.cal__weekrow { display: flex; align-items: baseline; gap: 10px; padding: 3px 0 }
.cal__weekrow:hover { background: var(--tint-hover) }
.cal__weekday { min-width: 72px }
.cal__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; margin-top: 20px }
