/* Escenas de Facturas. Calcan src/index.css (.invoice-table, .status-hit,
   .table-totals, .m-record-*) con la escala del marco (--t-*). */

/* ── La tabla ─────────────────────────────────────────────────────────── */
.inv-actions { display: flex; align-items: center; gap: 8px; }
.inv-search { width: 180px; }
.inv-add { gap: 4px; padding: 0 14px 0 10px; height: 28px; font-size: var(--t-sm); color: var(--text); }
.inv-add svg { width: 13px; height: 13px; }
.inv-scroll { margin: 0 -9px; container-type: inline-size; }
.inv-table { width: 100%; border-collapse: collapse; font-size: var(--t-base); -webkit-user-select: none; user-select: none; }
/* Todas las columnas a su medida y el cliente con lo que sobra */
.inv-table :is(th, td) { width: 1px; }
.inv-table :is(th, td).client { width: 100%; max-width: 0; }
/* Como la app, que esconde la fecha cuando la tabla no da para ella: aquí,
   con la ventana estrecha, se va el número (lo lleva la ficha). */
@container (max-width: 680px) { .inv-table .nr { display: none; } }
.inv-table th { padding: 6px 9px; text-align: left; font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-subtle); white-space: nowrap; }
.inv-table th.num, .inv-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.inv-table th.center, .inv-table td.center { text-align: center; }
.inv-table td { height: 46px; padding: 0 9px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text); }
.inv-table td:first-child { color: var(--text-muted); }
/* Filete entre filas que no llega a los bordes, y un velo al pasar */
.inv-table tbody tr {
  background-image: linear-gradient(color-mix(in srgb, var(--border) 55%, transparent), color-mix(in srgb, var(--border) 55%, transparent));
  background-size: calc(100% - 24px) 1px; background-position: center bottom; background-repeat: no-repeat;
  transition: background-color var(--duration-fast, 0.08s) var(--ease, ease);
}
.inv-table tbody tr:last-child { background-image: none; }
.inv-table tbody tr:is(:hover, [data-hover]) { background-color: color-mix(in srgb, var(--surface-hover) 35%, transparent); }
.inv-table tr.tr-selected td { background: rgba(128, 128, 128, 0.07); }
.inv-table tr.tr-selected td:first-child { box-shadow: inset 3px 0 0 var(--border-strong); }
.inv-table .cell-copy { cursor: copy; border-radius: 4px; padding: 1px 3px; margin: -1px -3px; transition: background-color var(--spring-fast); }
.inv-table .cell-copy:is(:hover, [data-hover]) { background: var(--control-fill-hover); }
.rate-badge { display: inline-block; margin-right: 5px; padding: 1px 4px; border-radius: var(--radius-xs); font-size: var(--t-xs); font-weight: 600; vertical-align: 1px; }
.rate-badge--yellow { color: var(--yellow); background: var(--yellow-dim); }
.rate-badge--red { color: var(--red); background: var(--red-dim); }
/* El estado es un punto; los días de espera, su cifra en ámbar */
.inv-table .badge-row { display: inline-flex; align-items: center; justify-content: center; gap: 4px; }
.status-hit { display: inline-flex; padding: 8px; margin: -8px; cursor: pointer; }
.status-hit:is(:hover, [data-hover]) .status-dot--paid { background: color-mix(in srgb, var(--green) 70%, transparent); }
.status-hit:is(:hover, [data-hover]) .status-dot--pending { background: color-mix(in srgb, var(--yellow) 70%, transparent); }
.status-dot.pop { animation: inv-dot-pop 0.36s cubic-bezier(0.25, 0.8, 0.25, 1) both; }
@keyframes inv-dot-pop { 0% { transform: scale(0.3); } 60% { transform: scale(1.5); } 100% { transform: scale(1); } }
.inv-table .days { margin-left: 3px; font-size: var(--t-xs); font-weight: 600; color: var(--yellow); max-width: 3em; overflow: hidden; transition: max-width var(--spring-moderate), opacity var(--spring-moderate), margin var(--spring-moderate); }
.inv-table .days--gone { max-width: 0; margin-left: 0; opacity: 0; }
.row-more { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: none; border-radius: var(--radius-pill); background: none; color: var(--text-subtle); cursor: pointer; opacity: 0; transition: opacity var(--spring-fast), background-color var(--spring-fast); }
.inv-table tr:is(:hover, [data-hover]) .row-more { opacity: 1; }
.inv-table td:last-child, .inv-table th:last-child { padding: 0 6px 0 0; }
.row-more:is(:hover, [data-hover]) { background: var(--control-fill-hover); color: var(--text); }

/* La barra de totales: una cápsula de cristal con cada cifra a plomo con
   su columna */
.inv-totals { position: absolute; left: 12px; right: 12px; bottom: 54px; z-index: 5; }
.inv-totals-inner {
  position: relative; height: 40px;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(1.4); backdrop-filter: blur(24px) saturate(1.4);
  box-shadow: var(--float-ring);
}
.inv-totals .tt { position: absolute; top: 0; bottom: 0; display: flex; align-items: center; font-size: var(--t-base); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-muted); white-space: nowrap; }
.inv-totals .tt.num { justify-content: flex-end; }
.inv-totals .tt.strong { color: var(--text); font-weight: 700; }
.inv-totals .tt-label { color: var(--text-muted); }

/* ── La lista del iPhone (MobileRecordGroups y MobileRecordCard) ─────────
   Por meses, como las listas agrupadas de iOS: el mes en pequeño y gris, y
   sus filas en una sola tarjeta con un filete fino que empieza con el texto */
.inv-groups { display: flex; flex-direction: column; gap: 20px; padding-top: 4px; }
.inv-group { display: flex; flex-direction: column; gap: 8px; }
.inv-group-title { margin: 0; padding: 0 16px; font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-muted); }
.inv-group-card { display: flex; flex-direction: column; border-radius: var(--radius-lg); background: var(--surface); overflow: hidden; }
.inv-swipe { position: relative; overflow: hidden; touch-action: pan-y; transition: height var(--spring-moderate), opacity var(--spring-moderate); }
.inv-swipe.leaving { height: 0 !important; opacity: 0; }
.inv-swipe.entering { opacity: 0; }
.inv-card {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px;
  background: var(--surface);
  cursor: pointer;
}
.inv-swipe + .inv-swipe .inv-card::before { content: ""; position: absolute; top: 0; left: 16px; right: 0; height: 0.5px; background: var(--border); }
.inv-swipe.settling .inv-card { transition: transform 0.26s cubic-bezier(0.25, 0.8, 0.25, 1); }
.inv-swipe.settling .card-act { transition: width 0.26s cubic-bezier(0.25, 0.8, 0.25, 1); }
.inv-card-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.inv-card-title { font-size: var(--t-base); font-weight: 600; line-height: 1.25; color: var(--text); text-wrap: balance; }
.inv-card-sub { font-size: var(--t-xs); color: var(--text-subtle); }
.inv-card-sub > span { white-space: nowrap; }
.inv-card-end { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.inv-card-amount { font-size: var(--t-base); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text); }
.card-act { position: absolute; top: 0; bottom: 0; width: 0; display: flex; align-items: center; overflow: hidden; white-space: nowrap; font-size: var(--t-sm); font-weight: 600; }
.card-act > span { padding: 0 16px; }
.card-act--right { left: 0; justify-content: flex-start; }
.card-act--left { right: 0; justify-content: flex-end; background: var(--red); color: #fff; }
.card-act--paid { background: var(--green); color: #0c0c0d; }
.card-act--pending { background: var(--yellow); color: #0c0c0d; }

/* ── El formulario de factura: editor, divisas e importador ──────────────
   Calcan InvoiceForm y FormPanel (.form-group, .form-row, .form-receipt,
   .sheet-nav, .inv-mobile-discard), ExchangeRateField y DatePicker, y
   BulkInvoiceImport (.bulk-*), con la escala del marco. Todo va bajo .fx
   (la ventana o el iPhone de estas escenas). */
.fx .win-body { padding: 0; }
.fx-scene { position: absolute; inset: 0; }

/* La página de detrás, apagada por el velo */
.fx-behind { position: absolute; inset: 0; padding: 8px 24px 0; }
.fx-behind--m { position: relative; inset: auto; padding: 10px 0 0; }
.fx-behind-title { margin-bottom: 16px; font-size: var(--t-2xl); font-weight: 700; letter-spacing: -0.03em; line-height: 1.1; color: var(--text); }
.fx-behind-list { display: flex; flex-direction: column; }
.fx-behind-row {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; height: 44px; padding: 0 9px;
  background-image: linear-gradient(color-mix(in srgb, var(--border) 55%, transparent), color-mix(in srgb, var(--border) 55%, transparent));
  background-size: calc(100% - 24px) 1px; background-position: center bottom; background-repeat: no-repeat;
  font-size: var(--t-base); color: var(--text);
}
.fx-behind--m .fx-behind-list { gap: 20px; }
.fx-behind-group { display: flex; flex-direction: column; gap: 8px; }
.fx-behind-month { margin: 0; padding: 0 16px; font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-muted); }
.fx-behind-card { display: flex; flex-direction: column; border-radius: var(--radius-lg); background: var(--surface); overflow: hidden; }
.fx-behind--m .fx-behind-row { position: relative; height: auto; min-height: 60px; padding: 12px 16px; background: none; }
.fx-behind--m .fx-behind-row + .fx-behind-row::before { content: ""; position: absolute; top: 0; left: 16px; right: 0; height: 0.5px; background: var(--border); }
.fx-behind-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.fx-behind--m .fx-behind-name { font-weight: 600; line-height: 1.25; }
.fx-behind-end { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.fx-behind-nr { order: -1; width: 72px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.fx-behind-sub { font-size: var(--t-xs); color: var(--text-subtle); }
.fx-behind-amt { font-weight: 600; font-variant-numeric: tabular-nums; }
.fx-behind-row--new { animation: fx-row-in var(--spring-slow) both; }
.fx-behind:not(.fx-behind--m) .fx-behind-row--new { animation: fx-row-in var(--spring-slow) both, fx-row-flash 1.4s ease-out 0.2s both; }
@keyframes fx-row-in { from { opacity: 0; transform: translateY(-6px); } }
@keyframes fx-row-flash { from { background-color: var(--surface-hover); } to { background-color: transparent; } }

/* El velo y lo que va encima: el panel, su hoja del iPhone o la ventana
   del importador. Al guardar, el panel se va y el velo con él. */
.fx-scrim { position: absolute; inset: 0; z-index: 2; background: var(--scrim); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); transition: opacity var(--spring-slow-exit); }
.fx-done > .fx-scrim { opacity: 0; pointer-events: none; }
/* En el iPhone, la barra de estado queda por encima del velo, como en iOS */
.fx > .phone-status { z-index: 4; }
.fx-editor { position: absolute; inset: 0; z-index: 3; display: flex; transition: opacity var(--spring-slow-exit), transform var(--spring-slow-exit); }
.fx-done > .fx-editor, .fx-done > .fx-msheet { opacity: 0; transform: translateY(16px); pointer-events: none; }
.fx-editor--panel { justify-content: flex-end; }
/* Sin hoja (quien apunta, o una factura en otra moneda), el panel solo */
.fx-editor--panel .fx-panel { width: clamp(300px, 62%, 400px); }

/* Detrás del editor, la página sin su título (lo cruzaría la barra de la
   hoja); vuelve cuando el editor se cierra */

.fx-panel {
  flex: none; display: flex; flex-direction: column;
  width: clamp(280px, 47%, 330px); padding: 16px 18px 0;
  background: var(--bg); border-left: 1px solid var(--border);
  border-radius: var(--radius-xl) 0 0 var(--radius-xl);
  overflow: hidden;
}
.fx-ph { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.fx-ph-title { font-size: var(--t-base); font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
.fx-x { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; border: none; border-radius: var(--radius-pill); background: var(--control-fill); color: var(--text-muted); font-size: var(--t-xs); cursor: pointer; transition: background-color var(--spring-fast), color var(--spring-fast); }
.fx-x:is(:hover, [data-hover]) { background: var(--control-fill-hover); color: var(--text); }

/* La hoja de abajo del iPhone (panel--sheet) con su barra (sheet-nav), que
   se queda arriba al desplazar la hoja. El hueco de abajo es el de la
   ventana que pasa por debajo del suelo de la escena. */
.fx-msheet {
  position: absolute; left: 0; right: 0; top: 62px; bottom: 0; z-index: 3;
  padding: 0 16px 76px; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none;
  background: var(--bg); border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  transition: opacity var(--spring-slow-exit), transform var(--spring-slow-exit);
}
.fx-msheet::-webkit-scrollbar { display: none; }
.fx-nav { position: sticky; top: 0; z-index: 2; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px; margin: 0 -16px 16px; padding: 20px 16px 12px; background: var(--bg); }
.fx-grabber { position: absolute; top: 8px; left: 50%; width: 36px; height: 5px; margin-left: -18px; border-radius: var(--radius-pill); background: var(--border-strong); }
.fx-nav-title { font-size: var(--t-base); font-weight: 600; text-align: center; white-space: nowrap; color: var(--text); }
.fx-nav-btn { justify-self: start; padding: 4px 0; border: none; background: none; font-size: var(--t-base); color: var(--text-muted); cursor: pointer; transition: color var(--spring-fast); }
.fx-nav-btn--primary { justify-self: end; color: var(--brand); font-weight: 600; }

/* Los editores son listas agrupadas de iOS (FormRows.jsx): cada grupo, una
   tarjeta; cada dato, una fila con el rótulo a la izquierda y el valor a la
   derecha, sin caja. Entre filas, el filete fino de Ajustes, que no llega a
   los bordes. En la ventana las filas van algo más bajas que los 44 px de
   la app para que el panel quepa entero en la escena. */
.fx { --fx-row-h: 34px; --fx-gap: 10px; --fx-pad: 14px; }
.phone.fx { --fx-row-h: 44px; --fx-gap: 14px; --fx-pad: 16px; }
.fx-group { margin-bottom: var(--fx-gap); padding: 0 var(--fx-pad); border-radius: var(--radius-lg); background: var(--surface); }
.fx-group > * + * { border-top: 0.5px solid var(--border); }
.fx-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: var(--fx-row-h); }
.fx-row-label { display: flex; flex-direction: column; gap: 1px; flex: 0 1 auto; max-width: 60%; padding: 6px 0; font-size: var(--t-base); line-height: 1.25; color: var(--text); }
.fx-row-hint { display: grid; font-size: var(--t-sm); color: var(--text-muted); }
/* La «i» del IRPF, tras el rótulo como en FormRow; su globo sale de la fila. */
.fx-row-name .info-anchor { margin-left: 6px; vertical-align: -1px; }
.fx-row:has(.info-anchor), .fx-group:has(.info-anchor) { overflow: visible; }
.fx-suggested { margin-left: 6px; color: var(--text-subtle); }
.fx-row-control { display: flex; align-items: center; justify-content: flex-end; gap: 10px; flex: 1 1 0; min-width: 0; }
.fx-input {
  -webkit-appearance: none; appearance: none; box-sizing: border-box;
  width: 100%; min-width: 0; padding: 4px 0; border: none; border-radius: 0; outline: none;
  background: none; color: var(--text);
  font: inherit; font-size: var(--t-base); line-height: 1.4; text-align: right; font-variant-numeric: tabular-nums;
}
.fx-input::placeholder { color: var(--text-subtle); }
/* Como en iOS, el campo de una fila no se rodea al escribir */
.fx .fx-input[data-focus] { box-shadow: none; }
/* La fecha, en su cápsula gris */
.fx-date { padding: 3px 12px; border-radius: var(--radius-pill); background: var(--control-fill-hover); font-variant-numeric: tabular-nums; color: var(--text); white-space: nowrap; }
/* El interruptor de iOS (Switch) */
.fx-switch { position: relative; flex: none; width: 44px; height: 26px; padding: 0; border: none; border-radius: var(--radius-pill); background: var(--control-fill-hover); cursor: pointer; transition: background-color var(--spring-fast); }
.fx-switch.is-on { background: var(--green); }
.fx-switch-thumb { position: absolute; top: 2px; left: 2px; width: 22px; height: 22px; border-radius: var(--radius-pill); background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18); transition: transform var(--spring-fast); }
.fx-switch.is-on .fx-switch-thumb { transform: translateX(18px); }
/* Lo que entra o sale (ROW_REVEAL): abre o cierra su hueco y se funde */
.fx-slot { display: grid; grid-template-rows: 1fr; transition: grid-template-rows var(--spring-moderate), opacity var(--spring-moderate), border-color var(--spring-moderate); }
.fx-slot > * { min-height: 0; overflow: hidden; }
.fx-slot--away { grid-template-rows: 0fr; opacity: 0; border-top-color: transparent !important; transition-duration: 120ms; }
.fx-slot > .fx-group { margin-bottom: 0; }
.fx-panel > .fx-slot, .fx-msheet > .fx-slot { margin-bottom: var(--fx-gap); transition: grid-template-rows var(--spring-moderate), opacity var(--spring-moderate), margin var(--spring-moderate); }
.fx-panel > .fx-slot--away, .fx-msheet > .fx-slot--away { margin-bottom: 0; }

/* El pie, como un recibo (FormReceipt): las partes con el punto de su
   color y, tras un filete, el total grande */
.fx-group.fx-receipt { padding-top: 4px; padding-bottom: 2px; }
.fx-group.fx-receipt > * + * { border-top: none; }
.fx-receipt-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: calc(var(--fx-row-h) * 0.66); font-size: var(--t-sm); font-variant-numeric: tabular-nums; }
.fx-receipt-row[hidden] { display: none; }
.fx-receipt-label { display: inline-flex; align-items: center; gap: 8px; color: var(--text-muted); }
.fx-receipt-value { color: var(--text); white-space: nowrap; }
.fx-group.fx-receipt > .fx-receipt-row--total { min-height: calc(var(--fx-row-h) * 1.3); margin-top: 4px; padding: 6px 0; border-top: 0.5px solid var(--border); font-size: var(--t-base); color: var(--text); }
.fx-group.fx-receipt--solo { padding-top: 0; }
.fx-group.fx-receipt--solo > .fx-receipt-row--total { margin-top: 0; border-top: none; }
.fx-receipt-total { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; }
.fx-receipt-total strong { font-size: var(--t-2xl); font-weight: 700; letter-spacing: -0.03em; line-height: 1.1; white-space: nowrap; }
.fx-receipt-note { font-size: var(--t-sm); color: var(--text-subtle); white-space: nowrap; }
.fx-receipt-note:empty { display: none; }
.fx-tone { flex: none; width: 7px; height: 7px; border-radius: var(--radius-pill); }
.fx-tone--income { background: var(--green); }
.fx-tone--vat { background: var(--yellow); }
.fx-tone--irpf { background: var(--red); }

/* «Descartar» en la hoja del iPhone: una fila más, en rojo */
.fx-discard { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 44px; padding: 0; border: none; border-radius: var(--radius-lg); background: var(--surface); color: var(--red); font: inherit; font-size: var(--t-base); cursor: pointer; transition: background-color var(--spring-fast); }
.fx-discard:is(:hover, [data-hover]) { background: var(--surface-hover); }

/* El desplegable en su fila (SelectDropdown): el valor en gris y su flecha,
   como un menú de iOS. El cliente (ClientPicker) va en negro y sin flecha;
   sin elegir, «Elegir» apagado. El menú cuelga de la fila. */
.fx .a-dd-wrap { position: relative; min-width: 0; }
.fx .fx-dd {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; gap: 6px; width: auto; max-width: 100%; min-height: 0; padding: 4px 0;
  border: none; border-radius: var(--radius-sm); outline: none; background: none;
  color: var(--text-muted); font: inherit; font-size: var(--t-base); line-height: 1.4; cursor: pointer; text-align: right;
  transition: color var(--spring-fast);
}
.fx .fx-dd:is(:hover, [data-hover]), .fx .fx-dd[data-open] { color: var(--text); }
.fx .fx-dd .a-dd-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fx .fx-dd--pick { color: var(--text); }
.fx .fx-dd--empty { color: var(--text-subtle); }
/* Medido contra su panel (popoverSide), el valor de una fila cae en el
   tercio derecho: el menú se alinea por la derecha */
.fx .fx-row-control .a-dd-menu { left: auto; right: 0; min-width: 150px; transform-origin: top right; }
.fx .fx-dd .a-dd-chev { display: inline-flex; color: var(--text-subtle); transition: transform var(--spring-moderate); }
.fx .fx-dd--pick .a-dd-chev { display: none; }
/* Sin la caja ni el anillo del campo suelto (.a-input), también al pasar */
.fx .fx-row-control .a-dd.fx-dd { background: none; box-shadow: none; }
/* En el iPhone, un desplegable abre el menú del sistema (useCoarsePointer):
   filas altas con filete y una ✓ en lo elegido, sin el gris */
.phone .fx .fx-dd:not(.fx-dd--pick) + .a-dd-menu { min-width: 190px; padding: 0; border-radius: 14px; overflow: hidden; }
.phone .fx .fx-dd:not(.fx-dd--pick) + .a-dd-menu .a-dd-item { display: flex; align-items: center; gap: 6px; padding: 11px 16px 11px 12px; border-radius: 0; background: none; font-weight: 400; }
.phone .fx .fx-dd:not(.fx-dd--pick) + .a-dd-menu .a-dd-item + .a-dd-item { border-top: 0.5px solid var(--border); }
.phone .fx .fx-dd:not(.fx-dd--pick) + .a-dd-menu .a-dd-item::before { content: ""; flex: none; width: 16px; font-weight: 600; }
.phone .fx .fx-dd:not(.fx-dd--pick) + .a-dd-menu .a-dd-item.selected::before { content: "✓"; }
.phone .fx .fx-dd:not(.fx-dd--pick) + .a-dd-menu .fluid-highlight { display: none; }
.fx .fx-dd[data-open] .a-dd-chev { transform: rotate(180deg); }
.fx .a-dd-menu {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 20; min-width: 100%; padding: 4px;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  -webkit-backdrop-filter: blur(20px) saturate(1.4); backdrop-filter: blur(20px) saturate(1.4);
  box-shadow: var(--float-ring); border-radius: var(--radius);
  transform-origin: top left; transform: scale(0.96); opacity: 0; pointer-events: none;
  transition: transform var(--spring-moderate-exit), opacity var(--spring-moderate-exit);
}
.fx .a-dd-menu[data-side="end"] { left: auto; right: 0; transform-origin: top right; }
.fx .a-dd-menu.open { transform: none; opacity: 1; pointer-events: auto; transition: transform var(--spring-moderate), opacity var(--spring-moderate); }
.fx .a-dd-item { position: relative; z-index: 1; padding: 6px 10px; border-radius: var(--radius-sm); font-size: var(--t-base); color: var(--text); white-space: nowrap; cursor: default; }
.fx .a-dd-item.selected { background: var(--surface-hover); font-weight: 600; }
.fx .a-dd-menu .fluid-highlight { border-radius: var(--radius-sm); }

.fx-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.fx-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 16px; border: none; border-radius: var(--radius-pill);
  background: var(--control-fill); color: var(--text-muted);
  font: inherit; font-size: var(--t-sm); font-weight: 500; line-height: 1.4; white-space: nowrap; cursor: pointer;
  transition: background-color var(--spring-fast), color var(--spring-fast), opacity var(--spring-moderate);
}
.fx-btn:is(:hover, [data-hover]) { background: var(--control-fill-hover); color: var(--text); }
.fx-btn--primary { padding: 7px 20px; color: var(--brand); font-weight: 600; }
.fx-btn--primary:is(:hover, [data-hover]) { color: var(--brand); }
.fx-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.fx-btn--away { opacity: 0; pointer-events: none; }
.fx-btn--sm { padding: 4px 12px; font-size: var(--t-xs); }


@keyframes fx-fade-in { from { opacity: 0; } }

/* ── El tipo de cambio (ExchangeRateField) y su calendario (DatePicker) ── */
.fx-row-control .fx-input + .fx-cal-btn { margin-right: -5px; }
.fx-cal-btn { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; border: none; border-radius: var(--radius-sm); background: none; color: var(--text-muted); cursor: pointer; transition: color var(--spring-fast), background-color var(--spring-fast); }
.fx-cal-btn:is(:hover, [data-hover]) { color: var(--text); background: var(--surface-hover); }
/* Lo que flota dentro del marco: el calendario y la ficha de la «!» */
.fx-float {
  position: absolute; z-index: 30;
  transform-origin: top left; transform: translateY(4px) scale(0.98); opacity: 0; pointer-events: none;
  transition: transform var(--spring-moderate-exit), opacity var(--spring-moderate-exit);
}
.fx-float[data-side="end"] { transform-origin: top right; }
.fx-float[data-side="center"] { transform-origin: top center; }
.fx-float[data-up] { transform-origin: bottom left; }
.fx-float[data-up][data-side="end"] { transform-origin: bottom right; }
.fx-float[data-up][data-side="center"] { transform-origin: bottom center; }
.fx-float.open { transform: none; opacity: 1; pointer-events: auto; transition: transform var(--spring-moderate), opacity var(--spring-moderate); }
.fx-cal { width: 232px; padding: 12px; background: var(--surface); box-shadow: var(--float-ring); border-radius: var(--radius); }
.phone .fx-cal { width: 280px; }
.fx-cal-shortcut { display: block; width: 100%; margin-bottom: 8px; padding: 6px 8px; border: none; border-radius: var(--radius-sm); background: var(--control-fill); color: var(--text); font: inherit; font-size: var(--t-xs); cursor: pointer; transition: background-color var(--spring-fast); }
.fx-cal-shortcut:is(:hover, [data-hover]) { background: var(--control-fill-hover); }
.fx-cal-shortcut.selected { background: var(--surface-hover); font-weight: 600; }
.fx-cal-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.fx-cal-arrow { width: 24px; height: 24px; padding: 0; border: none; border-radius: var(--radius-sm); background: none; color: var(--text-muted); font: inherit; font-size: var(--t-base); cursor: pointer; transition: background-color var(--spring-fast), color var(--spring-fast); }
.fx-cal-arrow:is(:hover, [data-hover]) { background: var(--surface-hover); color: var(--text); }
.fx-cal-month { font-size: var(--t-sm); font-weight: 600; color: var(--text); }
.fx-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.fx-cal-dayname { padding: 3px 0; text-align: center; font-size: var(--t-xs); font-weight: 500; color: var(--text-muted); }
.fx-cal-day { padding: 4px 0; border: none; border-radius: var(--radius-sm); background: none; color: var(--text); font: inherit; font-size: var(--t-xs); font-variant-numeric: tabular-nums; cursor: pointer; transition: background-color var(--spring-fast); }
.phone .fx-cal-day { padding: 6px 0; }
.fx-cal-day:is(:hover, [data-hover]) { background: color-mix(in srgb, var(--surface-hover) 60%, transparent); }
.fx-cal-day.selected { background: var(--surface-hover); font-weight: 600; }

/* ── El importador (BulkInvoiceImport) ───────────────────────────────── */
.fx-modal-wrap { position: absolute; inset: 0; z-index: 3; display: flex; justify-content: center; align-items: flex-start; padding: 22px 16px 0; }
.fx-modal { box-sizing: border-box; width: min(680px, 100%); padding: 22px 20px; background: var(--surface); border-radius: var(--radius-xl); }
.fx-modal-wrap--m { top: 54px; padding: 12px 12px 0; }
.fx-modal--m { padding: 20px 16px; }
/* En el iPhone la tabla es la misma y se desplaza de lado; sus columnas,
   a la medida de la letra del móvil */
.phone .fx-im-table { --col-k: 1.3; }
.phone .fx-im-input { height: 34px; }
.phone .fx-lead, .phone .fx-im-total { min-height: 34px; }
.fx-modal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.fx-modal-head h2 { font-size: var(--t-base); font-weight: 700; letter-spacing: -0.02em; line-height: 1.25; color: var(--text); text-wrap: balance; }
.fx-drop {
  display: flex; flex-direction: column; align-items: center; gap: 6px; margin-bottom: 16px; padding: 24px 20px;
  border: 2px dashed var(--border-strong); border-radius: var(--radius);
  text-align: center; cursor: pointer;
  transition: border-color var(--spring-fast), background-color var(--spring-fast), padding var(--spring-moderate);
}
.fx-drop:is(:hover, [data-hover]), .fx-drop--active { border-color: var(--blue); background: var(--blue-dim); }
.fx-drop-icon { display: inline-flex; color: var(--text-muted); }
.fx-drop--active .fx-drop-icon { color: var(--blue); }
.fx-drop-text { font-size: var(--t-base); font-weight: 500; color: var(--text); }
.fx-drop-hint { font-size: var(--t-xs); color: var(--text-muted); }
/* Con filas, la zona se queda más baja para que quepan */
.fx-drop:has(~ .fx-im-wrap:not(.fx-im-wrap--away)) { padding: 12px 16px; }
.fx-drop:has(~ .fx-im-wrap:not(.fx-im-wrap--away)) .fx-drop-icon svg { width: 20px; height: 20px; }
.fx-im-wrap { overflow-x: auto; margin-bottom: 4px; border: 1px solid var(--border); border-radius: var(--radius); scrollbar-width: none; transition: opacity var(--spring-moderate); }
.fx-im-wrap::-webkit-scrollbar { display: none; }
.fx-im-wrap--away { display: none; }
.fx-im-table { width: 100%; min-width: calc(550px * var(--col-k, 1)); table-layout: fixed; border-collapse: collapse; font-size: var(--t-sm); }
.fx-im-table th { padding: 7px 4px; border-bottom: 1px solid var(--border); font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-subtle); white-space: nowrap; }
.fx-im-table th.num, .fx-im-table td.num { text-align: right; }
.fx-im-table td { padding: 6px 4px; border-bottom: 1px solid var(--border); color: var(--text); white-space: nowrap; }
.fx-im-row:last-child td { border-bottom: none; }
.fx-im-row { animation: fx-row-in var(--spring-moderate) both; transition: opacity var(--spring-moderate-exit); }
.fx-im--out { opacity: 0; }
.fx-im--err td:not(:first-child):not(:last-child) { opacity: 0.4; }
.fx-lead { display: flex; align-items: center; justify-content: center; min-height: 28px; }
.fx-im-input { box-sizing: border-box; width: 100%; height: 28px; padding: 0 6px; border: none; border-radius: var(--radius-sm); outline: none; background: var(--surface-hover); color: var(--text); font: inherit; font-size: var(--t-sm); transition: background-color var(--spring-fast), box-shadow var(--spring-fast), color var(--spring-moderate); }
.fx-im-input:is(:focus, [data-focus]) { box-shadow: var(--focus-ring); }
.fx-im-input:disabled { opacity: 1; }
.fx-im-num { text-align: right; font-variant-numeric: tabular-nums; }
/* Mientras espera o se lee, la fila no enseña lo que aún no se ha leído */
.fx-im--reading .fx-im-input { color: transparent; }
.fx-im--reading .fx-chip, .fx-im--reading .fx-im-x { visibility: hidden; }
.fx-im--now .fx-im-input { background-color: var(--control-fill-hover); background-image: linear-gradient(90deg, transparent 40%, var(--shimmer-glint) 50%, transparent 60%); background-size: 300% 100%; background-position: var(--shimmer-at) 0; animation: shimmer-at 1.8s cubic-bezier(0.45, 0, 0.55, 1) infinite; }
.fx-im-client { display: flex; align-items: center; gap: 6px; }
.fx-im-client .fx-im-input { flex: 1; min-width: 0; }
.fx-chip { flex: none; padding: 1px 5px; border-radius: var(--radius-xs); background: var(--control-fill); font-size: var(--t-xs); font-weight: 600; color: var(--text-muted); }
.fx-im-total { display: flex; align-items: center; justify-content: flex-end; min-height: 28px; font-variant-numeric: tabular-nums; }
.fx-im-status { text-align: center; }
.fx-im-del { text-align: center; }
.fx-im-x { width: 22px; height: 22px; padding: 0; border: none; border-radius: var(--radius-sm); background: none; color: var(--text-subtle); font-size: var(--t-xs); cursor: pointer; transition: background-color var(--spring-fast), color var(--spring-fast); }
.fx-im-x:is(:hover, [data-hover]) { color: var(--red); background: var(--red-dim); }
/* La señal de cada fila (RowBadge): círculo vacío en cola, esqueleto
   mientras se lee y luego ✓, ! ámbar (se pulsa) o ! roja */
.fx-badge { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; padding: 0; border: none; border-radius: 50%; font: inherit; font-size: var(--t-xs); font-weight: 700; line-height: 1; flex-shrink: 0; }
.fx-badge--queued { box-shadow: inset 0 0 0 1.5px var(--border-strong); }
.fx-badge--ok { background: var(--green-dim); color: var(--green); }
.fx-badge--warn { background: var(--yellow-dim); color: var(--yellow); cursor: pointer; }
.fx-badge--err { background: var(--red-dim); color: var(--red); cursor: pointer; }
button.fx-badge { transition: filter var(--spring-fast); }
button.fx-badge:is(:hover, [data-hover]) { filter: brightness(1.25); }
.fx-badge--pop { animation: inv-dot-pop 0.36s cubic-bezier(0.25, 0.8, 0.25, 1) both; }
.fx-pop { width: 260px; padding: 10px 12px; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; background: color-mix(in srgb, var(--surface) 88%, transparent); -webkit-backdrop-filter: blur(20px) saturate(1.4); backdrop-filter: blur(20px) saturate(1.4); box-shadow: var(--float-ring); border-radius: var(--radius); }
.fx-pop-text { font-size: var(--t-sm); line-height: 1.4; color: var(--text); }
.fx-pop-ok { color: var(--text); }
/* Los archivos que llegan del Finder */
.fx-files { position: absolute; right: 52px; top: 70px; z-index: 6; width: 64px; height: 64px; cursor: grab; touch-action: none; transition: opacity var(--spring-moderate); }
.fx-files--drag { cursor: grabbing; transition: none; }
.fx-files--gone { opacity: 0; pointer-events: none; }
.fx-file { position: absolute; left: calc(var(--i) * 7px + 6px); top: calc(var(--i) * -4px + 10px); transform: rotate(calc((var(--i) - 1) * 7deg)); filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.3)); }
.fx-file svg { display: block; }
.fx-files-n { position: absolute; right: -2px; top: -2px; display: grid; place-items: center; min-width: 20px; height: 20px; padding: 0 5px; border-radius: var(--radius-pill); background: var(--red); color: #fff; font-size: 11px; font-weight: 700; }

/* Con «reducir movimiento», solo fundidos: nada se desplaza */
@media (prefers-reduced-motion: reduce) {
  .fx-behind-row--new, .fx-behind:not(.fx-behind--m) .fx-behind-row--new, .fx-im-row, .fx-badge--pop { animation: fx-fade-in var(--spring-moderate) both; }
  .fx-done > .fx-editor,
.fx-done > .fx-msheet,
.fx-float,
.fx-float.open,
.fx .a-dd-menu { transform: none; }
  .fx .fx-dd .a-dd-chev { transition: none; }
}
