/* ===========================================================================
   components.css — every primitive once, in CSS, driven by classes and custom
   properties (taken from negoly-nucleo). Part A is the primitive set; Part B the shell (sidebar,
   topbar, content), the sign-in card and a few text roles; Part C the date field.
   No literal colour, size, radius or shadow lives here.
   =========================================================================== */

/* ============================ A · PRIMITIVES ============================= */

/* ---- buttons: filled / tinted / plain / danger · sm / md / lg ------------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: var(--control-md); padding: 0 var(--space-4); border-radius: var(--radius-sm);
  font-weight: 600; font-size: var(--t-subhead-size); line-height: 1; white-space: nowrap;
  text-decoration: none;                 /* 40 of these are <a>: a download is still a button */
  transition: background var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard),
              box-shadow var(--motion-fast) var(--ease-standard); }
.btn, .btn.filled { background: var(--accent); color: var(--accent-fg); }
.btn:hover, .btn.filled:hover { background: var(--accent-hover); }
.btn.tinted { background: var(--accent-subtle); color: var(--accent-subtle-fg); }
.btn.tinted:hover { background: color-mix(in oklab, var(--accent-subtle) 80%, var(--accent)); }
.btn.plain { background: transparent; color: var(--accent-text); }
.btn.plain:hover { background: var(--surface-sunken); }
.btn.danger { background: transparent; color: var(--danger-text); box-shadow: inset 0 0 0 1px var(--hairline-2); }
.btn.danger:hover { background: var(--danger-subtle); }
.btn.sm { min-height: var(--control-sm); padding: 0 var(--space-3); font-size: var(--t-footnote-size); border-radius: var(--radius-xs); }
.btn.lg { min-height: var(--control-lg); padding: 0 var(--space-6); font-size: var(--t-body-size); }
.btn.icon-only { padding: 0; width: var(--control-md); }
.btn.icon-only.sm { width: var(--control-sm); }
.btn.block { width: 100%; }
.btn.block + .btn.block { margin-top: var(--space-2); }
.btn:disabled, .btn[aria-busy="true"] { opacity: 0.5; cursor: default; }
.btn[aria-busy="true"] .icon { animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- segmented control ------------------------------------------------- */
.segmented { display: inline-flex; background: var(--surface-sunken); border-radius: var(--radius-full); padding: 3px; gap: 2px; }
.segmented > button { display: inline-grid; grid-auto-flow: column; place-items: center; gap: var(--space-1);
  min-height: calc(var(--control-sm) - 6px); padding: 0 var(--space-4); border-radius: var(--radius-full);
  font-weight: 600; font-size: var(--t-footnote-size); color: var(--text-2); }
.segmented > button.on, .segmented > button[aria-pressed="true"] { background: var(--surface-raised); color: var(--text-1); box-shadow: var(--shadow-raised); }
/* A filter with more choices than a phone is wide scrolls sideways instead of pushing the page wider. */
.segmented.scroll { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.segmented.scroll::-webkit-scrollbar { display: none; }
.segmented.scroll > button { flex: none; }
/* the customer simulator (static/views/simulator.js): a chat tall enough to read a conversation in */
.sim-thread { min-height: 16rem; margin-bottom: var(--space-3); }
.sim-compose { flex-wrap: nowrap; }
.sim-compose input { min-width: 0; }

/* ---- fields ------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: var(--space-1); margin-block: var(--space-3); }
.field-label, label { display: block; font-size: var(--t-footnote-size); font-weight: 600; color: var(--text-2); }
label { margin: var(--space-3) 0 var(--space-1); }
.field-help { font-size: var(--t-footnote-size); color: var(--text-3); }
.field-error { font-size: var(--t-footnote-size); color: var(--danger-text); font-weight: 500; }
.field-error:empty { display: none; }
.check { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-2) 0; font-size: var(--t-subhead-size); color: var(--text-1); cursor: pointer; }
.check input { margin-top: 0.2em; width: 1rem; height: 1rem; accent-color: var(--accent); flex: 0 0 auto; }
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select, textarea {
  width: 100%; min-height: var(--control-md); padding: var(--space-2) var(--space-3);
  background: var(--surface-raised); color: var(--text-1);
  border: 1px solid var(--border-input); border-radius: var(--radius-sm);
  transition: border-color var(--motion-fast) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard); }
textarea { min-height: calc(var(--control-md) * 2); resize: vertical; line-height: var(--t-body-lh); }
input::placeholder, textarea::placeholder { color: var(--text-3); }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--accent-ring); outline-offset: 0; border-color: var(--accent-ring); }
.has-error input, .has-error select, .has-error textarea, [aria-invalid="true"] { border-color: var(--danger-solid); }
input[type="checkbox"], input[type="radio"] { width: 1.25rem; height: 1.25rem; accent-color: var(--accent); margin: 0; flex: none; }
select { appearance: none; -webkit-appearance: none; padding-right: var(--space-8);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - var(--space-4)) 50%, calc(100% - var(--space-4) + 5px) 50%; background-size: 5px 5px; background-repeat: no-repeat; }
.switch { position: relative; width: 2.75rem; height: 1.625rem; border-radius: var(--radius-full); background: var(--border-input); flex: none;
  transition: background var(--motion-fast) var(--ease-standard); }
.switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: 1.25rem; height: 1.25rem; border-radius: 50%;
  background: var(--surface-raised); box-shadow: var(--shadow-raised); transition: transform var(--motion-fast) var(--ease-standard); }
.switch[aria-checked="true"] { background: var(--accent); }
.switch[aria-checked="true"]::after { transform: translateX(1.125rem); }

/* ---- surfaces ------------------------------------------------------------ */
.card { background: var(--surface-raised); border: 1px solid var(--hairline-2); border-radius: var(--radius-md); padding: var(--space-5); }
.card > h3:first-child, .card > .card-head:first-child { margin-bottom: var(--space-3); }
.card-head { display: flex; align-items: center; gap: var(--space-3); }
.card-head > h3 { flex: 1; }
.well { background: var(--surface-sunken); border-radius: var(--radius-md); padding: var(--space-4); }
.divider { height: 1px; background: var(--hairline); margin-block: var(--space-4); }
.section { margin-top: var(--space-5); } .section > h3 { margin-bottom: var(--space-3); }
.cap::first-letter { text-transform: uppercase; }
.perm-group { border: 0; padding: 0; margin: 0 0 var(--space-2); min-width: 0; } .perm-group > legend { padding: 0; }
.check span small { display: block; color: var(--text-2); font-size: var(--t-footnote-size); font-weight: 400; }
.dot.branch { width: 0.75rem; height: 0.75rem; background: var(--branch-color, var(--text-3)); flex: none; }
.eyebrow { font-size: var(--t-caption-size); text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-2); font-weight: 600; margin: var(--space-4) 0 var(--space-2); }
.mono-box { white-space: pre-wrap; overflow-wrap: anywhere; background: var(--surface-sunken); padding: var(--space-3); border-radius: var(--radius-sm);
  font-family: ui-monospace, Menlo, Consolas, "Liberation Mono", monospace; font-size: var(--t-footnote-size); line-height: 1.5; margin: var(--space-3) 0; }
/* the non-fiscal invoice inside the receipt sheet: the document as it prints and as the patient gets it */
/* a supplier's invoice beside what was read from it (Gastos, 02.10.2026): side by side where there is room */
.exp-grid.has-view { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: var(--space-4); align-items: start; }
.modal-panel:has(.exp-grid.has-view) { width: min(64rem, 100%); }
.exp-view { position: sticky; top: 0; background: var(--surface-sunken); border-radius: var(--radius-sm); overflow: hidden; }
.exp-view img { display: block; width: 100%; height: auto; max-height: 70vh; object-fit: contain; }
.exp-view iframe { display: block; width: 100%; height: 70vh; border: 0; }
.exp-view p { padding: var(--space-4); margin: 0; }
@media (max-width: 47.5rem) { .exp-grid.has-view { display: block; } .exp-view { position: static; margin-bottom: var(--space-3); }
  .exp-view img { max-height: 40vh; } .exp-view iframe { height: 50vh; } }
.doc-frame { display: block; width: 100%; height: min(70vh, 760px); border: 1px solid var(--hairline-2); border-radius: var(--radius-sm); }
.card.warning { border-color: color-mix(in oklab, var(--warning-solid) 40%, var(--hairline-2)); background: var(--warning-subtle); }
.card-foot { margin-top: var(--space-3); }
/* Accordion: a card that folds. Native <details>, so keyboard and screen readers work without script. */
.card.acc > summary { list-style: none; display: flex; align-items: center; gap: var(--space-2); cursor: pointer; margin: calc(-1 * var(--space-2)) 0; padding: var(--space-2) 0; }
.card.acc > summary::-webkit-details-marker { display: none; }
.card.acc > summary > h3 { flex: 1; margin: 0; }
.card.acc > summary > .icon { transition: transform var(--motion-base) var(--ease-standard); color: var(--text-2); }
.card.acc:not([open]) > summary > .icon { transform: rotate(-90deg); }
.card.acc > .acc-body { margin-top: var(--space-4); display: grid; gap: var(--space-3); }

/* ---- inset grouped list rows --------------------------------------------- */
.rows { background: var(--surface-raised); border: 1px solid var(--hairline-2); border-radius: var(--radius-md); overflow: hidden; }
.row { display: flex; align-items: center; gap: var(--space-3); min-height: var(--control-md); padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--hairline); text-align: left; width: 100%; color: inherit; }
.row:first-child { border-top: 0; }
.row.link { cursor: pointer; }
.row.link:hover { background: var(--surface-sunken); }
.row .chev { margin-left: auto; color: var(--text-3); }
.row .primary { font-weight: 600; }
.row .secondary { color: var(--text-2); font-size: var(--t-footnote-size); }
.row .grow { flex: 1; min-width: 0; }
.row.wrap { flex-wrap: wrap; }
/* actions that need a line of their own under the row's text (a package session: Completar, No vino, Mover) */
.row.wrap > .row-actions { flex-basis: 100%; }
.row-group + .row-group { border-top: 1px solid var(--hairline); }
.rows .editor { padding: var(--space-3) var(--space-4) var(--space-4); background: var(--surface-sunken); border-top: 1px solid var(--hairline); }
.hours-row { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: var(--space-2); padding: var(--space-1) 0; border-bottom: 1px solid var(--hairline); }
.hours-row:last-of-type { border-bottom: 0; } .hours-row .check { padding: 0; } .hours-row input[type="time"] { width: 100%; min-width: 0; }
.faq-row { display: grid; gap: var(--space-2); padding: var(--space-3); background: var(--surface-sunken); border-radius: var(--radius-sm); margin-bottom: var(--space-2); }
.logo-box { display: flex; align-items: center; min-height: 4.5rem; padding: var(--space-3); margin: var(--space-2) 0; background: var(--surface-sunken); border-radius: var(--radius-sm); }
.logo-prev { display: block; max-height: 4rem; max-width: 100%; width: auto; object-fit: contain; }
@media (max-width: 35rem) { .row.wrap > .cluster { flex-basis: 100%; } .hours-row { grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); } .hours-row .check { grid-column: 1 / -1; padding-top: var(--space-2); } }

/* ---- data table ------------------------------------------------------------ */
.table { width: 100%; border-collapse: collapse; font-size: var(--t-subhead-size); }
.table th, .table td { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--hairline); text-align: left; vertical-align: middle; }
.table th { position: sticky; top: 0; background: var(--surface-sunken); color: var(--text-2); font-size: var(--t-caption-size);
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; z-index: 1; }
.table th[aria-sort] { cursor: pointer; }
.table .num, .table td.num, .table th.num { text-align: right; font-variant-numeric: tabular-nums lining-nums; }
.table tr:hover > td { background: color-mix(in oklab, var(--surface-sunken) 60%, var(--surface-raised)); }
/* The cash report (Caja → Reporte, 03.10.2026): a wide table that has to stay readable on a phone and
   print as a clean sheet, with nothing of the panel around it. */

.rp-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); margin: var(--space-4) 0 var(--space-3); }
.rp-head h2 { margin: 0; font-size: var(--t-title-3-size); }
.rp { font-size: var(--t-caption-size); }
.rp th, .rp td { padding: var(--space-1) var(--space-2); white-space: nowrap; }
.rp td.n, .rp th.n { text-align: right; font-variant-numeric: tabular-nums lining-nums; }
.rp td small { display: block; color: var(--text-3); }
.rp tr.neg td { color: var(--danger); }
.rp tfoot th { background: var(--surface-sunken); font-weight: 700; border-top: 2px solid var(--hairline-2); position: static; }
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--hairline-2); border-radius: var(--radius-md); }
/* Productos as a table (11.10.2026): a figure the owner may change in place looks like text with a dashed
   underline, and becomes a small input on a tap; the totals row stays put under the rows. */
.table .cell-edit { background: none; border: 0; border-bottom: 1px dashed var(--hairline-2); padding: 2px var(--space-1); color: inherit; font: inherit;
  border-radius: var(--radius-xs); cursor: text; }
.table .cell-edit:hover, .table .cell-edit:focus-visible { background: var(--accent-subtle); }
.table .cell-input { width: 6.5rem; min-height: var(--control-sm, 2rem); padding: 0 var(--space-2); text-align: right; }
.table td .sub { display: block; color: var(--text-3); font-size: var(--t-caption-size); }
.table td.acts { white-space: nowrap; text-align: right; }
.table tfoot th { position: static; background: var(--surface-sunken); color: var(--text-1); font-weight: 700; text-transform: none; letter-spacing: 0;
  font-size: var(--t-subhead-size); border-top: 2px solid var(--hairline-2); }
.ct-tools { margin: var(--space-3) 0 var(--space-2); }
.ct-tools input[type="search"] { flex: 1 1 16rem; width: auto; }
.ct-tools select { flex: 0 1 14rem; width: auto; }
/* any list shown as a table (static/views/datatable.js) */
.table.dtable tr.dtable-click { cursor: pointer; }
.table.dtable th[data-dt-sort]:focus-visible { outline: 2px solid var(--focus-ring, var(--accent)); outline-offset: -2px; }
.table.dtable td.num, .table.dtable th.num, .table.dtable .pill { white-space: nowrap; }
.table.dtable .dtable-clip { display: inline-block; max-width: 14rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
.dtable-switch { flex: none; }
.table .nowrap { white-space: nowrap; }
.t-danger { color: var(--danger-text); }
  padding: var(--space-3); cursor: pointer; box-shadow: var(--shadow-raised); }

/* ---- tabs -------------------------------------------------------------------- */
.tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--hairline); }
.tabs > button { min-height: var(--control-md); padding: 0 var(--space-3); color: var(--text-2); font-weight: 500; font-size: var(--t-subhead-size);
  border-bottom: 2px solid transparent; margin-bottom: -1px; }
.tabs > button.on, .tabs > button[aria-selected="true"] { color: var(--text-1); border-bottom-color: var(--accent); font-weight: 600; }

/* ---- modal / bottom sheet ---------------------------------------------------- */
.modal-root { position: fixed; inset: 0; z-index: var(--z-modal); display: grid; place-items: center; padding: var(--space-5); }
.modal-backdrop { position: absolute; inset: 0; background: color-mix(in oklab, var(--text-1) 45%, transparent);
  opacity: 0; transition: opacity var(--motion-base) var(--ease-standard); }
.modal-panel { position: relative; width: min(30rem, 100%); max-height: 90dvh; overflow: auto; background: var(--surface-raised);
  border-radius: var(--radius-xl); box-shadow: var(--shadow-modal); padding: var(--space-6);
  opacity: 0; transform: translateY(12px) scale(0.98);
  transition: opacity var(--motion-slow) var(--ease-standard), transform var(--motion-slow) var(--ease-standard); }
.modal-root.on .modal-backdrop { opacity: 1; }
.modal-root.on .modal-panel { opacity: 1; transform: none; }
.modal-root.leaving .modal-backdrop, .modal-root.leaving .modal-panel { transition-timing-function: var(--ease-exit); transition-duration: var(--motion-base); }
.modal-head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); }
.modal-head > h2 { flex: 1; }
.modal-actions { display: flex; gap: var(--space-2); justify-content: flex-end; margin-top: var(--space-5); flex-wrap: wrap; }
body.scroll-locked { overflow: hidden; }
@media (max-width: 34.99rem) {
  .modal-root.as-sheet { place-items: end stretch; padding: 0; }
  .modal-root.as-sheet .modal-panel { width: 100%; max-height: 88dvh; border-radius: var(--radius-xl) var(--radius-xl) 0 0; transform: translateY(100%); }
  .modal-root.as-sheet.on .modal-panel { transform: none; }
}

/* ---- dropdown menu ------------------------------------------------------------ */
.menu { position: absolute; z-index: var(--z-overlay); min-width: 12rem; padding: var(--space-1);
  background: var(--surface-raised); border-radius: var(--radius-md); box-shadow: var(--shadow-overlay); border: 1px solid var(--hairline-2); }
.menu > button, .menu > a { display: flex; align-items: center; gap: var(--space-2); width: 100%; min-height: var(--control-sm);
  padding: 0 var(--space-3); border-radius: var(--radius-xs); text-align: left; color: var(--text-1); text-decoration: none; }
.menu > button:hover, .menu > a:hover { background: var(--surface-sunken); }
.menu > .danger { color: var(--danger-text); }

/* ---- toast --------------------------------------------------------------------- */
.toast-region { position: fixed; left: 50%; bottom: var(--space-5); transform: translateX(-50%); z-index: var(--z-toast);
  display: flex; flex-direction: column; gap: var(--space-2); pointer-events: none; width: min(26rem, calc(100% - var(--space-8))); }
.toast { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-radius: var(--radius-md);
  background: var(--surface-raised); color: var(--text-1); box-shadow: var(--shadow-overlay); border: 1px solid var(--hairline-2);
  font-size: var(--t-subhead-size); pointer-events: auto; opacity: 0; transform: translateY(8px);
  transition: opacity var(--motion-base) var(--ease-standard), transform var(--motion-base) var(--ease-standard); }
.toast.on { opacity: 1; transform: none; }
.toast.success .icon { color: var(--success-text); } .toast.warning .icon { color: var(--warning-text); }
.toast.danger .icon { color: var(--danger-text); } .toast.info .icon { color: var(--info-text); }

/* ---- badge / status pill (never colour alone: icon or text carries it too) --- */
.pill { display: inline-flex; align-items: center; gap: var(--space-1); min-height: 1.5rem; padding: 0 var(--space-2);
  border-radius: var(--radius-full); font-size: var(--t-caption-size); font-weight: 600; letter-spacing: 0.01em;
  background: var(--surface-sunken); color: var(--text-2); white-space: nowrap; }
.pill.success { background: var(--success-subtle); color: var(--success-text); }
.pill.warning { background: var(--warning-subtle); color: var(--warning-text); }
.pill.danger  { background: var(--danger-subtle);  color: var(--danger-text); }
.pill.info    { background: var(--info-subtle);    color: var(--info-text); }
.pill.accent  { background: var(--accent-subtle);  color: var(--accent-subtle-fg); }
.count { display: inline-grid; place-items: center; min-width: 1.25rem; height: 1.25rem; padding: 0 var(--space-1);
  border-radius: var(--radius-full); background: var(--accent); color: var(--accent-fg); font-size: var(--t-caption-size); font-weight: 700; }

/* ---- avatar ------------------------------------------------------------------- */
.avatar { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; border-radius: 50%; flex: none;
  background: var(--accent-subtle); color: var(--accent-subtle-fg); font-weight: 700; font-size: var(--t-footnote-size); letter-spacing: 0.02em; }
.avatar.sm { width: 2rem; height: 2rem; font-size: var(--t-caption-size); }
.avatar.web { background: var(--info-subtle); color: var(--info-text); }
.avatar .icon { width: 1.25rem; height: 1.25rem; }
.avatar.square { border-radius: var(--radius-sm); }

/* ---- tooltip (pure CSS, on data-tip) ------------------------------------------- */
[data-tip] { position: relative; }
[data-tip]::after { content: attr(data-tip); position: absolute; left: 50%; bottom: calc(100% + 6px); transform: translateX(-50%);
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-xs); background: var(--text-1); color: var(--surface-raised);
  font-size: var(--t-caption-size); white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity var(--motion-fast); z-index: var(--z-overlay); }
[data-tip]:hover::after, [data-tip]:focus-visible::after { opacity: 1; }

/* ---- skeleton ------------------------------------------------------------------ */
.skeleton { display: grid; gap: var(--space-2); }
.skeleton-line { height: 0.875rem; width: var(--w, 100%); border-radius: var(--radius-xs);
  background: linear-gradient(90deg, var(--surface-sunken) 25%, color-mix(in oklab, var(--surface-sunken) 50%, var(--surface-raised)) 50%, var(--surface-sunken) 75%);
  background-size: 200% 100%; animation: shimmer 1.4s linear infinite; }
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* ---- empty / error state --------------------------------------------------------- */
.empty { display: grid; justify-items: center; gap: var(--space-2); text-align: center; padding: var(--space-12) var(--space-5); color: var(--text-2); }
.empty > .icon { color: var(--text-3); width: 2.5rem; height: 2.5rem; --icon-stroke: 1.5; }
.empty > .btn { margin-top: var(--space-2); }
.empty.error > .icon { color: var(--danger-text); }
.empty.compact { padding: var(--space-6) var(--space-4); }

/* ---- pagination -------------------------------------------------------------------- */
.pager { display: flex; align-items: center; gap: var(--space-1); justify-content: flex-end; }
.pager > .btn { min-width: var(--control-sm); }
.pager > .btn[aria-current="page"] { background: var(--accent-subtle); color: var(--accent-subtle-fg); }

/* ---- layout helpers ------------------------------------------------------------------ */
.stack { display: flex; flex-direction: column; gap: var(--space-3); }
.grid-2 > *, .grid-4 > * { min-width: 0; }   /* date/time inputs have a wide intrinsic size; let columns shrink them */
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.cluster > .grow { flex: 1; min-width: 0; }
/* A group that moves as one when its row runs out: the report's Ver · PDF · Excel used to split, Ver
   staying up and the two downloads dropping alone (06.10.2026). */
.cluster.nowrap { flex-wrap: nowrap; }
.fx-offer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-3); margin: var(--space-3) 0; }
.fx-offer p { flex: 1 1 16rem; margin: 0; }   /* a spacer or a caption that pushes the action to the end */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); align-items: start; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
@media (max-width: 68.75rem) { .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 56.25rem) { .grid-2 { grid-template-columns: 1fr; } }
@media (max-width: 35rem)    { .grid-4 { grid-template-columns: 1fr 1fr; } }

/* ======================= B · SHELL, SIGN-IN, TEXT ROLES (class names kept from negoly-nucleo) ======================= */

.btn.chico { width: auto; min-height: var(--control-sm); padding: 0 var(--space-3); font-size: var(--t-footnote-size); border-radius: var(--radius-xs); margin-top: 0; }
.btn.sec { background: var(--surface-raised); color: var(--text-1); box-shadow: inset 0 0 0 1px var(--hairline-2); }
.btn.sec:hover { background: var(--surface-sunken); color: var(--text-1); }
.btn.peligro { background: transparent; color: var(--danger-text); box-shadow: inset 0 0 0 1px var(--hairline-2); }
.btn.peligro:hover { background: var(--danger-subtle); }

/* -- text roles -- */
.error { color: var(--danger-text); font-size: var(--t-footnote-size); margin-top: var(--space-2); }
.ok { color: var(--success-text); font-size: var(--t-footnote-size); margin-top: var(--space-2); }
h2 { font-size: var(--t-title3-size); line-height: var(--t-title3-lh); font-weight: var(--t-title3-w); letter-spacing: var(--t-title3-ls); margin: 0 0 var(--space-4); }
h3 { font-size: var(--t-headline-size); line-height: var(--t-headline-lh); font-weight: var(--t-headline-w); letter-spacing: var(--t-headline-ls); }
.saludo { font-size: var(--t-title2-size); line-height: var(--t-title2-lh); font-weight: var(--t-title2-w); letter-spacing: var(--t-title2-ls); margin-bottom: 2px; }
.fila { display: flex; align-items: center; gap: var(--space-3); justify-content: space-between; } .fila > * { min-width: 0; }
.lista { display: flex; flex-direction: column; gap: var(--space-3); }
.item { background: var(--surface-raised); border: 1px solid var(--hairline-2); border-radius: var(--radius-md); padding: var(--space-3) var(--space-4); }
.item .t { font-weight: 600; } .item .s { color: var(--text-2); font-size: var(--t-footnote-size); }
.etiqueta.owner, .etiqueta.dueno, .etiqueta.ok { background: var(--success-subtle); color: var(--success-text); }

/* -- KPI tiles: numbers are content, not decoration → text-1, tabular; semantic tints keep meaning -- */
.metricas { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
.metricas:not(:last-child) { margin-bottom: var(--space-4); }
.metricas > * { min-width: 0; }
.metricas .m { background: var(--surface-raised); border: 1px solid var(--hairline-2); border-radius: var(--radius-md); padding: var(--space-4); }
.metricas .m b { display: block; font-size: var(--t-title2-size); line-height: 1.1; font-weight: 700; letter-spacing: var(--t-title2-ls); color: var(--text-1); font-variant-numeric: tabular-nums lining-nums; }
.metricas .m span { display: block; font-size: var(--t-footnote-size); color: var(--text-1); font-weight: 600; margin-top: var(--space-2); }
.metricas .m i { display: block; font-style: normal; font-size: var(--t-footnote-size); color: var(--text-2); margin-top: 2px; }
.metricas.chicas .m b { font-size: var(--t-headline-size); }
.metricas .m.ok b { color: var(--success-text); } .metricas .m.bad b { color: var(--danger-text); } .metricas .m.warn b { color: var(--warning-text); }
@media (max-width: 68.75rem) { .metricas { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 35rem)    { .metricas { grid-template-columns: 1fr 1fr; } }

/* -- login -- */
.centro { position: fixed; inset: 0; background: var(--surface-canvas); display: grid; grid-template-columns: minmax(0, 1fr); place-items: center; padding: var(--space-5); overflow: auto; }
.acceso { width: min(26rem, 100%); min-width: 0; }
.acceso .card { border-radius: var(--radius-xl); box-shadow: var(--shadow-raised); padding: var(--space-8); text-align: left; }
.acceso .mark { width: 3.5rem; height: 3.5rem; border-radius: var(--radius-md); background: var(--accent); color: var(--accent-fg); display: grid; place-items: center;
  font-weight: 700; font-size: var(--t-title3-size); margin: 0 auto var(--space-4); }
.acceso h1 { font-size: var(--t-title3-size); line-height: var(--t-title3-lh); font-weight: var(--t-title3-w); letter-spacing: var(--t-title3-ls); margin-bottom: var(--space-1); text-align: center; }
.acceso p.sub { color: var(--text-2); font-size: var(--t-subhead-size); margin: 0 0 var(--space-5); text-align: center; }
.acceso .cluster.center { justify-content: center; margin-top: var(--space-4); }
.acceso .btn.block { margin-top: var(--space-4); } .acceso .btn.plain.block { margin-top: var(--space-2); }
input.codigo { font-size: var(--t-title1-size); letter-spacing: 0.35em; text-align: center; font-variant-numeric: tabular-nums; font-weight: 600; }
.idioma { display: inline-flex; background: var(--surface-sunken); border-radius: var(--radius-full); padding: 3px; gap: 2px; }
.idioma button { min-height: calc(var(--control-sm) - 6px); padding: 0 var(--space-3); border-radius: var(--radius-full); font-size: var(--t-caption-size); font-weight: 600; color: var(--text-2); }
.idioma button.activo { background: var(--surface-raised); color: var(--text-1); box-shadow: var(--shadow-raised); }

/* -- shell -- */
.shell { min-height: 100dvh; }
.sidebar { position: fixed; left: 0; top: 0; bottom: 0; width: var(--sidebar-w); background: var(--surface-nav); color: var(--text-on-nav-2);
  display: flex; flex-direction: column; z-index: var(--z-modal); overflow: hidden;
  transition: width var(--motion-slow) var(--ease-standard), transform var(--motion-slow) var(--ease-standard), visibility 0s; }
/* -- the menu toggle: one state on the shell (data-nav), read differently by each breakpoint.
   Wide: the menu collapses to a rail of icons and the toggle lives in the sidebar's own header —
   a chevron pointing left to contract, right to expand. Narrow: it is closed unless opened, rides
   over the content with a backdrop, and the topbar hamburger drives it; `visibility` (delayed until
   the slide finishes) is what keeps that closed menu out of the tab order. -- */
.sb-toggle { display: none; margin-left: auto; place-items: center; flex: none; border-radius: var(--radius-sm);
  min-width: var(--control-sm); min-height: var(--control-sm); color: var(--text-on-nav-2); }
.sb-toggle:hover { background: var(--surface-nav-hover); color: var(--text-on-nav); }
.sb-toggle > span { display: inline-grid; place-items: center; }
.shell[data-nav="open"] .sb-toggle .when-closed, .shell[data-nav="closed"] .sb-toggle .when-open { display: none; }

@media (min-width: 55.0625rem) {
  .sb-toggle { display: inline-grid; }
  .shell[data-nav="closed"] .sidebar { width: var(--sidebar-rail); }
  .shell[data-nav="closed"] .main { margin-left: var(--sidebar-rail); }
  .shell[data-nav="closed"] .content { margin-inline: auto; }   /* reclaimed space is shared, not dumped on the right */
  .shell[data-nav="closed"] .sb-brand { flex-direction: column; gap: var(--space-2); padding: var(--space-3) var(--space-2); }
  .shell[data-nav="closed"] .sb-toggle { margin-left: 0; }
  .shell[data-nav="closed"] .sb-brand > div,
  .shell[data-nav="closed"] .sb-ws .nm,
  .shell[data-nav="closed"] .sb-foot .segmented,
  .shell[data-nav="closed"] .sb-foot .plan { display: none; }
  .shell[data-nav="closed"] .sb-ws { justify-content: center; padding: var(--space-3) var(--space-2); }
  .shell[data-nav="closed"] .nav { padding: var(--space-2); }
  .shell[data-nav="closed"] .nav a { justify-content: center; padding: 0; }
  /* the label still names the link for assistive tech; on the rail it also becomes the hover tooltip */
  .shell[data-nav="closed"] .nav a > span:not(.badge),
  .shell[data-nav="closed"] .sb-foot .out span { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .shell[data-nav="closed"] .nav a .badge { position: absolute; top: 2px; right: 2px; margin: 0; padding: 0 4px; }
  .shell[data-nav="closed"] .nav .sep { height: 1px; padding: 0; margin: var(--space-3) var(--space-2); background: var(--hairline); font-size: 0; line-height: 0; color: transparent; }
  .shell[data-nav="closed"] .sb-foot { padding: var(--space-2); }
  .shell[data-nav="closed"] .sb-foot .out { justify-content: center; margin-top: 0; }
}
.sidebar :focus-visible { outline-color: var(--accent-300); }
.sb-brand { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--hairline); }
.sb-brand .mark { width: 2.125rem; height: 2.125rem; border-radius: var(--radius-sm); background: var(--accent-400); color: var(--accent-950); display: grid; place-items: center; font-weight: 800; }
.sb-brand b { color: var(--text-on-nav); font-size: var(--t-headline-size); font-weight: 700; }
.sb-brand small { display: block; font-size: var(--t-caption-size); color: var(--text-on-nav-2); letter-spacing: 0.08em; text-transform: uppercase; }
.sb-brand .sb-ver { all: unset; cursor: pointer; text-transform: none; letter-spacing: 0; font-variant-numeric: tabular-nums; color: inherit; border-radius: var(--radius-sm); }   /* "v1.10.1", not "V1.10.1" */
.sb-brand .sb-ver:hover { text-decoration: underline; color: var(--text-on-nav); }
.sb-brand .sb-ver:focus-visible { outline: 2px solid var(--focus-ring, var(--accent)); outline-offset: 2px; }
.changelog h3 { margin: var(--space-5) 0 var(--space-2); } .changelog h3:first-child { margin-top: 0; }
.changelog h4 { margin: var(--space-3) 0 var(--space-1); }
.changelog ul { margin: 0 0 var(--space-2); padding-left: var(--space-5); } .changelog li { margin: var(--space-1) 0; }
.changelog hr { border: 0; border-top: 1px solid var(--hairline-2); margin: var(--space-4) 0; }
.changelog code { font-size: 0.92em; }
.sb-ws { padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--hairline); display: flex; align-items: center; gap: var(--space-3); }
.sb-ws .av { width: 2.125rem; height: 2.125rem; border-radius: var(--radius-sm); flex: none; background: var(--accent-subtle); color: var(--accent-subtle-fg); display: grid; place-items: center; font-weight: 700; font-size: var(--t-footnote-size); }
.sb-ws .nm { font-size: var(--t-subhead-size); font-weight: 600; color: var(--text-on-nav); line-height: 1.2; min-width: 0; }
.sb-ws .nm small { display: block; color: var(--text-on-nav-2); font-weight: 400; font-size: var(--t-caption-size); }
/* The account switcher keeps its chevron: without it the name read as a label, and Ivan could not find
   how to reach the Tienda Demo from the Clínica Demo (11.10.2026). */
.sb-ws select { background-color: transparent; border: 0; color: var(--text-on-nav); font-weight: 600; font-size: var(--t-subhead-size);
  padding: 0 var(--space-6) 0 0; min-height: 0; width: 100%; cursor: pointer; text-overflow: ellipsis;
  background-position: calc(100% - 10px) 50%, calc(100% - 5px) 50%; }
.sb-ws select:hover, .sb-ws select:focus-visible { color: var(--text-on-nav); text-decoration: underline; text-underline-offset: 3px; }
.nav { flex: 1; overflow-y: auto; padding: var(--space-2); }
/* The menu scrolls when the screen is short. With a mouse attached macOS shows classic scrollbars and
   Chrome paints a light one across the dark sidebar (Safari overlays it); keep it thin and in the
   sidebar's own colours (02.10.2026). */
.sidebar .nav { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--text-on-nav-2) 35%, transparent) transparent; }
.sidebar .nav::-webkit-scrollbar { width: 6px; }
.sidebar .nav::-webkit-scrollbar-track { background: transparent; }
.sidebar .nav::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--text-on-nav-2) 35%, transparent); border-radius: 3px; }
.nav a { display: flex; align-items: center; gap: var(--space-3); min-height: var(--control-md); padding: 0 var(--space-3); border-radius: var(--radius-sm);
  color: var(--text-on-nav-2); font-size: var(--t-subhead-size); font-weight: 500; margin-bottom: 2px; cursor: pointer; text-decoration: none; position: relative;
  transition: background var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard); }
.nav a:hover { background: var(--surface-nav-hover); color: var(--text-on-nav); }
.nav a.on { background: var(--surface-nav-active); color: var(--text-on-nav); font-weight: 600; }
.nav a.on::before { content: ""; position: absolute; left: 0; top: 25%; height: 50%; width: 3px; border-radius: var(--radius-full); background: var(--accent-300); }
.nav a .badge { margin-left: auto; background: var(--danger-solid); color: var(--on-solid); font-size: var(--t-caption-size); font-weight: 700; border-radius: var(--radius-full); padding: 1px var(--space-2); }
.nav .sep { font-size: var(--t-caption-size); text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-on-nav-2); opacity: 0.7; padding: var(--space-4) var(--space-3) var(--space-1); }
.sb-foot { padding: var(--space-3); border-top: 1px solid var(--hairline); }
.sb-foot .segmented { display: flex; width: 100%; background: var(--surface-nav-hover); margin-bottom: var(--space-2); }
.sb-foot .segmented > button { flex: 1; padding: 0; color: var(--text-on-nav-2); }
.sb-foot .segmented > button:hover { color: var(--text-on-nav); }
.sb-foot .segmented > button[aria-pressed="true"] { background: var(--surface-nav-active); color: var(--text-on-nav); box-shadow: none; }
.sb-foot .plan { background: var(--surface-nav-hover); border: 1px solid var(--hairline); border-radius: var(--radius-sm); padding: var(--space-3); font-size: var(--t-footnote-size); }
.sb-foot .plan b { color: var(--text-on-nav); }
.sb-foot .out { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2); color: var(--text-on-nav-2); font-size: var(--t-footnote-size); }
.main { margin-left: var(--sidebar-w); min-height: 100dvh; transition: margin-left var(--motion-slow) var(--ease-standard); }
.topbar { position: sticky; top: 0; z-index: var(--z-nav); background: var(--surface-overlay); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--hairline); display: flex; align-items: center; gap: var(--space-4); padding: 0 var(--space-6); min-height: 3.875rem; }
.topbar .ham { display: none; place-items: center; min-width: var(--control-md); min-height: var(--control-md); flex: none; }
.topbar h2 { font-size: var(--t-headline-size); line-height: var(--t-headline-lh); font-weight: var(--t-headline-w); letter-spacing: var(--t-headline-ls); margin: 0; }
.topbar .right { margin-left: auto; display: flex; align-items: center; gap: var(--space-3); }
.topbar .sede { width: auto; min-height: var(--control-sm); padding: 0 var(--space-8) 0 var(--space-3); font-size: var(--t-footnote-size); max-width: 12rem; border-radius: var(--radius-full); }
.content { padding: var(--space-6); max-width: var(--content-max); }
.content[data-wide] { max-width: none; }   /* tables, agenda, dashboards: the data wants the room */
/* Vertical rhythm of a screen: every top-level block after another gets one step of air. Views used to get
   it only from `.section` or inline margins, so cards, grids and empty states sat at 0 px on each other
   (measured on overview, plan, settings, profile, billing). A caption right under a heading stays tight. */
.content > * + * { margin-top: var(--space-5); }
.content > :is(h1, h2, h3) + p { margin-top: var(--space-1); }
.sb-backdrop { display: none; position: fixed; inset: 0; background: color-mix(in oklab, var(--text-1) 45%, transparent); z-index: var(--z-overlay); }

/* -- legacy #sheet: centred dialog on desktop, bottom sheet on phones -- */
#sheet { position: fixed; inset: 0; background: color-mix(in oklab, var(--text-1) 45%, transparent); z-index: var(--z-modal); display: flex; align-items: center; justify-content: center; padding: var(--space-5); }

@media (max-width: 55rem) {
  :root { --sidebar-w: 0px; }
  .sidebar { transform: translateX(-100%); visibility: hidden; width: 15.5rem; box-shadow: var(--shadow-modal);
    transition: transform var(--motion-slow) var(--ease-standard), visibility 0s linear var(--motion-slow); }
  .shell[data-nav="open"] .sidebar { transform: none; visibility: visible; transition-delay: 0s; }
  .shell[data-nav="open"] .sb-backdrop { display: block; }
  .topbar .ham { display: inline-grid; }
  .main, .shell[data-nav="open"] .main { margin-left: 0; }
  .topbar { padding: 0 var(--space-3); gap: var(--space-2); } .topbar .right { gap: var(--space-2); } .topbar .sede { max-width: 7.5rem; } .idioma button { padding: 0 var(--space-2); }
  .topbar h2 { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .content { padding: var(--space-4); }
  #sheet { align-items: flex-end; padding: 0; }
}
@media (max-width: 35rem) { .acceso .tarjeta { padding: var(--space-6); } }


/* --- the date field (ui.js dateField): month in letters, our own calendar ------------------------
   The native input stays in the DOM carrying the ISO value and is only taken out of the layout, so
   nothing that reads it changes. Everything visible here is ours. */
.dt { position: relative; display: inline-flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; min-width: 0; flex: 0 1 auto; }
.dt-native { display: none; }      /* kept for its ISO value and its id, never shown or reachable */
/* The face must hold "03/Oct/2026" whole: a year cut in half is the very confusion this replaced. The
   time may shrink and the pair may wrap onto two lines, but the date itself never gives ground. */
/* The base input rule is input:not([type=checkbox]):not([type=radio]):not([type=range]) -- three
   attribute selectors, specificity (0,3,1) -- and sets width:100%. A plain `.dt .dt-face` (0,2,0) lost
   to it, so every date field stretched to fill its row and pushed the calendar button underneath
   (Ivan, 06.10.2026). These match it and sit later in the file, so they win by order. */
.dt input.dt-face[type="text"] { flex: 0 0 auto; width: 10.5rem; min-width: 0; font-variant-numeric: tabular-nums; }
/* When the three do not fit on one line it is the TIME that drops, never the button that opens the
   calendar: a date with an orphaned icon under it reads like a mistake. */
.dt input.dt-time[type="time"] { order: 2; flex: 0 0 auto; width: 7.5rem; min-width: 0; }
.dt-open { order: 1; flex: 0 0 auto; }
.dt-warn { order: 3; }
.dt-warn { flex: 1 0 100%; margin: var(--space-1) 0 0; font-size: var(--t-footnote-size); color: var(--warning-text); }
.dt-warn:not(:empty) { order: 3; }
.dt-warn:empty { display: none; }
.dt.is-past .dt-face { border-color: var(--warning-solid); }

.dt-pop { position: fixed; z-index: var(--z-overlay); top: var(--pop-top, 0); left: var(--pop-left, 0);
  max-height: min(24rem, 60vh); overflow: auto;
  width: min(21rem, calc(100vw - 2rem));
  background: var(--surface-raised); border: 1px solid var(--hairline-2); border-radius: var(--radius-md);
  box-shadow: var(--shadow-overlay); padding: var(--space-3); }
.dt-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin: 0 0 var(--space-2); }
.dt-head b { font-size: var(--t-headline-size); }
.dt-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dt-w { display: flex; align-items: center; justify-content: center; height: 1.75rem;
  font-size: var(--t-caption-size); color: var(--text-3); }
.dt-d { display: flex; align-items: center; justify-content: center; min-height: 2.5rem; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-1); font: inherit; font-variant-numeric: tabular-nums; cursor: pointer;
  transition: background var(--motion-fast) var(--ease-standard); }
.dt-d:hover { background: var(--surface-sunken); }
.dt-d.past { color: var(--text-3); }
.dt-d.now { box-shadow: inset 0 0 0 1px var(--accent); }
.dt-d.on { background: var(--accent); color: var(--accent-fg); }
.dt-d:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.dt-foot { display: flex; justify-content: flex-end; margin: var(--space-3) 0 0; }
/* Opened near the foot of a sheet, the calendar hangs upwards instead of off the end of it. */
/* a package's sessions, one date each (card #174): two columns where they fit */
.pkg-dates { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 0 var(--space-4); }
/* a whole row that opens something reads as a row, not as an underlined link (Paquetes, Resumen) */
a.row { text-decoration: none; color: inherit; }
a.row:hover { background: var(--surface-sunken); }
/* moving one session of a package, right under its row (Ivan, 09.10.2026) */
.pk-move { padding: var(--space-3) var(--space-4); border-top: 1px solid var(--hairline); background: var(--surface-sunken); }
