/* ============================================================
   Tu Nómina · Design Layer v1
   Sits on top of Bootstrap 3 (Angle template). Token-first.
   Type: Geist (sans) + Geist Mono (tabular numerics).
   Aesthetic: modern enterprise, hairline borders, generous
   whitespace, slate-blue accent. Light theme only (v1).
   ============================================================ */

/* ---------- Fonts (self-hosted, variable) ---------- */
@font-face {
  font-family: "Geist";
  src: url("/assets/fonts/GeistVF.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("/assets/fonts/GeistMonoVF.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---------- Design tokens ---------- */
:root {
  /* Neutrals — slate-tinted gray scale */
  --tn-c-0:   #ffffff;
  --tn-c-25:  #fafafa;
  --tn-c-50:  #f5f6f8;
  --tn-c-100: #ebedf0;
  --tn-c-150: #dde0e6;
  --tn-c-200: #cdd1da;
  --tn-c-300: #a8aebc;
  --tn-c-400: #777e8c;
  --tn-c-500: #525864;
  --tn-c-600: #3a3f4a;
  --tn-c-700: #262a33;
  --tn-c-800: #181b22;
  --tn-c-900: #0c0e13;

  /* Accent — deep slate blue */
  --tn-a-50:  #eff4ff;
  --tn-a-100: #dbe6fe;
  --tn-a-200: #bfd2fe;
  --tn-a-400: #5f88f5;
  --tn-a-500: #3a64e8;
  --tn-a-600: #2549d4;
  --tn-a-700: #1d4ed8;   /* canonical accent */
  --tn-a-800: #1e3a99;
  --tn-a-900: #1d2f7a;

  /* Semantic */
  --tn-ok-50:   #ecfdf5;
  --tn-ok-600:  #059669;
  --tn-ok-700:  #047857;
  --tn-warn-50: #fffbeb;
  --tn-warn-600:#d97706;
  --tn-warn-700:#b45309;
  --tn-err-50:  #fef2f2;
  --tn-err-600: #dc2626;
  --tn-err-700: #b91c1c;

  /* Surface roles */
  --tn-surface-page:  var(--tn-c-25);
  --tn-surface-card:  var(--tn-c-0);
  --tn-surface-sunk:  var(--tn-c-50);
  --tn-border-soft:   var(--tn-c-100);
  --tn-border:        var(--tn-c-150);
  --tn-border-strong: var(--tn-c-200);

  --tn-text:       var(--tn-c-800);
  --tn-text-muted: var(--tn-c-500);
  --tn-text-soft:  var(--tn-c-400);

  /* Type */
  --tn-font-sans: "Geist", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --tn-font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --tn-fz-xs:  11px;
  --tn-fz-sm:  12px;
  --tn-fz-md:  14px;
  --tn-fz-lg:  16px;
  --tn-fz-xl:  20px;
  --tn-fz-2xl: 28px;
  --tn-lh-tight: 1.25;
  --tn-lh-norm:  1.5;

  /* Space (4px base) */
  --tn-s-1: 4px;
  --tn-s-2: 8px;
  --tn-s-3: 12px;
  --tn-s-4: 16px;
  --tn-s-5: 20px;
  --tn-s-6: 24px;
  --tn-s-8: 32px;
  --tn-s-10: 40px;

  /* Radii */
  --tn-r-sm: 4px;
  --tn-r-md: 6px;
  --tn-r-lg: 8px;
  --tn-r-xl: 12px;

  /* Effects */
  --tn-ring: 0 0 0 3px var(--tn-a-100);
  --tn-shadow-sm: 0 1px 2px rgba(15, 18, 27, 0.04);
  --tn-shadow-md: 0 4px 12px rgba(15, 18, 27, 0.06), 0 1px 2px rgba(15, 18, 27, 0.04);
  --tn-shadow-pop: 0 12px 32px -8px rgba(15, 18, 27, 0.18), 0 4px 12px rgba(15, 18, 27, 0.06);

  /* Motion */
  --tn-ease: cubic-bezier(0.2, 0.6, 0.2, 1);
  --tn-dur-quick: 120ms;
  --tn-dur-norm:  200ms;
}

/* ---------- Base ---------- */
html, body {
  background: var(--tn-surface-page);
}
body {
  font-family: var(--tn-font-sans) !important;
  font-size: var(--tn-fz-md);
  font-feature-settings: "ss01", "cv11"; /* Geist alt forms — humanist a, single-story g */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: var(--tn-text);
  line-height: var(--tn-lh-norm);
  letter-spacing: -0.005em;
}
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
  font-family: var(--tn-font-sans);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--tn-c-900);
  line-height: var(--tn-lh-tight);
}
h1, .h1 { font-size: var(--tn-fz-2xl); }
h2, .h2 { font-size: var(--tn-fz-xl); }
h3, .h3 { font-size: var(--tn-fz-lg); }
h4, .h4 { font-size: var(--tn-fz-md); font-weight: 600; }
h5, .h5 { font-size: var(--tn-fz-sm); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--tn-text-muted); }

a { color: var(--tn-a-700); text-decoration: none; transition: color var(--tn-dur-quick) var(--tn-ease); }
a:hover, a:focus { color: var(--tn-a-800); text-decoration: none; }

hr { border-color: var(--tn-border-soft); margin: var(--tn-s-6) 0; }

/* Tabular numerics anywhere a number lives */
.tn-num, td:has(> .tn-num), code, kbd, samp {
  font-family: var(--tn-font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "zero" 1;
  letter-spacing: -0.01em;
}

/* ---------- Layout shell ---------- */
.wrapper {
  background: var(--tn-surface-page);
  min-height: 100vh;
}
/* THE width-cap that defeated v3-v5: Angle ships
     .layout-h .wrapper > section { max-width: 1140px; margin: auto; }
   and the page body has class="layout-h", so <section> caps content at 1140
   regardless of what .content-wrapper does. Undo it. */
.layout-h .wrapper > section,
body.layout-h .wrapper > section {
  max-width: none !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
/* And Angle's app.css media-query sets padding: 20px on .content-wrapper at >=768px. */
.content-wrapper,
.layout-h .wrapper > section > .content-wrapper {
  padding: var(--tn-s-3) var(--tn-s-3) !important;   /* 12px */
  max-width: none !important;
  width: auto !important;
  margin: 0 !important;
}
.panel { width: 100%; }
.panel .table-responsive { width: 100%; }
.panel .table { width: 100% !important; table-layout: auto; }

/* Opt-IN narrow container for sparse pages (2-col data, few-column calc tables).
   The shell above uncaps width for wide data tables; pages that don't need the
   full 1920 add `tn-narrow` to their .content-wrapper (or any container) to get a
   centered, readable cap. Reusable across finiquito/liquidacion-style pages. */
.tn-narrow,
.content-wrapper.tn-narrow,
.layout-h .wrapper > section > .content-wrapper.tn-narrow,
body.layout-h .wrapper > section > .content-wrapper.tn-narrow {
  max-width: 1200px !important;
  width: auto !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* ---------- Panel (Bootstrap 3 card) ---------- */
.panel,
.panel-default {
  background: var(--tn-surface-card);
  border: 1px solid var(--tn-border);
  border-radius: var(--tn-r-lg);
  box-shadow: var(--tn-shadow-sm);
  margin-bottom: var(--tn-s-6);
}
.panel > .panel-heading,
.panel-default > .panel-heading {
  background: var(--tn-surface-card);
  border-bottom: 1px solid var(--tn-border-soft);
  border-top-left-radius: var(--tn-r-lg);
  border-top-right-radius: var(--tn-r-lg);
  padding: var(--tn-s-3) var(--tn-s-4);   /* slimmer than the original 20/24 */
  color: var(--tn-c-900);
  font-weight: 600;
}
/* Heading often acts as a filter bar (Cuenta select + Enviar). Defang the
   nested Bootstrap form-group margins + Angle's stray <br> spacer, and center
   the row's children vertically with flex. */
.panel-heading .row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin-left: -8px;
  margin-right: -8px;
}
.panel-heading .row > [class*="col-"] {
  padding-left: 8px;
  padding-right: 8px;
  display: flex;
  align-items: center;
}
.panel-heading .form-group { margin-bottom: 0; flex: 1; }
.panel-heading br { display: none; }
.panel-heading .control-label {
  padding-top: 0;
  padding-bottom: 0;
  margin-bottom: 0;
  white-space: nowrap;
  flex: 0 0 auto;
  text-align: left;
  width: auto;
  margin-right: 8px;
}
.panel-heading .form-control { flex: 1; }
.panel-body { padding: var(--tn-s-5) var(--tn-s-6); }
.panel-footer {
  background: var(--tn-surface-sunk);
  border-top: 1px solid var(--tn-border-soft);
  padding: var(--tn-s-4) var(--tn-s-6);
  border-bottom-left-radius: var(--tn-r-lg);
  border-bottom-right-radius: var(--tn-r-lg);
}

/* Panel that contains a table — drop the body padding so the table goes edge-to-edge */
.panel-body > .table-responsive,
.panel-body > .table { margin: calc(var(--tn-s-5) * -1) calc(var(--tn-s-6) * -1); width: auto; }
.panel-body > .table-responsive > .table { margin: 0; }

/* ---------- Table ---------- */
.table {
  width: 100%;
  margin-bottom: 0;
  color: var(--tn-text);
  font-size: var(--tn-fz-md);
  background: transparent;
  border-collapse: separate;
  border-spacing: 0;
}
/* Header-row detection is content-driven, not position-driven: a row is a header
   only if its cells wrap content in <h5> (Angle's column-header pattern used by
   historialFiniquitos.php). Position-based first-child styling was clobbering
   the first data row on tables that emit data starting at <tr>#1 like
   CalculoFiniquitos.php. */
.table > thead > tr:first-child > td,
.table > thead > tr:first-child > th,
.table > tbody > tr:has(> td > h5) > td,
.table > tbody > tr:has(> td > h5) > th {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: var(--tn-fz-xs);
  font-weight: 600;
  color: var(--tn-text-muted);
  padding: var(--tn-s-3) var(--tn-s-4);
  background: var(--tn-surface-sunk);
  border-top: 1px solid var(--tn-border-soft);
  border-bottom: 1px solid var(--tn-border);
  vertical-align: middle;
}
.table > tbody > tr:has(> td > h5) h5,
.table > tbody > tr:has(> td > h5) .h5 {
  font-size: inherit;
  font-weight: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  color: inherit;
  margin: 0;
  text-shadow: none;
}
.table > tbody > tr:has(> td > h5) strong { font-weight: 600; }

/* Some Tu Nómina tables (e.g. CalculoFiniquitos's "Cálculo negociado") open
   <thead> and never close it before </table>, so every data row lives inside
   <thead>. Only the literal first <tr> is a real header; siblings are data —
   neutralize the header styling on them. */
.table > thead > tr:not(:first-child) > td,
.table > thead > tr:not(:first-child) > th {
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--tn-fz-md);
  font-weight: 400;
  color: var(--tn-text);
  padding: var(--tn-s-3) var(--tn-s-4);
  background: var(--tn-surface-card);
  border-top: 1px solid var(--tn-border-soft);
  border-bottom: 0;
  vertical-align: middle;
}
.table > thead > tr:not(:first-child) strong { font-weight: 600; }
.table.tn-table-compact > thead > tr:not(:first-child) > td {
  padding: 5px var(--tn-s-3);
  line-height: 1.35;
}

/* Header-row OPT-IN class — for legacy list pages where the header row uses
   plain <td> cells (not <th>, not wrapped in <h5>). Add class="tn-table-head"
   to the <tr> and the row gets the design-system header treatment without
   per-cell edits. Used by ListaNominasChecador.php. */
.table > tbody > tr.tn-table-head > td,
.table > thead > tr.tn-table-head > td,
.table > tfoot > tr.tn-table-head > td,
.table > tr.tn-table-head > td {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: var(--tn-fz-xs);
  font-weight: 600;
  color: var(--tn-text-muted);
  padding: var(--tn-s-3) var(--tn-s-4);
  background: var(--tn-surface-sunk) !important;
  border-top: 1px solid var(--tn-border-soft) !important;
  border-bottom: 1px solid var(--tn-border) !important;
  vertical-align: middle;
  text-align: center;
}
.table > tbody > tr.tn-table-head > td *,
.table > thead > tr.tn-table-head > td *,
.table > tfoot > tr.tn-table-head > td *,
.table > tr.tn-table-head > td * {
  text-transform: inherit;
  letter-spacing: inherit;
  font-weight: inherit;
  color: inherit;
  font-style: normal;
  margin: 0;
}

/* Totals row — sits in <tfoot>, same font size as data rows but with bg-sunk
   surface + top border + medium weight for visual emphasis. Use this instead
   of `tn-table-head` when the row holds *values* (not labels), so font-size
   stays consistent with the data above. Apply class="tn-totals" to the <tr>. */
.table > tfoot > tr.tn-totals > td,
.table > tbody > tr.tn-totals > td,
.table > tr.tn-totals > td {
  padding: var(--tn-s-3) var(--tn-s-4);
  background: var(--tn-surface-sunk) !important;
  border-top: 2px solid var(--tn-accent-700) !important;
  font-weight: 600;
  vertical-align: middle;
  text-align: center;
  letter-spacing: -0.005em;
}
.table.tn-table-compact > tfoot > tr.tn-totals > td,
.table.tn-table-compact > tbody > tr.tn-totals > td,
.table.tn-table-compact > tr.tn-totals > td {
  padding: 5px var(--tn-s-3);
}

/* Inline secondary label above a value cell — small, muted, tracked uppercase
   so it reads as a deliberate mini-label that echoes the .tn-table-head row
   style. Use for the concept/label that annotates the dominant value below. */
.table td .tn-cell-sub,
.tn-cell-sub {
  font-family: var(--tn-font-sans);
  font-size: var(--tn-fz-xs);
  font-weight: 500;
  color: var(--tn-text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.4;
}
/* When the sub-label is itself a clickable <a>, keep it muted, drop the
   default browser underline, and reveal a tracked-arrow popup indicator on
   hover. Dotted underbar (not underline) signals "interactive" without making
   it look like a navigation link. */
a.tn-cell-sub {
  color: var(--tn-text-muted);
  text-decoration: none;
  border-bottom: 1px dotted transparent;
  transition: color var(--tn-dur-quick) var(--tn-ease),
              border-color var(--tn-dur-quick) var(--tn-ease);
}
a.tn-cell-sub::after {
  content: " \2197"; /* ↗ — opens-in-popup indicator */
  display: inline-block;
  opacity: 0;
  margin-left: 1px;
  transform: translate(-2px, 1px);
  transition: opacity var(--tn-dur-quick) var(--tn-ease),
              transform var(--tn-dur-quick) var(--tn-ease);
}
a.tn-cell-sub:hover,
a.tn-cell-sub:focus {
  color: var(--tn-accent-700);
  border-bottom-color: currentColor;
}
a.tn-cell-sub:hover::after,
a.tn-cell-sub:focus::after {
  opacity: 1;
  transform: translate(0, 0);
}

.table > tbody > tr > td {
  padding: var(--tn-s-3) var(--tn-s-4);
  vertical-align: middle;
  border-top: 1px solid var(--tn-border-soft);
  background: var(--tn-surface-card);
  transition: background var(--tn-dur-quick) var(--tn-ease);
}
.table > tbody > tr:hover > td { background: var(--tn-c-25); }
.table > tbody > tr:has(> td > h5) > td { background: var(--tn-surface-sunk); }
.table > tbody > tr:has(> td > h5):hover > td { background: var(--tn-surface-sunk); }
.table > thead > tr:not(:first-child):hover > td { background: var(--tn-c-25); }

/* Right-align money / numeric columns. The hidden inputs in Tu Nómina pages make
   detection tricky — use a data hook on the td or class `.tn-num-col`. */
.table td.tn-num-col,
.table td.tn-num-col strong { font-family: var(--tn-font-mono); font-variant-numeric: tabular-nums; text-align: right; }

/* Shrink icon/action cells to their content so text-heavy columns (Nombre, Fecha)
   get the leftover width. Apply class to <td> AND the matching header cell.
   Body cells nowrap (icons + short text); header cells WRAP so long labels like
   "Comprobante de pago" stack to two lines rather than forcing horizontal scroll. */
.table td.tn-col-shrink,
.table th.tn-col-shrink,
.table > tbody > tr:first-child > td.tn-col-shrink {
  width: 1%;
  padding-left: var(--tn-s-2);
  padding-right: var(--tn-s-2);
}
.table > tbody > tr > td.tn-col-shrink {
  white-space: nowrap;
}
.table > tbody > tr:has(> td > h5) > td.tn-col-shrink,
.table > thead > tr:first-child > td.tn-col-shrink,
.table > thead > tr:first-child > th.tn-col-shrink,
.table > thead > tr.tn-table-head > td.tn-col-shrink,
.table > thead > tr.tn-table-head > th.tn-col-shrink {
  white-space: normal;       /* header cells wrap */
  line-height: 1.25;
  max-width: 70px;           /* soft cap — long labels wrap rather than stretch */
}
.table > tbody > tr:has(> td > h5) > td.tn-col-shrink h5,
.table > thead > tr:first-child > td.tn-col-shrink h5 {
  white-space: normal;
}
/* OPT-IN min-width for text-heavy cells. Originally 140px blanket on every
   non-shrink cell, but that pushed wide tables (16+ cols) past viewport on
   1920 screens. Now: only cells with .tn-text-col get a generous min; other
   cells size to their content via auto-layout. */
.table td.tn-text-col,
.table th.tn-text-col { min-width: 240px; text-align: left; }

/* ---------- Utility: inline input + button row ----------
   Place a <.tn-input-row> wrapper around an <input class="form-control"> and a
   trailing <button> when you want them side-by-side instead of stacked.
   listaNominaIndividual.php's email/Enviar row uses this. */
.tn-input-row {
  display: flex;
  align-items: center;
  gap: var(--tn-s-2);
  max-width: 560px;
}
.tn-input-row > .form-control { flex: 1; min-width: 0; }
.tn-input-row > .btn { flex: 0 0 auto; }

/* Compact table — opt-in via `class="table tn-table-compact"` on data-heavy
   pages where each row holds one number and rows pile up vertically.
   Only padding/line-height tighten; font sizes left at defaults so numbers stay
   readable and consistent with non-compact tables. */
.table.tn-table-compact > tbody > tr > td {
  padding: 5px var(--tn-s-3);   /* 5px 12px — was 12px 16px */
  line-height: 1.35;
}
.table.tn-table-compact > tbody > tr:first-child > td {
  padding-top: var(--tn-s-2);
  padding-bottom: var(--tn-s-2);
}
.table.tn-table-compact > tbody > tr > td strong {
  font-weight: 600;
}

/* Inline images inside table cells (icon-thumbnails, status images, etc.) align
   to baseline by default which drops them below the text baseline. Center them
   on the text middle so a row of mixed text + image stays one consistent height.
   Note: Bootstrap's `.media-object` sets display:block, which would defeat
   vertical-align, so we force inline-block. listaNominaIndividual.php's
   "Neto a Pagar" cell mixes a money string with a 16px PDF icon — this rule
   keeps the icon centered with the text. */
.table td img,
.table td img.media-object {
  display: inline-block !important;
  vertical-align: middle !important;
}

/* PDF / file action icons in cells */
.table .fa-file-pdf-o {
  color: var(--tn-err-600);
  font-size: 16px;
  transition: transform var(--tn-dur-quick) var(--tn-ease);
}
.table .fa-file-pdf-o:hover { transform: scale(1.1); color: var(--tn-err-700); }
.table .fa-trash-o { color: var(--tn-c-400); transition: color var(--tn-dur-quick) var(--tn-ease); }
.table .fa-trash-o:hover { color: var(--tn-err-600); }
.table .fa-check.text-success { color: var(--tn-ok-600) !important; }
.table .fa-upload.text-danger { color: var(--tn-warn-600) !important; }

/* ---------- Buttons ---------- */
.btn {
  font-family: var(--tn-font-sans);
  font-size: var(--tn-fz-md);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.005em;
  padding: 8px 14px;
  border-radius: var(--tn-r-md);
  border: 1px solid transparent;
  transition: background var(--tn-dur-quick) var(--tn-ease),
              border-color var(--tn-dur-quick) var(--tn-ease),
              color var(--tn-dur-quick) var(--tn-ease),
              box-shadow var(--tn-dur-quick) var(--tn-ease),
              transform var(--tn-dur-quick) var(--tn-ease);
  cursor: pointer;
  user-select: none;
}
.btn:focus-visible { outline: none; box-shadow: var(--tn-ring); }
.btn:active { transform: translateY(0.5px); }

.btn-primary,
.btn-primary.btn-labeled {
  background: var(--tn-a-700);
  border-color: var(--tn-a-700);
  color: #fff;
  box-shadow: var(--tn-shadow-sm);
}
.btn-primary:hover, .btn-primary:focus {
  background: var(--tn-a-800);
  border-color: var(--tn-a-800);
  color: #fff;
}
.btn-primary:active { background: var(--tn-a-900); border-color: var(--tn-a-900); }

.btn-default, .btn-secondary {
  background: var(--tn-surface-card);
  border-color: var(--tn-border-strong);
  color: var(--tn-c-700);
}
.btn-default:hover, .btn-secondary:hover {
  background: var(--tn-surface-sunk);
  border-color: var(--tn-c-300);
  color: var(--tn-c-900);
}

.btn-success { background: var(--tn-ok-600); border-color: var(--tn-ok-600); color: #fff; }
.btn-success:hover { background: var(--tn-ok-700); border-color: var(--tn-ok-700); color: #fff; }
.btn-danger  { background: var(--tn-err-600); border-color: var(--tn-err-600); color: #fff; }
.btn-danger:hover { background: var(--tn-err-700); border-color: var(--tn-err-700); color: #fff; }
.btn-warning { background: var(--tn-warn-600); border-color: var(--tn-warn-600); color: #fff; }
.btn-warning:hover { background: var(--tn-warn-700); border-color: var(--tn-warn-700); color: #fff; }

.btn-sm { padding: 6px 10px; font-size: var(--tn-fz-sm); border-radius: var(--tn-r-sm); }
.btn-lg { padding: 10px 18px; font-size: var(--tn-fz-lg); }

/* btn-labeled — Angle ships .btn-label with `position:relative; left:-16px` AND
   `padding: 6px 16px` on an inline-block, so it pokes out the button's left edge
   and the button's own text drifts to the top. Rewrite as a flex container with
   align-items:center so the text + icon co-center vertically. .btn-label gets
   align-self:stretch so the chip fills the full button height as a colored block. */
.btn.btn-labeled {
  display: inline-flex !important;
  align-items: center;
  padding: 0 14px 0 0 !important;
  line-height: 1;
  min-height: 34px;
}
.btn-labeled > .btn-label,
.btn.btn-labeled > .btn-label {
  position: relative;
  left: 0;
  margin: 0 10px 0 0;
  padding: 0 12px;
  background: rgba(0, 0, 0, 0.16);
  color: inherit;
  border-radius: var(--tn-r-md) 0 0 var(--tn-r-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  align-self: stretch;
  min-width: 34px;
}
.btn-default.btn-labeled > .btn-label,
.btn-secondary.btn-labeled > .btn-label {
  background: var(--tn-surface-sunk);
  color: var(--tn-text-muted);
}
.btn-labeled > .btn-label.btn-label-right {
  margin: 0 0 0 10px;
  border-radius: 0 var(--tn-r-md) var(--tn-r-md) 0;
}

/* ---------- Forms ---------- */
.form-control {
  font-family: var(--tn-font-sans);
  font-size: var(--tn-fz-md);
  color: var(--tn-c-900);
  background: var(--tn-surface-card);
  background-image: none;
  border: 1px solid var(--tn-border-strong);
  border-radius: var(--tn-r-md);
  padding: 8px 12px;
  height: auto;
  line-height: 1.4;
  box-shadow: none;
  transition: border-color var(--tn-dur-quick) var(--tn-ease),
              box-shadow var(--tn-dur-quick) var(--tn-ease);
}
.form-control:focus {
  border-color: var(--tn-a-500);
  box-shadow: var(--tn-ring);
  outline: none;
}
.form-control::placeholder { color: var(--tn-text-soft); }

select.form-control {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--tn-text-muted) 50%),
    linear-gradient(135deg, var(--tn-text-muted) 50%, transparent 50%);
  background-position:
    calc(100% - 17px) 50%,
    calc(100% - 12px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  appearance: none;
  -webkit-appearance: none;
  padding-right: 32px;
}

.control-label, .col-form-label {
  font-size: var(--tn-fz-sm);
  font-weight: 500;
  color: var(--tn-text-muted);
  margin-bottom: var(--tn-s-1);
  text-transform: none;
  letter-spacing: 0;
}

.input-group .input-group-addon {
  background: var(--tn-surface-sunk);
  border: 1px solid var(--tn-border-strong);
  color: var(--tn-text-muted);
  font-size: var(--tn-fz-md);
  font-family: var(--tn-font-mono);
}
.input-group .form-control { z-index: 1; }

/* Bootstrap 3 checkbox with .c-checkbox decorator.
   Angle's .c-checkbox span has `margin-left: -20px; vertical-align: top` — both
   wrong for our usage (cut off on the left, top-aligned). Override hard. */
.checkbox.c-checkbox { padding: 0; margin: 0; line-height: 1; }
.checkbox.c-checkbox label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 !important;
  margin: 0;
  font-weight: 400;
  line-height: 1;
  cursor: pointer;
}
.checkbox.c-checkbox input[type="checkbox"] {
  position: absolute !important;
  opacity: 0;
  pointer-events: none;
  width: 18px; height: 18px;
}
.checkbox.c-checkbox label > .fa-check,
.checkbox.c-checkbox label > span {
  position: relative;
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--tn-border-strong);
  border-radius: var(--tn-r-sm);
  background: var(--tn-surface-card);
  color: transparent;
  font-size: 11px;
  line-height: 14px;
  text-align: center;
  vertical-align: middle !important;
  margin: 0 !important;       /* defeat Angle's margin-left:-20px */
  transition: all var(--tn-dur-quick) var(--tn-ease);
  cursor: pointer;
}
.checkbox.c-checkbox label > .fa-check::before,
.checkbox.c-checkbox label > span::before {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  font-family: "FontAwesome";
}
.checkbox.c-checkbox input[type="checkbox"]:checked ~ .fa-check,
.checkbox.c-checkbox input[type="checkbox"]:checked ~ span,
.checkbox.c-checkbox input[type="checkbox"]:checked + .fa-check,
.checkbox.c-checkbox input[type="checkbox"]:checked + span {
  background: var(--tn-a-700);
  border-color: var(--tn-a-700);
  color: #fff;
}
.checkbox.c-checkbox input[type="checkbox"]:checked ~ .fa-check::before,
.checkbox.c-checkbox input[type="checkbox"]:checked ~ span::before,
.checkbox.c-checkbox input[type="checkbox"]:checked + .fa-check::before,
.checkbox.c-checkbox input[type="checkbox"]:checked + span::before {
  opacity: 1;
  color: #fff;
}
.checkbox.c-checkbox input[type="checkbox"]:focus-visible + .fa-check,
.checkbox.c-checkbox input[type="checkbox"]:focus-visible + span { box-shadow: var(--tn-ring); }

/* Switch (Angle pattern) — full override.
   Angle ships .switch with `top:0` on the thumb and `left:50%` on :checked,
   which together drift the thumb off-center and over the track edge with our
   smaller sizes. We re-anchor with top:50% + translateY centering and use
   `left: calc(100% - thumb_w - 2px)` so the right edge always lands at 2px. */
.switch, label.switch { display: inline-block; vertical-align: middle; line-height: 1; }
.switch input[type="checkbox"] {
  position: absolute; opacity: 0; pointer-events: none; z-index: -1;
}
.switch > span,
.switch.switch-sm > span,
.switch.switch-lg > span {
  position: relative;
  display: inline-block;
  background: var(--tn-c-200);
  border: 1px solid var(--tn-c-200);
  border-radius: 999px;
  box-shadow: none;
  transition: background var(--tn-dur-norm) var(--tn-ease),
              border-color var(--tn-dur-norm) var(--tn-ease);
  vertical-align: middle;
  cursor: pointer;
}
.switch > span                { width: 36px; height: 20px; }
.switch.switch-sm > span      { width: 30px; height: 17px; }
.switch.switch-lg > span      { width: 44px; height: 24px; }

.switch > span::after,
.switch.switch-sm > span::after,
.switch.switch-lg > span::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 2px;
  transform: translateY(-50%);
  background: #fff;
  border: 0;
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18), 0 1px 1px rgba(0, 0, 0, 0.06);
  transition: left var(--tn-dur-norm) var(--tn-ease);
}
.switch > span::after                { width: 16px; height: 16px; }
.switch.switch-sm > span::after      { width: 13px; height: 13px; }
.switch.switch-lg > span::after      { width: 20px; height: 20px; }

.switch input[type="checkbox"]:checked + span,
.switch.switch-sm input[type="checkbox"]:checked + span,
.switch.switch-lg input[type="checkbox"]:checked + span {
  background: var(--tn-a-700);
  border-color: var(--tn-a-700);
}
.switch input[type="checkbox"]:checked + span::after           { left: calc(100% - 18px); }
.switch.switch-sm input[type="checkbox"]:checked + span::after { left: calc(100% - 15px); }
.switch.switch-lg input[type="checkbox"]:checked + span::after { left: calc(100% - 22px); }

.switch input[type="checkbox"]:disabled + span { background: var(--tn-c-100); border-color: var(--tn-c-100); cursor: not-allowed; }

/* ---------- Modal ---------- */
.modal-content {
  background: var(--tn-surface-card);
  border: 1px solid var(--tn-border);
  border-radius: var(--tn-r-xl);
  box-shadow: var(--tn-shadow-pop);
}
.modal-header {
  border-bottom: 1px solid var(--tn-border-soft);
  padding: var(--tn-s-5) var(--tn-s-6);
  border-top-left-radius: var(--tn-r-xl);
  border-top-right-radius: var(--tn-r-xl);
}
.modal-header .modal-title {
  font-size: var(--tn-fz-lg);
  font-weight: 600;
  color: var(--tn-c-900);
  line-height: var(--tn-lh-tight);
}
.modal-header .close {
  font-size: 22px;
  line-height: 1;
  color: var(--tn-text-muted);
  opacity: 0.7;
  text-shadow: none;
  transition: opacity var(--tn-dur-quick) var(--tn-ease);
}
.modal-header .close:hover { opacity: 1; color: var(--tn-c-900); }
.modal-body { padding: var(--tn-s-6); }
.modal-footer {
  border-top: 1px solid var(--tn-border-soft);
  padding: var(--tn-s-4) var(--tn-s-6);
  background: var(--tn-surface-sunk);
  border-bottom-left-radius: var(--tn-r-xl);
  border-bottom-right-radius: var(--tn-r-xl);
}
.modal-backdrop.in { opacity: 0.55; background: var(--tn-c-900); }

/* ---------- Page header strip (slim, under whatever Encabezado.php emits) ---------- */
.tn-pageheader {
  background: var(--tn-surface-card);
  border: 1px solid var(--tn-border);
  border-radius: var(--tn-r-lg);
  padding: var(--tn-s-4) var(--tn-s-6);
  margin-bottom: var(--tn-s-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--tn-s-4);
  box-shadow: var(--tn-shadow-sm);
}
.tn-pageheader__title {
  margin: 0;
  font-size: var(--tn-fz-xl);
  font-weight: 600;
  color: var(--tn-c-900);
  letter-spacing: -0.015em;
}
.tn-pageheader__meta {
  font-size: var(--tn-fz-sm);
  color: var(--tn-text-muted);
  font-family: var(--tn-font-mono);
  font-variant-numeric: tabular-nums;
}

/* ---------- Status pills ---------- */
.tn-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  font-size: var(--tn-fz-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-radius: 999px;
  border: 1px solid transparent;
  line-height: 1.4;
}
.tn-pill--ok   { background: var(--tn-ok-50);   color: var(--tn-ok-700);   border-color: #a7f3d0; }
.tn-pill--warn { background: var(--tn-warn-50); color: var(--tn-warn-700); border-color: #fed7aa; }
.tn-pill--err  { background: var(--tn-err-50);  color: var(--tn-err-700);  border-color: #fecaca; }
.tn-pill--info { background: var(--tn-a-50);    color: var(--tn-a-700);    border-color: var(--tn-a-200); }

/* ---------- Misc Angle template normalizations ---------- */
.text-success { color: var(--tn-ok-600) !important; }
.text-danger  { color: var(--tn-err-600) !important; }
.text-warning { color: var(--tn-warn-600) !important; }
.text-info    { color: var(--tn-a-700) !important; }
.text-muted   { color: var(--tn-text-muted) !important; }

/* Remove the legacy yellow inline color used for `MensajeDivEnvia` etc. — pick up the theme. */
[id^="MensajeDivEnvia"]:not([id$="Correcto"]) { color: var(--tn-warn-700) !important; font-family: var(--tn-font-sans); }
[id^="MensajeDivEnvia"][id$="Correcto"]      { color: var(--tn-ok-700) !important; font-family: var(--tn-font-sans); }

/* Center-aligned table cells inside the data table — keep them centered (Angle uses align="center" widely),
   but cell text-align falls back to design defaults: left for text, right for money. */
.table td[align="center"], .table th[align="center"] { text-align: center; }

/* Hide the visible <option> the legacy code echoes (it dumps the session value as an extra <option> before the loop) */
/* Leaving in place: that's a behavior change, deferred. */

/* ---------- Selection / focus ---------- */
::selection { background: var(--tn-a-200); color: var(--tn-c-900); }
:focus-visible { outline: 2px solid var(--tn-a-500); outline-offset: 2px; border-radius: var(--tn-r-sm); }

/* === Legacy detail-page italics standardization ===
   Tu Nómina legacy detail pages emit values like <td><div><em>$value</em></div>
   — the <em> is decorative, not semantic. Strip italics inside any <td> that's
   NOT in a styled .table (the .table rule earlier covers list-page tables).
   Exclude FontAwesome / icon-prefixed classes since those use <i>/<em> for icons. */
table:not(.table) td em,
table:not(.table) td i:not(.fa):not([class*="icon-"]) {
  font-style: normal;
}

/* === Section banner === opt-in via class="tn-section-banner" on the <td> that
   serves as a section heading inside legacy detail-page tables (e.g. the
   "DATOS GENERALES SUCURSAL" / "DIRECCIÓN DEL EMPLEADO" headings on
   DatosCompletosEmpleado.php). Reads as a clean section header without
   restructuring the surrounding markup. */
.tn-section-banner,
td.tn-section-banner {
  background: var(--tn-c-100) !important;
  color: var(--tn-c-900) !important;
  font-family: var(--tn-font-sans);
  font-weight: 600 !important;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--tn-fz-sm) !important;
  padding: 10px 14px !important;
  border-top: 1px solid var(--tn-border) !important;
  border-bottom: 1px solid var(--tn-border) !important;
  text-align: center;
}
.tn-section-banner *,
td.tn-section-banner * {
  font-style: normal !important;
  font-weight: inherit !important;
  color: inherit !important;
  letter-spacing: inherit !important;
  text-transform: inherit !important;
  margin: 0 !important;
}

/* Legacy-stack tables sit directly on the page bg (--tn-c-25 / #fafafa) because
   there's no .panel wrapping them on legacy pages. Give .table itself a card
   look (white surface + hairline + radius + sub-card shadow) so it visually
   "lifts" from the page. Tables wrapped in a .panel keep their transparent
   ride (more-specific selector below overrides). */
.table {
  background: var(--tn-surface-card);
  border: 1px solid var(--tn-border);
  border-radius: var(--tn-r-lg);
  box-shadow: var(--tn-shadow-sm);
  overflow: hidden;
}
.panel .table,
.panel-body .table,
.panel-body .table-responsive .table {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}

/* Toolbar utility — for legacy <table>-based menu rows (a row of dropdowns +
   buttons that used to fill a fixed 1024px). Add class="tn-toolbar" to the
   <table> tag; the table sizes to its content and centers horizontally. */
.tn-toolbar {
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
  margin: 0 auto !important;
  border-collapse: separate !important;
  border-spacing: 8px 0 !important;
  width: auto !important;
}
.tn-toolbar > tbody > tr > td,
.tn-toolbar > tr > td {
  padding: 4px 6px !important;
  border: 0 !important;
  background: transparent !important;
  vertical-align: middle !important;
  text-align: center !important;
}

/* Action-bar utility — horizontal row of buttons below a data table. Wraps on
   narrow viewports. Add class="tn-actionbar" to the <div> wrapping the row. */
.tn-actionbar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: center;
  margin: 20px 0 16px;
  padding-top: 16px;
  border-top: 1px solid var(--tn-border-soft);
}
.tn-actionbar > .btn { flex: 0 0 auto; }
/* When the action-bar sits at the very top of a page (above the encabezado
   and before any table), skip the divider line — it'd float in space. */
.tn-actionbar.tn-actionbar-top {
  border-top: none;
  padding-top: 0;
}

/* "Select all" affordance for legacy pages that emit a bare checkbox + label
   above a data table. Add class="tn-selectall" to a <label> wrapping the
   checkbox and the label text. */
.tn-selectall {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0;
  font-weight: 500;
  color: var(--tn-c-700);
}
.tn-selectall input[type="checkbox"] { margin: 0; }

/* ============================================================
   Phase 3b — Legacy-stack table support.
   Tu Nómina's legacy pages emit raw <table border="1" bgcolor="..." width="..."
   cellspacing/cellpadding> with inline width/bgcolor/bordercolor attrs on cells,
   <th>-based headers (no <thead> wrapper), and inconsistent <em>/<i> italic
   wrappers. To opt a legacy table into the design system, add class="table" to
   the <table> tag; CSS below defangs all the inline decoration and styles
   <th>-cells as design-system headers without requiring per-cell edits.
   ============================================================ */

/* <th> cells become design-system header cells, even when there's no <thead> */
.table th {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: var(--tn-fz-xs);
  font-weight: 600;
  color: var(--tn-text-muted);
  padding: var(--tn-s-3) var(--tn-s-4);
  background: var(--tn-surface-sunk) !important;   /* defeat HTML4 bgcolor */
  border-top: 1px solid var(--tn-border-soft) !important;
  border-bottom: 1px solid var(--tn-border) !important;
  border-left: 0 !important;
  border-right: 0 !important;
  vertical-align: middle;
  text-align: center;
  width: auto !important;        /* defeat width="X" */
  height: auto !important;
}
.table th * {
  text-transform: inherit;
  letter-spacing: inherit;
  font-weight: inherit;
  color: inherit;
  font-style: normal;           /* kill <em> inside headers */
  text-decoration: none;
  margin: 0;
  padding: 0;
}
.table th a { color: var(--tn-text-muted); }
.table th a:hover { color: var(--tn-a-700); }

/* Default-center cells; opt-out with .tn-text-col / .tn-num-col */
.table > tbody > tr > td,
.table > tr > td {
  text-align: center;
}
.table td.tn-text-col,
.table th.tn-text-col { text-align: left; }
.table td.tn-num-col,
.table th.tn-num-col { text-align: right; }

/* Standardize: kill italics inside tables. Legacy <em> wrappers were used
   inconsistently (some headers italic, others not). Wholesale removal yields
   uniform formatting regardless of which cells the author wrapped. */
.table em,
.table i:not(.fa):not([class*="icon-"]),
.table .style2 em { font-style: normal !important; }

/* Defang inline HTML4 cell decoration (bgcolor, bordercolor, width attrs) */
.table td[bgcolor], .table th[bgcolor] { background-color: inherit !important; }
.table td[bordercolor], .table th[bordercolor] { border-color: var(--tn-border-soft) !important; }
.table td[width], .table th[width] { width: auto !important; }
.table[border] { border: 0 !important; }
.table[cellspacing] { border-spacing: 0 !important; }

/* Legacy class="style2" / "stylenombre" are per-cell font/color presets. Neutralize. */
.table .style2,
.table .stylenombre,
.table td.style2,
.table th.style2 {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  font-style: normal;
  background: transparent !important;
}

/* HTML4 align="center"/"left"/"right" on cells: keep these honored (page-authored
   alignment intent), they override our defaults. */
.table td[align="center"], .table th[align="center"] { text-align: center; }
.table td[align="left"],   .table th[align="left"]   { text-align: left; }
.table td[align="right"],  .table th[align="right"]  { text-align: right; }

/* The legacy <div align='center'><p align='center'>... wrapper pattern adds vertical
   space. Tighten <p> inside data cells so rows don't double-height. */
.table > tbody > tr > td > p,
.table > tbody > tr > th > p,
.table > tr > td > p { margin: 0; }
.table > tbody > tr > td > div[align="center"] > p,
.table > tbody > tr > th > div[align="center"] > p { margin: 0; }

/* ==========================================================================
   Product card grid — ListaProductosFacturacion.php and any future product /
   inventory list pages. Responsive grid; cards have uniform height.
   ========================================================================== */
.tn-product-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
	gap: 16px;
	padding: 16px 0;
	max-width: 1600px;
	margin: 0 auto;
}

.tn-product-card {
	position: relative;
	background: var(--tn-c-surface-card, #fff);
	border: 1px solid var(--tn-c-border-soft, #e5e7eb);
	border-radius: 8px;
	padding: 16px 16px 18px;
	display: flex;
	flex-direction: column;
	gap: 8px;
	transition: box-shadow 150ms ease, border-color 150ms ease, transform 150ms ease;
}
.tn-product-card:hover {
	border-color: var(--tn-accent-300, #93c5fd);
	box-shadow: 0 4px 12px -2px rgba(15, 23, 42, 0.08), 0 2px 4px -1px rgba(15, 23, 42, 0.04);
	transform: translateY(-1px);
}

.tn-product-card .tn-product-radio {
	position: absolute;
	top: 12px;
	left: 12px;
	z-index: 1;
	width: 18px;
	height: 18px;
	cursor: pointer;
	accent-color: var(--tn-accent-700, #1d4ed8);
}

.tn-product-card .tn-product-img-wrap {
	width: 100%;
	height: 160px;
	background: #fff;
	border: 1px solid var(--tn-border-soft, #ebedf0);
	border-radius: 6px;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	margin-bottom: 4px;
}
.tn-product-card .tn-product-img {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
	transition: opacity 150ms ease;
}

.tn-product-card .tn-product-numero {
	font-family: var(--tn-font-mono, ui-monospace, monospace);
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--tn-c-text-muted, #64748b);
	margin-top: 2px;
}

.tn-product-card .tn-product-name {
	font-size: 15px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--tn-c-text-base, #0f172a);
	letter-spacing: -0.005em;
	/* clamp to 2 lines */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.tn-product-card .tn-product-meta {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 2px 12px;
	margin: 4px 0 0;
	font-size: 12px;
	line-height: 1.5;
}
.tn-product-card .tn-product-meta dt {
	font-weight: 600;
	color: var(--tn-c-text-muted, #64748b);
	letter-spacing: 0.02em;
}
.tn-product-card .tn-product-meta dd {
	margin: 0;
	color: var(--tn-c-text-base, #0f172a);
	min-width: 0;
	overflow-wrap: anywhere;
}

.tn-product-card .tn-product-desc {
	font-size: 12px;
	line-height: 1.5;
	color: var(--tn-c-text-muted, #64748b);
	margin-top: 4px;
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.tn-product-card .tn-product-proveedor {
	font-size: 11px;
	color: var(--tn-c-text-muted, #64748b);
	border-top: 1px solid var(--tn-c-border-soft, #e5e7eb);
	padding-top: 8px;
	margin-top: 4px;
}

.tn-product-card .tn-product-price {
	font-family: var(--tn-font-mono, ui-monospace, monospace);
	font-feature-settings: 'tnum';
	font-size: 22px;
	font-weight: 600;
	color: var(--tn-accent-700, #1d4ed8);
	margin-top: auto;
	letter-spacing: -0.01em;
}

/* Picker variant: highlight cards with qty > 0 */
.tn-product-card.is-added {
	border-color: var(--tn-accent-700, #1d4ed8);
	box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.12);
}

.tn-product-card-action-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-top: 12px;
	padding-top: 12px;
	border-top: 1px solid var(--tn-c-border-soft, #e5e7eb);
}
.tn-product-card-action-row .tn-qty-label {
	font-size: 11px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--tn-c-text-muted, #64748b);
}

.tn-qty-stepper {
	display: inline-flex;
	align-items: stretch;
	border: 1px solid var(--tn-c-border, #d4d4d8);
	border-radius: 6px;
	overflow: hidden;
	background: #fff;
}
.tn-qty-stepper .tn-qty-btn {
	width: 32px;
	height: 32px;
	border: 0;
	background: var(--tn-c-25, #fafafa);
	color: var(--tn-c-text-base, #0f172a);
	font-size: 16px;
	font-weight: 600;
	cursor: pointer;
	user-select: none;
	line-height: 1;
	padding: 0;
	transition: background 120ms ease;
}
.tn-qty-stepper .tn-qty-btn:hover { background: var(--tn-c-100, #f4f4f5); }
.tn-qty-stepper .tn-qty-btn:active { background: var(--tn-c-200, #e4e4e7); }
.tn-qty-stepper .tn-qty-input {
	width: 48px;
	height: 32px;
	border: 0;
	border-left: 1px solid var(--tn-c-border, #d4d4d8);
	border-right: 1px solid var(--tn-c-border, #d4d4d8);
	text-align: center;
	font-family: var(--tn-font-mono, ui-monospace, monospace);
	font-size: 14px;
	font-weight: 600;
	color: var(--tn-c-text-base, #0f172a);
	padding: 0;
	background: #fff;
	-moz-appearance: textfield;
}
.tn-qty-stepper .tn-qty-input::-webkit-outer-spin-button,
.tn-qty-stepper .tn-qty-input::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}
.tn-qty-stepper .tn-qty-input:focus {
	outline: none;
	background: var(--tn-accent-50, #eff6ff);
}

/* Money / numeric display in table cells — readonly, not an input. */
.tn-money-display {
	display: inline-block;
	font-family: var(--tn-font-mono, ui-monospace, monospace);
	font-feature-settings: 'tnum';
	font-size: 14px;
	font-weight: 600;
	color: var(--tn-c-text-base, #0f172a);
	text-align: right;
	letter-spacing: -0.005em;
	padding: 0 4px;
	min-width: 110px;
}
.tn-money-display.is-total {
	font-size: 16px;
	color: var(--tn-accent-700, #1d4ed8);
}

/* ==========================================================================
   Notification bell (Encabezado.php) — replaces .notification-bell / .ventana.
   ========================================================================== */
.tn-notif-bell {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	cursor: pointer;
	transition: background 150ms ease;
}
.tn-notif-bell:hover { background: var(--tn-c-100, #f4f4f5); }
.tn-notif-bell svg {
	width: 22px;
	height: 22px;
	color: var(--tn-c-text-base, #0f172a);
}
.tn-notif-badge {
	position: absolute;
	top: 2px;
	right: 2px;
	min-width: 18px;
	height: 18px;
	padding: 0 5px;
	background: #dc2626;
	color: #fff;
	border-radius: 9px;
	font-size: 11px;
	font-weight: 700;
	font-family: var(--tn-font-mono, ui-monospace, monospace);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 0 0 2px #fff;
	line-height: 1;
}
.tn-notif-badge:empty { display: none; }

.tn-notif-panel {
	position: absolute;
	top: 56px;
	right: 8px;
	width: 400px;
	max-height: 600px;
	overflow-y: auto;
	background: #fff;
	border: 1px solid var(--tn-c-border-soft, #e5e7eb);
	border-radius: 12px;
	box-shadow: 0 20px 48px -16px rgba(15, 23, 42, 0.25), 0 4px 12px -4px rgba(15, 23, 42, 0.1);
	display: none;
	z-index: 500;
}
.tn-notif-panel.is-open { display: block; }

.tn-notif-panel-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 14px 16px;
	border-bottom: 1px solid var(--tn-c-border-soft, #e5e7eb);
	position: sticky;
	top: 0;
	background: #fff;
	border-radius: 12px 12px 0 0;
}
.tn-notif-panel-title {
	font-size: 14px;
	font-weight: 600;
	color: var(--tn-c-text-base, #0f172a);
	margin: 0;
}
.tn-notif-panel-count {
	font-family: var(--tn-font-mono, ui-monospace, monospace);
	font-size: 11px;
	background: var(--tn-c-100, #f4f4f5);
	color: var(--tn-c-text-muted, #64748b);
	padding: 2px 8px;
	border-radius: 999px;
}

.tn-notif-panel-body {
	padding: 12px;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.tn-notif-card {
	border: 1px solid var(--tn-c-border-soft, #e5e7eb);
	border-radius: 8px;
	overflow: hidden;
	background: #fff;
}
.tn-notif-card-header {
	padding: 8px 12px;
	background: var(--tn-c-25, #fafafa);
	border-bottom: 1px solid var(--tn-c-border-soft, #e5e7eb);
	font-size: 11px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--tn-c-text-muted, #64748b);
}
.tn-notif-card-body { padding: 12px; }
.tn-notif-card .tn-notif-name {
	font-size: 14px;
	font-weight: 600;
	color: var(--tn-c-text-base, #0f172a);
	margin: 6px 0 8px;
}
.tn-notif-card select.tn-notif-tipo {
	width: 100%;
	padding: 6px 10px;
	font-size: 12px;
	border: 1px solid var(--tn-c-border, #d4d4d8);
	border-radius: 6px;
	background: #fff;
	color: var(--tn-c-text-base, #0f172a);
}
.tn-notif-dates {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 8px 0;
}
.tn-notif-date-pill {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 8px;
	background: var(--tn-c-50, #f9fafb);
	border: 1px solid var(--tn-c-border-soft, #e5e7eb);
	border-radius: 6px;
	font-size: 11px;
	font-family: var(--tn-font-mono, ui-monospace, monospace);
	color: var(--tn-c-text-base, #0f172a);
	text-decoration: none;
	cursor: pointer;
}
.tn-notif-date-pill:hover { border-color: var(--tn-accent-700, #1d4ed8); }
.tn-notif-dias {
	font-size: 11px;
	color: var(--tn-c-text-muted, #64748b);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.05em;
}
.tn-notif-comentario {
	margin-top: 8px;
	padding: 8px 10px;
	background: var(--tn-c-25, #fafafa);
	border-left: 3px solid var(--tn-c-border, #d4d4d8);
	border-radius: 0 4px 4px 0;
	font-size: 12px;
	color: var(--tn-c-text-muted, #64748b);
	line-height: 1.4;
	max-height: 60px;
	overflow-y: auto;
}
.tn-notif-comentario:empty { display: none; }
.tn-notif-actions {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 6px;
	margin-top: 10px;
}
.tn-notif-actions.is-three { grid-template-columns: 1fr 1fr 1fr; }
.tn-notif-btn {
	padding: 6px 8px;
	font-size: 11px;
	font-weight: 600;
	border: 1px solid var(--tn-c-border-soft, #e5e7eb);
	border-radius: 6px;
	cursor: pointer;
	background: #fff;
	color: var(--tn-c-text-base, #0f172a);
	text-align: center;
	transition: background 120ms ease, border-color 120ms ease;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.tn-notif-btn:hover { background: var(--tn-c-50, #f9fafb); border-color: var(--tn-c-border, #d4d4d8); }
.tn-notif-btn.is-pending {
	background: var(--tn-accent-700, #1d4ed8);
	color: #fff;
	border-color: var(--tn-accent-700, #1d4ed8);
}
.tn-notif-btn.is-pending:hover { background: #1e3a8a; }
.tn-notif-btn.is-done {
	background: var(--tn-c-100, #f4f4f5);
	color: var(--tn-c-text-muted, #64748b);
	border-color: var(--tn-c-border-soft, #e5e7eb);
}
.tn-notif-btn.is-cierre {
	background: #fef2f2;
	color: #b91c1c;
	border-color: #fecaca;
}
.tn-notif-btn.is-cierre:hover { background: #fee2e2; border-color: #fca5a5; }

.tn-notif-empty {
	padding: 40px 20px;
	text-align: center;
	color: var(--tn-c-text-muted, #64748b);
}
.tn-notif-empty-icon { font-size: 32px; margin-bottom: 8px; opacity: 0.5; }

/* ==========================================================================
   Anchor-based modal (no-JS pattern using :target).
   Open with <a href="#modal-id">, close with <a href="#">.
   ========================================================================== */
.tn-modal {
	position: fixed;
	inset: 0;
	z-index: 1000;
	background: rgba(15, 23, 42, 0.55);
	display: none;
	align-items: flex-start;
	justify-content: center;
	padding: 40px 20px;
	overflow-y: auto;
}
.tn-modal:target {
	display: flex;
}
.tn-modal-dialog {
	background: #fff;
	border-radius: 12px;
	box-shadow: 0 24px 64px -12px rgba(15, 23, 42, 0.4), 0 8px 16px -4px rgba(15, 23, 42, 0.1);
	max-width: 600px;
	width: 100%;
	overflow: hidden;
	display: flex;
	flex-direction: column;
}
.tn-modal-dialog.is-wide { max-width: 900px; }
.tn-modal-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 16px 20px;
	border-bottom: 1px solid var(--tn-c-border-soft, #e5e7eb);
}
.tn-modal-title {
	font-size: 16px;
	font-weight: 600;
	margin: 0;
	color: var(--tn-c-text-base, #0f172a);
}
.tn-modal-close {
	width: 32px;
	height: 32px;
	border: 0;
	background: transparent;
	font-size: 20px;
	line-height: 1;
	color: var(--tn-c-text-muted, #64748b);
	cursor: pointer;
	border-radius: 6px;
	display: flex;
	align-items: center;
	justify-content: center;
	text-decoration: none;
}
.tn-modal-close:hover { background: var(--tn-c-100, #f4f4f5); color: var(--tn-c-text-base, #0f172a); }
.tn-modal-body { padding: 20px; }
.tn-modal-footer {
	padding: 14px 20px;
	border-top: 1px solid var(--tn-c-border-soft, #e5e7eb);
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	background: var(--tn-c-25, #fafafa);
}

/* Image viewer body (used inside the image-preview modal). */
.tn-image-viewer {
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--tn-c-25, #fafafa);
	min-height: 320px;
	max-height: 70vh;
	padding: 16px;
}
.tn-image-viewer img {
	max-width: 100%;
	max-height: 65vh;
	object-fit: contain;
	transition: transform 200ms ease;
}
.tn-rotate-controls {
	display: inline-flex;
	gap: 4px;
}
.tn-rotate-btn {
	width: 36px;
	height: 36px;
	border: 1px solid var(--tn-c-border, #d4d4d8);
	background: #fff;
	border-radius: 6px;
	cursor: pointer;
	font-size: 16px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
.tn-rotate-btn:hover { background: var(--tn-c-100, #f4f4f5); }

/* Filter bar pattern: dropdown(s) on the left, segmented pills on the right. */
.tn-filter-bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
	margin: 16px auto;
	max-width: 1400px;
	padding: 0 8px;
}
.tn-filter-bar .tn-filter-label {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--tn-c-text-muted, #64748b);
	margin-right: 8px;
}

/* Segmented control — pill toggle group rendered as <a> links (page-reload). */
.tn-segmented {
	display: inline-flex;
	border: 1px solid var(--tn-c-border, #d4d4d8);
	border-radius: 8px;
	overflow: hidden;
	background: #fff;
}
.tn-segmented > a {
	padding: 7px 16px;
	font-size: 13px;
	font-weight: 500;
	color: var(--tn-c-text-base, #0f172a);
	text-decoration: none;
	background: #fff;
	border-right: 1px solid var(--tn-c-border-soft, #e5e7eb);
	transition: background 120ms ease, color 120ms ease;
}
.tn-segmented > a:last-child { border-right: 0; }
.tn-segmented > a:hover { background: var(--tn-c-50, #f9fafb); }
.tn-segmented > a.active {
	background: var(--tn-accent-700, #1d4ed8);
	color: #fff;
	font-weight: 600;
}

/* Incapacidades photo cell — thumbnail + compact upload + delete trio. */
.tn-photo-cell {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	min-width: 130px;
}
.tn-photo-thumb {
	width: 110px;
	height: 110px;
	border: 1px solid var(--tn-c-border-soft, #e5e7eb);
	border-radius: 6px;
	object-fit: cover;
	background: var(--tn-c-50, #f9fafb);
	cursor: zoom-in;
	transition: transform 150ms ease, border-color 150ms ease;
}
.tn-photo-thumb:hover {
	border-color: var(--tn-accent-700, #1d4ed8);
	transform: scale(1.03);
}
.tn-photo-thumb-empty {
	width: 110px;
	height: 110px;
	border: 1px dashed var(--tn-c-border, #d4d4d8);
	border-radius: 6px;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 11px;
	color: var(--tn-c-text-muted, #64748b);
	background: var(--tn-c-25, #fafafa);
}
.tn-photo-actions {
	display: inline-flex;
	gap: 4px;
	align-items: center;
}
.tn-photo-upload {
	font-size: 0;
	position: relative;
	overflow: hidden;
}
.tn-photo-upload input[type=file] {
	position: absolute;
	inset: 0;
	opacity: 0;
	cursor: pointer;
}

/* Two-column responsive form grid. Replaces the legacy 6-col table-with-spacer-cells
   layout (label | spacer | input | label | spacer | input) used across the older forms. */
.tn-form-grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: 32px;
	row-gap: 18px;
	max-width: 900px;
	margin: 24px auto;
	padding: 0 16px;
}
.tn-form-grid.is-single { grid-template-columns: 1fr; }
@media (max-width: 720px) {
	.tn-form-grid { grid-template-columns: 1fr; column-gap: 0; }
}
.tn-field {
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-width: 0;
}
.tn-field.is-full { grid-column: 1 / -1; }
.tn-field-label {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--tn-c-text-muted, #64748b);
}
.tn-field > .form-control { width: 100%; }

/* Money input restyled as plain text — keeps the form-field name (so legacy JS that
   writes `.value` still works) but reads as a non-editable display. */
.tn-money-input {
	border: 0;
	background: transparent;
	padding: 0 4px;
	font-family: var(--tn-font-mono, ui-monospace, monospace);
	font-feature-settings: 'tnum';
	font-size: 14px;
	font-weight: 600;
	color: var(--tn-c-text-base, #0f172a);
	text-align: right;
	letter-spacing: -0.005em;
	width: 110px;
	cursor: default;
	pointer-events: none;
	outline: none;
}
.tn-money-input.is-total {
	font-size: 16px;
	color: var(--tn-accent-700, #1d4ed8);
}

/* Editable quantity input inside a table row (LevantarPedidos cart). */
.tn-qty-cell-input {
	width: 64px;
	padding: 6px 8px;
	text-align: center;
	font-family: var(--tn-font-mono, ui-monospace, monospace);
	font-feature-settings: 'tnum';
	font-size: 14px;
	font-weight: 600;
	border: 1px solid var(--tn-c-border, #d4d4d8);
	border-radius: 6px;
	background: #fff;
	color: var(--tn-c-text-base, #0f172a);
	-moz-appearance: textfield;
}
.tn-qty-cell-input::-webkit-outer-spin-button,
.tn-qty-cell-input::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}
.tn-qty-cell-input:focus {
	outline: none;
	border-color: var(--tn-accent-700, #1d4ed8);
	box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.12);
}

/* Cart summary chip — fixed pill that floats while picking */
.tn-cart-summary {
	position: sticky;
	top: 12px;
	z-index: 5;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 8px 14px;
	background: var(--tn-accent-700, #1d4ed8);
	color: #fff;
	border-radius: 999px;
	font-size: 13px;
	font-weight: 600;
	box-shadow: 0 4px 12px -2px rgba(29, 78, 216, 0.35);
	margin-left: auto;
}
.tn-cart-summary .tn-cart-summary-count {
	font-family: var(--tn-font-mono, ui-monospace, monospace);
	font-feature-settings: 'tnum';
	background: rgba(255, 255, 255, 0.18);
	padding: 2px 8px;
	border-radius: 999px;
}

/* Top toolbar row on product pages — replaces the legacy bgcolor='#CCFFFF' bar. */
tr.tn-toolbar-row > td {
	background: var(--tn-c-25, #fafafa) !important;
	border-top: 1px solid var(--tn-border-soft, #ebedf0);
	border-bottom: 1px solid var(--tn-border-soft, #ebedf0);
	padding: 8px 6px;
}

/* ==========================================================================
   Encabezado layout fix — the header is a 4-cell row: LEFT logo, CENTER content,
   RIGHT logo, NOTIFICATION BELL (always emitted, width=50). For the center cell
   to sit at the true visual center, left side total = right side total. So:
   left = right_logo + bell_width = 220 + 50 = 270.
   ========================================================================== */
.classEncabezado > table {
	table-layout: fixed !important;
	width: 100% !important;
	max-width: 1400px;
	margin: 0 auto;
}
.classEncabezado > table > tbody > tr > td:first-child {
	width: 270px !important;
	max-width: 270px;
	min-width: 270px;
	text-align: center;
	vertical-align: middle;
	padding: 8px;
}
.classEncabezado > table > tbody > tr > td:nth-last-child(2) {
	width: 220px !important;
	max-width: 220px;
	min-width: 220px;
	text-align: center;
	vertical-align: middle;
	padding: 8px;
}
.classEncabezado > table > tbody > tr > td:last-child {
	width: 50px !important;
	max-width: 50px;
	min-width: 50px;
	vertical-align: middle;
	padding: 0;
}
.classEncabezado > table > tbody > tr > td:first-child > img,
.classEncabezado > table > tbody > tr > td:nth-last-child(2) > img {
	max-width: 100%;
	max-height: 80px;
	width: auto;
	height: auto;
	object-fit: contain;
	display: inline-block;
}

/* Compact-width table modifier — for small tables (few short columns) that
   shouldn't stretch full-page. Pairs with .table.tn-table-compact. */
.table.tn-table-fit {
	width: auto !important;
	max-width: max-content;
	margin-left: auto !important;
	margin-right: auto !important;
}

/* ==========================================================================
   Product page toolbar + filter/sort controls (ListaProductosFacturacion.php)
   ========================================================================== */
.tn-page-actions {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	flex-wrap: wrap;
	max-width: 1600px;
	margin: 16px auto 0;
	padding: 0 4px;
}
.tn-page-actions .tn-page-actions-group {
	display: flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
}
.tn-page-actions select.form-control,
.tn-page-actions .tn-action-select {
	min-width: 200px;
	height: 36px;
	padding: 6px 28px 6px 10px;
	font-size: 14px;
	border: 1px solid var(--tn-border-soft, #ebedf0);
	border-radius: 6px;
	background: #fff;
}

.tn-product-controls {
	display: flex;
	gap: 16px;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	max-width: 1600px;
	margin: 12px auto 0;
	padding: 12px 16px;
	background: var(--tn-surface-card, #fff);
	border: 1px solid var(--tn-border-soft, #ebedf0);
	border-radius: 8px;
}
.tn-filter-input {
	flex: 1 1 320px;
	min-width: 0;
	max-width: 560px;
	height: 38px;
	padding: 8px 12px 8px 38px;
	border: 1px solid var(--tn-border-soft, #ebedf0);
	border-radius: 6px;
	background: #fff url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='8'/><path d='m21 21-4.3-4.3'/></svg>") no-repeat 12px center;
	background-size: 18px 18px;
	font: inherit;
	font-size: 14px;
	color: var(--tn-c-text-base, #0f172a);
	transition: border-color 150ms ease, box-shadow 150ms ease;
}
.tn-filter-input::placeholder { color: var(--tn-text-muted, #64748b); }
.tn-filter-input:focus {
	outline: none;
	border-color: var(--tn-a-700, #1d4ed8);
	box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.12);
}

.tn-sort-group {
	display: inline-flex;
	gap: 0;
	border: 1px solid var(--tn-border-soft, #ebedf0);
	border-radius: 6px;
	overflow: hidden;
	background: #fff;
}
.tn-sort-group-label {
	font-size: 13px;
	color: var(--tn-text-muted, #64748b);
	margin-right: 8px;
	align-self: center;
}
.tn-sort-btn {
	padding: 8px 14px;
	background: #fff;
	border: 0;
	border-right: 1px solid var(--tn-border-soft, #ebedf0);
	font: inherit;
	font-size: 13px;
	color: var(--tn-text-muted, #64748b);
	cursor: pointer;
	transition: background 100ms ease, color 100ms ease;
	white-space: nowrap;
	display: inline-flex;
	align-items: center;
	gap: 6px;
}
.tn-sort-btn:last-child { border-right: 0; }
.tn-sort-btn:hover { background: var(--tn-c-25, #fafafa); color: var(--tn-c-text-base, #0f172a); }
.tn-sort-btn.active {
	background: var(--tn-c-25, #fafafa);
	color: var(--tn-a-700, #1d4ed8);
	font-weight: 600;
}
.tn-sort-btn .tn-sort-arrow {
	display: inline-block;
	width: 0; height: 0;
	border-left: 4px solid transparent;
	border-right: 4px solid transparent;
	opacity: 0;
	transition: opacity 120ms ease;
}
.tn-sort-btn.active .tn-sort-arrow { opacity: 1; }
.tn-sort-btn.active.asc .tn-sort-arrow { border-bottom: 5px solid currentColor; }
.tn-sort-btn.active.desc .tn-sort-arrow { border-top: 5px solid currentColor; }

.tn-empty-state {
	grid-column: 1 / -1;
	padding: 48px 16px;
	text-align: center;
	color: var(--tn-text-muted, #64748b);
	font-size: 14px;
}

/* Renglón con datos incompletos/ inválidos (reemplaza el legacy bgcolor="#FF9595").
   Usado por ListaCuentasBancarias.php. */
.table > tbody > tr.tn-row-warn > td { background: var(--tn-err-50); }
.table > tbody > tr.tn-row-warn:hover > td { background: #fde4e4; }

/* ListaCuentasBancarias.php — tabla acotada y todo centrado (títulos y valores). */
.tn-cuentas { max-width: 1200px; margin: 0 auto; }
.tn-cuentas .table th,
.tn-cuentas .table td,
.tn-cuentas .table > thead > tr:first-child > td,
.tn-cuentas .table td.tn-num-col,
.tn-cuentas .table th.tn-num-col { text-align: center !important; }
.tn-cuentas .table .tn-nowrap { white-space: nowrap; }
