/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

:root {
  --background: #fdf8f3;
  --foreground: #0a0a0a;
  --report-slice-neutral: #262626;
  --card: #ffffff;
  --card-foreground: #0a0a0a;
  --popover: #ffffff;
  --popover-foreground: #0a0a0a;
  --muted: #f5f5f4;
  --muted-foreground: #737373;
  --secondary: #f5f5f4;
  --secondary-foreground: #171717;
  --accent: #f5f5f4;
  --accent-foreground: #171717;
  --border: #e7e5e4;
  --input: #d6d3d1;
  --ring: #a8a29e;
  --primary: #171717;
  --primary-foreground: #fafafa;
  /* red-700, not red-600: white on #dc2626 is 4.80:1, which squeaks past AA and
     reads as unreadable at the 12px of .button--small (reported in the first
     human review pass over the screenshot baseline, on devices-index's
     "Desasignar"). #b91c1c takes the same white to 6.52:1. */
  --destructive: #b91c1c;
  --destructive-foreground: #ffffff;
  --success: #10b981;
  --danger: #ef4444;
  --radius: 8px;
  --shadow: 0 1px 2px rgb(15 23 42 / 5%), 0 10px 28px rgb(15 23 42 / 6%);
  --badge-slide-dur: 260ms;
  --badge-pop-dur: 500ms;
  --badge-pop-close-dur: 180ms;
  --badge-fade-dur: 400ms;
  --badge-fade-close-dur: 180ms;
  --badge-blur: 2px;
  --badge-offset-x: -8.2px;
  --badge-offset-y: 12.4px;
  --badge-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --badge-pop-ease: cubic-bezier(0.34, 1.36, 0.64, 1);
  --badge-close-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --dropdown-open-dur: 250ms;
  --dropdown-close-dur: 150ms;
  --dropdown-pre-scale: 0.97;
  --dropdown-closing-scale: 0.99;
  --dropdown-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --modal-open-dur: 250ms;
  --modal-close-dur: 150ms;
  --modal-scale: 0.96;
  --modal-scale-close: 0.96;
  --modal-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --shake-distance: 6px;
  --shake-overshoot: 4px;
  --shake-dur-a: 80ms;
  --shake-dur-b: 60ms;
  --shake-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --revert-dur: 280ms;
  /* App tooltips: tweak this block to change the shared look and feel. */
  --tooltip-background: #171717;
  --tooltip-foreground: #fafafa;
  --tooltip-border: rgb(255 255 255 / 12%);
  --tooltip-shadow: 0 8px 24px rgb(15 23 42 / 18%);
  --tooltip-radius: 6px;
  --tooltip-font-size: 12px;
  --tooltip-font-weight: 600;
  --tooltip-line-height: 1.3;
  --tooltip-padding-y: 6px;
  --tooltip-padding-x: 9px;
  --tooltip-max-width: 260px;
  --tooltip-gap: 8px;
  --tooltip-duration: 100ms;
  color-scheme: light;
  font-family:
    Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

.dark {
  --background: #09090b;
  --foreground: #fafafa;
  --report-slice-neutral: #e5e7eb;
  --card: #18181b;
  --card-foreground: #fafafa;
  --popover: #18181b;
  --popover-foreground: #fafafa;
  --muted: #27272a;
  --muted-foreground: #a1a1a1;
  --secondary: #27272a;
  --secondary-foreground: #fafafa;
  --accent: #27272a;
  --accent-foreground: #fafafa;
  --border: #3f3f46;
  --input: #52525b;
  --ring: #71717a;
  --primary: #fafafa;
  --primary-foreground: #18181b;
  /* Dark's red was #ef4444, which under the same white foreground is 3.69:1 —
     an outright AA failure, worse than the light theme that was reported. Found
     while fixing light; the dark variant of that screen was never looked at. */
  --destructive: #dc2626;
  --destructive-foreground: #ffffff;
  --shadow: 0 1px 2px rgb(0 0 0 / 20%), 0 12px 30px rgb(0 0 0 / 24%);
  --tooltip-background: #fafafa;
  --tooltip-foreground: #18181b;
  --tooltip-border: rgb(24 24 27 / 12%);
  --tooltip-shadow: 0 8px 24px rgb(0 0 0 / 32%);
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html {
  min-height: 100%;
}

body {
  /* `dvh`, like every full-height screen below: `100vh` is the height with the
     phone's URL bar collapsed, so it floors the page taller than what is
     visible and leaves every screen a few pixels of scroll — which is what
     makes the bar flicker on a screen that otherwise fits exactly. */
  min-height: 100dvh;
  margin: 0;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--background) 92%, var(--card)) 0, var(--background) 240px);
  color: var(--foreground);
  font-feature-settings: "rlig" 1, "calt" 1;
}

a {
  color: inherit;
  text-underline-offset: 3px;
}

button,
input,
textarea {
  font: inherit;
}

/* The `hidden` attribute must always win over component display rules
   (e.g. `.button { display: inline-flex }`), which otherwise have equal
   specificity and override the user-agent `[hidden] { display: none }`. */
[hidden] {
  display: none !important;
}

@keyframes t-badge-slide-in {
  from { transform: translate(var(--badge-offset-x), var(--badge-offset-y)); }
  to { transform: translate(0, 0); }
}

@keyframes t-input-shake {
  0% { transform: translateX(0); animation-timing-function: var(--shake-ease); }
  28.57% { transform: translateX(var(--shake-distance)); animation-timing-function: var(--shake-ease); }
  57.14% { transform: translateX(calc(var(--shake-distance) * -1)); animation-timing-function: var(--shake-ease); }
  78.57% { transform: translateX(var(--shake-overshoot)); animation-timing-function: var(--shake-ease); }
  100% { transform: translateX(0); }
}

.t-badge {
  position: absolute;
  top: -6px;
  right: -8px;
  pointer-events: none;
  will-change: transform;
}

.t-badge[data-open="true"] {
  animation: t-badge-slide-in var(--badge-slide-dur) var(--badge-slide-ease);
}

.t-badge-dot {
  display: block;
  transform: scale(1);
  transform-origin: center;
  opacity: 1;
  filter: blur(0);
  transition:
    transform var(--badge-pop-dur) var(--badge-pop-ease),
    opacity var(--badge-fade-dur) var(--badge-pop-ease),
    filter var(--badge-pop-dur) var(--badge-pop-ease);
  will-change: transform, opacity, filter;
}

.t-badge[data-open="false"] .t-badge-dot {
  transform: scale(0);
  opacity: 0;
  filter: blur(var(--badge-blur));
  transition:
    transform var(--badge-pop-close-dur) var(--badge-close-ease),
    opacity var(--badge-fade-close-dur) var(--badge-close-ease),
    filter var(--badge-pop-close-dur) var(--badge-close-ease);
}

.t-dropdown {
  transform: scale(var(--dropdown-pre-scale));
  transform-origin: top left;
  opacity: 0;
  pointer-events: none;
  transition:
    transform var(--dropdown-open-dur) var(--dropdown-ease),
    opacity var(--dropdown-open-dur) var(--dropdown-ease);
  will-change: transform, opacity;
}

.t-dropdown[data-origin="top-right"] { transform-origin: top right; }
.t-dropdown[data-origin="top-center"] { transform-origin: top center; }
.t-dropdown[data-origin="bottom-left"] { transform-origin: bottom left; }
.t-dropdown[data-origin="bottom-center"] { transform-origin: bottom center; }
.t-dropdown[data-origin="bottom-right"] { transform-origin: bottom right; }

.t-dropdown.is-open {
  transform: scale(1);
  opacity: 1;
  pointer-events: auto;
}

.t-dropdown.is-closing {
  transform: scale(var(--dropdown-closing-scale));
  opacity: 0;
  pointer-events: none;
  transition:
    transform var(--dropdown-close-dur) var(--dropdown-ease),
    opacity var(--dropdown-close-dur) var(--dropdown-ease);
}

.t-modal {
  transform: scale(var(--modal-scale));
  transform-origin: center;
  opacity: 0;
  pointer-events: none;
  transition:
    transform var(--modal-open-dur) var(--modal-ease),
    opacity var(--modal-open-dur) var(--modal-ease);
  will-change: transform, opacity;
}

.t-modal.is-open {
  transform: scale(1);
  opacity: 1;
  pointer-events: auto;
}

.t-modal.is-closing {
  transform: scale(var(--modal-scale-close));
  opacity: 0;
  pointer-events: none;
  transition:
    transform var(--modal-close-dur) var(--modal-ease),
    opacity var(--modal-close-dur) var(--modal-ease);
}

/* Native modal dialogs are centered by the UA stylesheet's `margin: auto`.
   Tailwind's preflight resets `margin: 0` on every element, which overrides
   that and pins the dialog to the top-left (it computes `inset: 0; margin: 0`).
   Restore centering, scoped to real <dialog> modals — the command palette is a
   div overlay that centers itself, so it must not get this. */
dialog.t-modal {
  margin: auto;
}

.t-input {
  transition: border-color 150ms ease-out;
  will-change: transform;
}

.t-input.is-error {
  transition: border-color var(--revert-dur, 280ms) ease-out;
}

.t-error-msg {
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--revert-dur, 280ms) ease-out,
    visibility 0s linear var(--revert-dur, 280ms);
}

.t-input-wrap.is-error .t-error-msg {
  opacity: 1;
  visibility: visible;
  transition:
    opacity var(--revert-dur, 280ms) ease-out,
    visibility 0s linear 0s;
}

.t-input.is-shaking {
  animation: t-input-shake calc(var(--shake-dur-a) * 2 + var(--shake-dur-b) * 2) linear;
}

.app-tooltip {
  inset: auto;
  position: fixed;
  z-index: 1300;
  width: max-content;
  max-width: min(var(--tooltip-max-width), calc(100vw - 16px));
  padding: var(--tooltip-padding-y) var(--tooltip-padding-x);
  border: 1px solid var(--tooltip-border);
  border-radius: var(--tooltip-radius);
  background: var(--tooltip-background);
  box-shadow: var(--tooltip-shadow);
  color: var(--tooltip-foreground);
  font-size: var(--tooltip-font-size);
  font-weight: var(--tooltip-font-weight);
  line-height: var(--tooltip-line-height);
  margin: 0;
  opacity: 0;
  pointer-events: none;
  text-align: center;
  text-wrap: balance;
  transform: translateY(-2px) scale(0.98);
  transition:
    opacity var(--tooltip-duration) ease-out,
    transform var(--tooltip-duration) ease-out;
}

.app-tooltip[data-placement="top"] {
  transform: translateY(2px) scale(0.98);
}

.app-tooltip[data-position-context="dialog"] {
  position: absolute;
}

.app-tooltip[data-visible="true"] {
  opacity: 1;
  transform: translateY(0) scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .t-badge,
  .t-badge-dot,
  .t-dropdown,
  .t-modal,
  .t-input,
  .app-tooltip {
    animation: none !important;
    transition: none !important;
  }

  .t-input {
    transform: none !important;
  }
}

.auth-shell {
  display: grid;
  background: var(--background);
}

.auth-main {
  display: grid;
  min-height: 100dvh;
  place-items: center;
  padding: 24px;
}

.auth-main--setup {
  align-items: start;
}

.auth-card {
  width: min(100%, 420px);
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 12px;
  background: color-mix(in srgb, var(--card) 92%, transparent);
  box-shadow: var(--shadow);
  padding: 24px;
}

.auth-card--setup {
  width: min(100%, 780px);
}

.auth-card__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 34px;
}

.auth-card__brand--logo {
  justify-content: center;
}

.auth-logo {
  width: auto;
  height: 40px;
}

/* Light logo (dark wordmark) on the light theme; dark logo (white wordmark)
   on the dark theme. The unused variant is hidden per theme. */
.auth-logo--dark {
  display: none;
}

.dark .auth-logo--light {
  display: none;
}

.dark .auth-logo--dark {
  display: block;
}

.icon {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
}

.auth-card__copy h2,
.auth-card__copy p {
  margin: 0;
}

.auth-card__copy p,
.auth-card__footer {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.5;
}

.auth-card__copy {
  margin-bottom: 18px;
}

.eyebrow {
  display: block;
  margin-bottom: 6px;
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: uppercase;
}

.auth-card__copy h2 {
  font-size: 24px;
  line-height: 1.15;
  margin-bottom: 8px;
}

.auth-form {
  display: grid;
  gap: 12px;
  margin-top: 18px;
}

.auth-form label {
  display: grid;
  gap: 6px;
  color: var(--foreground);
  font-size: 12px;
  font-weight: 500;
}

.auth-form input:not([type="submit"]),
.auth-form select {
  width: 100%;
  height: 38px;
  border: 1px solid var(--input);
  border-radius: 8px;
  background: var(--card);
  color: var(--foreground);
  padding: 0 10px;
  outline: none;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.auth-form input:not([type="submit"])::placeholder {
  color: color-mix(in srgb, var(--muted-foreground) 75%, transparent);
}

.auth-form input:not([type="submit"]):focus,
.auth-form select:focus {
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 20%, transparent);
}

.auth-form--setup {
  gap: 16px;
}

.setup-fieldset {
  display: grid;
  gap: 12px;
  min-width: 0;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 8px;
  padding: 14px;
}

.setup-fieldset legend {
  padding: 0 6px;
  color: var(--foreground);
  font-size: 12px;
  font-weight: 700;
}

.setup-grid {
  display: grid;
  gap: 12px;
}

.setup-grid--two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.setup-grid--three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.button,
.auth-form input[type="submit"] {
  display: inline-flex;
  min-height: 36px;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: 0 12px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  box-shadow: 0 1px 1px rgb(15 23 42 / 3%);
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
}

/* Icons inside buttons track the button's text size, so `button_label` callers
   never pass an explicit icon-size class. Small/compact controls get a 12px glyph. */
.button .icon {
  width: 14px;
  height: 14px;
}

.button--small .icon,
.button--compact .icon {
  width: 12px;
  height: 12px;
}

.button--primary,
.auth-form input[type="submit"] {
  background: var(--primary);
  color: var(--primary-foreground);
}

.auth-form input[type="submit"],
.auth-form button[type="submit"] {
  width: 100%;
}

.button--primary:hover,
.auth-form input[type="submit"]:hover {
  background: color-mix(in srgb, var(--primary) 88%, var(--foreground));
}

.button--ghost {
  border-color: color-mix(in srgb, var(--border) 78%, transparent);
  background: var(--card);
  color: var(--foreground);
}

.button--ghost:hover {
  background: var(--accent);
  color: var(--accent-foreground);
}

.button:focus-visible,
.auth-form input[type="submit"]:focus-visible,
.icon-button:focus-visible,
.command-button:focus-visible,
.notif__bell:focus-visible,
.data-import-widget__button:focus-visible,
.settings-link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 24%, transparent);
}

.auth-card__footer {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  justify-content: space-between;
  margin-top: 16px;
}

.auth-card__footer a {
  color: var(--foreground);
  font-weight: 500;
}

.flash {
  border-radius: 8px;
  margin: 14px 0;
  padding: 9px 10px;
  font-size: 12px;
  line-height: 1.4;
}

/* One line per reason inside an inline flash, so a refusal with several causes
   reads as a list instead of a single run-on sentence. */
.flash__reasons {
  margin: 5px 0 0;
  padding-left: 18px;
}

.flash-stack {
  position: fixed;
  top: 16px;
  left: 50%;
  z-index: 1000;
  display: grid;
  justify-items: center;
  gap: 8px;
  width: auto;
  max-width: min(560px, calc(100vw - 32px));
  pointer-events: none;
  transform: translateX(-50%);
}

.app-shell .flash-stack {
  top: 94px;
}

.flash-stack .flash {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) 20px;
  min-height: 28px;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 5px 10px;
  border-radius: 999px;
  box-shadow: 0 8px 32px color-mix(in srgb, black 22%, transparent);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  pointer-events: auto;
  text-align: center;
  transition: opacity 160ms ease, transform 160ms ease;
  animation:
    flash-pop-in 380ms cubic-bezier(0.34, 1.56, 0.64, 1),
    flash-glow 2.5s ease-in-out infinite;
}

.flash-stack .flash__icon {
  display: inline-grid;
  place-items: center;
}

@keyframes flash-pop-in {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.85);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes flash-glow {
  0%,
  100% {
    box-shadow:
      0 8px 32px color-mix(in srgb, black 22%, transparent),
      0 0 0 0 color-mix(in srgb, var(--flash-glow) 0%, transparent);
  }
  50% {
    box-shadow:
      0 8px 32px color-mix(in srgb, black 22%, transparent),
      0 0 16px 3px color-mix(in srgb, var(--flash-glow) 55%, transparent);
  }
}

@media (prefers-reduced-motion: reduce) {
  .flash-stack .flash {
    animation: none;
  }
}

.flash--dismissed {
  opacity: 0;
  transform: translateY(-6px);
}

.flash__message {
  min-width: 0;
}

.flash__dismiss {
  display: inline-grid;
  width: 20px;
  height: 20px;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.flash__dismiss:hover {
  background: color-mix(in srgb, currentColor 14%, transparent);
}

.flash--alert {
  /* Legacy Handy (web-g2) danger red: bg red-60 = --danger */
  --flash-glow: #fa5053;
  border: 1px solid #fa5053;
  background: #fa5053;
  color: #ffffff;
}

.integrity-route-banner {
  display: grid;
  overflow: hidden;
  margin: 0 0 1rem;
  border: 1px solid color-mix(in srgb, var(--danger) 24%, var(--border));
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--danger) 4%, var(--card));
}

.integrity-route-banner__header {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 0.75rem;
  align-items: start;
  padding: 0.875rem 1rem;
}

.integrity-route-banner__icon {
  display: grid;
  width: 30px;
  height: 30px;
  place-items: center;
  border-radius: 999px;
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  color: var(--danger);
}

.integrity-route-banner__icon .icon {
  width: 16px;
  height: 16px;
}

.integrity-route-banner__intro {
  display: grid;
  gap: 0.2rem;
  min-width: 0;
}

.integrity-route-banner__intro > strong {
  font-size: 14px;
  line-height: 1.3;
}

.integrity-route-banner__intro p {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12.5px;
  line-height: 1.45;
}

.integrity-route-banner__total {
  display: grid;
  gap: 0.15rem;
  text-align: right;
  white-space: nowrap;
}

.integrity-route-banner__total small {
  color: var(--muted-foreground);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.035em;
  text-transform: uppercase;
}

.integrity-route-banner__total strong {
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.integrity-route-banner__list {
  display: grid;
  margin: 0;
  padding: 0;
  border-top: 1px solid color-mix(in srgb, var(--danger) 16%, var(--border));
  list-style: none;
}

.integrity-route-banner__list li + li {
  border-top: 1px solid color-mix(in srgb, var(--border) 62%, transparent);
}

.integrity-route-banner__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 0.75rem;
  align-items: center;
  padding: 0.75rem 1rem;
  color: var(--foreground);
  text-decoration: none;
}

.integrity-route-banner__item:hover {
  background: color-mix(in srgb, var(--danger) 6%, transparent);
}

.integrity-route-banner__item-copy,
.integrity-diff-row,
.integrity-timeline li,
.integrity-review-history li { display: grid; gap: 0.25rem; }

.integrity-route-banner__item-copy > strong {
  overflow: hidden;
  font-size: 13px;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.integrity-route-banner__item-copy > span {
  color: var(--danger);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
}

.integrity-route-banner__amount {
  font-size: 12.5px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.integrity-route-banner__chevron {
  width: 14px;
  height: 14px;
  color: var(--muted-foreground);
}

.device-installation-alert {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 1rem;
  border: 1px solid color-mix(in srgb, var(--danger) 58%, var(--border));
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--danger) 11%, var(--card));
  color: color-mix(in srgb, var(--danger) 55%, var(--foreground));
}
.device-installation-alert__icon { flex: 0 0 auto; width: 20px; height: 20px; color: var(--danger); }
.device-installation-alert div { display: grid; gap: 0.35rem; }
.device-installation-alert strong { color: var(--danger); }
.device-installation-alert p,
.device-installation-alert ul { margin: 0; }
.device-installation-alert ul { padding-left: 1.1rem; font-size: 0.8rem; }
.integrity-hero p { max-width: 68ch; }
.integrity-state-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding: 1rem;
  border-bottom: 1px solid var(--border);
}
.integrity-filters {
  display: grid;
  grid-template-columns: minmax(250px, 2fr) minmax(210px, 1.35fr) minmax(145px, 0.8fr) minmax(145px, 0.8fr) auto;
  gap: 0.75rem;
  align-items: end;
  padding: 1rem;
  background: color-mix(in srgb, var(--muted) 32%, var(--card));
  border-bottom: 1px solid var(--border);
}
.integrity-filter-field { display: grid; gap: 0.4rem; min-width: 0; }
.integrity-filter-field > span,
.integrity-review-field > span {
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.035em;
  text-transform: uppercase;
}
/* Field chrome comes from the shared .input/.select classes on the controls;
   only the layout constraints live here. */
.integrity-filter-field select,
.integrity-filter-field input {
  width: 100%;
  min-width: 0;
  font-size: 13px;
}
/* The native select arrow sits ~5px from the border, while the date fields'
   calendar glyph and the topbar switcher's chevron both sit ~18px in. Use the
   same custom chevron as .cedis-switcher__select so the inset is ours. */
.integrity-filter-field select {
  appearance: none;
  -webkit-appearance: none;
  padding: 0 32px 0 10px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23737373' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 16px 16px;
}

.dark .integrity-filter-field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23a1a1a1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

.integrity-filter-field .autocomplete-picker { width: 100%; }
.integrity-filter-field .autocomplete-results { z-index: 20; }
.integrity-filter-actions { display: flex; gap: 0.4rem; align-items: center; }
.integrity-filter-actions .button { white-space: nowrap; }
.integrity-table__row { grid-template-columns: minmax(260px, 2.4fr) minmax(180px, 1.4fr) minmax(90px, 0.6fr) minmax(130px, 0.8fr) minmax(150px, 0.9fr); }
.integrity-table__row > * { min-width: 0; }
/* One bold per row: the change itself. Seller, figure and timestamp are
   supporting data and step down instead of competing with it.
   The two <strong> modifiers are qualified by the row on purpose: the row also
   carries `.admin-table__row`, whose `strong { font-weight: 600 }` (further down
   this file) is 0,1,1 and would outrank a bare 0,1,0 class here — the seller
   would silently stay at 600 instead of stepping down to 500. */
.integrity-table__primary strong { line-height: 1.3; font-weight: 600; }
.integrity-table__row .integrity-table__seller { font-weight: 500; }
.integrity-table__row .integrity-table__amount { font-weight: 600; font-variant-numeric: tabular-nums; }
.integrity-table__time {
  display: block;
  font-weight: 400;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}
.integrity-detail__header { align-items: flex-start; }
.integrity-detail__badges { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.integrity-summary-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.75rem;
  padding: 1rem;
  border-bottom: 1px solid var(--border);
}
.integrity-summary-grid .route-fact {
  min-width: 0;
  padding: 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 25%, var(--card));
}
.integrity-summary-grid .route-fact strong { overflow-wrap: anywhere; }
.integrity-detail-card { margin: 1rem; }
.integrity-section-heading {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: flex-end;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--border);
}
.integrity-section-heading h2 { margin: 0.15rem 0 0; }
.integrity-section-heading > p { max-width: 52ch; margin: 0; color: var(--muted-foreground); font-size: 0.85rem; text-align: right; }
.integrity-diff-list,
.integrity-timeline,
.integrity-review-history { display: grid; gap: 0.75rem; margin: 1rem 0 0; padding: 0; list-style: none; }
.integrity-diff-row,
.integrity-timeline li,
.integrity-review-history li { padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); }
.integrity-diff-row { gap: 0.85rem; background: color-mix(in srgb, var(--muted) 18%, var(--card)); }
.integrity-diff-product { display: grid; gap: 0.2rem; }
.integrity-diff-product small { color: var(--muted-foreground); }
.integrity-diff-values { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0.65rem; margin: 0; }
.integrity-diff-values div { display: grid; gap: 0.15rem; }
.integrity-diff-values dt { color: var(--muted-foreground); font-size: 0.75rem; }
.integrity-diff-values dd { margin: 0; font-weight: 700; }
.integrity-timeline li { grid-template-columns: auto 1fr; align-items: flex-start; gap: 0.75rem; }
.integrity-timeline li > div:last-child { display: grid; gap: 0.2rem; }
.integrity-timeline__icon {
  display: grid;
  width: 2rem;
  height: 2rem;
  place-items: center;
  border-radius: 999px;
  background: var(--muted);
  color: var(--muted-foreground);
}
.integrity-timeline small { color: var(--muted-foreground); }
.integrity-review-form { display: grid; gap: 0.75rem; margin-top: 1rem; }
.integrity-review-field { display: grid; gap: 0.4rem; }
.integrity-review-form textarea { min-height: 6rem; }
.integrity-review-actions { display: flex; justify-content: flex-end; }
.integrity-review-history p { margin: 0; }

/* Labels the otherwise-bare "Diferencia" figure once the table header collapses
   away on phones. */
.integrity-mobile-label {
  display: none;
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.035em;
  text-transform: uppercase;
}

/* The date filters can be left empty, so the list states its own range rather
   than leaving the reader to infer it from the rows. */
.integrity-range-summary {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 10px 24px 12px;
  color: var(--muted-foreground);
  font-size: 12px;
}

.integrity-range-summary .icon {
  flex: 0 0 auto;
  color: var(--muted-foreground);
}

@media (max-width: 700px) {
  .integrity-filters,
  .integrity-summary-grid { grid-template-columns: 1fr; }
  .integrity-filter-actions { justify-content: stretch; }
  .integrity-filter-actions .button { flex: 1; }
  .integrity-table .admin-table__head { display: none; }
  .integrity-table__row { grid-template-columns: 1fr; gap: 0.65rem; }
  .integrity-mobile-label { display: block; }
  .integrity-section-heading { display: grid; align-items: start; }
  .integrity-section-heading > p { text-align: left; }
  .integrity-detail-card { margin: 0.65rem; }
  .integrity-detail__badges { justify-content: flex-start; }
}

.flash--notice {
  /* Legacy Handy (web-g2) success green: bg green-70, glow --success */
  --flash-glow: #20b062;
  border: 1px solid #1ea25a;
  background: #1ea25a;
  color: #ffffff;
}

.app-shell {
  --app-shell-bottom-gutter: clamp(24px, 4vh, 44px);
  --app-shell-top-inset: 0px;
  --app-shell-topbar-height: 115px;
  /* Measured: 10px padding + two 40px rows + 10px gap + the 1px bottom border.
     Under-reporting it leaves a full-height screen taller than the viewport, so
     the page scrolls a few pixels and the phone's URL bar flickers with it. */
  --app-shell-compact-topbar-height: 111px;
  background: var(--background);
}

.home-topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  background: color-mix(in srgb, var(--background) 88%, transparent);
  backdrop-filter: blur(16px);
  padding: 12px 24px;
  /* During a Turbo view transition the topbar is the persistent app chrome:
     naming it keeps it pinned instead of cross-fading with the page body
     (see the "View transitions" block below). It sits on both the leaving and
     arriving page, so the browser treats it as the same element. */
  view-transition-name: handy-topbar;
}

/* View transitions (Turbo 8) — opted in via <meta name="view-transition"> in the
   layout. The page body cross-fades on cross-page Drive visits while the topbar
   (named above) stays put. Keep it quick so navigation still feels instant;
   Turbo skips the whole animation under prefers-reduced-motion, so no media
   query is needed here. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 180ms;
  animation-timing-function: ease;
}

/* Top row: CEDIS at the left, centered command bar, account at the right. The
   1fr side columns keep the center element optically centered regardless of how
   wide each side gets. */
.home-topbar__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 16px;
}

.home-topbar__left,
.home-topbar__user {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.home-topbar__left {
  justify-self: start;
}

.home-topbar__user {
  justify-self: end;
}

/* Native desktop wrapper: when the app runs with an overlaid title bar
   (window-controls-overlay), the macOS traffic lights sit on top of the
   top-left of this row. Inset ONLY the left group so the CEDIS control clears
   the controls without leaving a wider dead gap — and inset just as far as the
   controls actually reach (`env(titlebar-area-x)`), so the CEDIS hugs them
   instead of floating out to the right. Because the inset lands on the left
   group (not the row's grid tracks), the centered command bar and section tabs
   stay centered on the true window. Inert in a normal browser: the media query
   doesn't match and `env()` falls back to 0. */
@media (display-mode: window-controls-overlay) {
  .home-topbar__left {
    padding-left: env(titlebar-area-x, 0px);
  }
}

.avatar {
  display: grid;
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  place-items: center;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--foreground);
  font-size: 12px;
  font-weight: 700;
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.settings-link {
  display: grid;
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--muted-foreground);
  box-shadow: 0 1px 1px rgb(15 23 42 / 3%);
  transition: border-color 120ms ease, background-color 120ms ease, color 120ms ease;
}

.settings-link:hover {
  background: color-mix(in srgb, var(--muted) 50%, var(--card));
}

.settings-link svg {
  width: 18px;
  height: 18px;
}

.settings-link--active {
  border-color: transparent;
  background: var(--primary);
  color: var(--primary-foreground);
  box-shadow: 0 4px 12px rgb(0 0 0 / 14%);
}

/* Keep the active icon readable on hover. `.settings-link:hover` (0,2,0) outranks
   `.settings-link--active` (0,1,0), so without this the hover swaps in the muted
   background while the icon color stays primary-foreground (white) — making the
   icon vanish. Darken the primary instead and keep the white icon. */
.settings-link--active:hover {
  background: color-mix(in srgb, var(--primary) 88%, black);
  color: var(--primary-foreground);
}

/* Theme picker on the profile page: a segmented control of Claro / Oscuro /
   Sistema radios. Replaces the old top-bar <details> theme menu. */
.appearance-options {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  max-width: 420px;
  margin: 0;
  padding: 0;
  border: 0;
}

.appearance-option {
  display: flex;
  min-height: 40px;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--foreground);
  cursor: pointer;
  font-size: 13px;
  padding: 0 10px;
  transition: border-color 120ms ease, background-color 120ms ease, color 120ms ease;
}

.appearance-option:hover {
  background: color-mix(in srgb, var(--muted) 55%, var(--card));
}

.appearance-option svg {
  width: 16px;
  height: 16px;
}

.appearance-option input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.appearance-option:has(input:checked) {
  border-color: transparent;
  background: var(--primary);
  color: var(--primary-foreground);
}

.appearance-option:has(input:focus-visible) {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 24%, transparent);
}

.command-button {
  display: flex;
  height: 36px;
  min-width: 0;
  align-items: center;
  gap: 9px;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  padding: 0 10px;
  text-align: left;
  box-shadow: 0 1px 1px rgb(15 23 42 / 3%);
  transition: border-color 120ms ease, background-color 120ms ease;
}

.command-button:hover {
  border-color: color-mix(in srgb, var(--border) 100%, transparent);
  background: color-mix(in srgb, var(--muted) 50%, var(--card));
}

/* Header search trigger: compact, sits next to the avatar. */
.command-button--inline {
  width: clamp(120px, 16vw, 190px);
}

/* Centered header search bar (mirrors the Vue web app's prominent command bar). */
.command-button--header {
  width: clamp(220px, 42vw, 460px);
  height: 38px;
  justify-self: center;
}

.command-button--header span {
  flex: 1;
}

.command-button svg {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2;
}

.command-button span {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.command-button kbd {
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--muted);
  color: var(--foreground);
  font-size: 11px;
  line-height: 1;
  padding: 3px 5px;
}

.cedis-switcher {
  position: relative;
  min-width: 150px;
}

.cedis-switcher__select {
  width: 100%;
  height: 36px;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--foreground);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  /* Replace the native arrow with a custom chevron so we control the gap to the
     right edge (the native glyph sits flush against the border). */
  appearance: none;
  -webkit-appearance: none;
  padding: 0 32px 0 10px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23737373' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 16px 16px;
}

.dark .cedis-switcher__select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23a1a1a1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

/* The CEDIS warehouse glyph only surfaces on smartphones, where the switcher
   collapses to an icon-only button (see the max-width: 640px block). */
.cedis-switcher__icon,
.cedis-badge__icon {
  display: none;
}

/* Account menu: avatar trigger + dropdown holding the user's identity/actions. */
.user-menu {
  position: relative;
  display: flex;
  align-items: center;
}

.user-menu__trigger {
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: none;
  cursor: pointer;
}

/* The top-bar account button sits next to the square icon buttons (settings,
   notifications, data-import), so square its avatar to match them instead of
   the round profile-photo treatment used elsewhere (menu identity, profile). */
.user-menu__trigger .avatar {
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
}

.user-menu__trigger:hover .avatar,
.user-menu__trigger[aria-expanded="true"] .avatar {
  border-color: var(--primary);
}

.user-menu__panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 50;
  width: min(240px, 92vw);
  display: grid;
  gap: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
  padding: 6px;
}

.user-menu__panel[hidden] {
  display: none;
}

.user-menu__identity {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  margin-bottom: 4px;
}

.user-menu__identity-text {
  min-width: 0;
}

.user-menu__identity-text strong {
  display: block;
  font-size: 13px;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.user-menu__identity-text span {
  display: block;
  color: var(--muted-foreground);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.user-menu__form {
  margin: 0;
}

.user-menu__item {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 9px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--foreground);
  font: inherit;
  font-size: 13px;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  padding: 9px 10px;
  transition: background-color 120ms ease;
}

.user-menu__item .icon {
  width: 15px;
  height: 15px;
}

.user-menu__item:hover {
  background: color-mix(in srgb, var(--muted) 55%, var(--card));
}

.user-menu__item--danger {
  color: var(--danger);
}

.home-main {
  width: min(100%, 1300px);
  margin: 0 auto;
  padding: 12px 24px var(--app-shell-bottom-gutter);
}

.tabs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 4px;
  width: min(100%, 560px);
  margin: 0 auto 12px;
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--card) 72%, transparent);
  box-shadow: 0 1px 2px rgb(0 0 0 / 4%);
  padding: 4px;
}

.tab {
  display: flex;
  min-height: 32px;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 0;
  border-radius: 6px;
  color: var(--muted-foreground);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
}

/* Tabs rendered as <button> (e.g. the Configuración sub-tabs) need the native
   button chrome reset so they match the <a class="tab"> top-menu links. */
button.tab {
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  font-family: inherit;
}

.tab span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* `button.tab--active` repeats at the same specificity as the reset above so
   the active background wins for <button> tabs too — otherwise the reset's
   `background: transparent` (specificity 0,1,1) beats the plain `.tab--active`
   (0,1,0) and leaves white text on a transparent pill. */
.tab--active,
button.tab--active {
  background: var(--primary);
  color: var(--primary-foreground);
  box-shadow: 0 4px 12px rgb(0 0 0 / 14%);
}

/* Alt-to-navigate cue: a one-letter <kbd> badge that fades in over each main-menu
   item while Alt is held (see the `nav-hotkeys` Stimulus controller). The host
   element (`.tab`, `.settings-link`) needs positioning so the badge can float
   just above it. */
.tab,
.settings-link {
  position: relative;
}

.nav-hotkey-cue {
  position: absolute;
  top: -8px;
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  padding: 1px 4px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--card);
  color: var(--foreground);
  font-size: 10px;
  font-weight: 600;
  line-height: 1.4;
  box-shadow: 0 1px 2px rgb(0 0 0 / 12%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 150ms ease;
}

.nav-hotkeys--active .nav-hotkey-cue,
.action-hotkeys--active .nav-hotkey-cue {
  opacity: 1;
}

/* Page-level action hotkeys (route-create/edit buttons) reuse the same <kbd>
   cue. The host button/link needs positioning so the badge can float above it. */
.route-create-actions .button,
.form-actions .button,
.operation-loader__add {
  position: relative;
}

/* Respect reduced-motion: keep the show/hide instant instead of fading. */
@media (prefers-reduced-motion: reduce) {
  .nav-hotkey-cue {
    transition: none;
  }
}

.home-panel,
.home-card,
.metric-card {
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  background: var(--card);
  box-shadow: var(--shadow);
}

.home-panel {
  border-radius: var(--radius);
  overflow: hidden;
}

.home-panel__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 24px 16px;
}

.home-panel__header h1,
.home-panel__header p,
.home-card h2,
.home-card p {
  margin: 0;
}

.home-panel__header h1 {
  font-size: 23px;
  font-weight: 650;
  line-height: 1.15;
}

/* Catalog list title + total-count pill (Productos 15, Clientes 75…). The pill
   sits beside the heading and is a sibling of <h1> so the heading text stays
   clean for tests/accessibility. */
.catalog-title {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
}

.catalog-count {
  padding: 2px 10px;
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--muted-foreground);
  background: color-mix(in srgb, var(--muted-foreground) 14%, transparent);
  border-radius: 999px;
}

.home-panel__header p,
.home-card p {
  color: var(--muted-foreground);
  font-size: 13px;
  line-height: 1.45;
}

.home-panel__actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Catalog panel header that carries its own action toolbar (e.g. Productos:
   Ajustes / Transferencias / Nuevo ingreso / Nuevo producto) instead of pushing
   those into the top-right topbar menu. */
.catalog-header__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}

@media (max-width: 720px) {
  .home-panel__header.catalog-header {
    flex-wrap: wrap;
    gap: 12px;
  }

  .catalog-header__actions {
    width: 100%;
    justify-content: stretch;
  }

  .catalog-header__actions .button {
    flex: 1 1 auto;
    justify-content: center;
  }
}

/* On phones the active nav tab already names the section (Operación, Reportes,
   Asistente, Catálogos), so the large in-page heading + subtitle below the menu
   is redundant and just eats scarce vertical space. Hide the heading block on
   narrow screens while keeping any sibling controls (report range, assistant day
   nav, route actions). Desktop is unchanged. */
@media (max-width: 720px) {
  .section-heading {
    display: none;
  }

  /* When the heading was the only thing in the header, drop the now-empty bar. */
  .home-panel__header:has(> .section-heading:only-child),
  .routes-panel__header:has(> .section-heading:only-child),
  .assistant-screen__header:has(> .section-heading:only-child) {
    display: none;
  }
}

.avatar--lg {
  width: 44px;
  height: 44px;
  font-size: 17px;
}

.avatar--profile {
  width: 64px;
  height: 64px;
  font-size: 26px;
}

/* Editable avatar: the photo (or initials) with an upload overlay and a
   delete badge layered directly on top of it. */
.avatar-edit {
  position: relative;
  width: 64px;
  height: 64px;
  flex: 0 0 auto;
}

.avatar-edit .avatar {
  width: 100%;
  height: 100%;
}

/* Click anywhere on the photo to add / replace it. The camera overlay fades
   in on hover or keyboard focus. */
.avatar-edit__pick {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: 999px;
  cursor: pointer;
  color: #fff;
  background: color-mix(in srgb, #000 45%, transparent);
  opacity: 0;
  transition: opacity 0.15s ease;
}

.avatar-edit__pick:hover,
.avatar-edit__pick:focus-within {
  opacity: 1;
}

.avatar-edit__pick .icon {
  width: 20px;
  height: 20px;
}

.avatar-edit__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* Delete badge in the corner (only rendered when a photo exists). */
.avatar-edit__remove {
  position: absolute;
  right: -4px;
  bottom: -4px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--foreground);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.avatar-edit__remove:hover {
  background: var(--destructive);
  color: var(--destructive-foreground);
  border-color: transparent;
}

.avatar-edit__remove .icon {
  width: 13px;
  height: 13px;
}

.avatar-edit__remove-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* Marked for deletion: badge stays pressed and the photo dims so the pending
   removal is obvious before saving. */
.avatar-edit__remove:has(.avatar-edit__remove-input:checked) {
  background: var(--destructive);
  color: var(--destructive-foreground);
  border-color: transparent;
}

.avatar-edit:has(.avatar-edit__remove-input:checked) .avatar {
  opacity: 0.35;
}

/* Customer storefront photo: a rounded square (not a round avatar) shown in the
   customers catalog list and edit form. Always present — the attached photo or
   the bundled default storefront image. */
.customer-photo {
  display: grid;
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  place-items: center;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card);
}

.customer-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Neutral placeholder shown when a customer has no uploaded photo. */
.customer-photo__placeholder {
  width: 55%;
  height: 55%;
  color: var(--muted-foreground);
}

.customer-photo--small {
  width: 38px;
  height: 38px;
  border-radius: 9px;
}

.customer-photo--profile {
  width: 96px;
  height: 96px;
  border-radius: 14px;
}

/* Cliente cell in the catalog list: the thumbnail beside the stacked name/code. */
.customer-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.customer-cell__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Editable customer photo on the edit form: a larger square with the same
   upload-overlay + delete-badge affordances as the avatar editor. */
.customer-photo-editor {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 16px;
}

.customer-photo-editor__hint {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.customer-photo-editor__hint small {
  color: var(--muted-foreground);
}

.customer-photo-edit {
  position: relative;
  width: 96px;
  height: 96px;
  flex: 0 0 auto;
}

.customer-photo-edit .customer-photo {
  width: 100%;
  height: 100%;
}

.customer-photo-edit__pick {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: 14px;
  cursor: pointer;
  color: #fff;
  background: color-mix(in srgb, #000 45%, transparent);
  opacity: 0;
  transition: opacity 0.15s ease;
}

.customer-photo-edit__pick:hover,
.customer-photo-edit__pick:focus-within {
  opacity: 1;
}

.customer-photo-edit__pick .icon {
  width: 22px;
  height: 22px;
}

.customer-photo-edit__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.customer-photo-edit__remove {
  position: absolute;
  right: -6px;
  bottom: -6px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--foreground);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.customer-photo-edit__remove:hover,
.customer-photo-edit__remove:has(.customer-photo-edit__remove-input:checked) {
  background: var(--destructive);
  color: var(--destructive-foreground);
  border-color: transparent;
}

.customer-photo-edit__remove .icon {
  width: 14px;
  height: 14px;
}

.customer-photo-edit__remove-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.customer-photo-edit:has(.customer-photo-edit__remove-input:checked) .customer-photo {
  opacity: 0.35;
}

/* Product images: same rounded-square treatment as the customer storefront photo.
   A product carries up to Product::MAX_IMAGES; the catalog list shows the first,
   the form shows them all. */
.product-photo {
  display: grid;
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  place-items: center;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card);
}

.product-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Neutral placeholder shown when a product has no uploaded image. */
.product-photo__placeholder {
  width: 55%;
  height: 55%;
  color: var(--muted-foreground);
}

.product-photo--small {
  width: 38px;
  height: 38px;
  border-radius: 9px;
}

/* Producto cell in the catalog list: the thumbnail beside the stacked name/SKU. */
.product-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.product-cell__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Image strip on the product form: the existing images, each with a delete badge,
   followed by the tile that opens the (multiple) file picker. */
.product-images-editor {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
}

.product-images-editor__hint {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.product-images-editor__hint small {
  color: var(--muted-foreground);
}

.product-images {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

.product-image-edit {
  position: relative;
  flex: 0 0 auto;
}

.product-image-edit .product-photo {
  width: 84px;
  height: 84px;
  border-radius: 12px;
}

.product-image-edit__remove {
  position: absolute;
  right: -6px;
  bottom: -6px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--foreground);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.product-image-edit__remove:hover,
.product-image-edit__remove:has(.product-image-edit__remove-input:checked) {
  background: var(--destructive);
  color: var(--destructive-foreground);
  border-color: transparent;
}

.product-image-edit__remove .icon {
  width: 14px;
  height: 14px;
}

.product-image-edit__remove-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.product-image-edit:has(.product-image-edit__remove-input:checked) .product-photo {
  opacity: 0.35;
}

.product-image-add {
  position: relative;
  display: grid;
  width: 84px;
  height: 84px;
  flex: 0 0 auto;
  place-items: center;
  border: 1px dashed var(--border);
  border-radius: 12px;
  background: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.product-image-add:hover,
.product-image-add:focus-within {
  color: var(--foreground);
  border-color: var(--foreground);
}

.product-image-add .icon {
  width: 22px;
  height: 22px;
}

.product-image-add__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* ---- Route operation detail (tight, minimal layout) ---- */
.route-op__header {
  padding: 16px 18px 14px;
}

/* Identity block: profile picture beside the rep's name. */
.route-op__identity {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.route-op__identity-text {
  min-width: 0;
}

.route-op__header h1 {
  font-size: 20px;
}

.route-op__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 3px;
}

/* Page actions sit top-right of the panel; wrap on tight widths. */
.route-op__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}

.route-op__body {
  display: grid;
  gap: 16px;
  padding: 16px 18px 18px;
}

.route-op__body .settings-card {
  padding: 14px 16px;
  gap: 12px;
}

.badge {
  display: inline-flex;
  min-height: 24px;
  align-items: center;
  gap: 5px;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 0 9px;
  font-size: 11px;
  font-weight: 650;
  line-height: 1;
  white-space: nowrap;
}

.badge--green {
  border-color: color-mix(in srgb, #10b981 28%, transparent);
  background: #dcfce7;
  color: #047857;
}

.badge--warning {
  border-color: color-mix(in srgb, #f59e0b 32%, transparent);
  background: #fef3c7;
  color: #92400e;
}

.badge--muted {
  border-color: color-mix(in srgb, var(--border) 72%, transparent);
  background: var(--muted);
  color: var(--muted-foreground);
}

.badge--danger-soft {
  border-color: color-mix(in srgb, #dc2626 32%, transparent);
  background: color-mix(in srgb, #dc2626 16%, var(--card));
  color: color-mix(in srgb, #dc2626 50%, var(--foreground));
}

/* Icon-only chip (e.g. the "requires photo" camera). Square padding and
   full-contrast foreground so the glyph reads clearly instead of fading
   into the muted pill. */
.badge--icon {
  gap: 0;
  padding: 0;
  width: 24px;
  justify-content: center;
  color: var(--foreground);
}

.badge--icon .icon {
  width: 15px;
  height: 15px;
}

.home-summary {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  padding: 0 24px 22px;
}

.metric-card {
  min-height: 164px;
  border-radius: var(--radius);
  padding: 16px;
}

.metric-card > span,
.home-card h2 {
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.2;
  text-transform: uppercase;
}

.metric-card strong {
  display: block;
  margin-top: 6px;
  font-size: 24px;
  line-height: 1.15;
}

.metric-card small {
  display: block;
  margin-top: 5px;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.4;
}

.mini-bars {
  display: flex;
  height: 42px;
  align-items: end;
  gap: 6px;
  margin-top: 18px;
}

.mini-bars i,
.mini-bars__bar {
  flex: 1;
  min-width: 8px;
  border-radius: 4px 4px 2px 2px;
  background: color-mix(in srgb, var(--success) 62%, white);
}

.mini-bars__bar {
  transition: background-color .15s ease;
  cursor: pointer;
}

/* Past ~20 bars the row's minimum width (8px each + a 6px gap) outgrows the
   metric card, which then clips it. A month of daily bars already did; an
   arbitrary range folded into weeks or months goes further. Thin them instead. */
.mini-bars--dense {
  gap: 2px;
}

.mini-bars--dense .mini-bars__bar {
  min-width: 3px;
  border-radius: 2px 2px 1px 1px;
}

.mini-bars .mini-bars__active {
  background: #059669;
}

.mini-bars__bar:hover,
.mini-bars__bar:focus-visible {
  background: #047857;
  outline: none;
}

.status-list {
  display: grid;
  gap: 8px;
  margin-top: 20px;
  color: var(--muted-foreground);
  font-size: 12px;
}

.status-list span {
  display: flex;
  align-items: center;
  gap: 7px;
}

.status-dot {
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  border-radius: 999px;
}

.status-dot--green {
  background: #10b981;
}

.status-dot--blue {
  background: #3b82f6;
}

.status-dot--purple {
  background: #8b5cf6;
}

.status-dot--amber {
  background: #f59e0b;
}

.reports-panel {
  display: grid;
  gap: 18px;
  padding-bottom: 24px;
}

/* The filter strip on Reportes and Ventas: one or more segmented controls in a
   row (the CEDIS scope, the period), all built from the same pill so the screen
   reads as one control instead of a pill row plus a separate form. */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}

.segmented {
  display: inline-flex;
  flex-shrink: 0;
  gap: 4px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, var(--card) 72%, transparent);
  padding: 4px;
}

.segmented__item {
  display: inline-flex;
  min-height: 30px;
  align-items: center;
  gap: 5px;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--muted-foreground);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  padding: 0 10px;
  text-decoration: none;
}

.segmented__item--active {
  background: var(--primary);
  color: var(--primary-foreground);
}

.segmented__item .icon {
  width: 14px;
  height: 14px;
}

/* The arbitrary range hides behind the last pill so the strip keeps one height
   and one rhythm; opened, it is an ordinary dropdown panel. */
.segmented__custom {
  position: relative;
}

.segmented__popover {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 30;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
  padding: 12px;
}

.segmented__popover[hidden] {
  display: none;
}

.segmented__popover .date-range-form {
  display: grid;
  gap: 8px;
  min-width: 190px;
}

.segmented__popover .date-range-form__field {
  display: grid;
  grid-template-columns: 22px 1fr;
  align-items: center;
  gap: 8px;
}

.segmented__popover .date-range-form__field input[type="date"] {
  width: 100%;
}

.segmented__popover .button {
  justify-content: center;
  width: 100%;
}

.reports-summary,
.reports-grid {
  display: grid;
  gap: 16px;
  padding-inline: 24px;
}

.reports-summary {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.reports-grid {
  grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
}

.report-metric {
  min-height: 178px;
}

.report-progress {
  height: 10px;
  overflow: hidden;
  border-radius: 999px;
  margin-top: 16px;
  background: color-mix(in srgb, var(--muted) 85%, var(--card));
}

.report-progress span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--success);
}

.report-card {
  display: grid;
  gap: 16px;
  border-radius: 10px;
  padding: 16px;
}

.report-card--wide {
  margin-inline: 24px;
}

.report-card--span {
  grid-column: 1 / -1;
}

.report-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.report-card__header h2,
.report-card__header strong,
.report-card__header small {
  display: block;
  margin: 0;
}

.report-card__header > strong,
.report-card__totals strong {
  font-size: 24px;
  line-height: 1.1;
}

.report-card__totals {
  text-align: right;
}

.report-card__totals small {
  color: var(--muted-foreground);
  font-size: 12px;
  margin-top: 4px;
}

.settlement-metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
}

.settlement-metrics__group {
  display: grid;
  gap: 12px;
  align-content: start;
}

.settlement-metrics__title {
  display: grid;
  gap: 2px;
}

.settlement-metrics__title h3 {
  margin: 0;
  font-size: 15px;
}

.settlement-metrics__title small {
  color: var(--muted-foreground);
  font-size: 12px;
}

.settlement-metrics__loss {
  color: var(--danger);
}

.report-pie-row {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 18px;
  align-items: center;
}

.report-pie {
  width: 150px;
  aspect-ratio: 1;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 999px;
  /* Clip the conic gradient to the content box instead of painting a card-colored
     inset ring over it — the old box-shadow let ~1px of gradient bleed through
     at the border. */
  padding: 20px;
  background-clip: content-box;
}

.report-legend,
.report-list {
  display: grid;
  gap: 10px;
}

.report-legend__row,
.report-list__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
  min-width: 0;
}

.report-list__row {
  grid-template-columns: minmax(0, 1fr) auto;
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding-top: 10px;
}

.report-list--compact {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.report-legend__row span {
  width: 10px;
  height: 10px;
  border-radius: 999px;
}

.report-legend__row strong,
.report-list__row strong {
  overflow: hidden;
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.report-legend__row small,
.report-list__row small {
  color: var(--muted-foreground);
  font-size: 12px;
}

.report-list__row span {
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}

/* Interactive report data → opens the assistant with a pre-filled question.
   `report-ask` is the shared hover/focus affordance; element-specific modifiers
   keep the underlying layout (metric value, card header, grid row). */
.report-ask {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  border-radius: 8px;
  transition: background-color .15s ease, box-shadow .15s ease;
}

.report-ask:hover {
  background: color-mix(in srgb, var(--primary) 9%, transparent);
}

.report-ask:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 45%, transparent);
}

.report-ask--metric {
  display: block;
  margin-inline: -8px;
  padding: 4px 8px;
}

.report-ask--header {
  display: block;
  margin: -8px -8px 0;
  padding: 8px;
}

.report-legend__row.report-ask,
.report-list__row.report-ask {
  padding-inline: 8px;
  margin-inline: -8px;
}

.report-list__row.report-ask {
  padding-top: 10px;
}

.admin-table--embedded {
  padding: 0;
}

.home-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 18px;
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 22px 24px 24px;
}

.home-card {
  border-radius: var(--radius);
  padding: 16px;
}

.admin-table {
  padding: 0 24px 24px;
}

.admin-table__head,
.admin-table__row {
  display: grid;
  gap: 14px;
  align-items: start;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 14px 0;
}

.admin-table__head {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

.admin-table__row--promotions {
  grid-template-columns: minmax(220px, 1.35fr) minmax(120px, .7fr) minmax(220px, 1fr) minmax(170px, .8fr) minmax(110px, auto);
}

.admin-table__row--route-operations {
  grid-template-columns: minmax(190px, 1.15fr) minmax(170px, .9fr) minmax(190px, 1fr) minmax(130px, .65fr) minmax(120px, auto);
}

.admin-table__row--inventory-purchases {
  grid-template-columns: minmax(180px, .9fr) minmax(190px, 1fr) minmax(150px, .75fr) minmax(130px, .6fr) minmax(90px, auto);
}

.admin-table__row--inventory-adjustments {
  grid-template-columns: minmax(220px, 1.1fr) minmax(150px, .65fr) minmax(190px, .9fr) minmax(170px, .8fr) minmax(90px, auto);
}

.admin-table__row--inventory-transfers {
  grid-template-columns: minmax(180px, .95fr) minmax(110px, .5fr) minmax(190px, 1fr) minmax(150px, .75fr) minmax(90px, auto);
}

.admin-table__row--catalog-products {
  grid-template-columns: minmax(220px, 1.2fr) minmax(130px, .65fr) minmax(100px, .45fr) minmax(110px, .5fr) minmax(90px, .4fr) minmax(160px, auto);
}

.admin-table__row--product-categories {
  grid-template-columns: minmax(220px, 1fr) minmax(130px, .45fr) minmax(100px, .35fr) minmax(150px, auto);
}

.admin-table__row--price-lists {
  grid-template-columns: minmax(220px, 1.2fr) minmax(110px, .5fr) minmax(110px, .5fr) minmax(90px, .4fr) minmax(160px, auto);
}

.admin-table__row--catalog-customers {
  grid-template-columns: minmax(220px, 1.1fr) minmax(180px, .9fr) minmax(220px, 1fr) minmax(90px, .45fr) minmax(150px, auto);
}

.admin-table__row--holidays {
  grid-template-columns: minmax(220px, 1.2fr) minmax(170px, .75fr) minmax(90px, .45fr) minmax(150px, auto);
}

.admin-table__row--taxes {
  grid-template-columns: minmax(90px, .45fr) minmax(170px, 1fr) minmax(90px, .45fr) minmax(90px, auto) minmax(80px, auto);
}

.admin-table__row--route-load-templates {
  grid-template-columns: minmax(220px, 1.2fr) minmax(150px, .7fr) minmax(110px, .5fr) minmax(90px, .45fr) minmax(190px, auto);
}

.admin-table__row--sales-orders {
  grid-template-columns: minmax(220px, 1.2fr) minmax(160px, .8fr) minmax(150px, .75fr) minmax(80px, .4fr) minmax(110px, .5fr);
}

/* The period moved into the header's filter strip, so this row carries only the
   exports and sits with them at the trailing edge. */
.sales-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
}

.date-range-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.date-range-form__field {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted-foreground);
  font-size: 12px;
}

.date-range-form__field input[type="date"] {
  border: 1px solid var(--input);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--foreground);
  padding: 6px 8px;
  outline: none;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.date-range-form__field input[type="date"]:focus {
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 18%, transparent);
}

.sales-toolbar__downloads {
  display: flex;
  gap: 8px;
}

.sales-summary {
  padding: 0 24px 14px;
}

.route-color-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 999px;
  margin-right: 6px;
  vertical-align: baseline;
}

.route-load-templates-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
}

/* Downloads stay grouped on the left; the destructive "Borrar todas" is pushed
   to the far right so it reads as a separate, deliberate action. */
.route-load-templates-toolbar__group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.route-load-templates-toolbar__delete-all {
  margin-left: auto;
}

/* Helper copy always drops onto its own full-width line under the buttons. */
.route-load-templates-toolbar__hint {
  flex-basis: 100%;
  margin: 2px 0 0;
}

.admin-table__row strong,
.admin-table__row small,
.stacked-line {
  display: block;
}

.admin-table__row small,
.stacked-line,
.form-hint {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.4;
}

/* Weight marks ONE thing per row: the record's identifier. Everything else in a
   row — a repeated date, a seller, a count — reads by size, colour and
   alignment. Semibold, not bold: same reasoning as the figure strip below, at
   700 every cell shouts and the row has no primary left. */
.admin-table__row strong {
  font-weight: 600;
}

/* Ventas: the date repeats verbatim down the whole page, so it is metadata, not
   emphasis. The total keeps one step so the money column still scans. */
.admin-table__row--sales-orders > div:nth-of-type(2) strong {
  font-weight: 400;
}

.admin-table__row--sales-orders > div:nth-of-type(5) strong {
  font-weight: 500;
}

/* Productos: the name is the identifier (600, above); price and stock are
   figures the eye scans, not headlines. */
.admin-table__row--catalog-products > div:nth-of-type(3) strong,
.admin-table__row--catalog-products > div:nth-of-type(4) strong {
  font-weight: 500;
}

.admin-table__actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  align-items: center;
}

/* An open row-actions menu must paint above later rows' action cells (which
   also sit at z-index 2 over the stretched row link). */
.admin-table__actions:has(.row-menu__panel:not([hidden])) {
  z-index: 10;
}

/* The dropdown overflows the panel's rounded frame, so this surface opts out of
   the shared .home-panel clip (no child paints into the corners here). */
.route-load-templates-panel {
  overflow: visible;
}

/* Trash trigger for the per-row delete menu: borderless like the kebab, but
   tints destructive-red on hover/open. */
.row-menu__trigger--danger:hover,
.row-menu__trigger--danger[aria-expanded="true"] {
  background: color-mix(in srgb, var(--destructive) 12%, transparent);
  color: var(--destructive);
}

/* Wider panel + stacked items so each delete option can carry a description. */
.row-menu__panel--wide {
  min-width: 288px;
}

.row-menu__item--stacked {
  align-items: flex-start;
  white-space: normal;
}

.row-menu__item-body {
  display: grid;
  gap: 2px;
}

.row-menu__item-title {
  font-weight: 600;
}

.row-menu__item-desc {
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.35;
}

/* Keep the description muted even on the danger item (only the title reads red). */
.row-menu__item--danger .row-menu__item-desc {
  color: var(--muted-foreground);
}

/* Whole-row / whole-card clickable lists (stretched-link pattern). The
   overlay link covers the row, while real action buttons sit above it. */
.admin-table__row--link,
.catalog-list__item--link,
.users-table tbody tr {
  position: relative;
}

.admin-table__row--link,
.catalog-list__item--link,
.users-table__row--link {
  cursor: pointer;
}

.admin-table__row--link:hover,
.catalog-list__item--link:hover,
.users-table__row--link:hover {
  background: color-mix(in srgb, var(--accent) 72%, var(--card));
}

.row-link {
  position: absolute;
  inset: 0;
  z-index: 1;
}

.admin-table__actions,
.users-table__actions {
  position: relative;
  z-index: 2;
}

.button--small {
  min-height: 32px;
  padding-inline: 10px;
}

.empty-state {
  border: 1px dashed color-mix(in srgb, var(--border) 82%, var(--foreground));
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 48%, var(--card));
  color: var(--muted-foreground);
  margin: 12px 0 0;
  padding: 24px;
  text-align: center;
}

.catalog-toolbar {
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 14px 24px;
}

.catalog-search {
  display: flex;
  gap: 8px;
}

.catalog-search input[type="search"] {
  min-width: 0;
  flex: 1;
  border: 1px solid var(--input);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--foreground);
  padding: 8px 10px;
  outline: none;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.catalog-search input[type="search"]:focus {
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 18%, transparent);
}

.catalog-search .button--primary {
  width: auto;
}

.catalog-pagination {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 14px 24px 18px;
  color: var(--muted-foreground);
  font-size: 12px;
}

.catalog-pagination--single {
  justify-content: flex-start;
}

/* Dense surfaces mirror the routes screen on phones: the page frame goes
   edge-to-edge so narrow devices spend their width on data, not nested chrome. */
@media (max-width: 720px) {
  .catalog-main.home-main,
  .catalog-main.profile-main,
  .mobile-full-main.home-main,
  .mobile-full-main.profile-main,
  .mobile-full-main.account-main {
    width: 100%;
    padding: 8px 0 0;
  }

  .catalog-main .home-panel,
  .catalog-main .profile-section,
  .mobile-full-main .home-panel,
  .mobile-full-main .profile-section,
  .mobile-full-main .settings-card {
    border-right: 0;
    border-left: 0;
    border-radius: 0;
    box-shadow: none;
  }

  .catalog-main .profile-section,
  .mobile-full-main .profile-section {
    min-width: 0;
    overflow-x: auto;
    padding: 16px 14px 20px;
  }

  .mobile-full-main .settings-card {
    min-width: 0;
  }

  .catalog-main .admin-table,
  .catalog-main .integrity-range-summary,
  .catalog-main .catalog-toolbar,
  .catalog-main .catalog-pagination,
  .catalog-main .settings-form {
    padding-right: 14px;
    padding-left: 14px;
  }

  .mobile-full-main .reports-summary,
  .mobile-full-main .reports-grid {
    padding-right: 14px;
    padding-left: 14px;
  }

  .catalog-main .catalog-list__item {
    padding-right: 14px;
    padding-left: 14px;
  }

  .catalog-main .catalog-list {
    gap: 8px;
    padding: 12px 14px 14px;
  }

  .catalog-main .catalog-list__item {
    grid-template-columns: auto minmax(0, 1fr) auto;
    min-height: 52px;
    padding-top: 12px;
    padding-bottom: 12px;
  }

  .catalog-main .catalog-list__item strong {
    font-size: 14px;
  }

  .catalog-main .admin-table__head {
    display: none;
  }

  .catalog-main .admin-table__row--catalog-products,
  .catalog-main .admin-table__row--price-lists,
  .catalog-main .admin-table__row--product-categories,
  .catalog-main .admin-table__row--catalog-customers,
  .catalog-main .admin-table__row--promotions,
  .catalog-main .admin-table__row--holidays,
  .catalog-main .admin-table__row--inventory-purchases,
  .catalog-main .admin-table__row--inventory-adjustments,
  .catalog-main .admin-table__row--inventory-transfers {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px 10px;
    align-items: center;
    padding-top: 10px;
    padding-bottom: 10px;
  }

  .catalog-main .admin-table__row--catalog-products > div,
  .catalog-main .admin-table__row--price-lists > div,
  .catalog-main .admin-table__row--product-categories > div,
  .catalog-main .admin-table__row--catalog-customers > div,
  .catalog-main .admin-table__row--promotions > div,
  .catalog-main .admin-table__row--holidays > div,
  .catalog-main .admin-table__row--inventory-purchases > div,
  .catalog-main .admin-table__row--inventory-adjustments > div,
  .catalog-main .admin-table__row--inventory-transfers > div {
    min-width: 0;
  }

  .catalog-main .admin-table__row--catalog-products strong,
  .catalog-main .admin-table__row--price-lists strong,
  .catalog-main .admin-table__row--product-categories strong,
  .catalog-main .admin-table__row--catalog-customers strong,
  .catalog-main .admin-table__row--promotions strong,
  .catalog-main .admin-table__row--holidays strong,
  .catalog-main .admin-table__row--inventory-purchases strong,
  .catalog-main .admin-table__row--inventory-adjustments strong,
  .catalog-main .admin-table__row--inventory-transfers strong {
    font-size: 14px;
    line-height: 1.2;
  }

  .catalog-main .admin-table__row--catalog-products small,
  .catalog-main .admin-table__row--price-lists small,
  .catalog-main .admin-table__row--product-categories small,
  .catalog-main .admin-table__row--catalog-customers small,
  .catalog-main .admin-table__row--promotions small,
  .catalog-main .admin-table__row--inventory-purchases small,
  .catalog-main .admin-table__row--inventory-adjustments small,
  .catalog-main .admin-table__row--inventory-transfers small,
  .catalog-main .admin-table__row--catalog-products .stacked-line,
  .catalog-main .admin-table__row--price-lists .stacked-line,
  .catalog-main .admin-table__row--catalog-customers .stacked-line,
  .catalog-main .admin-table__row--promotions .stacked-line,
  .catalog-main .admin-table__row--holidays .stacked-line,
  .catalog-main .admin-table__row--inventory-purchases .stacked-line,
  .catalog-main .admin-table__row--inventory-adjustments .stacked-line,
  .catalog-main .admin-table__row--inventory-transfers .stacked-line {
    font-size: 11px;
    line-height: 1.25;
  }

  .catalog-main .admin-table__row--catalog-products > div:nth-of-type(2),
  .catalog-main .admin-table__row--price-lists > div:nth-of-type(2),
  .catalog-main .admin-table__row--price-lists > div:nth-of-type(3),
  .catalog-main .admin-table__row--product-categories > div:nth-of-type(2),
  .catalog-main .admin-table__row--catalog-customers > div:nth-of-type(2),
  .catalog-main .admin-table__row--promotions > div:nth-of-type(2),
  .catalog-main .admin-table__row--inventory-purchases > div:nth-of-type(2),
  .catalog-main .admin-table__row--inventory-adjustments > div:nth-of-type(2),
  .catalog-main .admin-table__row--inventory-transfers > div:nth-of-type(3),
  .catalog-main .admin-table__row--catalog-products > div:nth-of-type(3),
  .catalog-main .admin-table__row--catalog-customers > div:nth-of-type(3),
  .catalog-main .admin-table__row--promotions > div:nth-of-type(3),
  .catalog-main .admin-table__row--promotions > div:nth-of-type(4),
  .catalog-main .admin-table__row--holidays > div:nth-of-type(2),
  .catalog-main .admin-table__row--inventory-purchases > div:nth-of-type(3),
  .catalog-main .admin-table__row--inventory-transfers > div:nth-of-type(4) {
    grid-column: 1;
  }

  .catalog-main .admin-table__row--catalog-products > div:nth-of-type(3),
  .catalog-main .admin-table__row--price-lists > div:nth-of-type(4),
  .catalog-main .admin-table__row--catalog-customers > div:nth-of-type(4),
  .catalog-main .admin-table__row--inventory-purchases > div:nth-of-type(4),
  .catalog-main .admin-table__row--inventory-adjustments > div:nth-of-type(2) {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
    text-align: right;
  }

  .catalog-main .admin-table__row--inventory-transfers > div:nth-of-type(2) {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
  }

  .catalog-main .admin-table__row--catalog-products > div:nth-of-type(4) {
    grid-column: 1;
  }

  .catalog-main .admin-table__row--catalog-products > div:nth-of-type(5) {
    grid-column: 1;
  }

  .catalog-main .admin-table__row--catalog-products > .admin-table__actions,
  .catalog-main .admin-table__row--price-lists > .admin-table__actions,
  .catalog-main .admin-table__row--product-categories > .admin-table__actions,
  .catalog-main .admin-table__row--catalog-customers > .admin-table__actions,
  .catalog-main .admin-table__row--promotions > .admin-table__actions,
  .catalog-main .admin-table__row--holidays > .admin-table__actions,
  .catalog-main .admin-table__row--inventory-purchases > .admin-table__actions,
  .catalog-main .admin-table__row--inventory-adjustments > .admin-table__actions,
  .catalog-main .admin-table__row--inventory-transfers > .admin-table__actions {
    grid-column: 2;
    grid-row: 2 / span 3;
    align-self: end;
    justify-self: end;
  }

  .catalog-main .admin-table__row--product-categories > div:nth-of-type(3) {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
  }

  .catalog-main .admin-table__actions .button {
    position: relative;
    width: 44px;
    min-height: 40px;
    padding-inline: 0;
  }

  .catalog-main .admin-table__actions .button span {
    position: absolute;
    overflow: hidden;
    clip: rect(0 0 0 0);
    width: 1px;
    height: 1px;
    white-space: nowrap;
  }

  /* Phone: the desktop `margin-left: auto` on the delete form (line 2725) turns
     into a right-aligned orphan once the toolbar wraps. Give the downloads a
     line of their own and let the destructive action fill the next one, so all
     three share the panel's gutters — the same stretch pattern
     `.catalog-header__actions` already uses at line 1622. */
  .route-load-templates-toolbar__group {
    flex: 1 1 100%;
  }

  .route-load-templates-toolbar__group .button {
    flex: 1 1 auto;
  }

  .route-load-templates-toolbar__delete-all {
    flex: 1 1 100%;
    margin-left: 0;
  }

  .route-load-templates-toolbar__delete-all .button {
    width: 100%;
  }

  /* The row's delete control is a `.row-menu__trigger`, not a `.button`, so the
     icon-only mobile sizing above (line 3104) skips it and it stays a bare
     32×32 next to two framed 44×40 ghost buttons. Match it to its neighbours.
     Deliberately no `background`: the hover/open tints at lines 2770 and 14096
     are 0,3,0 / 0,2,0 and a background here would override the first and
     out-specify the second, killing both hover states. */
  .catalog-main .admin-table__actions .row-menu__trigger {
    width: 44px;
    height: 40px;
    border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
    border-radius: var(--radius);
  }

  .catalog-main .admin-table__actions .row-menu__trigger .icon {
    width: 12px;
    height: 12px;
  }

  .catalog-main .admin-table__row--route-load-templates {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px 10px;
    align-items: center;
    padding-top: 10px;
    padding-bottom: 10px;
  }

  .catalog-main .admin-table__row--route-load-templates > div {
    min-width: 0;
    grid-column: 1;
  }

  .catalog-main .admin-table__row--route-load-templates > .admin-table__actions {
    grid-column: 2;
    grid-row: 1 / span 4;
    align-self: center;
    justify-self: end;
  }

  .catalog-main .sales-summary {
    padding-right: 14px;
    padding-left: 14px;
  }

  .catalog-main .admin-table__row--sales-orders {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px 10px;
    align-items: center;
    padding-top: 10px;
    padding-bottom: 10px;
  }

  .catalog-main .admin-table__row--sales-orders > div {
    min-width: 0;
    grid-column: 1;
  }

  .catalog-main .admin-table__row--sales-orders > div:last-of-type {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
    text-align: right;
  }

  .catalog-main .admin-table__row--sales-orders strong {
    font-size: 14px;
    line-height: 1.2;
  }

  .catalog-main .admin-table__row--sales-orders small,
  .catalog-main .admin-table__row--sales-orders .stacked-line {
    font-size: 11px;
    line-height: 1.25;
  }

  .catalog-main .admin-table__row--promotions > div:first-of-type .badge {
    margin-top: 4px;
  }

  .catalog-main .users-table,
  .catalog-main .users-table thead,
  .catalog-main .users-table tbody,
  .catalog-main .users-table tr,
  .catalog-main .users-table td {
    display: block;
  }

  .catalog-main .users-table {
    font-size: 12px;
  }

  .catalog-main .users-table thead {
    display: none;
  }

  .catalog-main .users-table tbody {
    display: grid;
    gap: 8px;
  }

  .catalog-main .users-table tbody tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px 10px;
    align-items: center;
    border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
    padding-bottom: 8px;
  }

  .catalog-main .users-table tbody td {
    min-width: 0;
    border-bottom: 0;
    padding: 0;
  }

  .catalog-main .users-table td.users-table__user {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .catalog-main .users-table td.users-table__user .avatar {
    width: 32px;
    height: 32px;
  }

  .catalog-main .users-table td.users-table__user strong {
    font-size: 14px;
    line-height: 1.2;
  }

  .catalog-main .users-table small,
  .catalog-main .users-table__muted {
    font-size: 11px;
    line-height: 1.25;
  }

  /* Explicit placement: content stacks in column 1, and the "⋯" menu rides
     the top-right corner of the card, level with the name row. */
  .catalog-main .users-table tbody td:nth-child(1) {
    grid-row: 1;
    grid-column: 1;
  }

  .catalog-main .users-table tbody td:nth-child(2) {
    grid-row: 2;
    grid-column: 1;
  }

  .catalog-main .users-table tbody td:nth-child(3) {
    grid-row: 3;
    grid-column: 1;
  }

  .catalog-main .users-table__actions {
    grid-row: 1;
    grid-column: 2;
    width: auto;
    align-self: start;
    justify-self: end;
  }
}

.settings-form {
  padding: 0 24px 24px;
}

.settings-grid {
  display: grid;
  gap: 16px;
}

.settings-card {
  display: grid;
  gap: 14px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  padding: 16px;
}

.settings-card h2 {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12px;
  text-transform: uppercase;
}

/* Card heading with an inline action (e.g. "Devolver todo a almacén" on the
   liquidación item list); wraps under the heading on narrow widths. */
.settings-card__header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.settings-form label {
  display: grid;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
}

.settings-form input:not([type="checkbox"]):not([type="submit"]):not([type="button"]):not([type="hidden"]):not(.product-filter__input):not(.scan-bar__input):not(.scan-overlay__input),
.settings-form select,
.settings-form textarea {
  width: 100%;
  border: 1px solid var(--input);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--foreground);
  padding: 9px 10px;
  outline: none;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.settings-form input:not([type="checkbox"]):not([type="submit"]):not([type="button"]):not([type="hidden"]):not(.product-filter__input):not(.scan-bar__input):not(.scan-overlay__input):focus,
.settings-form select:focus,
.settings-form textarea:focus {
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 18%, transparent);
}

/* A form control holds a value, not a heading: the `font: inherit` reset hands a
   control inside a <label> the semibold of `.settings-form label`, so captured
   text rendered as bold as its own caption. Broader than the `:not()` list above
   (the filter/scanner inputs skip the bordered box but still sit in a <label>),
   except for submit/button inputs, whose text IS a label — they keep `.button`'s
   600, which this selector would otherwise outrank. */
.settings-form input:not([type="submit"]):not([type="button"]),
.settings-form select,
.settings-form textarea {
  font-weight: 400;
}

.catalog-form {
  --catalog-field-min: 150px;
}

.catalog-form__section {
  align-items: start;
  gap: 16px;
}

.catalog-form .field {
  min-width: 0;
}

.catalog-form .field--span-all,
.catalog-form .field--span-2 {
  grid-column: span 2;
}

.field-grid.catalog-field-grid {
  grid-template-columns: repeat(4, minmax(var(--catalog-field-min), 1fr));
  align-items: end;
}

.field-grid.catalog-field-grid--product {
  grid-template-columns: minmax(280px, 1.7fr) minmax(130px, .75fr) minmax(180px, 1fr) minmax(120px, .65fr);
}

.field-grid.catalog-field-grid--customer {
  grid-template-columns: minmax(280px, 1.55fr) minmax(140px, .75fr) minmax(150px, .8fr) minmax(150px, .8fr);
}

.field-grid.catalog-field-grid--contact,
.field-grid.catalog-field-grid--billing {
  grid-template-columns: minmax(220px, 1fr) minmax(160px, .7fr) minmax(260px, 1.25fr);
}

.field-grid.catalog-field-grid--coordinates {
  grid-template-columns: repeat(2, minmax(150px, 220px));
}

.field-grid.promo-field-grid--general {
  grid-template-columns: minmax(240px, 1fr) minmax(210px, .65fr) minmax(180px, .55fr) minmax(250px, .75fr);
}

.field-grid.promo-field-grid--condition {
  grid-template-columns: minmax(240px, .8fr) minmax(150px, .35fr) minmax(210px, .45fr);
}

.field-grid.promo-field-grid--dates {
  grid-template-columns: repeat(2, minmax(220px, 280px));
}

.field-grid.promo-field-grid--limits {
  grid-template-columns: repeat(5, minmax(140px, 1fr));
}

.catalog-form .field--code,
.catalog-form .field--compact,
.catalog-form .field--money,
.catalog-form .field--phone,
.catalog-form .field--zip,
.catalog-form .field--coordinate,
.catalog-form .field--quantity,
.catalog-form .field--date,
.catalog-form .field--select {
  max-width: 230px;
}

.catalog-form .field--money,
.catalog-form .field--coordinate,
.catalog-form .field--quantity {
  max-width: 180px;
}

.catalog-form .field--zip {
  max-width: 160px;
}

.catalog-form .field--switch {
  align-self: stretch;
}

.settings-form .catalog-switch {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 42px;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 34%, var(--card));
  color: var(--foreground);
  cursor: pointer;
  padding: 9px 10px;
}

.settings-form .catalog-switch input[type="hidden"] {
  display: none;
}

.settings-form .catalog-switch input[type="checkbox"] {
  appearance: none;
  display: inline-grid;
  width: 38px;
  height: 22px;
  flex: 0 0 38px;
  align-items: center;
  border: 1px solid color-mix(in srgb, var(--input) 82%, var(--foreground));
  border-radius: 999px;
  background: var(--card);
  cursor: pointer;
  margin: 0;
  padding: 2px;
  transition: background-color 140ms ease, border-color 140ms ease;
}

.settings-form .catalog-switch input[type="checkbox"]::before {
  content: "";
  width: 16px;
  height: 16px;
  border-radius: 999px;
  background: var(--muted-foreground);
  transition: transform 140ms ease, background-color 140ms ease;
}

.settings-form .catalog-switch input[type="checkbox"]:checked {
  border-color: var(--primary);
  background: var(--primary);
}

.settings-form .catalog-switch input[type="checkbox"]:checked::before {
  background: var(--primary-foreground);
  transform: translateX(16px);
}

.settings-form .catalog-switch span {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.settings-form .catalog-switch strong {
  font-size: 13px;
  line-height: 1.2;
}

.settings-form .catalog-switch small {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.25;
}

.settings-form .catalog-switch--danger {
  background: color-mix(in srgb, var(--danger) 5%, var(--card));
}

.settings-form .catalog-switch--danger input[type="checkbox"]:checked {
  border-color: var(--danger);
  background: var(--danger);
}

/* Tidy catalog forms — clean, evenly aligned two-column layout */
.tidy-form .settings-grid {
  gap: 18px;
}

.tidy-form__section {
  display: grid;
  gap: 16px;
}

.tidy-form__section h2 {
  letter-spacing: .04em;
}

.tidy-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  align-items: start;
}

/* Helper links inside field hints (e.g. "Administrar categorías") need their
   underline back — preflight strips it and they read as inert copy. */
.tidy-form .field > small a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.tidy-grid .field {
  min-width: 0;
  max-width: none;
}

.tidy-grid .field--full {
  grid-column: 1 / -1;
}

.tidy-grid--narrow {
  grid-template-columns: repeat(2, minmax(0, 220px));
  justify-content: start;
}

.tidy-grid--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 900px) {
  .tidy-grid--3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  .tidy-grid,
  .tidy-grid--narrow,
  .tidy-grid--3 {
    grid-template-columns: minmax(0, 1fr);
  }

  .tidy-grid .field--full {
    grid-column: auto;
  }
}

/* Customer edit — "Ruta y días de visita" day picker */
.route-days__hint {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.45;
}

.route-days {
  margin: 14px 0 0;
  padding: 0;
  border: 0;
}

.route-days legend {
  padding: 0;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 600;
}

.route-days__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
  margin-top: 10px;
}

/* Scoped under the grid so the chip row beats the generic `.settings-form label`
   display:grid (which would stack the checkbox above the label). */
.route-days__grid .route-day {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 42px;
  padding: 9px 12px;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 34%, var(--card));
  cursor: pointer;
  transition: border-color 120ms ease, background-color 120ms ease;
}

.route-days__grid .route-day:hover {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
}

.route-days__grid .route-day:has(input:checked) {
  border-color: var(--primary);
  background: color-mix(in srgb, var(--primary) 8%, var(--card));
}

.route-days__grid .route-day input[type="checkbox"] {
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  accent-color: var(--primary);
  cursor: pointer;
  margin: 0;
}

.route-day__label {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.route-day__label strong {
  font-size: 13px;
  line-height: 1.2;
}

.route-day__label small {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 500;
}

.promo-selection-grid {
  grid-template-columns: minmax(320px, 1.2fr) minmax(260px, .8fr);
  align-items: start;
}

.promo-picker-block {
  display: grid;
  gap: 8px;
  min-width: 0;
}

.promo-picker-block > strong {
  font-size: 13px;
}

.promo-form .reward-row {
  grid-template-columns: minmax(300px, 1fr) minmax(120px, .25fr) minmax(140px, .3fr) minmax(170px, auto);
  align-items: start;
}

.promo-form .reward-row__destroy {
  align-self: start;
  margin-top: 24px;
}

.check-list .choice-option {
  min-height: 36px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  cursor: pointer;
  padding: 8px 10px;
}

.check-list .choice-option input[type="checkbox"] {
  appearance: none;
  display: grid;
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
  place-items: center;
  border: 1px solid var(--input);
  border-radius: 5px;
  background: var(--card);
  cursor: pointer;
  margin: 0;
}

.check-list .choice-option input[type="checkbox"]::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 3px;
  background: var(--primary-foreground);
  opacity: 0;
}

.check-list .choice-option input[type="checkbox"]:checked {
  border-color: var(--primary);
  background: var(--primary);
}

.check-list .choice-option input[type="checkbox"]:checked::before {
  opacity: 1;
}

.check-list .choice-option:has(input:checked) {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  background: color-mix(in srgb, var(--primary) 6%, var(--card));
}

.field-grid,
.selection-grid,
.reward-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.reward-row {
  grid-template-columns: minmax(220px, 1fr) 120px 140px auto;
  align-items: end;
}

.operation-summary {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}

/* Route flow: an interlocking arrow breadcrumb of the operation's lifecycle.
   Reached steps fill green with a solid bottom accent; pending steps stay quiet
   and only reached/closed steps reveal their timestamp. */
.routeflow {
  display: flex;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}

.routeflow__step {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  margin-left: -13px;
  padding: 10px 14px 11px 26px;
  background: color-mix(in srgb, var(--muted) 36%, var(--card));
  color: var(--muted-foreground);
  box-shadow: inset 0 -3px 0 color-mix(in srgb, var(--border) 75%, transparent);
  clip-path: polygon(13px 50%, 0 0, calc(100% - 13px) 0, 100% 50%, calc(100% - 13px) 100%, 0 100%);
}

.routeflow__step:first-child {
  margin-left: 0;
  padding-left: 18px;
  clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 50%, calc(100% - 13px) 100%, 0 100%);
}

.routeflow__step:last-child {
  clip-path: polygon(13px 50%, 0 0, 100% 0, 100% 100%, 0 100%);
}

/* A hairline chevron tracing each arrow's leading edge, so two adjacent
   completed (green) stages read as separate steps instead of one block. */
.routeflow__step:not(:last-child)::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: color-mix(in srgb, var(--foreground) 17%, transparent);
  clip-path: polygon(
    calc(100% - 13px) 0,
    100% 50%,
    calc(100% - 13px) 100%,
    calc(100% - 14.5px) 100%,
    calc(100% - 1.5px) 50%,
    calc(100% - 14.5px) 0
  );
}

.routeflow__icon {
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
  color: color-mix(in srgb, var(--muted-foreground) 80%, transparent);
}

.routeflow__text {
  min-width: 0;
}

.routeflow__text strong,
.routeflow__text small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.routeflow__text strong {
  color: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
}

.routeflow__text small {
  margin-top: 1px;
  font-size: 11.5px;
  line-height: 1.2;
  opacity: 0.75;
}

.routeflow__step.is-done {
  background: color-mix(in srgb, #16a34a 20%, var(--card));
  color: var(--foreground);
  box-shadow: inset 0 -3px 0 #16a34a;
}

.routeflow__step.is-done .routeflow__icon {
  color: #16a34a;
}

.routeflow__step.is-canceled {
  background: color-mix(in srgb, #dc2626 18%, var(--card));
  color: var(--foreground);
  box-shadow: inset 0 -3px 0 #dc2626;
}

.routeflow__step.is-canceled .routeflow__icon {
  color: #dc2626;
}

/* Collapsing the stages into a deck is a phone-only affordance — the desktop
   arrow breadcrumb fits on one line and needs no control. The mobile block far
   below turns this back on; keeping the base here means desktop is untouched. */
.routeflow-stack__toggle {
  display: none;
}

.operation-summary > *,
.operation-total-preview {
  display: grid;
  align-content: center;
  gap: 4px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  padding: 12px;
}

.operation-summary small,
.operation-total-preview span {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.4;
}

.operation-summary strong {
  font-size: 18px;
}

/* Figure strip: one bordered panel split by hairline dividers, used for both the
   setup snapshot and the settlement totals — a single tidy container instead of
   cards floating inside cards. The 1px grid gap reveals the divider color. */
.operation-summary--figures {
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1px;
  margin-bottom: 0;
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, var(--border) 50%, transparent);
  overflow: hidden;
}

.operation-summary--figures > * {
  border: 0;
  border-radius: 0;
  background: var(--card);
  padding: 11px 14px;
}

.operation-summary--figures small {
  font-size: 11.5px;
}

/* A strip cell whose figure is editable (the settlement's Efectivo liquidado), so
   the capture field sits among the numbers it moves instead of in a field row of
   its own. It is a <label>, so its caption has to opt out of the form's semibold
   label weight to read like the plain <small> captions of the sibling cells. The
   weight has to land on the <small> itself: on the cell it would lose to
   `.settings-form label`, which is the more specific selector. */
.operation-summary__cell--input small {
  font-weight: 400;
}

/* Semibold, not bold. A figure strip is a row of <strong>s side by side, so at
   700 every cell shouts and the one that matters — a faltante, a difference —
   has nothing left to shout with. */
.operation-summary--figures strong {
  font-size: 16px;
  font-weight: 600;
}

.operation-summary--figures .stat-value {
  font-weight: 700;
}

.operation-summary__cell--emphasis {
  background: color-mix(in srgb, var(--muted) 30%, var(--card)) !important;
}

.stat-value.is-negative {
  color: #dc2626;
}

.stat-value.is-positive {
  color: #16a34a;
}

.stat-tag {
  justify-self: start;
  margin-top: 2px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--muted);
  color: var(--muted-foreground);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.stat-tag.is-negative {
  background: #fee2e2;
  color: #b91c1c;
}

.stat-tag.is-positive {
  background: #dcfce7;
  color: #047857;
}

/* Inline notice (e.g. a route closed in móvil awaiting validation). */
.callout {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 13px;
  line-height: 1.45;
}

.callout p {
  margin: 0;
}

.callout__icon {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: 1px;
}

.callout--pending {
  border: 1px solid color-mix(in srgb, #f59e0b 48%, transparent);
  background: color-mix(in srgb, #f59e0b 13%, var(--card));
  color: color-mix(in srgb, #f59e0b 34%, var(--foreground));
}

.callout--pending .callout__icon {
  color: #f59e0b;
}

.callout--pending strong {
  color: color-mix(in srgb, #f59e0b 44%, var(--foreground));
}

/* Compact icon-in-a-box search field: the client-side product filter, which
   lives in a section header (top-right) rather than taking its own full-width
   row, and the settlement scanner's code box, which shares its look. Purely
   presentational — see list_filter_controller.js and barcode_scan_controller.js. */
.product-filter,
.scan-bar__field {
  position: relative;
  display: inline-flex;
  align-items: center;
  margin: 0;
}

.product-filter__icon,
.scan-bar__icon {
  position: absolute;
  left: 10px;
  width: 15px;
  height: 15px;
  color: var(--muted-foreground);
  pointer-events: none;
}

.product-filter__input,
.scan-bar__input {
  width: 220px;
  max-width: 100%;
  padding: 7px 12px 7px 32px;
  font-size: 13px;
  color: var(--foreground);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  outline: none;
}

.product-filter__input:focus,
.scan-bar__input:focus {
  border-color: color-mix(in srgb, var(--primary) 55%, var(--border));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
}

/* Rows the client-side filter hides. `!important` beats the grid/flex `display`
   on the row classes it targets (.reconcile__row, .operation-item-row). */
.is-filtered-out {
  display: none !important;
}

/* A settings-card heading that carries a control (e.g. the product filter) on
   its right, so the control shares the title's row instead of a new line. */
.settings-card__head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 16px;
  margin-bottom: 12px;
}

.settings-card__head-row h2 {
  margin: 0;
}

.route-recharges {
  display: grid;
  gap: 14px;
}

.route-recharge {
  display: grid;
  gap: 12px;
  padding-top: 14px;
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
}

.route-recharge:first-child {
  padding-top: 0;
  border-top: 0;
}

.route-recharge__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 14px;
}

.route-recharge__header > div:first-child,
.route-recharge__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 7px;
}

.route-recharge__meta,
.route-recharge__notes {
  color: var(--muted-foreground);
  font-size: 12px;
}

.route-recharge__notes {
  margin: 0;
}

/* Recargas the seller already picked up (or inventory canceled) collapse behind
   a counter so the settlement screen is not buried under finished history. */
.route-recharges + .route-recharges-history {
  margin-top: 14px;
}

/* The disclosure reads as a control, not as a caption: a full-width button with
   the count on the left and the caret on the right, so on a phone it is an
   obvious thing to press instead of a small grey line of text. */
.route-recharges-history__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  min-height: 38px;
  border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 38%, var(--card));
  color: var(--foreground);
  cursor: pointer;
  font-size: 13px;
  font-weight: 650;
  list-style: none;
  padding: 8px 12px;
}

.route-recharges-history__summary::-webkit-details-marker {
  display: none;
}

.route-recharges-history__summary:hover {
  background: color-mix(in srgb, var(--muted) 72%, var(--card));
}

.route-recharges-history__caret {
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  color: var(--muted-foreground);
  transition: transform 120ms ease;
}

.route-recharges-history[open] .route-recharges-history__caret {
  transform: rotate(180deg);
}

.route-recharges-history[open] .route-recharges {
  margin-top: 12px;
}

/* Right-aligned filter above the settlement reconcile table. */
.reconcile-block__toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 10px;
}

@media (max-width: 640px) {
  /* When a section header wraps on phones, let the filter span the full width
     instead of clinging to a narrow right-hand slot. */
  .route-create-card__head-actions .product-filter,
  .settings-card__head-row .product-filter,
  .reconcile-block__toolbar .product-filter,
  .route-create-card__head-actions .product-filter__input,
  .settings-card__head-row .product-filter__input,
  .reconcile-block__toolbar .product-filter__input {
    width: 100%;
  }
}

.operation-items {
  display: grid;
  gap: 8px;
  overflow-x: auto;
}

.operation-items__head,
.operation-item-row {
  display: grid;
  grid-template-columns: minmax(240px, 1.4fr) repeat(6, minmax(92px, .55fr)) minmax(74px, auto);
  gap: 8px;
  align-items: end;
  min-width: 1030px;
}

.operation-items--initial-edit .operation-items__head,
.operation-items--initial-edit .operation-item-row {
  grid-template-columns: minmax(280px, 1.5fr) repeat(2, minmax(108px, .55fr)) minmax(120px, .7fr) minmax(82px, auto);
  min-width: 740px;
}

/* Every cell in a load row is already a bordered field, so the row rule drew a
   second line right above them and the chosen product's semibold made a column
   of shouting names. Tighter, quieter, and the boxes do the separating. */
.operation-items--initial-edit .operation-item-row {
  border-top: 0;
  padding-top: 0;
}

.operation-items--initial-edit {
  gap: 6px;
}

.operation-items--initial-edit .autocomplete-chosen__label {
  font-weight: 400;
}

.operation-items--readonly .operation-items__head,
.operation-items--readonly .operation-item-row {
  grid-template-columns: minmax(240px, 1.7fr) minmax(90px, .6fr) minmax(110px, .7fr) minmax(120px, .8fr);
  min-width: 620px;
}

/* On phones the read-only item table drops the unit-price column (the total
   still tells the story) so the remaining columns fit without a hidden
   horizontal scroll. */
@media (max-width: 640px) {
  .operation-items--readonly .operation-items__head,
  .operation-items--readonly .operation-item-row {
    grid-template-columns: minmax(0, 1.7fr) minmax(64px, .6fr) minmax(84px, .8fr);
    min-width: 0;
  }

  .operation-items--readonly .operation-items__head > :nth-child(3),
  .operation-items--readonly .operation-item-row > :nth-child(3) {
    display: none;
  }

  /* A load table (the route's carga, a recarga's pieces) is read for what is on
     the truck, not what it is worth — its money columns are already totalled
     above it. Dropping them leaves product and quantity the whole width, which
     is what a long product name needs on a phone. The sales screen keeps its
     amounts: there the money IS the answer, which is why this is a modifier and
     not a change to `--readonly`. */
  .operation-items--load .operation-items__head,
  .operation-items--load .operation-item-row {
    grid-template-columns: minmax(0, 1fr) minmax(52px, auto);
    gap: 10px;
  }

  .operation-items--load .operation-items__head > :nth-child(n + 3),
  .operation-items--load .operation-item-row > :nth-child(n + 3) {
    display: none;
  }

  .operation-items--load .operation-items__head > :nth-child(2),
  .operation-items--load .operation-item-row > :nth-child(2) {
    text-align: right;
  }

  .operation-items--load .operation-items__head {
    font-size: 10px;
  }

  .operation-items--load .operation-item-row {
    align-items: start;
    padding-top: 7px;
    font-size: 12.5px;
    line-height: 1.35;
  }
}

.operation-items--settlement .operation-items__head,
.operation-items--settlement .operation-item-row {
  grid-template-columns: minmax(260px, 1.5fr) repeat(5, minmax(96px, .55fr)) minmax(120px, .7fr);
  min-width: 960px;
}

.operation-items--settlement-edit .operation-items__head,
.operation-items--settlement-edit .operation-item-row {
  grid-template-columns: minmax(260px, 1.5fr) repeat(5, minmax(96px, .55fr)) minmax(120px, .7fr);
  min-width: 960px;
}

.operation-items--inventory-purchase .operation-items__head,
.operation-items--inventory-purchase .operation-item-row {
  grid-template-columns: minmax(260px, 1.5fr) repeat(4, minmax(110px, .65fr));
  min-width: 760px;
}

.operation-items--inventory-transfer .operation-items__head,
.operation-items--inventory-transfer .operation-item-row {
  grid-template-columns: minmax(260px, 1.5fr) minmax(120px, .5fr);
}

.operation-items__head {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

.operation-item-row {
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding-top: 8px;
}

.operation-item-row label {
  min-width: 0;
}

.operation-item-row .autocomplete-picker {
  margin-top: 0;
}

.route-operation-readonly-field,
.route-operation-item-value,
.route-operation-product-lock {
  display: grid;
  min-height: 39px;
  align-content: center;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 44%, var(--card));
  padding: 8px 10px;
}

.route-operation-readonly-field {
  gap: 3px;
}

.route-operation-readonly-field span {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.2;
}

.route-operation-readonly-field strong {
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 14px;
  line-height: 1.25;
  white-space: nowrap;
}

.route-operation-product-lock {
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 13px;
  font-weight: 650;
  white-space: nowrap;
}

.route-operation-item-value {
  justify-content: end;
  color: var(--foreground);
  font-size: 13px;
  font-weight: 650;
  text-align: right;
}

/* Ingreso de inventario reads as a table of five bold cells per row. Scoped to
   this list (the same classes are shared with the transfer and route-operation
   screens): the product is the row's identifier, the figures are figures. */
.operation-items--inventory-purchase .route-operation-product-lock {
  font-weight: 600;
}

.operation-items--inventory-purchase .route-operation-item-value {
  font-weight: 500;
}

.operation-item-row__destroy {
  min-height: 39px;
  justify-content: center;
  font-size: 12px;
}

/* The locked half of the edit screen's Operación card: who the load belongs to,
   with their avatar, and the one other figure frozen with it — on one line.
   What used to sit here as two more figure cells now reads where it belongs:
   the status in the lifecycle deck above, the date as the card's subtitle. */
.operation-locked {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 16px;
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: 10px;
  padding: 9px 14px;
}

.operation-locked__identity {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.operation-locked small {
  display: block;
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 400;
  line-height: 1.3;
}

.operation-locked strong {
  display: block;
  overflow: hidden;
  font-size: 14px;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.operation-locked__figure {
  text-align: right;
}

.route-operation-settlement {
  display: grid;
  gap: 16px;
}

.route-operation-settlement__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.route-operation-settlement .operation-summary {
  margin-bottom: 0;
}

.route-operation-empty-state {
  display: grid;
  gap: 5px;
  border: 1px dashed color-mix(in srgb, var(--border) 86%, var(--foreground));
  border-radius: 8px;
  background: color-mix(in srgb, var(--muted) 48%, var(--card));
  padding: 16px;
}

.route-operation-empty-state strong {
  font-size: 14px;
}

.route-operation-empty-state p {
  max-width: 760px;
  margin: 0;
  color: var(--muted-foreground);
  font-size: 13px;
  line-height: 1.45;
}

/* "Nothing here yet" needs to say exactly that. The paragraph explaining how the
   section will eventually fill up was two or three lines of prose on a phone,
   above the numbers the page exists for — so these states are one centred label
   inside the same dashed frame. */
.route-operation-empty-state--compact {
  place-content: center;
  place-items: center;
  min-height: 66px;
  margin: 0;
  padding: 14px;
  color: var(--muted-foreground);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
}

/* Flat vertical timeline — a single dot-and-rail column instead of one bordered
   card per change, matching the flatter route-operation show layout. */
.route-op-history {
  list-style: none;
  margin: 0;
  padding: 0;
}

.route-op-history__entry {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 12px;
  padding-bottom: 18px;
}

/* The rail that links each node to the next; the opaque node masks it where
   they overlap, giving the classic timeline dot-on-line look. */
.route-op-history__entry::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 4px;
  bottom: 0;
  width: 2px;
  background: var(--border);
}

.route-op-history__entry:last-child {
  padding-bottom: 0;
}

.route-op-history__entry:last-child::before {
  display: none;
}

.route-op-history__node {
  position: relative;
  z-index: 1;
  width: 10px;
  height: 10px;
  margin-top: 5px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--muted-foreground) 45%, var(--card));
}

.route-op-history__body {
  display: grid;
  gap: 5px;
  min-width: 0;
}

.route-op-history__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
}

.route-op-history__actor {
  font-weight: 600;
  font-size: 13px;
}

.route-op-history__action {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 13px;
}

.route-op-history__action strong {
  color: var(--foreground);
  font-weight: 600;
}

.route-op-history__time {
  margin-left: auto;
  color: var(--muted-foreground);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.route-op-history__changes {
  list-style: none;
  margin: 2px 0 0;
  padding: 8px 12px;
  display: grid;
  gap: 4px;
  background: color-mix(in srgb, var(--muted-foreground) 6%, transparent);
  border-radius: 8px;
}

.route-op-history__changes li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 13px;
}

.route-op-history__field {
  min-width: 110px;
  color: var(--muted-foreground);
}

.route-op-history__from {
  color: var(--muted-foreground);
  text-decoration: line-through;
}

.route-op-history__to {
  font-weight: 600;
}

.route-op-history__arrow {
  color: var(--muted-foreground);
}

.route-operation-notes {
  display: flex;
  justify-content: center;
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding-top: 22px;
}

.sticky-note {
  position: relative;
  width: 100%;
  max-width: 290px;
  padding: 20px 20px 24px;
  /* Same warning-amber tone as the .callout--pending / .badge--warning notices,
     mixed against theme tokens so it adapts to light and dark mode. */
  background: color-mix(in srgb, #f59e0b 13%, var(--card));
  color: color-mix(in srgb, #f59e0b 34%, var(--foreground));
  border: 1px solid color-mix(in srgb, #f59e0b 32%, transparent);
  border-radius: 2px;
  transform: rotate(-2.2deg);
  box-shadow:
    0 1px 1px rgba(0, 0, 0, 0.14),
    0 8px 18px -6px rgba(0, 0, 0, 0.28);
  transition: transform 140ms ease, box-shadow 140ms ease;
}

.sticky-note::after {
  /* subtle curled corner shadow, bottom-right */
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  width: 28px;
  height: 22px;
  background: linear-gradient(135deg, transparent 50%, rgba(0, 0, 0, 0.08) 52%, transparent 56%);
}

.sticky-note:hover {
  transform: rotate(-0.6deg) translateY(-2px);
  box-shadow:
    0 2px 2px rgba(0, 0, 0, 0.16),
    0 14px 26px -8px rgba(0, 0, 0, 0.32);
}

.sticky-note__tape {
  position: absolute;
  top: -13px;
  left: 50%;
  width: 92px;
  height: 26px;
  transform: translateX(-50%) rotate(-3deg);
  background: rgba(255, 255, 255, 0.45);
  border-left: 1px dashed rgba(0, 0, 0, 0.07);
  border-right: 1px dashed rgba(0, 0, 0, 0.07);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
  backdrop-filter: blur(1px);
}

.sticky-note__body p {
  margin: 0 0 6px;
  font-size: 15px;
  line-height: 1.5;
  color: inherit;
}

.sticky-note__body p:last-child {
  margin-bottom: 0;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

.toggle-row,
.checkbox-inline {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

.toggle-row label,
.checkbox-inline {
  display: flex;
  align-items: center;
  gap: 7px;
}

.check-list {
  display: grid;
  max-height: 220px;
  overflow: auto;
  gap: 6px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 8px;
  margin-top: 8px;
  padding: 10px;
}

.check-list label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
}

.autocomplete-picker {
  position: relative;
  display: grid;
  gap: 8px;
  margin-top: 8px;
}

.autocomplete-results {
  position: absolute;
  top: 40px;
  right: 0;
  left: 0;
  z-index: 20;
  display: grid;
  max-height: 240px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
}

.autocomplete-results:empty {
  display: none;
}

.autocomplete-option {
  display: grid;
  gap: 2px;
  border: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
  padding: 9px 10px;
  text-align: left;
}

.autocomplete-option:hover,
.autocomplete-option:focus {
  background: var(--muted);
  outline: none;
}

.autocomplete-option small,
.autocomplete-status,
.autocomplete-empty {
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 500;
}

.autocomplete-status {
  padding: 10px;
}

.autocomplete-selected {
  display: flex;
  flex-wrap: wrap;
  min-height: 30px;
  gap: 6px;
}

.autocomplete-selected--single {
  min-height: auto;
}

.autocomplete-chip {
  display: inline-flex;
  max-width: 100%;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--muted);
  padding: 5px 7px;
  font-size: 12px;
  font-weight: 600;
}

.autocomplete-chip span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.autocomplete-chip--single {
  width: 100%;
  justify-content: space-between;
}

.autocomplete-chip__remove {
  display: grid;
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  place-items: center;
  border: 0;
  border-radius: 6px;
  background: color-mix(in srgb, var(--foreground) 9%, transparent);
  color: var(--foreground);
  cursor: pointer;
  line-height: 1;
  padding: 0;
}

.form-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  padding-top: 16px;
}

.settings-form .form-actions .button--primary,
.role-form__actions .button--primary {
  width: auto;
  min-width: 160px;
}

/* ---- Route operation creation screen ---- */
.icon-16 {
  width: 16px;
  height: 16px;
}

.route-create-form {
  display: grid;
  gap: 18px;
  margin-top: 8px;
}

/* Grid children default to min-width:auto, which let a wide item table force
   the whole form past the phone viewport (clipping the action buttons). */
.route-create-form > * {
  min-width: 0;
}

/* No native spinner buttons on the quantity/money fields — they crowd every row
   of a long load or settlement table and only serve the mouse. Keyed off the
   controller rather than a form class (`.route-create-form` also dresses the
   purchase/transfer/template forms) so the chrome can only disappear where
   number-step has taken the keyboard stepping over. */
[data-controller~="number-step"] input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

[data-controller~="number-step"] input[type="number"]::-webkit-outer-spin-button,
[data-controller~="number-step"] input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Flat sections inside the single outer panel — no nested card boxes. Adjacent
   sections are separated by a hairline divider instead of stacking bordered
   cards inside the panel. */
.route-create-card {
  padding: 0;
}

.route-create-card + .route-create-card {
  padding-top: 20px;
  border-top: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
}

.route-create-card__head {
  margin-bottom: 16px;
}

.route-create-card__head h2 {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.route-create-card__head p {
  max-width: 60ch;
  margin: 5px 0 0;
  color: var(--muted-foreground);
  font-size: 13px;
  line-height: 1.45;
}

.route-create-card__head--load {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
}

.route-load-summary {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 18px;
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 42%, var(--card));
  padding: 9px 16px;
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

.route-load-summary strong {
  margin-right: 5px;
  color: var(--foreground);
  font-size: 17px;
  font-variant-numeric: tabular-nums;
}

.route-create-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 18px;
  align-items: start;
}

/* Let each field cell shrink instead of forcing its track wider than 1fr — a
   long chosen value (e.g. the vendedor pill) then truncates within its column
   instead of overflowing into the next field. */
.route-create-fields > * {
  min-width: 0;
}

.route-create-fields .field-hint {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted-foreground);
}

.operation-loader__head,
.operation-load-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 140px 44px;
  gap: 12px;
}

.operation-loader__head {
  align-items: end;
  padding: 0 2px 10px;
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.operation-loader__rows {
  display: grid;
  gap: 10px;
}

.operation-load-row {
  align-items: start;
}

.operation-load-row .autocomplete-picker {
  margin-top: 0;
}

.operation-load-row__product,
.operation-load-row__qty {
  min-width: 0;
  margin: 0;
}

.operation-load-row__mobile-label {
  display: none;
}

.operation-load-row__remove {
  display: grid;
  place-items: center;
  width: 44px;
  min-height: 40px;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.operation-load-row__remove:hover {
  color: var(--destructive);
  border-color: color-mix(in srgb, var(--destructive) 45%, var(--border));
  background: color-mix(in srgb, var(--destructive) 8%, var(--card));
}

.operation-load-row__remove:focus-visible {
  outline: none;
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 22%, transparent);
}

/* A load line the server refused, on either the creation or the edit screen:
   the reason reads under the row that caused it, spanning whatever column count
   that screen's grid uses so it sits below the fields rather than beside them. */
.load-line-error {
  display: flex;
  align-items: center;
  grid-column: 1 / -1;
  gap: 6px;
  margin: 0;
  color: var(--destructive);
  font-size: 12px;
  font-weight: 600;
  /* The edit screen's load table is wider than a phone and scrolls sideways, so
     the reason is pinned to the visible edge and wraps there — spanning the
     grid alone would run it off with the columns, cut mid-sentence. */
  position: sticky;
  left: 0;
  max-width: min(100%, 92vw);
}

.operation-load-row.is-invalid .autocomplete-input,
.operation-load-row.is-invalid .autocomplete-chosen,
.operation-load-row.is-invalid input[type="number"],
.operation-item-row.is-invalid .autocomplete-input,
.operation-item-row.is-invalid .autocomplete-chosen,
.operation-item-row.is-invalid input[type="number"] {
  border-color: var(--destructive);
}

.operation-loader__add {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  justify-self: start;
  margin-top: 14px;
  border: 1px dashed color-mix(in srgb, var(--border) 92%, var(--foreground));
  border-radius: var(--radius);
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
  padding: 10px 15px;
  font-size: 13px;
  font-weight: 600;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.operation-loader__add:hover {
  border-style: solid;
  background: color-mix(in srgb, var(--muted) 52%, var(--card));
}

.operation-loader__add:focus-visible {
  outline: none;
  border-style: solid;
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 22%, transparent);
}

.operation-loader--purchase .operation-loader__head,
.operation-loader--purchase .operation-load-row {
  grid-template-columns: minmax(0, 1fr) 140px 140px 44px;
}

.autocomplete-option.is-active {
  background: var(--muted);
}

/* Inline single-field combobox: the search box and the chosen product occupy
   the same slot, swapped by the .is-filled state. */
.autocomplete-picker--inline {
  gap: 0;
  margin-top: 0;
  /* Pin the single column to the field width so a long chosen label truncates
     (ellipsis) instead of letting the picker grow to its max-content width and
     spill into the neighbouring field. */
  grid-template-columns: minmax(0, 1fr);
}

.autocomplete-input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

.autocomplete-picker--inline.is-filled .autocomplete-input {
  display: none;
}

.autocomplete-chosen {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 40px;
  border: 1px solid var(--input);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 38%, var(--card));
  padding: 6px 8px 6px 12px;
}

.autocomplete-picker--inline.is-filled .autocomplete-chosen {
  display: flex;
}

.autocomplete-chosen__label {
  overflow: hidden;
  flex: 1;
  min-width: 0;
  color: var(--foreground);
  font-size: 14px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.autocomplete-chosen__clear {
  display: grid;
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  place-items: center;
  border: 0;
  border-radius: 6px;
  background: color-mix(in srgb, var(--foreground) 8%, transparent);
  color: var(--muted-foreground);
  cursor: pointer;
  padding: 0;
  transition: color 0.15s ease, background 0.15s ease;
}

.autocomplete-chosen__clear:hover {
  color: var(--foreground);
  background: color-mix(in srgb, var(--foreground) 14%, transparent);
}

.autocomplete-chosen__clear:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 28%, transparent);
}

.route-create-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 10px;
  padding-top: 4px;
}

/* The repeated top action bar reads as a toolbar over the form; the bottom copy
   keeps its normal trailing spacing. */
.route-create-actions--top {
  padding-top: 0;
  padding-bottom: 12px;
  margin-bottom: 4px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
}

.route-field__label {
  font-size: 12px;
  font-weight: 600;
}

/* Locked figures on the route-operation edit screen: a flat label/value pair
   (no faux-input box) so the read-only state doesn't stack more boxes. */
.route-fact {
  display: grid;
  gap: 3px;
  align-content: start;
}

.route-fact > span {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.2;
}

.route-fact strong {
  overflow: hidden;
  font-size: 15px;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Read-only fact grid for the inventory-adjustment detail: the flat `.route-fact`
   label/value pairs (no faux-input boxes) inside the settings card that already
   frames them, two-up on a desktop and stacked on a phone. */
.adjustment-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 18px;
}

/* The inventory-movement id is an opaque identifier, so it opts out of
   `.route-fact strong`'s single-line ellipsis — a truncated id cannot be matched
   back against the ledger — and reads in a monospace face at caption size so it
   does not outweigh the figures above it. */
.adjustment-facts .route-fact--id strong {
  overflow-wrap: anywhere;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.45;
  white-space: normal;
}

@media (max-width: 720px) {
  .adjustment-facts {
    grid-template-columns: minmax(0, 1fr);
  }
}

.route-create-card__head-actions {
  display: flex;
  flex-shrink: 0;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.route-field--comments textarea {
  width: 100%;
}

/* Settlement reconciliation table (route-operation edit once the rep closes):
   one row per product — the route context (carga, vendidas, devoluciones, merma
   de ruta), the expected return, the manager's counted figures and the live
   difference. Dense and borderless like the create-screen loader; scrolls
   sideways on mid widths and collapses into labeled cards on phones. */
.reconcile__scroll {
  overflow-x: auto;
}

.reconcile__head,
.reconcile__row {
  display: grid;
  align-items: center;
  grid-template-columns: minmax(190px, 1.6fr) repeat(8, minmax(76px, 0.5fr));
  gap: 10px;
  min-width: 950px;
}

.reconcile__head {
  padding: 0 2px 8px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 62%, transparent);
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.reconcile__head span:not(:first-child) {
  text-align: right;
}

.reconcile__row {
  padding: 5px 2px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 34%, transparent);
}

.reconcile__cell {
  min-width: 0;
  margin: 0;
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* The product name anchors the row without shouting: the figures beside it are
   what the eye is scanning, and a whole column of semibold names reads as
   emphasis on everything (the flatter item tables on these screens already do
   this). */
.reconcile__cell--product {
  overflow: hidden;
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reconcile__load-breakdown {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.72rem;
  line-height: 1.25;
  color: var(--muted-foreground);
}

.reconcile__cell--expected,
.reconcile__cell--diff {
  font-weight: 700;
}

.reconcile__cell--input input {
  width: 100%;
  min-height: 36px;
  padding: 7px 10px;
  text-align: right;
}

.reconcile__cell--diff.is-negative {
  color: #dc2626;
}

.reconcile__cell--diff.is-positive {
  color: #16a34a;
}

.reconcile__row--total {
  padding-top: 8px;
  border-top: 1px solid color-mix(in srgb, var(--border) 62%, transparent);
  border-bottom: 0;
  font-weight: 700;
}

/* Merma recognized at the warehouse is captured by cause, so the "Merma alm."
   cell only shows the sum, and the causes live in a panel that opens on its own
   full-width line under the product — a cause needs a picker, a quantity and a
   photo, which no 76px column can hold. The panel is inset and tinted so a long
   settlement still reads as one row per product with a detail hanging off it,
   not as a second table. */
.reconcile__cell--waste {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 5px;
  font-weight: 700;
}

/* Calls up the causes panel on a line that has no merma yet — where the panel
   itself is hidden, because a settlement runs to dozens of products and most of
   them come back whole. It disappears once the panel is on the row (`:has` on
   the row, since the panel is a later sibling of this cell). */
.reconcile__waste-add {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  flex: 0 0 20px;
  border: 1px solid color-mix(in srgb, var(--border) 85%, transparent);
  border-radius: 999px;
  background: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  padding: 0;
}

.reconcile__waste-add:hover {
  border-color: color-mix(in srgb, var(--foreground) 45%, transparent);
  color: var(--foreground);
}

.reconcile__row:not(:has(.settlement-wastes--empty)) .reconcile__waste-add {
  display: none;
}

.settlement-wastes {
  grid-column: 1 / -1;
  margin: 2px 0 4px;
}

/* No merma captured and closed: the whole disclosure stays out of the row. The
   "+" beside the row's Merma alm. figure is the way back in, and opening it
   drops this modifier for good (see settlement_wastes_controller#openCauses) so
   an unsaved cause can never be hidden while its fields still submit. */
.settlement-wastes--empty:not([open]) {
  display: none;
}

.settlement-wastes__summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: var(--radius);
  padding: 3px 8px 3px 4px;
  color: var(--muted-foreground);
  font-size: 11.5px;
  font-weight: 600;
  list-style: none;
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease;
}

.settlement-wastes__summary::-webkit-details-marker {
  display: none;
}

.settlement-wastes__summary:hover {
  color: var(--foreground);
  background: color-mix(in srgb, var(--foreground) 6%, transparent);
}

.settlement-wastes__chevron {
  color: var(--muted-foreground);
  transition: transform 0.15s ease;
}

.settlement-wastes[open] .settlement-wastes__chevron {
  transform: rotate(90deg);
}

/* The captured count doubles as the "there is something in here" cue when the
   panel is closed, so it keeps its weight against the muted summary. */
.settlement-wastes__count:not(:empty) {
  border-radius: 999px;
  padding: 1px 7px;
  background: color-mix(in srgb, var(--foreground) 8%, transparent);
  color: var(--foreground);
  font-variant-numeric: tabular-nums;
}

.settlement-wastes__panel {
  display: grid;
  gap: 8px;
  margin: 4px 0 2px;
  border-left: 2px solid color-mix(in srgb, var(--border) 85%, transparent);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: color-mix(in srgb, var(--foreground) 3.5%, transparent);
  padding: 10px 12px;
}

.settlement-wastes__legacy {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 11.5px;
}

.settlement-wastes__rows {
  display: grid;
  gap: 6px;
}

.settlement-waste-row {
  display: grid;
  align-items: center;
  gap: 8px;
  /* Sized to the content, not the table: a cause label is short and the panel is
     as wide as the product row, so a stretched picker would read as a form. */
  grid-template-columns: minmax(190px, 320px) 104px auto auto;
  justify-content: start;
}

.settlement-waste-row select,
.settlement-waste-row input[type="number"] {
  width: 100%;
  min-height: 38px;
}

.settlement-waste-row__qty input {
  text-align: right;
}

/* The native file input is hidden behind this label (same idiom as the customer
   photo picker) — "Choose File / No file chosen" is browser chrome we can
   neither translate nor size. */
.settings-form .settlement-waste-row__photo {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  position: relative;
  min-height: 38px;
  border: 1px dashed color-mix(in srgb, var(--border) 92%, var(--foreground));
  border-radius: var(--radius);
  padding: 0 10px;
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.settlement-waste-row__photo:hover,
.settlement-waste-row__photo:focus-within {
  color: var(--foreground);
  border-color: color-mix(in srgb, var(--foreground) 40%, var(--border));
}

/* A cause that demands a photo on the phone only asks for one here. */
.settlement-waste-row__photo.is-required {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  color: var(--primary);
}

.settlement-waste-row__photo-label {
  max-width: 130px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settlement-waste-row__photo-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.settlement-waste-row__photo-link,
.settlement-waste-row__remove {
  display: grid;
  place-items: center;
  width: 38px;
  min-height: 38px;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.settlement-waste-row__photo-link:hover {
  color: var(--foreground);
}

.settlement-waste-row__remove:hover {
  color: var(--destructive);
  border-color: color-mix(in srgb, var(--destructive) 45%, var(--border));
  background: color-mix(in srgb, var(--destructive) 8%, var(--card));
}

.settlement-waste-row__remove:focus-visible {
  outline: none;
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 22%, transparent);
}

.settlement-wastes__add {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  justify-self: start;
  border: 0;
  background: transparent;
  padding: 2px 0;
  color: var(--primary);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

.settlement-wastes__add:hover {
  text-decoration: underline;
}

/* The same breakdown, read-only, on the settled screens: one cause per line
   under the quantity, so the column still scans as a number. */
.settlement-waste-causes {
  display: grid;
  gap: 1px;
  margin-top: 2px;
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 400;
  white-space: normal;
}

.settlement-waste-causes__quantity {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* Barcode scanning above the settlement count: a camera toggle, the code box a
   scanner gun types into, and the live camera preview it reads from. See
   barcode_scan_controller.js. */
.scan-bar {
  display: grid;
  gap: 8px;
  margin-bottom: 14px;
}

.scan-bar__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

/* Only the sizing differs from the product filter it shares its look with: the
   code box grows with the toolbar and shows codes in tabular figures. */
.scan-bar__field {
  flex: 1 1 200px;
  max-width: 260px;
}

.scan-bar__input {
  width: 100%;
  font-variant-numeric: tabular-nums;
}

.scan-bar__viewport {
  position: relative;
  max-width: 420px;
  overflow: hidden;
  background: #000;
  border: 1px solid var(--border);
  border-radius: 10px;
}

.scan-bar__video {
  display: block;
  width: 100%;
  max-height: 260px;
  object-fit: cover;
}

.scan-bar .scan-bar__close {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  color: #fff;
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 999px;
  cursor: pointer;
}

/* On a phone the camera is the working surface, so it spans the whole screen
   instead of sitting inside the page gutter, and gets more height to aim with. */
@media (max-width: 640px) {
  .scan-bar__viewport:not([hidden]) {
    width: 100vw;
    max-width: 100vw;
    margin-inline: calc(50% - 50vw);
    border-inline: 0;
    border-radius: 0;
  }

  .scan-bar__video {
    max-height: 340px;
  }
}

/* On a desktop the count runs down a long table, so the camera floats at the top
   centre of the screen and stays there while the page scrolls under it (the
   route-operation form's topbar is not pinned, so nothing is covered). On phones
   it stays inline: the table is one card per product and the toolbar sits right
   above it. */
@media (min-width: 641px) {
  .scan-bar__viewport:not([hidden]) {
    position: fixed;
    top: 16px;
    left: 50%;
    z-index: 12;
    width: min(420px, calc(100vw - 32px));
    transform: translateX(-50%);
    box-shadow: var(--shadow);
  }
}

/* The capture card each read opens over the video: which product was scanned and
   the quantity box, so product after product is counted without leaving the
   camera. Always dark — it sits on the camera image, not on the page. */
.scan-overlay {
  position: absolute;
  inset: auto 0 0 0;
  display: grid;
  gap: 6px;
  padding: 10px 12px;
  color: #fff;
  background: color-mix(in srgb, #000 78%, transparent);
}

.scan-overlay__product {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
}

.scan-overlay__expected {
  margin: 0;
  color: rgba(255, 255, 255, 0.75);
  font-size: 12px;
}

.scan-overlay__expected:empty {
  display: none;
}

.scan-overlay__input {
  width: 100%;
  padding: 8px 10px;
  color: #fff;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 8px;
  outline: none;
}

.scan-overlay__input::placeholder {
  color: rgba(255, 255, 255, 0.6);
}

.scan-overlay__input:focus {
  border-color: #fff;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.18);
}

.scan-overlay__actions {
  display: flex;
  gap: 8px;
}

/* The overlay lives on the camera image, so its buttons carry their own light-on
   dark palette instead of the page's (which the surrounding form restyles). */
.scan-overlay__actions .button {
  padding: 7px 12px;
  color: #111;
  font-size: 13px;
  font-weight: 600;
  background: #fff;
  border: 1px solid transparent;
  border-radius: 6px;
}

.scan-overlay__actions .button--ghost {
  color: #fff;
  background: transparent;
  border-color: rgba(255, 255, 255, 0.45);
}

.scan-bar__status {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.4;
}

.scan-bar__status.is-ok {
  color: #16a34a;
}

.scan-bar__status.is-error {
  color: #dc2626;
}

/* Denser, borderless table for the product loader on the route-create screen and
   on the price-list form (desktop). An account can load or reprice tens of
   products, so it reads as a table — a header rule and light row dividers —
   without adding another boxed container inside the section. The mobile
   stacked-card layout (<= 640px) is untouched. */
@media (min-width: 641px) {
  .route-create-form .operation-loader__head,
  .route-create-form .operation-load-row {
    grid-template-columns: minmax(0, 1fr) 120px 40px;
    gap: 10px;
  }

  /* Same three-column table, one wider amount column: "PRECIO ESPECIAL" is a
     longer caption than "CARGA"/"CANTIDAD" and the values carry two decimals. */
  .price-list-form .operation-loader__head,
  .price-list-form .operation-load-row {
    grid-template-columns: minmax(0, 1fr) 140px 40px;
    gap: 10px;
  }

  /* The purchase loader carries an extra "Costo unitario" column; without this
     override the generic three-column rule above wins (same specificity, later
     in the cascade than the base --purchase rule) and crushes the cost input
     into the 40px remove slot. */
  .route-create-form .operation-loader--purchase .operation-loader__head,
  .route-create-form .operation-loader--purchase .operation-load-row {
    grid-template-columns: minmax(0, 1fr) 120px 120px 40px;
  }

  .route-create-form .operation-loader__head,
  .price-list-form .operation-loader__head {
    align-items: center;
    padding: 0 2px 8px;
    border-bottom: 1px solid color-mix(in srgb, var(--border) 62%, transparent);
  }

  .route-create-form .operation-loader__rows,
  .price-list-form .operation-loader__rows {
    gap: 0;
  }

  .route-create-form .operation-load-row,
  .price-list-form .operation-load-row {
    align-items: center;
    padding: 5px 2px;
    border-bottom: 1px solid color-mix(in srgb, var(--border) 34%, transparent);
  }

  .route-create-form .operation-load-row:last-child,
  .price-list-form .operation-load-row:last-child {
    border-bottom: 0;
  }

  .route-create-form .operation-loader .autocomplete-input,
  .route-create-form .operation-load-row__qty input,
  .price-list-form .operation-loader .autocomplete-input,
  .price-list-form .operation-load-row__qty input {
    min-height: 36px;
    padding: 7px 10px;
  }

  .route-create-form .autocomplete-picker--inline .autocomplete-chosen,
  .price-list-form .autocomplete-picker--inline .autocomplete-chosen {
    min-height: 36px;
  }

  .route-create-form .operation-load-row__remove,
  .price-list-form .operation-load-row__remove {
    min-height: 36px;
  }

  .route-create-form .operation-loader__add,
  .price-list-form .operation-loader__add {
    margin: 12px 2px 0;
  }
}

/* Route create/edit/detail go edge-to-edge on phones, like the routes board:
   `.catalog-main` already drops the outer panel chrome; here we flatten the inner
   cards too so the form/detail spends the full width on data instead of stacking
   nested boxes. The card's side gutter collapses onto the parent's single gutter
   (the `.catalog-main .settings-form` 14px on the forms, `.route-op__body` on the
   detail), and the top/bottom borders stay as section dividers. */
@media (max-width: 720px) {
  /* Descendant, not child: on the edit/settlement screen the banner renders
     inside `.home-panel.route-create`, which carries no gutter of its own. */
  .catalog-main .integrity-route-banner {
    margin-right: 14px;
    margin-left: 14px;
  }

  .integrity-route-banner__header {
    grid-template-columns: auto minmax(0, 1fr);
    padding: 0.8rem 0.875rem;
  }

  .integrity-route-banner__total {
    grid-column: 2;
    grid-template-columns: auto auto;
    justify-content: start;
    gap: 0.4rem;
    align-items: baseline;
    text-align: left;
  }

  .integrity-route-banner__item {
    padding-right: 0.875rem;
    padding-left: 0.875rem;
  }

  .catalog-main .settings-form .settings-grid {
    gap: 10px;
  }

  .catalog-main .settings-form .settings-card,
  .catalog-main .home-panel > .settings-card {
    border-right: 0;
    border-left: 0;
    border-radius: 0;
    padding-right: 0;
    padding-left: 0;
  }

  .catalog-main .settings-card > h2,
  .catalog-main .settings-card > p {
    padding-right: 14px;
    padding-left: 14px;
  }

  .catalog-main .settings-form .tidy-grid,
  .catalog-main .settings-form .field-grid,
  .catalog-main .settings-form .selection-grid,
  .catalog-main .settings-form .reward-row,
  .catalog-main .settings-form .check-list,
  .catalog-main .settings-form .operation-loader,
  .catalog-main .settings-form .reconcile,
  .catalog-main .home-panel > .settings-card .adjustment-facts,
  .catalog-main .home-panel > .settings-card .operation-items,
  .catalog-main .home-panel > .settings-card .reconcile {
    padding-right: 14px;
    padding-left: 14px;
  }

  .catalog-main .promo-selection-grid,
  .catalog-main .promo-form .reward-row,
  .catalog-main .reward-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .catalog-main .promo-form .reward-row__destroy {
    align-self: stretch;
  }

  .catalog-main .route-create-card,
  .catalog-main .route-operation-form .settings-card,
  .catalog-main .route-op__body .settings-card {
    border-right: 0;
    border-left: 0;
    border-radius: 0;
    padding-right: 0;
    padding-left: 0;
  }

  /* The lifecycle deck sits outside `.route-op__body`, so it was the one block
     with no side gutter — its card ran edge to edge while everything under it
     stopped 14px short, which reads as the deck being misaligned rather than as
     deliberate bleed. */
  .catalog-main .routeflow-stack {
    padding-right: 14px;
    padding-left: 14px;
  }
}

@media (max-width: 640px) {
  .route-op__header {
    gap: 14px;
    padding-right: 14px;
    padding-left: 14px;
  }

  /* One row, always. Wrapped, the icon actions dropped a second line carrying a
     single lonely button (usually the destructive one) under the group they
     belong to. Anything that genuinely will not fit scrolls sideways instead of
     breaking the line — with up to six actions that is rare, and a partly
     visible button reads as "there is more here" where a stray one below does
     not. */
  .route-op__actions {
    width: 100%;
    justify-content: flex-start;
    flex-wrap: nowrap;
    gap: 7px;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .route-op__actions::-webkit-scrollbar {
    display: none;
  }

  .route-op__actions form {
    display: flex;
    flex: 0 0 auto;
    margin: 0;
  }

  .route-op__action--compact {
    width: 40px;
    min-width: 40px;
    flex: 0 0 40px;
    padding: 0;
  }

  /* Labelled actions keep their natural size. Letting them shrink to share the
     row squeezed "Editar" into a sliver of a button; if the whole row will not
     fit, it scrolls (above) rather than crushing the one action that matters. */
  .route-op__action--primary,
  .route-op__action--secondary {
    flex: 0 0 auto;
    white-space: nowrap;
  }

  .route-op__action--compact > span {
    display: none;
  }

  .route-op__action--compact .icon {
    width: 15px;
    height: 15px;
  }


  /* The settlement form is a stack of short sections, and between the form's own
     18px gap, each section's 20px top padding and the head's 16px bottom margin
     there was more blank space between two rows of figures than the figures
     themselves occupied. Tighten all three on a phone; the divider rule is what
     separates the sections, not the air around it. */
  .route-create-card {
    padding: 16px;
  }

  /* Scoped to `.route-operation-form`, not `.route-create-form`: the latter also
     dresses the load-template, recarga, purchase and transfer forms, which are
     ordinary field forms that want the roomier rhythm. This one is a stack of
     short figure strips and tables where the air between sections outweighed the
     figures themselves. */
  .catalog-main .route-operation-form {
    gap: 10px;
  }

  .catalog-main .route-operation-form .route-create-card + .route-create-card {
    padding-top: 12px;
  }

  .catalog-main .route-operation-form .route-create-card__head {
    margin-bottom: 10px;
  }

  .catalog-main .route-operation-form .route-create-card__head p {
    margin-top: 2px;
  }

  /* Stacked, the base `align-items: center` would centre the heading over its
     action row; keep both flush left and let the actions span the width. */
  .route-create-card__head--load {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .operation-loader__head {
    display: none;
  }

  /* Stack each product into its own block: the search spans the full width, then
     a labeled quantity field shares a row with the remove button. The previous
     three-column grid squeezed the quantity input too narrow to actually load a
     quantity on a phone. */
  .operation-loader__rows {
    gap: 14px;
  }

  .operation-load-row {
    grid-template-columns: minmax(0, 1fr) 52px;
    grid-template-areas:
      "product product"
      "qty     remove";
    gap: 10px;
    align-items: end;
    padding: 12px;
    border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--muted) 22%, var(--card));
  }

  .operation-load-row__product {
    grid-area: product;
  }

  .operation-load-row__qty {
    grid-area: qty;
    display: grid;
    gap: 4px;
  }

  /* Surface the otherwise sr-only "Carga" caption so the stacked field is labeled. */
  .operation-load-row__qty .operation-load-row__label {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip: auto;
    clip-path: none;
    white-space: normal;
    color: var(--muted-foreground);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }

  .operation-loader--purchase .operation-load-row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 52px;
    grid-template-areas:
      "product product product"
      "qty     cost    remove";
  }

  .operation-loader--transfer .operation-load-row {
    grid-template-columns: minmax(0, 1fr) 52px;
    grid-template-areas:
      "product product"
      "qty     remove";
  }

  .operation-load-row__cost {
    grid-area: cost;
  }

  .operation-load-row__mobile-label {
    display: block;
    margin-bottom: 4px;
    color: var(--muted-foreground);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }

  .catalog-main .operation-items--inventory-purchase,
  .catalog-main .operation-items--inventory-transfer {
    overflow-x: visible;
  }

  .catalog-main .operation-items--inventory-purchase .operation-items__head,
  .catalog-main .operation-items--inventory-transfer .operation-items__head {
    display: none;
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row,
  .catalog-main .operation-items--inventory-transfer .operation-item-row {
    min-width: 0;
    gap: 8px 10px;
    border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--muted) 18%, var(--card));
    padding: 10px;
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-areas:
      "product product product"
      "qty     cost    total"
      "ledger  ledger  ledger";
  }

  .catalog-main .operation-items--inventory-transfer .operation-item-row {
    grid-template-columns: minmax(0, 1fr) minmax(72px, auto);
    grid-template-areas: "product qty";
    align-items: center;
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row > :nth-child(1),
  .catalog-main .operation-items--inventory-transfer .operation-item-row > :nth-child(1) {
    grid-area: product;
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row > :nth-child(2),
  .catalog-main .operation-items--inventory-transfer .operation-item-row > :nth-child(2) {
    grid-area: qty;
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row > :nth-child(3) {
    grid-area: cost;
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row > :nth-child(4) {
    grid-area: total;
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row > :nth-child(5) {
    grid-area: ledger;
  }

  .catalog-main .operation-items--inventory-purchase .route-operation-item-value,
  .catalog-main .operation-items--inventory-transfer .route-operation-item-value {
    display: grid;
    gap: 2px;
    justify-items: start;
    min-width: 0;
    font-size: 13px;
    font-weight: 700;
  }

  /* The mobile card re-asserts 700 for both lists; only the ingreso list is
     demoted here, so the transfer screen keeps its current weight. */
  .catalog-main .operation-items--inventory-purchase .route-operation-item-value {
    font-weight: 500;
  }

  .catalog-main .operation-items--inventory-transfer .route-operation-item-value {
    justify-items: end;
    text-align: right;
  }

  .catalog-main .operation-items--inventory-purchase .route-operation-item-value::before,
  .catalog-main .operation-items--inventory-transfer .route-operation-item-value::before {
    color: var(--muted-foreground);
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row > :nth-child(2)::before,
  .catalog-main .operation-items--inventory-transfer .operation-item-row > :nth-child(2)::before {
    content: "Cantidad";
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row > :nth-child(3)::before {
    content: "Costo";
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row > :nth-child(4)::before {
    content: "Total";
  }

  .catalog-main .operation-items--inventory-purchase .operation-item-row > :nth-child(5)::before {
    content: "Almacén";
  }

  .operation-load-row__qty input {
    width: 100%;
    min-height: 44px;
  }

  .operation-load-row__remove {
    grid-area: remove;
    width: 100%;
    min-height: 44px;
  }

  .route-create-actions {
    flex-direction: column-reverse;
  }

  .route-create-actions .button {
    width: 100%;
  }

  /* On a phone the reconciliation stays a table and scrolls sideways. It used to
     collapse into one labeled card per product, and a settlement is not read
     that way: you compare a column down the list, and every product had become
     a block to scroll past. The columns are ordered so the four that decide the
     count — esperado, recibido, merma de almacén, diferencia — are the ones on
     screen, with the route context that produced them off to the right. The
     product name is pinned to the left edge so a row stays identifiable while
     the numbers scroll under it.

     `min-width: auto` on a grid/flex item is its CONTENT minimum, and that row
     is deliberately wider than the screen — so without this the table pushes
     every ancestor out and the whole page scrolls sideways (the settlement
     figures and the carga table slide off with it) instead of just the table.
     Only the scroll container may be the one that gives. */
  .route-op__body,
  .route-op__body > *,
  .route-operation-settlement,
  .route-operation-settlement > *,
  .route-create-card,
  .reconcile-block,
  .reconcile {
    min-width: 0;
  }

  /* …and even contained, a sideways-scrolling grid still hands part of its
     scrollable overflow up to the document, so the page rubber-bands ~30px onto
     blank space. `contain: paint` stops the propagation at the block that holds
     the scroller (the scroller itself already clips, so nothing that was visible
     is lost). Measured on the corrección screen, where the table is widest. */
  .reconcile,
  .operation-items {
    contain: paint;
  }

  /* The product column is fixed rather than `1.1fr`: given any free space it
     took it, and the four columns that must be on screen lost the pixels that
     decide whether Diferencia is visible or cut in half. The eight numeric
     columns share whatever is left. */
  .reconcile__head,
  .reconcile__row {
    grid-template-columns: 96px repeat(8, minmax(52px, 1fr));
    gap: 6px;
    min-width: 560px;
  }

  /* Esperado · Recibido · Merma alm. · Diferencia have to be readable before any
     scrolling: 96 + 4 × 52 + gaps = 328px, inside the 334px a 390px phone gives
     this table — and the ~30px of the next column left showing is what says
     there is more to the right. */
  .reconcile__head {
    font-size: 9.5px;
    letter-spacing: 0.02em;
  }

  /* Swap in the short heading for the columns whose full word does not fit —
     "DIFERENCIA" wrapped to two lines and still clipped. `font-size: 0` on the
     cell collapses the real text; the pseudo-element carries the short one. */
  .reconcile__head span[data-short] {
    font-size: 0;
  }

  .reconcile__head span[data-short]::before {
    content: attr(data-short);
    font-size: 9.5px;
  }

  .reconcile__cell {
    font-size: 12.5px;
  }

  /* Sticky needs something opaque behind it, and the head sits on the card while
     the rows carry the hairline rule the sticky cell must not paint over. */
  .reconcile__head > span:first-child,
  .reconcile__cell--product {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--card);
    font-size: 12px;
  }

  .reconcile__cell--input input {
    min-height: 36px;
    padding: 6px 7px;
  }

  /* The causes panel spans the row, and the row is wider than the screen — so it
     stays with the left edge and takes exactly the width on show, rather than
     sitting 500px off to the right. `100cqi` is the scrollport's own width:
     deriving it from `100vw` means subtracting every gutter between the viewport
     and this table by hand, and being 28px wrong cuts the delete button off the
     end of each cause row. */
  .reconcile__scroll {
    container-type: inline-size;
  }

  .settlement-wastes {
    position: sticky;
    left: 0;
    width: 100cqi;
  }

  /* A cause row cannot keep four columns on a phone: the picker takes the width
     and the quantity, photo and trash share the line under it. */
  .settlement-waste-row {
    grid-template-columns: 110px 1fr auto;
  }

  .settlement-waste-row__reason {
    grid-column: 1 / -1;
  }

  .settlement-waste-row__photo {
    justify-content: center;
  }
}

.card-title-row {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.route-list {
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: var(--radius);
  overflow: hidden;
}

.route-row {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  min-height: 58px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 10px 12px 10px 16px;
}

.route-row:last-child {
  border-bottom: 0;
}

.route-row::before {
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  content: "";
}

.route-row--green::before {
  background: #10b981;
}

.route-row--blue::before {
  background: #3b82f6;
}

.route-row--purple::before {
  background: #8b5cf6;
}

.route-row--amber::before {
  background: #f59e0b;
}

.route-row strong {
  display: block;
  font-size: 14px;
  line-height: 1.25;
}

.route-row span,
.route-row em {
  color: var(--muted-foreground);
  font-size: 12px;
  font-style: normal;
  line-height: 1.35;
}

.stack-list {
  display: grid;
  gap: 0;
  margin: 12px 0 0;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: var(--radius);
  overflow: hidden;
}

.stack-list div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 10px 12px;
  font-size: 12px;
}

.stack-list div:last-child {
  border-bottom: 0;
}

.stack-list dt {
  color: var(--muted-foreground);
}

.stack-list dd {
  margin: 0;
  font-weight: 700;
  text-align: right;
}

/* The tabs row mirrors `.home-topbar__row`: an identical `1fr <center> 1fr`
   grid so the centered tab strip and the centered command bar above it share
   the exact same geometric center. Relying on the same grid mechanism (rather
   than a flex `align-self`) keeps the two locked together in every renderer,
   including the native desktop wrapper. */
.assistant-tabs {
  display: grid;
  grid-template-columns: minmax(0, 1fr) min(100%, 600px) minmax(0, 1fr);
  align-items: center;
}

.assistant-tabs__list {
  grid-column: 2;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, var(--card) 72%, transparent);
  box-shadow: 0 1px 2px rgb(0 0 0 / 4%);
  padding: 4px;
}

.catalog-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 12px;
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 16px 24px 24px;
}

.catalog-list__item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  padding: 16px;
  box-shadow: 0 1px 1px rgb(15 23 42 / 3%);
  transition: background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
}

.catalog-list__item:hover {
  border-color: color-mix(in srgb, var(--primary) 18%, var(--border));
  box-shadow: var(--shadow);
}

.catalog-list__item:hover .catalog-list__chevron {
  color: var(--foreground);
  transform: translateX(2px);
}

.catalog-list__icon {
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: var(--radius);
  background: var(--muted);
  color: var(--muted-foreground);
}

.catalog-list__icon .icon {
  width: 19px;
  height: 19px;
}

.catalog-list__body {
  min-width: 0;
}

.catalog-list__item strong {
  display: block;
  font-size: 15px;
  line-height: 1.3;
}

.catalog-list__item p {
  margin: 3px 0 0;
  color: var(--muted-foreground);
  font-size: 13px;
  line-height: 1.4;
}

.catalog-list__chevron {
  display: grid;
  place-items: center;
  color: color-mix(in srgb, var(--muted-foreground) 70%, transparent);
  transition: color 120ms ease, transform 120ms ease;
}

.catalog-list__chevron .icon {
  width: 18px;
  height: 18px;
}

.assistant-main {
  width: min(100%, 1300px);
  height: calc(100dvh - var(--app-shell-topbar-height) - var(--app-shell-top-inset));
  min-height: 0;
  margin: 0 auto;
  padding: 12px 24px var(--app-shell-bottom-gutter);
  display: flex;
  flex-direction: column;
}

.assistant-screen {
  /* One edge for the whole screen, so its children line up on a phone where
     there is no card border left to align against. Only the mobile block reads
     it, but it is declared here: a token defined inside a media block leaves
     every `var()` outside that block invalid, silently. */
  --assistant-gutter: 14px;

  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-rows: auto minmax(0, 1fr);
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 12px;
  background: var(--card);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.assistant-screen__header {
  display: flex;
  min-height: 78px;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 16px 20px;
}

.assistant-screen__header h1,
.assistant-screen__header p {
  margin: 0;
}

.assistant-screen__header h1 {
  font-size: 20px;
  line-height: 1.2;
}

.assistant-screen__header p {
  margin-top: 4px;
  color: var(--muted-foreground);
  font-size: 13px;
  line-height: 1.4;
}

.assistant-screen__tools {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Day navigator: one conversation per calendar day, arrows browse past days. */
.assistant-daynav {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 999px;
  background: var(--muted);
  padding: 2px;
}

.assistant-daynav__button {
  display: inline-flex;
  width: 26px;
  height: 26px;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  color: var(--muted-foreground);
  transition: background 120ms ease, color 120ms ease;
}

.assistant-daynav__button .icon {
  width: 15px;
  height: 15px;
}

a.assistant-daynav__button:hover {
  background: color-mix(in srgb, var(--foreground) 8%, transparent);
  color: var(--foreground);
}

.assistant-daynav__button--disabled {
  opacity: 0.35;
}

.assistant-daynav__label {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--foreground);
  font-size: 12px;
  font-weight: 600;
  padding: 0 8px;
  height: 26px;
  border-radius: 999px;
  white-space: nowrap;
  cursor: pointer;
  transition: background 120ms ease;
}

.assistant-daynav__label:hover {
  background: color-mix(in srgb, var(--foreground) 8%, transparent);
}

.assistant-daynav__icon {
  width: 13px;
  height: 13px;
  color: var(--muted-foreground);
}

/* Native date input covers the label so a click anywhere opens the picker,
   while the styled "Hoy"/date text and calendar icon stay visible beneath it. */
.assistant-daynav__date {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}

.assistant-daynav__date::-webkit-calendar-picker-indicator {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}

/* Header status pill: dot turns primary and pulses while a reply streams. */
.assistant-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 999px;
  background: var(--muted);
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 500;
  padding: 4px 11px;
  white-space: nowrap;
}

.assistant-status::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--success);
  flex: none;
}

.assistant-status[data-state="busy"] {
  color: var(--foreground);
}

.assistant-status[data-state="busy"]::before {
  background: color-mix(in srgb, var(--primary) 80%, var(--foreground));
  animation: assistant-status-pulse 1.2s ease-in-out infinite;
}

@keyframes assistant-status-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.45; transform: scale(0.8); }
}

.assistant-screen__body {
  display: grid;
  min-height: 0;
  grid-template-rows: minmax(0, 1fr) auto auto auto;
  gap: 12px;
  padding: 14px 20px 18px;
}

/* The conversation is the screen's own surface, not a panel drawn on top of it:
   a bordered box here would nest a frame inside the card inside the page, which
   is what made the chat read as broken on a phone. */
.assistant-conversation {
  display: grid;
  align-content: start;
  gap: 14px;
  min-height: 0;
  overflow-y: auto;
  padding: 6px var(--assistant-gutter);
}

/* Nothing said yet: centre the greeting (or the past-day note) in the column
   rather than stacking it at the top of an otherwise empty screen. */
.assistant-conversation:has(> .assistant-welcome, > .assistant-empty-day) {
  /* `safe`: centring a box taller than its own scroll track (landscape phone,
     short window) would push the top past the scroll start edge, where
     `.assistant-screen`'s `overflow: hidden` clips it out of reach. `safe`
     falls back to start alignment exactly then. */
  align-content: safe center;
}

.assistant-history-loader {
  justify-self: center;
}

.assistant-message {
  display: flex;
  min-width: 0;
}

.assistant-message--user {
  justify-content: flex-end;
}

.assistant-message--assistant {
  justify-content: flex-start;
}

.assistant-message__content {
  display: grid;
  width: min(100%, 760px);
  min-width: 0;
  max-width: min(100%, 760px);
  gap: 8px;
}

/* Only the user's turn is a bubble. The reply reads as page text so a long
   answer isn't boxed inside a box, and the eye can tell the two apart at a
   glance without any chrome on the assistant's side. */
.assistant-message--user .assistant-message__content {
  width: auto;
  max-width: min(100%, 560px);
}

.assistant-message__bubble {
  color: var(--foreground);
  font-size: 13.5px;
  line-height: 1.55;
  overflow-wrap: anywhere;
}

.assistant-message--user .assistant-message__bubble {
  border-radius: 14px;
  background: var(--primary);
  color: var(--primary-foreground);
  padding: 9px 13px;
  white-space: pre-wrap;
}

/* In-chat typing indicator: three dots that read well on light and dark. */
.assistant-typing {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 2px;
}

.assistant-typing span {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--foreground) 55%, transparent);
  animation: assistant-typing-bounce 1.2s ease-in-out infinite;
}

.assistant-typing span:nth-child(2) {
  animation-delay: 0.15s;
}

.assistant-typing span:nth-child(3) {
  animation-delay: 0.3s;
}

@keyframes assistant-typing-bounce {
  0%, 60%, 100% {
    opacity: 0.35;
    transform: translateY(0);
  }
  30% {
    opacity: 1;
    transform: translateY(-3px);
  }
}

/* Greeting shown while today's conversation is still empty. It only sizes to its
   own content; the centring belongs to the `:has()` rule above. */
.assistant-welcome {
  display: grid;
  justify-items: center;
  gap: 6px;
  padding: 24px 16px;
  text-align: center;
}

.assistant-welcome__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  margin-bottom: 4px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  color: var(--primary);
}

.assistant-welcome__icon .icon {
  width: 21px;
  height: 21px;
}

.assistant-welcome h2 {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.3;
}

.assistant-welcome p {
  margin: 0;
  max-width: 44ch;
  color: var(--muted-foreground);
  font-size: 13px;
  line-height: 1.5;
}

.assistant-empty-day {
  display: grid;
  place-items: center;
  min-height: 120px;
  color: var(--muted-foreground);
  font-size: 13px;
}

/* Bar shown instead of the composer when browsing a past day's conversation. */
.assistant-readonly-note {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px dashed color-mix(in srgb, var(--border) 90%, transparent);
  border-radius: 10px;
  background: var(--muted);
  color: var(--muted-foreground);
  font-size: 13px;
  padding: 10px 14px;
}

.assistant-readonly-note__icon {
  width: 15px;
  height: 15px;
  flex: none;
}

.assistant-readonly-note__today {
  margin-left: auto;
  color: var(--primary);
  font-weight: 600;
  text-decoration: underline;
  white-space: nowrap;
}

/* Markdown rendered inside assistant bubbles */
.assistant-message__bubble > :first-child {
  margin-top: 0;
}

.assistant-message__bubble > :last-child {
  margin-bottom: 0;
}

.assistant-message__bubble p,
.assistant-message__bubble ul,
.assistant-message__bubble ol,
.assistant-message__bubble pre,
.assistant-message__bubble blockquote,
.assistant-message__bubble table {
  margin: 0 0 8px;
}

/* The base reset strips list markers app-wide; inside a reply they are content,
   and without them a markdown list reads as randomly indented lines. `revert`
   hands the marker back to the browser default, which also keeps the
   disc/circle/square progression a nested list needs. */
.assistant-message__bubble ul,
.assistant-message__bubble ol {
  padding-left: 20px;
  list-style: revert;
}

.assistant-message__bubble li + li {
  margin-top: 2px;
}

.assistant-message__bubble h1,
.assistant-message__bubble h2,
.assistant-message__bubble h3,
.assistant-message__bubble h4 {
  margin: 12px 0 6px;
  line-height: 1.3;
}

.assistant-message__bubble h1 { font-size: 16px; }
.assistant-message__bubble h2 { font-size: 15px; }
.assistant-message__bubble h3 { font-size: 14px; }
.assistant-message__bubble h4 { font-size: 13px; }

.assistant-message__bubble a {
  color: var(--primary);
  text-decoration: underline;
}

.assistant-message__bubble code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  background: color-mix(in srgb, var(--border) 35%, transparent);
  border-radius: 4px;
  padding: 1px 4px;
}

.assistant-message__bubble pre {
  background: color-mix(in srgb, var(--border) 35%, transparent);
  border-radius: 6px;
  padding: 10px;
  overflow-x: auto;
}

.assistant-message__bubble pre code {
  background: none;
  padding: 0;
}

.assistant-message__bubble blockquote {
  border-left: 3px solid color-mix(in srgb, var(--border) 75%, transparent);
  padding-left: 10px;
  color: color-mix(in srgb, var(--foreground) 75%, transparent);
}

.assistant-message__bubble table {
  border-collapse: collapse;
  font-size: 12px;
}

.assistant-message__bubble th,
.assistant-message__bubble td {
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  padding: 4px 8px;
  text-align: left;
}

.assistant-message__artifacts,
.assistant-artifacts {
  display: flex;
  width: 100%;
  min-width: 0;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 0;
}

.assistant-chart {
  flex: 1 1 100%;
  width: min(100%, 760px);
  min-width: 0;
  max-width: 760px;
  margin: 2px 0 0;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 12px;
  background: var(--card);
}

.assistant-chart__canvas {
  width: 100%;
  min-height: 320px;
}

.assistant-chart__status {
  padding: 14px;
  color: var(--muted-foreground);
  font-size: 12px;
  text-align: center;
}

.assistant-artifact {
  display: inline-flex;
  max-width: min(100%, 260px);
  min-height: 28px;
  align-items: center;
  gap: 6px;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 999px;
  background: var(--card);
  color: var(--foreground);
  font-size: 12px;
  font-weight: 600;
  padding: 0 10px;
  text-decoration: none;
}

.assistant-artifact:hover {
  background: var(--muted);
}

.assistant-artifact__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The small document glyph on an attachment chip or a download link. Muted so
   the file name stays the thing you read. */
.assistant-file-icon {
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
  color: var(--muted-foreground);
}

.assistant-suggestions {
  display: flex;
  min-height: 30px;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 2px;
}

.assistant-suggestions button {
  min-height: 28px;
  flex: 0 0 auto;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 999px;
  background: var(--muted);
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: 12px;
  padding: 0 10px;
  white-space: nowrap;
}

.assistant-suggestions button:hover:not(:disabled) {
  color: var(--foreground);
  background: color-mix(in srgb, var(--muted) 70%, var(--card));
}

.assistant-suggestions button:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

.assistant-suggestion {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.assistant-suggestion .icon {
  width: 14px;
  height: 14px;
  flex: none;
}

.assistant-suggestion--catalog {
  color: var(--foreground) !important;
  background: var(--card) !important;
}

.assistant-suggestion--favorite {
  color: var(--foreground) !important;
}

.assistant-suggestion--favorite .icon {
  color: #f59e0b;
  fill: currentColor;
}

.assistant-prompt-dialog {
  width: min(960px, calc(100vw - 32px));
  max-height: min(820px, calc(100dvh - 40px));
  border: 0;
  border-radius: 14px;
  background: transparent;
  color: var(--foreground);
  padding: 0;
}

.assistant-prompt-dialog::backdrop {
  background: rgb(15 23 42 / 48%);
}

.assistant-prompt-dialog__shell {
  display: grid;
  height: min(820px, calc(100dvh - 40px));
  grid-template-rows: auto auto minmax(0, 1fr);
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 14px;
  background: var(--card);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.assistant-prompt-dialog__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 18px 20px;
}

.assistant-prompt-dialog__header h2,
.assistant-prompt-dialog__header p,
.assistant-prompt-form h3,
.assistant-prompt-form p {
  margin: 0;
}

.assistant-prompt-dialog__header h2 {
  font-size: 18px;
  font-weight: 650;
  line-height: 1.25;
}

.assistant-prompt-dialog__header p,
.assistant-prompt-form p {
  margin-top: 4px;
  color: var(--muted-foreground);
  font-size: 13px;
  line-height: 1.4;
}

.assistant-prompt-dialog__search {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 10px 20px;
}

.assistant-prompt-dialog__search .icon {
  width: 16px;
  height: 16px;
  color: var(--muted-foreground);
}

.assistant-prompt-dialog__search input {
  width: 100%;
  border: 0;
  background: transparent;
  color: var(--foreground);
  font: inherit;
  font-size: 14px;
  outline: 0;
  padding: 7px 0;
}

.assistant-prompt-dialog__body {
  display: grid;
  min-height: 0;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 16px;
  background: var(--muted);
  padding: 16px;
}

.assistant-prompt-list {
  display: grid;
  align-content: start;
  gap: 14px;
  min-height: 0;
  overflow-y: auto;
  padding-right: 2px;
}

.assistant-prompt-list[aria-busy="true"] {
  opacity: 0.65;
}

.assistant-catalog-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  color: var(--muted-foreground);
  font-size: 12px;
  padding-top: 10px;
}

.assistant-catalog-pagination--single {
  justify-content: flex-start;
}

.assistant-prompt-group {
  display: grid;
  gap: 8px;
}

.assistant-prompt-group[hidden] {
  display: none;
}

.assistant-prompt-group__title {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.25;
}

.assistant-prompt-group__items {
  display: grid;
  gap: 10px;
}

.assistant-prompt-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 8px;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: 8px;
  background: var(--card);
  padding: 10px;
}

.assistant-prompt-card[hidden] {
  display: none;
}

.assistant-prompt-card--favorite {
  border-color: color-mix(in srgb, #f59e0b 45%, var(--border));
}

.assistant-prompt-card__actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.assistant-prompt-card__favorite-form {
  margin: 0;
}

.assistant-prompt-card__favorite,
.assistant-prompt-card__edit {
  display: inline-flex;
  width: 30px;
  height: 30px;
  align-items: center;
  justify-content: center;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 8px;
  background: var(--muted);
  color: var(--muted-foreground);
  cursor: pointer;
  padding: 0;
}

.assistant-prompt-card__favorite .icon,
.assistant-prompt-card__edit .icon {
  width: 15px;
  height: 15px;
}

.assistant-prompt-card__favorite.is-favorite {
  border-color: color-mix(in srgb, #f59e0b 55%, var(--border));
  color: #f59e0b;
}

.assistant-prompt-card__favorite.is-favorite .icon {
  fill: currentColor;
}

.assistant-prompt-card__edit:hover,
.assistant-prompt-card__favorite:hover {
  color: var(--foreground);
  background: color-mix(in srgb, var(--muted) 70%, var(--card));
}

.assistant-prompt-card__run {
  display: grid;
  min-width: 0;
  gap: 6px;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  padding: 0;
  text-align: left;
}

.assistant-prompt-card__title {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.25;
}

.assistant-prompt-card__body {
  display: -webkit-box;
  overflow: hidden;
  color: var(--muted-foreground);
  font-size: 12.5px;
  line-height: 1.45;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

.assistant-prompt-card__meta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: color-mix(in srgb, var(--muted-foreground) 86%, var(--foreground));
  font-size: 11.5px;
  font-weight: 400;
}

.assistant-prompt-card__meta .icon {
  width: 13px;
  height: 13px;
}

.assistant-prompt-list__empty {
  display: grid;
  min-height: 160px;
  place-items: center;
  border: 1px dashed color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 8px;
  color: var(--muted-foreground);
  font-size: 13px;
}

.assistant-prompt-form {
  display: grid;
  align-content: start;
  gap: 12px;
  min-height: 0;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 8px;
  background: var(--card);
  overflow-y: auto;
  padding: 14px;
}

.assistant-prompt-form h3 {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.25;
}

.assistant-prompt-form label {
  display: grid;
  gap: 6px;
  color: var(--foreground);
  font-size: 12px;
  font-weight: 500;
}

.assistant-prompt-form input,
.assistant-prompt-form textarea,
.assistant-prompt-form select {
  width: 100%;
  border: 1px solid color-mix(in srgb, var(--border) 85%, transparent);
  border-radius: 8px;
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  font-weight: 400;
  font-size: 13px;
  line-height: 1.4;
  outline: 0;
  padding: 9px 10px;
}

.assistant-prompt-form textarea {
  min-height: 148px;
  resize: vertical;
}

.assistant-prompt-form input:focus,
.assistant-prompt-form textarea:focus,
.assistant-prompt-form select:focus {
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 18%, transparent);
}

.assistant-prompt-form__footer {
  display: flex;
  position: sticky;
  bottom: -14px;
  justify-content: flex-end;
  gap: 8px;
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  background: var(--card);
  padding-top: 10px;
  padding-bottom: 2px;
}

/* The native file control follows the browser chrome otherwise — give the picker
   button the app's small-ghost-button look and mute the filename text. */
.assistant-prompt-form input[type="file"] {
  color: var(--muted-foreground);
}

.assistant-prompt-form input[type="file"]::file-selector-button {
  margin-right: 8px;
  border: 1px solid color-mix(in srgb, var(--border) 85%, transparent);
  border-radius: 6px;
  background: var(--muted);
  color: var(--foreground);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
}

.assistant-prompt-form__hint {
  color: var(--muted-foreground);
  font-size: 11.5px;
  font-weight: 400;
}

.assistant-prompt-form__schedule {
  display: grid;
  gap: 10px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 8px;
  padding: 10px 12px 12px;
}

.assistant-prompt-form__schedule legend {
  color: var(--foreground);
  font-size: 12px;
  font-weight: 600;
  padding: 0 4px;
}

.assistant-prompt-form__schedule-toggle {
  display: flex !important;
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

.assistant-prompt-form__schedule-toggle input[type="checkbox"] {
  width: auto;
  margin: 0;
}

.assistant-prompt-form__schedule-fields {
  display: grid;
  gap: 10px;
}

.assistant-prompt-form__schedule-fields[hidden] {
  display: none;
}

.assistant-prompt-card__files {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.assistant-prompt-card__file {
  display: inline-flex;
  max-width: 100%;
  align-items: center;
  gap: 5px;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 999px;
  background: var(--muted);
  color: var(--muted-foreground);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.2;
  padding: 3px 8px;
}

.assistant-prompt-card__file .icon {
  width: 12px;
  height: 12px;
  flex: none;
}

.assistant-prompt-card__file-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.assistant-prompt-card__file-remove-form {
  display: inline-flex;
  margin: 0;
}

.assistant-prompt-card__file-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  padding: 0;
}

.assistant-schedule-list__items {
  display: grid;
  gap: 8px;
}

.assistant-schedule-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 10px;
  background: var(--card);
  padding: 10px 12px;
}

.assistant-schedule-row--paused {
  opacity: 0.65;
}

.assistant-schedule-row__info {
  display: grid;
  min-width: 0;
  gap: 4px;
}

.assistant-schedule-row__title {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.25;
}

.assistant-schedule-row__meta {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  color: var(--muted-foreground);
  font-size: 11.5px;
  font-weight: 400;
}

.assistant-schedule-row__meta .icon {
  width: 13px;
  height: 13px;
}

.assistant-schedule-row__error {
  color: #dc2626;
}

.assistant-schedule-row__actions {
  display: flex;
  flex: none;
  gap: 6px;
}

.assistant-schedule-row__action-form {
  margin: 0;
}

.assistant-input {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 8px;
  align-items: end;
  border: 1px solid color-mix(in srgb, var(--border) 85%, transparent);
  border-radius: 14px;
  background: var(--card);
  box-shadow: 0 1px 2px rgb(0 0 0 / 4%);
  padding: 8px 8px 8px 14px;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.assistant-input__body {
  display: grid;
  min-width: 0;
  gap: 6px;
}

.assistant-input__files {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-top: 1px;
}

.assistant-input__files[hidden] {
  display: none;
}

.assistant-input__file {
  display: inline-flex;
  max-width: min(100%, 220px);
  min-height: 24px;
  align-items: center;
  gap: 5px;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 999px;
  background: var(--muted);
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  overflow: hidden;
  padding: 0 9px;
  white-space: nowrap;
}

.assistant-input__file-name {
  overflow: hidden;
  text-overflow: ellipsis;
}

.assistant-input:focus-within {
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 22%, transparent);
}

.assistant-input textarea {
  width: 100%;
  min-height: 38px;
  max-height: 160px;
  resize: none;
  border: 0;
  background: transparent;
  color: var(--foreground);
  font-family: inherit;
  font-size: 14px;
  line-height: 1.5;
  outline: none;
  padding: 8px 0;
}

.assistant-input textarea::placeholder {
  color: var(--muted-foreground);
}

.assistant-input__attach,
.assistant-input__send {
  display: inline-flex;
  width: 36px;
  height: 36px;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 999px;
  background: var(--primary);
  color: var(--primary-foreground);
  cursor: pointer;
  margin-bottom: 1px;
  transition: opacity 120ms ease, transform 120ms ease;
}

.assistant-input__attach {
  position: relative;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  background: var(--muted);
  color: var(--muted-foreground);
}

.assistant-input__attach input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

.assistant-input__attach:hover {
  color: var(--foreground);
  background: color-mix(in srgb, var(--muted) 70%, var(--card));
}

.assistant-input__attach .icon,
.assistant-input__send .icon {
  width: 17px;
  height: 17px;
}

.assistant-input__send:hover {
  opacity: 0.88;
}

.assistant-input__send:active {
  transform: scale(0.94);
}

.command-open {
  overflow: hidden;
}

.command-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: grid;
  align-items: start;
  justify-items: center;
  background: rgb(0 0 0 / 24%);
  padding: min(12vh, 96px) 16px 24px;
}

.command-overlay[hidden] {
  display: none;
}

.command-panel {
  width: min(100%, 640px);
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--popover) 96%, transparent);
  box-shadow: 0 24px 60px rgb(0 0 0 / 18%);
  backdrop-filter: blur(14px);
}

.command-input-wrap {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  padding: 12px 14px;
}

.command-input-wrap svg {
  width: 17px;
  height: 17px;
  color: var(--muted-foreground);
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2;
}

.command-input-wrap input {
  width: 100%;
  border: 0;
  background: transparent;
  color: var(--foreground);
  font-size: 14px;
  outline: none;
}

.command-input-wrap input::-webkit-search-cancel-button {
  display: none;
}

.command-input-wrap kbd,
.command-shortcut {
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--muted);
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  padding: 4px 6px;
  white-space: nowrap;
}

.command-list {
  display: grid;
  align-content: start;
  height: min(420px, calc(100vh - 180px));
  max-height: min(420px, calc(100vh - 180px));
  overflow-y: auto;
  padding: 8px;
}

.command-group {
  display: grid;
  align-content: start;
  gap: 2px;
  padding: 5px 0;
}

.command-group + .command-group,
.command-loading + .command-group {
  border-top: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
}

.command-group[hidden],
.command-item[hidden],
.command-loading[hidden] {
  display: none;
}

.command-group h2 {
  margin: 0;
  padding: 6px 8px;
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  text-transform: uppercase;
}

.command-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 36px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
  padding: 6px 8px;
  text-align: left;
  font-size: 14px;
}

.command-item:hover,
.command-item--active {
  background: var(--accent);
}

.command-item--danger:hover,
.command-item--danger.command-item--active {
  background: color-mix(in srgb, var(--danger) 8%, var(--muted));
}

.command-item--active-cedis .command-item__icon {
  color: var(--primary);
}

.command-item--active-cedis .command-item__body small {
  color: var(--primary);
  font-weight: 600;
}

.command-item__icon {
  display: grid;
  width: 16px;
  height: 16px;
  place-items: center;
  color: var(--muted-foreground);
  font-size: 14px;
  line-height: 1;
}

.command-item__icon .icon,
.command-item__icon svg {
  width: 16px;
  height: 16px;
}

.command-item__body {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.command-item__body strong {
  flex: 0 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.25;
}

.command-item__body small {
  flex: 0 1 auto;
  margin-left: auto;
  padding-left: 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.25;
  text-align: right;
}

/* On phone widths the panel goes edge-to-edge and the title + right-aligned
   description compete for the same narrow row, so both get truncated to
   unreadable stubs. Drop the description and give the title the whole row
   (stacking it onto a second line would make every result too tall). */
@media (max-width: 640px) {
  .command-item__body small {
    display: none;
  }
}

.command-loading {
  display: flex;
  min-height: 48px;
  align-items: center;
  gap: 10px;
  border-top: 1px solid color-mix(in srgb, var(--border) 68%, transparent);
  color: var(--muted-foreground);
  padding: 8px;
}

.command-loading__spinner {
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
  border: 2px solid color-mix(in srgb, var(--border) 90%, transparent);
  border-top-color: var(--primary);
  border-radius: 999px;
  animation: command-spin 0.8s linear infinite;
}

.command-loading span:last-child {
  display: grid;
  min-width: 0;
  gap: 2px;
}

.command-loading strong {
  color: var(--foreground);
  font-size: 13px;
  line-height: 1.25;
}

.command-loading small {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.25;
}

.command-empty {
  display: grid;
  min-height: 208px;
  place-items: center;
  align-content: center;
  gap: 9px;
  color: var(--muted-foreground);
  padding: 26px 20px;
  text-align: center;
}

.command-empty[hidden] {
  display: none;
}

.command-empty strong {
  color: var(--foreground);
  font-size: 15px;
  line-height: 1.3;
  /* Fade + rise in each time the empty state appears. */
  animation: command-empty-rise 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
  animation-delay: 0.06s;
}

.command-empty > span {
  font-size: 12px;
  line-height: 1.35;
  animation: command-empty-rise 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
  animation-delay: 0.11s;
}

/* "para" and the connective text stay in the normal headline color; only the
   quoted query is emphasized (weight, still in the neutral foreground color). */
.command-empty__qwrap {
  color: var(--foreground);
  font-weight: 600;
}

.command-empty__qwrap[hidden] {
  display: none;
}

.command-empty__q {
  color: var(--foreground);
  font-weight: 700;
}

/* --- Assistant orb — a soft, quietly breathing sparkle chip -------------- */

.command-empty__orb {
  position: relative;
  display: grid;
  place-items: center;
  width: 68px;
  height: 68px;
  margin-bottom: 4px;
  animation: command-orb-float 6s ease-in-out infinite;
}

/* A gentle neutral bloom that only breathes very slightly. */
.command-empty__orb-halo {
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  background: radial-gradient(
    circle at 50% 45%,
    color-mix(in srgb, var(--foreground) 12%, transparent),
    transparent 70%
  );
  animation: command-orb-pulse 5s ease-in-out infinite;
}

.command-empty__orb-core {
  position: relative;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 18px;
  color: var(--foreground);
  border: 1px solid color-mix(in srgb, var(--border) 85%, transparent);
  background: color-mix(in srgb, var(--muted) 55%, var(--card));
  box-shadow:
    0 8px 20px -10px color-mix(in srgb, var(--foreground) 22%, transparent),
    inset 0 1px 0 color-mix(in srgb, var(--card) 80%, transparent);
}

.command-empty__orb-core svg {
  width: 24px;
  height: 24px;
}

/* --- "Preguntar al Asistente" call to action ----------------------------- */

.command-empty__ask {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 6px;
  padding: 9px 12px 9px 13px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--foreground);
  font: inherit;
  font-size: 13px;
  font-weight: 650;
  cursor: pointer;
  box-shadow: 0 4px 12px -10px color-mix(in srgb, var(--foreground) 30%, transparent);
  animation: command-empty-rise 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
  animation-delay: 0.14s;
  transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}

.command-empty__ask:hover {
  transform: translateY(-1px);
  border-color: color-mix(in srgb, var(--foreground) 30%, var(--border));
  box-shadow: 0 8px 18px -12px color-mix(in srgb, var(--foreground) 40%, transparent);
}

.command-empty__ask:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

.command-empty__ask-icon {
  display: grid;
  place-items: center;
  color: var(--muted-foreground);
}

.command-empty__ask-icon svg {
  width: 16px;
  height: 16px;
}

.command-empty__ask kbd {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--muted);
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  padding: 4px 6px;
}

@keyframes command-empty-rise {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Barely-there drift so the orb feels alive without demanding attention. */
@keyframes command-orb-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); }
}

@keyframes command-orb-pulse {
  0%, 100% { opacity: 0.5; transform: scale(0.96); }
  50% { opacity: 0.72; transform: scale(1.04); }
}

@media (prefers-reduced-motion: reduce) {
  .command-empty strong,
  .command-empty > span,
  .command-empty__ask,
  .command-empty__orb,
  .command-empty__orb-halo {
    animation: none;
  }
}

.command-hidden-form {
  display: none;
}

@keyframes command-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (max-width: 520px) {
  .auth-main {
    align-items: stretch;
    padding: 0;
  }

  .auth-card {
    min-height: 100dvh;
    width: 100%;
    border-width: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 22px;
  }

  .auth-card__footer {
    display: grid;
  }

  .setup-grid--two,
  .setup-grid--three {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 900px) {
  .home-topbar {
    padding: 10px 14px;
  }

  .home-topbar__row {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }

  .command-button kbd {
    display: none;
  }

  .command-button--header {
    width: 100%;
    justify-content: center;
  }

  .command-button--header span {
    display: none;
  }

  .command-button--inline {
    width: 38px;
    justify-content: center;
    padding: 0;
  }

  .command-button--inline span {
    display: none;
  }

  .home-main {
    padding: 8px 14px 24px;
  }

  .tabs {
    overflow-x: auto;
    width: 100%;
  }

  .home-panel__header,
  .home-panel__actions {
    flex-direction: column;
    align-items: stretch;
  }

  /* The header stacks, so the filters read from the left edge like the rest of
     the screen instead of hugging the right one — and the custom-range popover
     drops from the left with them, since there is no longer a right edge to
     hang off. */
  .filter-bar {
    justify-content: flex-start;
  }

  /* Two classes, so this also beats `.t-dropdown[data-origin="top-right"]`'s
     transform-origin — a one-class selector here would move the panel and
     leave it growing out of the corner it no longer sits in. */
  .segmented__popover.t-dropdown {
    right: auto;
    left: 0;
    transform-origin: top left;
  }

  /* Arrows collapse to a compact vertical list on phones. */
  .routeflow {
    flex-direction: column;
  }

  .routeflow__step,
  .routeflow__step:first-child,
  .routeflow__step:last-child {
    margin-left: 0;
    padding: 9px 14px;
    clip-path: none;
    box-shadow: inset 3px 0 0 color-mix(in srgb, var(--border) 75%, transparent);
    border-bottom: 1px solid color-mix(in srgb, var(--border) 50%, transparent);
  }

  .routeflow__step::after {
    display: none;
  }

  .routeflow__step:last-child {
    border-bottom: 0;
  }

  .routeflow__step.is-done {
    box-shadow: inset 3px 0 0 #16a34a;
  }

  .routeflow__step.is-canceled {
    box-shadow: inset 3px 0 0 #dc2626;
  }

  /* --- The status deck (phones only) ---
     Six stacked stages used to push the figures the page exists for below the
     fold, so collapsed they overlap into a deck: the stage the route has
     actually reached (`is-current`) sits in front at full size and each earlier
     one recedes 7px up and one step further back in Z. Depth is real
     perspective rather than a scale() fake, so the edges converge the way the
     cards behind a physical deck do. Later siblings paint over earlier ones by
     default, which is exactly the order we want, so no z-index is needed.

     The ladder is measured backwards from `is-current` rather than from the end
     of the list, because the front card is the stage that happened — leading
     with the list's last entry would head an operating route "Liquidada".

     The steps are given a fixed height while stacked: the overlap is a negative
     margin, and reading it off variable content would make the peek drift. Both
     lines already fit in it. */
  .routeflow-stack {
    position: relative;
  }

  /* 900px of perspective shrank the card behind the front one by ~2 %, which at
     this width is a visible step down rather than depth — the front card just
     read as bigger. A longer focal length keeps the deck reading as a deck while
     the cards stay the same size as each other. */
  .routeflow-stack .routeflow {
    perspective: 2600px;
    transform-style: preserve-3d;
    border: 0;
  }

  .routeflow-stack .routeflow__step {
    /* The base rule's `flex: 1 1 0` shares one row between the arrows on
       desktop; stacked in a column it means "no intrinsic height", and the
       `overflow: hidden` below waives the automatic minimum that was hiding
       that — leaving a deck of zero-height cards. Size them by content. */
    flex: 0 0 auto;
    transform-origin: center top;
    transition: height 220ms ease, margin-top 220ms ease, transform 220ms ease,
      border-radius 220ms ease;
  }

  .routeflow-stack:not(.is-expanded) .routeflow__step {
    height: 46px;
    overflow: hidden;
    /* A full outline, not just the list's bottom rule: it is the only thing that
       draws the edge of each card still buried in the deck. */
    border: 1px solid color-mix(in srgb, var(--foreground) 16%, transparent);
    border-radius: 8px;
  }

  .routeflow-stack:not(.is-expanded) .routeflow__step + .routeflow__step {
    /* 46px tall minus the 7px of each earlier card left peeking above it. */
    margin-top: -39px;
  }

  /* Stages still ahead of the route are not part of the deck — they are the
     future, and stacking them in front of the current one is what made this read
     wrong. The toggle still says how many there are in total. */
  .routeflow-stack:not(.is-expanded) .routeflow__step.is-current ~ .routeflow__step {
    display: none;
  }

  .routeflow-stack:not(.is-expanded) .routeflow__step:has(+ .is-current) {
    transform: translateZ(-18px);
  }

  .routeflow-stack:not(.is-expanded) .routeflow__step:has(+ * + .is-current) {
    transform: translateZ(-36px);
  }

  .routeflow-stack:not(.is-expanded) .routeflow__step:has(+ * + * + .is-current) {
    transform: translateZ(-54px);
  }

  /* One rung per card, all the way back. These were a `~` catch-all at -72px,
     which put every card four or more from the front at the same depth — so on
     a liquidada route, where the whole six-stage deck is behind the front card,
     the last three came out identical and the taper died at the top of the
     stack. `+` chains match an exact distance; the `~` one only picks up
     anything deeper than the ladder goes. */
  .routeflow-stack:not(.is-expanded) .routeflow__step:has(+ * + * + * + .is-current) {
    transform: translateZ(-72px);
  }

  .routeflow-stack:not(.is-expanded) .routeflow__step:has(+ * + * + * + * + .is-current) {
    transform: translateZ(-90px);
  }

  .routeflow-stack:not(.is-expanded) .routeflow__step:has(+ * + * + * + * + * ~ .is-current) {
    transform: translateZ(-108px);
  }

  /* Stacked, the accent bar alone no longer separates the cards — each needs its
     own lift. Restated per state because the accent is an inset shadow on the
     same property. */
  .routeflow-stack:not(.is-expanded) .routeflow__step {
    box-shadow: inset 3px 0 0 color-mix(in srgb, var(--border) 75%, transparent),
      0 -1px 6px color-mix(in srgb, var(--foreground) 14%, transparent);
  }

  .routeflow-stack:not(.is-expanded) .routeflow__step.is-done {
    box-shadow: inset 3px 0 0 #16a34a,
      0 -1px 6px color-mix(in srgb, var(--foreground) 14%, transparent);
  }

  .routeflow-stack:not(.is-expanded) .routeflow__step.is-canceled {
    box-shadow: inset 3px 0 0 #dc2626,
      0 -1px 6px color-mix(in srgb, var(--foreground) 14%, transparent);
  }

  /* The deck IS the control, in both states: the button covers it, so pressing
     any status card deals the stages out and pressing one again re-stacks them.
     It carries nothing visible — a stack of cards already reads as "there is
     more behind this", and the legend plus caret it used to show were a line of
     chrome explaining what the shape says by itself. */
  .routeflow-stack__toggle {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: block;
    border: 0;
    background: transparent;
    cursor: pointer;
    font: inherit;
    padding: 0;
  }

  .home-summary,
  .home-grid {
    grid-template-columns: 1fr;
  }

  .admin-table__row--promotions,
  .admin-table__row--route-operations,
  .admin-table__row--inventory-purchases,
  .admin-table__row--inventory-transfers,
  .admin-table__row--catalog-products,
  .admin-table__row--price-lists,
  .admin-table__row--product-categories,
  .admin-table__row--catalog-customers,
  .admin-table__row--holidays,
  .admin-table__row--taxes,
  .operation-summary,
  .field-grid.catalog-field-grid,
  .field-grid {
    grid-template-columns: 1fr;
  }

  /* The hairline figure strip is the exception: its labels are short, so it pairs
     two-up instead of becoming one tall column that spends the width on nothing. */
  .operation-summary.operation-summary--figures {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* An odd number of figures would leave a half-empty cell showing the strip's
     divider colour; the last one takes the whole row instead. */
  .operation-summary--figures > *:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }

  /* `--inline` opts a strip out of that pairing: three or four short figures fit
     on one line at this type size, and two-up they were a block half a screen
     tall standing between the header and the data. Must come after the pairing
     rules above — same specificity, so file order decides. */
  .operation-summary.operation-summary--figures.operation-summary--inline {
    grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  }

  /* The strip paints its dividers by showing its own background through a 1px
     grid gap, which means any part of a row the cells do not fill shows up as a
     slab of grey — five figures in a four-up row left three empty tracks of it.
     Wrapping is the whole point of `--inline`, so the fix is to stop the
     container from being the divider: the cells carry their own hairline and the
     gap falls on card colour. (Stretching the last cell with `grid-column: auto /
     -1` looks like the tidier answer and is not — a definite end line changes how
     auto-placement resolves the whole row, and it dropped the third figure of a
     three-figure strip onto a line of its own.) */
  .operation-summary--figures.operation-summary--inline {
    background: var(--card);
  }

  .operation-summary--inline > * {
    box-shadow: 0 0 0 0.5px color-mix(in srgb, var(--border) 62%, transparent);
  }

  /* And the two-up rule's odd-cell fixup has to be undone here as well: made to
     span the whole row, an odd last figure lands on a line of its own and leaves
     the track beside it empty — the exact hole this variant exists to avoid. */
  .operation-summary--inline > *:last-child:nth-child(odd) {
    grid-column: auto;
  }

  .operation-summary--inline > * {
    min-width: 0;
    padding: 8px 9px;
  }

  /* The caption wraps rather than truncating: at this width "Devoluciones al
     cambio" ellipsised to "Devolucion…" in every cell, which is a label nobody
     can read. The figure below it is the one that must stay on one line, and
     the grid keeps the cells the same height anyway. */
  .operation-summary--inline small {
    font-size: 10px;
    line-height: 1.25;
  }

  .operation-summary--inline strong {
    overflow: hidden;
    font-size: 13px;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .operation-summary--inline .operation-summary__cell--input input {
    min-height: 34px;
    padding: 5px 7px;
  }

  .catalog-form .field--span-all,
  .catalog-form .field--span-2 {
    grid-column: auto;
  }

  .catalog-form .field--code,
  .catalog-form .field--compact,
  .catalog-form .field--money,
  .catalog-form .field--phone,
  .catalog-form .field--zip,
  .catalog-form .field--coordinate,
  .catalog-form .field--quantity,
  .catalog-form .field--date,
  .catalog-form .field--select {
    max-width: none;
  }

  .tax-row__display {
    align-items: flex-start;
  }

  .tax-row__edit,
  .tax-add {
    grid-template-columns: 1fr;
  }

  .tax-row__edit .switch,
  .tax-add .switch {
    justify-content: space-between;
  }

  .catalog-search,
  .catalog-pagination {
    align-items: stretch;
    flex-direction: column;
  }

  .catalog-list__item {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
  }

  .home-summary,
  .home-grid,
  .home-panel__header {
    padding-left: 14px;
    padding-right: 14px;
  }

  .assistant-tabs {
    grid-template-columns: 1fr;
  }

  .assistant-tabs__list {
    grid-column: 1;
  }

  /* The bottom gutter goes — on a phone it is dead space under the composer. */
  .assistant-main {
    height: calc(100dvh - var(--app-shell-compact-topbar-height) - var(--app-shell-top-inset));
    padding: 8px 0 10px;
  }

  .assistant-screen {
    border-right: 0;
    border-left: 0;
    border-radius: 0;
    box-shadow: none;
  }

  /* The header shrinks to whatever it actually holds. Below 720px the heading
     block is hidden (see the `.section-heading` rule), and the desktop
     min-height would keep reserving room for the title that is gone — an empty
     band above the day navigator. */
  .assistant-screen__header {
    flex-wrap: wrap;
    align-items: flex-start;
    min-height: 0;
    padding: var(--assistant-gutter);
  }

  .assistant-screen__tools {
    width: 100%;
    justify-content: space-between;
  }

  .assistant-screen__body {
    padding: 0 0 10px;
  }

  .assistant-artifacts,
  .assistant-suggestions {
    padding-right: var(--assistant-gutter);
    padding-left: var(--assistant-gutter);
  }

  /* Here the chips genuinely run past the edge, and a touch scrollbar is not a
     handle anyone can grab — so hide it and fade the trailing chip instead, so
     it reads as "there is more" rather than as a clipped layout. On desktop the
     native scrollbar stays: it is the affordance, and it can be dragged. */
  .assistant-suggestions {
    scrollbar-width: none;
    mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent);
  }

  .assistant-suggestions::-webkit-scrollbar {
    display: none;
  }

  .assistant-prompt-dialog {
    width: calc(100vw - 16px);
    max-height: calc(100dvh - 20px);
  }

  /* `height`, not `max-height`: the base rule already sets a 40px-inset height,
     which a larger `max-height` can never bind against — the shell would stay
     20px shorter than the dialog around it asks for at this width. */
  .assistant-prompt-dialog__shell {
    height: calc(100dvh - 20px);
  }

  .assistant-prompt-dialog__header {
    padding: 14px;
  }

  .assistant-prompt-dialog__search {
    padding-right: 14px;
    padding-left: 14px;
  }

  .assistant-prompt-dialog__body {
    grid-template-columns: 1fr;
    overflow-y: auto;
    padding: 12px;
  }

  .assistant-prompt-list {
    max-height: 44dvh;
    overflow-y: auto;
  }

  .assistant-prompt-form {
    padding: 12px;
  }

  .assistant-prompt-form__footer {
    display: grid;
    grid-template-columns: 1fr;
  }

  .assistant-input {
    margin-right: var(--assistant-gutter);
    margin-left: var(--assistant-gutter);
  }

  .assistant-readonly-note {
    flex-wrap: wrap;
    margin-right: var(--assistant-gutter);
    margin-left: var(--assistant-gutter);
  }

  .command-overlay {
    padding-top: 64px;
  }

  .command-list {
    max-height: calc(100vh - 150px);
  }

  .command-item {
    min-height: 40px;
  }

  .command-shortcut {
    display: none;
  }
}

/* Smartphone top bar: collapse the wide controls (CEDIS switcher, search,
   page actions) into icon-only buttons so the row stops overflowing and reads
   cleanly on a narrow screen. */
@media (max-width: 640px) {
  .flash-stack {
    top: 10px;
    right: 10px;
    left: 10px;
    width: auto;
    transform: none;
  }

  .app-shell .flash-stack {
    top: var(--app-shell-compact-topbar-height);
  }

  .home-topbar {
    padding: 10px 0;
  }

  .home-topbar__row {
    grid-template-columns: auto auto minmax(0, 1fr);
    gap: 8px;
    padding: 0 14px;
  }

  .home-topbar__left,
  .home-topbar__user {
    gap: 6px;
  }

  /* Search trigger → icon-only button (the label/⌘K already hide at 900px). */
  .command-button--header {
    width: 38px;
    min-width: 38px;
    justify-self: start;
    padding: 0;
  }

  .assistant-tabs {
    grid-template-columns: 1fr;
  }

  .assistant-tabs__list {
    grid-column: 1;
    border-right: 0;
    border-left: 0;
    border-radius: 0;
  }

  /* CEDIS switcher → icon-only button. The native <select> stays a fully
     transparent tap overlay; the warehouse glyph shows beneath it, so the
     control keeps working without exposing the long center name. */
  .cedis-switcher {
    width: 36px;
    height: 36px;
    min-width: 0;
    border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
    border-radius: var(--radius);
    background: var(--card);
    box-shadow: 0 1px 1px rgb(15 23 42 / 3%);
  }

  /* Match the sibling top-bar icon button (.settings-link):
     the warehouse glyph reads as muted, not full-strength foreground. */
  .cedis-switcher__icon {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    pointer-events: none;
    color: var(--muted-foreground);
  }

  .cedis-switcher__icon .icon {
    width: 18px;
    height: 18px;
  }

  .cedis-switcher__select {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    opacity: 0;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }

  /* Single-CEDIS info badge mirrors the switcher: icon only. */
  .cedis-badge {
    width: 36px;
    height: 36px;
    padding: 0;
    display: grid;
    place-items: center;
  }

  .cedis-badge__icon {
    display: grid;
    place-items: center;
  }

  .cedis-badge__icon .icon {
    width: 18px;
    height: 18px;
  }

  .cedis-badge__label {
    display: none;
  }

}

/* ---- Profile (device data + breadcrumb map) ---- */

.profile-main {
  width: min(100%, 960px);
  margin: 0 auto;
  padding: 24px 20px 48px;
  display: grid;
  gap: 24px;
}

/* The users list is a wide data table, not a profile form, so it matches the
   catalog screens (`.home-main`) rather than the narrower form container. */
.profile-main--wide {
  width: min(100%, 1300px);
}

.profile-section {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
}

.profile-section__header {
  margin-bottom: 16px;
}

.profile-section__header--with-avatar {
  display: flex;
  align-items: center;
  gap: 14px;
}

.profile-section__header--with-avatar .profile-section__heading {
  min-width: 0;
}

/* Push a trailing header action (e.g. the profile "Editar" link) to the far
   right of the avatar header row. */
.profile-section__header--with-avatar .profile-section__header-action {
  flex: 0 0 auto;
  margin-left: auto;
}

.profile-section__header h1 {
  font-size: 20px;
  margin: 0 0 4px;
}

.profile-section__header h2 {
  font-size: 16px;
  margin: 0 0 4px;
}

.profile-section__header p {
  color: var(--muted-foreground);
  font-size: 13px;
  margin: 0;
}

.profile-empty {
  color: var(--muted-foreground);
  font-size: 13px;
  margin: 0;
}

/* Customer business profile: one compact operational read surface, with the
   summary first and bounded history lists below it. The rows are card-like on
   phones instead of becoming a horizontally scrolling detail table. */
.customer-profile {
  width: min(100%, 1120px);
}

.customer-profile__back {
  margin-bottom: -12px;
}

.customer-profile__identity .profile-section__header {
  margin-bottom: 0;
}

.customer-profile__identity .badge {
  margin-left: auto;
}

.customer-profile__identity .profile-section__header-action {
  margin-left: 0;
}

.customer-profile__metrics {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

.customer-profile__metric {
  min-width: 0;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
}

.customer-profile__metric > span,
.customer-profile__facts dt {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.customer-profile__metric strong {
  display: block;
  margin-top: 6px;
  overflow-wrap: anywhere;
  font-size: 24px;
  line-height: 1.15;
}

.customer-profile__metric small,
.customer-profile__latest p,
.customer-profile__activity-list small,
.customer-profile__product-list small {
  display: block;
  margin-top: 5px;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.4;
}

.customer-profile__columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  align-items: start;
}

.customer-profile__columns--wide-left {
  grid-template-columns: minmax(0, 1.35fr) minmax(280px, 0.65fr);
}

.customer-profile__latest-value {
  display: block;
  margin-bottom: 8px;
  font-size: 19px;
  line-height: 1.25;
}

.customer-profile__latest p {
  margin: 4px 0 0;
}

.customer-profile__product-list,
.customer-profile__activity-list {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.customer-profile__product-list li,
.customer-profile__activity-list li {
  display: grid;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 12px 0;
  border-top: 1px solid var(--border);
}

.customer-profile__product-list li:first-child,
.customer-profile__activity-list li:first-child {
  padding-top: 0;
  border-top: 0;
}

.customer-profile__product-list li {
  grid-template-columns: auto minmax(0, 1fr) auto;
}

.customer-profile__activity-list li {
  grid-template-columns: minmax(0, 1fr) auto;
}

.customer-profile__activity-list li > :last-child {
  text-align: right;
}

.customer-profile__rank {
  display: grid;
  width: 32px;
  height: 32px;
  place-items: center;
  border-radius: 999px;
  background: var(--muted);
  color: var(--muted-foreground);
}

.customer-profile__rank .icon {
  width: 16px;
  height: 16px;
}

.customer-profile__facts {
  display: grid;
  margin: 0;
}

.customer-profile__facts > div {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr);
  gap: 12px;
  padding: 10px 0;
  border-top: 1px solid var(--border);
}

.customer-profile__facts > div:first-child {
  padding-top: 0;
  border-top: 0;
}

.customer-profile__facts dd {
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
  font-size: 13px;
}

.customer-profile__route {
  display: block;
  margin-bottom: 5px;
}

.customer-profile__route i {
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: 5px;
  border-radius: 999px;
  background: var(--route-color);
}

.recovery-code-panel {
  display: grid;
  gap: 14px;
}

.recovery-code-panel p {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 13px;
}

.recovery-code-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.recovery-code-list code {
  display: block;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--foreground);
  font-weight: 800;
  letter-spacing: 0.04em;
}

.device-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
}

.device-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px;
  background: var(--muted);
}

.device-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}

.device-card__specs {
  display: grid;
  gap: 8px;
  margin: 0;
}

.device-card__specs > div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
}

.device-card__specs dt {
  color: var(--muted-foreground);
}

.device-card__specs dd {
  margin: 0;
  font-weight: 500;
  text-align: right;
  overflow-wrap: anywhere;
}

.device-admin-list {
  display: grid;
  gap: 12px;
}

.device-admin-row {
  display: grid;
  grid-template-columns: minmax(200px, 0.75fr) minmax(0, 1.25fr);
  gap: 16px;
  align-items: center;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px;
}

/* A grid item's `min-width: auto` is its CONTENT minimum, and the action
   buttons in the right column are `white-space: nowrap` — without this the
   device card grows past the row's own 16px right padding on a phone. */
.device-admin-row > * {
  min-width: 0;
}

.device-admin-row__user {
  display: flex;
  align-items: center;
  gap: 12px;
}

.device-admin-row__identity {
  display: grid;
  min-width: 0;
  gap: 2px;
}

.device-admin-row__identity strong {
  font-size: 14px;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

/* Scoped to the identity/meta text on purpose. The blanket
   `.device-admin-device span` this replaces also matched the <span> that
   `button_label("Desasignar", :ban)` wraps its label in, painting it
   #737373 on the solid red button — that, not the --destructive token, is
   where the unreadable label came from. Never widen this back to `span`. */
.device-admin-row__identity span,
.device-admin-device__meta {
  color: var(--muted-foreground);
  font-size: 12px;
  overflow-wrap: anywhere;
}

.device-admin-row__devices {
  display: grid;
  gap: 10px;
}

.device-admin-device {
  display: grid;
  min-width: 0;
  gap: 12px;
  border: 1px solid color-mix(in srgb, var(--border) 82%, transparent);
  border-radius: 8px;
  background: var(--card);
  padding: 12px;
  box-shadow: 0 1px 2px rgb(15 23 42 / 4%);
}

.device-admin-device__head {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 12px;
}

.device-admin-device__icon {
  display: grid;
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  place-items: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--primary) 12%, var(--card));
  color: var(--primary);
}

.device-admin-device__identity {
  display: grid;
  min-width: 0;
  flex: 1 1 auto;
  gap: 3px;
}

.device-admin-device__identity strong {
  font-size: 14px;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.device-admin-device__status {
  flex: 0 0 auto;
  text-decoration: none;
}

.device-admin-device__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}

.device-admin-device__actions > * {
  min-width: 0;
}

/* The destructive action sits apart from the two constructive ones. */
.device-admin-device__release {
  margin-left: auto;
}

.device-diagnostic-options {
  position: relative;
}

.device-diagnostic-options > summary {
  display: inline-flex;
  min-height: 32px;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0 12px;
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  list-style: none;
  white-space: nowrap;
}

.device-diagnostic-options > summary::-webkit-details-marker {
  display: none;
}

.device-diagnostic-options > summary:hover {
  border-color: color-mix(in srgb, var(--foreground) 25%, var(--border));
  color: var(--foreground);
}

.device-diagnostic-options form {
  position: absolute;
  z-index: 5;
  right: 0;
  top: calc(100% + 8px);
  width: min(310px, 82vw);
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
}

.device-diagnostic-options fieldset {
  display: grid;
  gap: 8px;
}

.device-diagnostic-options fieldset {
  margin: 0 0 12px;
  padding: 0;
  border: 0;
}

.device-diagnostic-options label {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 13px;
}

.device-diagnostic-main {
  display: grid;
  gap: 16px;
}

.device-diagnostic-back {
  margin-bottom: 14px;
}

.device-diagnostic-header__state {
  display: grid;
  justify-items: end;
  gap: 4px;
  text-align: right;
}

.device-diagnostic-header__state small {
  color: var(--muted-foreground);
  font-size: 11px;
}

.device-diagnostic-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
  margin: 0 0 14px;
}

.device-diagnostic-facts > div {
  display: grid;
  min-width: 0;
  gap: 4px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--muted) 42%, var(--card));
  padding: 10px 12px;
}

.device-diagnostic-facts dt {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.device-diagnostic-facts dd {
  margin: 0;
  font-size: 13px;
  overflow-wrap: anywhere;
}

.device-diagnostic-facts__actor {
  display: flex;
  align-items: center;
  gap: 8px;
}

.device-diagnostic-facts__actor .avatar {
  width: 24px;
  height: 24px;
  font-size: 10px;
}

.device-diagnostic-analysis {
  border-color: color-mix(in srgb, var(--primary) 35%, var(--border));
}

.device-diagnostic-verdict {
  display: grid;
  gap: 12px;
  margin: 0;
}

.device-diagnostic-verdict__part {
  display: grid;
  gap: 5px;
  border-left: 3px solid color-mix(in srgb, var(--border) 80%, transparent);
  padding-left: 12px;
}

.device-diagnostic-verdict dt {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.device-diagnostic-verdict dd {
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* The verdict is the answer the screen exists to give: bigger, full contrast,
   and the only part with a primary accent. */
.device-diagnostic-verdict__part--lead {
  border-left-color: var(--primary);
}

.device-diagnostic-verdict__part--lead dd {
  color: var(--foreground);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.45;
}

/* The one part somebody has to act on gets a surface of its own. */
.device-diagnostic-verdict__part--action {
  border-left-color: color-mix(in srgb, var(--primary) 45%, transparent);
  border-radius: 0 8px 8px 0;
  background: color-mix(in srgb, var(--muted) 45%, var(--card));
  padding: 10px 12px;
}

.device-diagnostic-probes {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}

.device-diagnostic-raw {
  margin-top: 20px;
}

.device-diagnostic-raw summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  list-style: none;
}

.device-diagnostic-raw summary::-webkit-details-marker {
  display: none;
}

.device-diagnostic-raw summary:hover {
  color: var(--foreground);
}

.device-diagnostic-raw[open] summary .icon {
  transform: rotate(180deg);
}

.device-diagnostic-raw pre {
  max-height: 520px;
  overflow: auto;
  padding: 14px;
  border-radius: var(--radius);
  background: var(--muted);
  font-size: 12px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.user-device-panel {
  margin-top: 22px;
  border-color: color-mix(in srgb, var(--primary) 16%, var(--border));
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--primary) 5%, var(--card)) 0%,
    color-mix(in srgb, var(--card) 92%, var(--muted)) 100%
  );
}

.user-device-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  border: 1px solid color-mix(in srgb, var(--border) 82%, transparent);
  border-radius: 8px;
  background: var(--card);
  padding: 14px;
  box-shadow: 0 1px 2px rgb(15 23 42 / 4%);
}

.user-device-card__main {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 12px;
}

.user-device-card__icon,
.user-device-empty__icon {
  display: grid;
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  place-items: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--primary) 12%, var(--card));
  color: var(--primary);
}

.user-device-card__identity {
  display: grid;
  min-width: 0;
  gap: 3px;
}

.user-device-card__identity strong {
  overflow-wrap: anywhere;
}

.user-device-card__identity span {
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 600;
}

.user-device-card__meta {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin: 0;
}

.user-device-card__meta > div {
  display: grid;
  gap: 3px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--muted) 45%, var(--card));
  padding: 9px 10px;
}

.user-device-card__meta dt {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

.user-device-card__meta dd {
  margin: 0;
  color: var(--foreground);
  font-size: 13px;
  font-weight: 650;
}

.user-device-card__actions {
  grid-column: 2;
  grid-row: 1;
}

.user-device-card__release,
.user-device-card__release span,
.user-device-card__release .icon {
  color: var(--destructive-foreground);
}

.user-device-empty {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px dashed color-mix(in srgb, var(--border) 88%, var(--foreground));
  border-radius: 8px;
  background: color-mix(in srgb, var(--muted) 42%, var(--card));
  padding: 14px;
}

.user-device-empty p {
  margin: 0 0 2px;
  color: var(--foreground);
  font-size: 13px;
  font-weight: 700;
}

.user-device-empty small {
  color: var(--muted-foreground);
  font-size: 12px;
}

.button--danger {
  background: var(--destructive);
  border-color: var(--destructive);
  color: var(--destructive-foreground);
}

.button--danger:hover {
  background: color-mix(in srgb, var(--destructive) 88%, #000);
}

/* Outline destructive: lighter than a solid red, still clearly a cancel. */
.button--outline-danger {
  background: transparent;
  border-color: color-mix(in srgb, var(--destructive) 50%, transparent);
  color: var(--destructive);
}

.button--outline-danger:hover {
  background: color-mix(in srgb, var(--destructive) 12%, transparent);
  border-color: var(--destructive);
}

.day-picker {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}

.day-picker label {
  font-size: 13px;
  color: var(--muted-foreground);
}

.day-picker select {
  flex: 1;
  max-width: 320px;
  height: 36px;
  border: 1px solid var(--input);
  border-radius: 8px;
  background: var(--card);
  color: var(--foreground);
  padding: 0 10px;
  font-size: 13px;
}

.route-map {
  height: 420px;
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  z-index: 0;
}

.route-meta {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

/* ---- Route sales scaffold ---- */

.routes-main {
  width: min(100%, 1300px);
  margin: 0 auto;
  /* Keep a roomy bottom gutter so the board's card doesn't sit flush against the
     viewport's bottom edge (the fixed-height frame below otherwise glues it there). */
  padding: 12px 24px var(--app-shell-bottom-gutter);
  /* Anchor the board to the viewport (topbar is ~115px) so it's a fixed-height
     app frame: the route list scrolls inside its own column instead of the whole
     page growing with the number of routes. `--app-shell-top-inset` is zero in
     browsers and lets native wrappers reserve their titlebar space without
     losing the bottom gutter. Reset to natural flow on mobile. */
  height: calc(100vh - var(--app-shell-topbar-height) - var(--app-shell-top-inset));
  display: flex;
  flex-direction: column;
}

.routes-panel {
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
  overflow: hidden;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.routes-panel__header {
  display: flex;
  min-height: 62px;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 18px 8px;
}

.routes-panel__header h1,
.routes-panel__header p {
  margin: 0;
}

.routes-panel__header h1 {
  font-size: 20px;
  line-height: 1.2;
}

.routes-panel__header p {
  margin-top: 4px;
  color: var(--muted-foreground);
  font-size: 13px;
  line-height: 1.4;
}

.routes-title-row,
.route-card__head,
.route-card__driver,
.route-card__metrics,
.route-detail__header,
.route-customer-panel__header,
.route-customer-row {
  display: flex;
  align-items: center;
}

.routes-title-row {
  gap: 10px;
}

.icon-button {
  display: grid;
  width: 32px;
  height: 32px;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
}

.icon-button:hover {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  background: var(--accent);
  color: var(--foreground);
}

.icon-button .icon {
  width: 16px;
  height: 16px;
}

.icon-button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

/* Held-down look for an icon button that toggles something open (the settlement
   scanner), matching `.button.is-active`. */
.icon-button.is-active {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  background: color-mix(in srgb, var(--primary) 10%, var(--card));
  color: var(--foreground);
}

.button--compact {
  min-height: 32px;
  padding: 0 12px;
}

.route-color-field__controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.route-color-swatches {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

.route-color-swatch {
  width: 24px;
  height: 24px;
  border: 2px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: 8px;
  background: var(--swatch);
  cursor: pointer;
  padding: 0;
}

.route-color-swatch:hover {
  border-color: color-mix(in srgb, var(--foreground) 35%, var(--border));
}

.route-color-swatch--active {
  border-color: var(--foreground);
  box-shadow: 0 0 0 2px var(--card), 0 0 0 4px color-mix(in srgb, var(--swatch) 60%, transparent);
}

.route-color-field .route-color-input {
  width: 40px;
  height: 32px;
  flex: 0 0 auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  cursor: pointer;
  padding: 2px;
}

.route-color-randomize {
  display: grid;
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  place-items: center;
  margin-left: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
}

.route-color-randomize:hover {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  color: var(--foreground);
}

.route-week-strip {
  display: flex;
  align-items: stretch;
  padding: 6px 18px 0;
}

/* `.route-day` is shared with the customer-form visit-day chips (styled around
   line 3200). Every board rule below stays scoped under `.route-week-days`, and
   any new chip rule must be checked against the strip — an unscoped `.route-day`
   declaration leaks into whichever component doesn't override that property. */
.route-week-button,
.route-week-days .route-day {
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  background: var(--card);
  color: var(--muted-foreground);
}

.route-week-button {
  width: 40px;
  min-height: 68px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
  transition: background-color 120ms ease, color 120ms ease;
}

.route-week-button:first-child {
  border-radius: 8px 0 0 8px;
}

.route-week-button:last-child {
  border-radius: 0 8px 8px 0;
}

.route-week-days {
  display: grid;
  min-width: 0;
  flex: 1;
  grid-template-columns: repeat(7, minmax(86px, 1fr));
  margin-block: -8px;
  overflow-x: auto;
  padding-block: 8px;
}

.route-week-days .route-day {
  position: relative;
  display: grid;
  min-height: 68px;
  place-items: center;
  align-content: center;
  gap: 3px;
  margin-left: -1px;
  color: var(--foreground);
  cursor: pointer;
  line-height: 1.15;
  padding: 12px 8px 9px;
  text-align: center;
  text-decoration: none;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
}

/* The week-strip days share the `.route-day` class name with the rounded
   operating-days chips (defined earlier), which would otherwise leak their
   `border-radius` onto the strip and round every day cell. The strip is a
   single joined group — only its outer ends (the week buttons) are rounded —
   so force the day cells square. */
.route-week-days .route-day {
  border-radius: 0;
}

.route-week-button:hover,
.route-week-days .route-day:not(.route-day--selected):hover {
  background: var(--muted);
  color: var(--foreground);
}

.route-week-days .route-day--selected {
  z-index: 1;
  border-color: var(--primary);
  background: var(--primary);
  color: var(--primary-foreground);
  box-shadow: var(--shadow);
}

/* A selected day keeps its primary fill on hover (just a touch deeper for
   affordance) so the date text stays readable, instead of being overridden by
   the generic hover style above — which, as a pseudo-class, outranks the plain
   `.route-day--selected` class and would wash the number into the background. */
.route-week-days .route-day--selected:hover {
  background: color-mix(in srgb, var(--primary) 90%, var(--primary-foreground));
}

.route-week-days .route-day--muted:not(.route-day--selected) {
  background: color-mix(in srgb, var(--muted) 45%, var(--card));
  color: var(--muted-foreground);
}

.route-day__weekday {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* The cycle-day caption ("Día N") stays muted so the weekday + date read as
   the primary text, matching the Vue prototype's hierarchy. */
.route-week-days .route-day span:last-child {
  font-size: 10px;
  font-weight: 500;
  color: var(--muted-foreground);
}

.route-week-days .route-day--selected span:last-child {
  color: color-mix(in srgb, var(--primary-foreground) 80%, transparent);
}

.route-week-days .route-day strong {
  font-size: 16px;
  font-weight: 600;
}

.route-day__flag,
.route-day__holiday,
.route-day__non-operating {
  position: absolute;
  top: -8px;
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 9px;
  font-weight: 700;
  line-height: 1;
  box-shadow: var(--shadow);
}

.route-day__flag {
  right: 8px;
  background: #e0f2fe;
  color: #0369a1;
}

.route-day__holiday {
  left: 8px;
  background: #fff1f2;
  color: #be123c;
}

.route-day__non-operating {
  left: 8px;
  background: color-mix(in srgb, var(--muted) 78%, var(--card));
  color: var(--muted-foreground);
}

.route-filter-bar {
  display: flex;
  flex-wrap: wrap;
  position: relative;
  z-index: 2;
  width: fit-content;
  max-width: calc(100% - 36px);
  margin: 14px auto 16px;
  justify-content: center;
  gap: 6px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: 999px;
  background: var(--card);
  padding: 4px;
  box-shadow: var(--shadow);
}

.route-filter {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 6px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  padding: 5px 10px;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.route-filter:hover,
.route-filter--active {
  border-color: color-mix(in srgb, var(--primary) 22%, transparent);
  background: color-mix(in srgb, var(--primary) 7%, var(--card));
  color: var(--foreground);
}

.route-filter strong {
  color: var(--foreground);
}

.route-filter__dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--muted-foreground);
}

.route-filter__dot--programada {
  background: #0ea5e9;
}

.route-filter__dot--en-curso {
  background: #f59e0b;
}

.route-filter__dot--completada {
  background: #10b981;
}

.route-mobile-menu {
  display: none;
}

.route-mobile-menu__summary {
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  border: 0;
  background: transparent;
  color: inherit;
  list-style: none;
  cursor: pointer;
  font: inherit;
}

.route-mobile-menu__summary::-webkit-details-marker {
  display: none;
}

.route-mobile-menu__summary-main,
.route-mobile-menu__summary-meta,
.mobile-route-card,
.mobile-route-card__top,
.mobile-route-card__meta {
  display: flex;
  align-items: center;
}

.route-mobile-menu__summary-main {
  min-width: 0;
  gap: 8px;
}

.route-mobile-menu__summary-main .icon {
  width: 18px;
  height: 18px;
}

.route-mobile-menu__summary-meta {
  flex: 0 0 auto;
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 600;
}

.route-mobile-menu__panel {
  display: grid;
  gap: 10px;
}

.route-mobile-menu__panel[hidden] {
  display: none;
}

.route-mobile-date-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 8px;
}

.route-mobile-date-form label {
  display: grid;
  min-width: 0;
  gap: 5px;
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
}

.route-mobile-date-form input[type="date"] {
  width: 100%;
  min-height: 36px;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--foreground);
  font: inherit;
  padding: 7px 9px;
}

.route-mobile-date-form input[type="date"]:focus {
  border-color: var(--primary);
  outline: 2px solid color-mix(in srgb, var(--primary) 16%, transparent);
  outline-offset: 0;
}

.route-mobile-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-bottom: 2px;
}

.route-mobile-list {
  display: grid;
  align-content: start;
  max-height: min(46vh, 420px);
  overflow: auto;
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: var(--radius);
}

.mobile-route-card {
  position: relative;
  min-width: 0;
  color: inherit;
  text-decoration: none;
  background: var(--card);
}

.mobile-route-card + .mobile-route-card {
  border-top: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
}

.mobile-route-card:hover {
  background: color-mix(in srgb, var(--muted) 60%, var(--card));
}

.mobile-route-card--selected {
  background: color-mix(in srgb, var(--route-color) 12%, var(--card));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--route-color) 42%, transparent);
}

.mobile-route-card__stripe {
  align-self: stretch;
  width: 4px;
  flex: 0 0 auto;
  background: var(--route-color);
}

.mobile-route-card__body {
  display: grid;
  min-width: 0;
  flex: 1;
  gap: 4px;
  padding: 9px 10px;
}

.mobile-route-card__top {
  min-width: 0;
  gap: 6px;
}

.mobile-route-card__top strong {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mobile-route-card__top .route-badge {
  flex: 0 0 auto;
}

.mobile-route-card__meta {
  justify-content: space-between;
  gap: 10px;
  color: var(--muted-foreground);
  font-size: 11px;
  line-height: 1.25;
}

.mobile-route-card__meta span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mobile-route-card__meta span:last-child {
  flex: 0 0 auto;
}

/* Route status badges mirror the Vue prototype: a small, dense pill with a solid
   pastel fill, no border, and a deep matching text color (Tailwind 100/700). */
.badge.route-badge {
  min-height: 0;
  border-color: transparent;
  padding: 2px 8px;
  font-size: 10px;
  font-weight: 600;
}

.route-badge--programada {
  background: #e0f2fe;
  color: #0369a1;
}

.route-badge--en-curso {
  background: #fef3c7;
  color: #b45309;
}

.route-badge--completada {
  background: #d1fae5;
  color: #047857;
}

.route-badge--pausada {
  background: #fee2e2;
  color: #b91c1c;
}

.route-badge--plantilla {
  background: var(--muted);
  color: var(--muted-foreground);
}

.route-badge--foreign {
  background: color-mix(in srgb, #0f766e 14%, var(--card));
  color: #0f766e;
}

.routes-workspace {
  display: grid;
  grid-template-columns: minmax(280px, var(--routes-list-width, 38%)) 8px minmax(0, 1fr);
  /* A single full-height row gives the columns a definite height so the list and
     detail panels scroll internally rather than stretching the page. */
  grid-template-rows: minmax(0, 1fr);
  flex: 1;
  min-height: 0;
  border-top: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
}

.is-routes-loading .routes-list,
.is-routes-loading .route-customer-panel {
  opacity: 0.72;
  transition: opacity 120ms ease;
}

.routes-list {
  display: grid;
  align-content: start;
  overflow: hidden;
}

/* Drag divider styled after the Vue prototype: a hairline seam with a small
   rounded grip pill (vertical grip dots) centered on it, both lighting up on
   hover/drag. The grip overlaps the seam, so the 8px track stays a thin line. */
.route-resize-handle {
  position: relative;
  display: grid;
  place-items: center;
  background: transparent;
  cursor: col-resize;
  touch-action: none;
}

/* The hairline seam. */
.route-resize-handle::after {
  content: "";
  position: absolute;
  inset-block: 0;
  left: 50%;
  width: 1px;
  transform: translateX(-50%);
  background: color-mix(in srgb, var(--border) 85%, transparent);
  transition: background-color 120ms ease;
}

/* A wider, invisible grab target so the thin seam is easy to grab. */
.route-resize-handle::before {
  content: "";
  position: absolute;
  inset: 0 -5px;
  z-index: 1;
}

.route-resize-handle__grip {
  /* Center the pill on the 8px handle box (same reference as the ::after seam)
     instead of via grid placement: an implicit `auto` grid column grows to the
     15px pill and left-aligns it in the 8px track, pushing the pill ~3.5px off
     the seam. Absolute + left:50% keeps grip and seam on the same axis. */
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  display: grid;
  place-items: center;
  width: 15px;
  height: 26px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--card);
  color: color-mix(in srgb, var(--muted-foreground) 80%, transparent);
  box-shadow: 0 1px 2px rgb(15 23 42 / 6%);
  transition: border-color 120ms ease, color 120ms ease, background-color 120ms ease;
}

.route-resize-handle__grip .icon {
  width: 14px;
  height: 14px;
}

.route-resize-handle:hover .route-resize-handle__grip,
.route-resize-handle:focus-visible .route-resize-handle__grip,
.is-resizing-pane .route-resize-handle__grip {
  border-color: color-mix(in srgb, var(--primary) 40%, var(--border));
  background: var(--accent);
  color: var(--foreground);
}

.route-resize-handle:hover::after,
.is-resizing-pane .route-resize-handle::after {
  background: color-mix(in srgb, var(--primary) 32%, var(--border));
}

.route-resize-handle:focus-visible {
  outline: none;
}

.is-resizing-pane {
  cursor: col-resize;
  user-select: none;
}

.route-card {
  position: relative;
  display: flex;
  color: inherit;
  text-decoration: none;
  transition: background-color 120ms ease, box-shadow 120ms ease;
}

.route-card + .route-card {
  border-top: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
}

.route-card:hover {
  background: color-mix(in srgb, var(--muted) 60%, var(--card));
}

.route-card--selected {
  background: color-mix(in srgb, var(--route-color) 12%, var(--card));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--route-color) 45%, transparent);
}

.route-card__stripe {
  width: 4px;
  flex: 0 0 auto;
  background: var(--route-color);
}

.route-card--selected .route-card__stripe {
  width: 6px;
}

.route-card__body {
  display: grid;
  min-width: 0;
  flex: 1;
  gap: 4px;
  padding: 9px 12px 10px;
}

/* The name grows to push the badge to the right edge; the name ellipsizes as the
   column narrows. flex-wrap is the safety net: if the badge can no longer sit
   beside even a truncated name, it drops to its own line — it is never clipped. */
.route-card__head {
  min-width: 0;
  flex-wrap: wrap;
  gap: 2px 8px;
}

.route-card__head strong {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.route-card__head .route-badge {
  flex: 0 0 auto;
}

.route-card__driver {
  min-width: 0;
  gap: 6px;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.25;
}

.avatar--small {
  width: 16px;
  height: 16px;
  font-size: 8px;
}

.route-card__metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px;
  color: var(--muted-foreground);
  font-size: 10px;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.route-card__metrics span:last-child {
  text-align: right;
}

.route-progress {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin-top: 1px;
}

.route-progress i {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--foreground) 80%, transparent);
}

.route-progress__dot--empty {
  background: color-mix(in srgb, var(--muted-foreground) 22%, transparent) !important;
}

.route-detail {
  display: grid;
  min-width: 0;
  position: relative;
  grid-template-rows: auto minmax(0, 1fr);
}

.route-detail--empty > :not(.route-detail__empty-state) {
  pointer-events: none;
  visibility: hidden;
}

.route-detail__empty-state {
  position: absolute;
  z-index: 2;
  inset: 0;
  background: var(--card);
}

/* The bar on top of the map. Flex-wrap (not grid) so a tight width never lets one
   cell slide under another and clip the status badge — items wrap instead. The
   route color is a full-height stripe flush to the left edge (0 left padding). */
.route-detail__header {
  position: relative;
  flex-wrap: wrap;
  gap: 6px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  background: color-mix(in srgb, var(--muted) 45%, var(--card));
  /* 41px = the routes-list toolbar's height (`.routes-filter` min-height 40px +
     `.routes-list-toolbar`'s 1px hairline). The two bars sit side by side at the
     same top edge, so anything else leaves their bottom hairlines out of step —
     which is what made the action cell read as squat. 41 - 1 border - 4 - 4
     padding = a 32px content box, and the action cells' -4px margins turn that
     back into a 40px cell. */
  min-height: 41px;
  padding: 4px 12px 4px 16px;
}

.route-detail__stripe {
  position: absolute;
  inset-block: 0;
  left: 0;
  width: 5px;
  background: var(--route-color);
}

.route-detail__actions {
  display: flex;
  flex: 0 0 auto;
  align-items: stretch;
  gap: 0;
  /* Actions sit on the left (closer to the routes list/cursor); the informative
     data (route name, seller, badges) is pushed to the right. The group is
     flush with the strip edges (full height, left edge) and its cells share
     1px dividers, like the "+ nueva ruta" button in the list toolbar. */
  order: -1;
  align-self: stretch;
  margin: -4px auto -4px -16px;
  padding-left: 5px; /* clear the route-color stripe on the left edge */
  border-right: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
}

/* Each action becomes a full-height, square-cornered cell. The 40px floor is
   what `align-self: stretch` cannot supply on the wrapped mobile line, where
   the group is its own `flex: 1 1 100%` line and nothing stretches it — the
   old `min-height: 0` collapsed the CTA to 16px there. On desktop the stretch
   already resolves to exactly 40px, so this floor changes nothing. */
.route-detail__actions > .button,
.route-detail__actions > .icon-button {
  align-self: stretch;
  height: auto;
  min-height: 40px;
  border-radius: 0;
}

/* The primary cell carries the whole bar's weight, so it gets more horizontal
   room and a full-size glyph than `.button--compact` (12px) would give it in a
   40px-tall cell. Both selectors are 0,2,0 / 0,3,0, so they beat
   `.button--compact` (line 9472) and `.button--compact .icon` (line 551). */
.route-detail__actions > .button {
  padding: 0 16px;
}

.route-detail__actions > .button .icon {
  width: 14px;
  height: 14px;
}

/* Icon actions are ghost cells with a shared left divider (mirrors the
   .routes-new-button "+" cell above the route list). */
.route-detail__actions > .icon-button {
  width: 40px;
  border: 0;
  border-left: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  background: transparent;
}

.route-detail__actions > .icon-button:hover {
  background: var(--accent);
  border-left-color: color-mix(in srgb, var(--border) 65%, transparent);
}

.route-detail__identity,
.route-detail__meta {
  display: flex;
  align-items: center;
  min-width: 0;
}

.route-detail__identity {
  gap: 8px;
  flex: 0 1 auto;
}

.route-detail__meta {
  flex: 1 1 auto;
  gap: 8px;
}

/* Keep the badge intact at any width; the seller name shrinks/ellipsizes first. */
.route-detail__meta .route-badge {
  flex: 0 0 auto;
}

.route-detail__seller {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.25;
}

.route-detail__seller-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.route-detail__header strong {
  overflow: hidden;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.route-edit-dialog {
  width: min(460px, calc(100vw - 28px));
  max-height: calc(100dvh - 28px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
  color: var(--foreground);
  overflow: hidden;
  padding: 0;
}

.route-edit-dialog::backdrop {
  background: color-mix(in srgb, var(--background) 55%, transparent);
}

.route-edit-dialog__form {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  max-height: inherit;
}

.route-edit-dialog__header,
.route-edit-dialog__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px;
}

.route-edit-dialog__header {
  border-bottom: 1px solid var(--border);
}

.route-edit-dialog__header div {
  display: grid;
  gap: 3px;
}

.route-edit-dialog__header strong {
  font-size: 16px;
}

.route-edit-dialog__header span {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.35;
}

.route-edit-dialog__body {
  display: grid;
  gap: 14px;
  overflow-y: auto;
  padding: 14px;
}

.route-edit-field,
.route-edit-toggle {
  display: grid;
  gap: 6px;
}

.route-edit-field span,
.route-edit-toggle strong {
  font-size: 12px;
  font-weight: 700;
}

.route-edit-field small {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.35;
}

.route-edit-field input,
.route-edit-field select {
  width: 100%;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--foreground);
  font: inherit;
  padding: 10px 11px;
}

.route-edit-field input:focus,
.route-edit-field select:focus {
  border-color: var(--primary);
  outline: 2px solid color-mix(in srgb, var(--primary) 18%, transparent);
  outline-offset: 0;
}

.route-edit-toggle {
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 36%, var(--card));
  padding: 12px;
}

.route-edit-toggle input {
  margin-top: 2px;
}

.route-edit-toggle span {
  display: grid;
  gap: 3px;
}

.route-edit-toggle small {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.35;
}

.route-edit-permissions {
  display: grid;
  gap: 12px;
  border: 1px solid color-mix(in srgb, var(--border) 88%, transparent);
  border-radius: var(--radius);
  padding: 12px;
}

.route-edit-permissions > div:first-child {
  display: grid;
  gap: 3px;
}

.route-edit-permissions > div:first-child strong {
  font-size: 12px;
}

.route-edit-permissions > div:first-child small {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.35;
}

.route-edit-permissions__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

@media (max-width: 520px) {
  .route-edit-permissions__grid {
    grid-template-columns: 1fr;
  }
}

.route-edit-dialog__footer {
  border-top: 1px solid var(--border);
  justify-content: flex-end;
}

.route-detail__body {
  display: grid;
  /* map | resize handle | customer panel (width is drag-adjustable). */
  grid-template-columns: minmax(0, 1fr) 8px var(--route-customer-width, 300px);
  min-height: 0;
}

.route-map-live {
  position: relative;
  min-height: 0;
  overflow: hidden;
  background: color-mix(in srgb, var(--muted) 42%, var(--card));
}

.route-map-live__canvas {
  width: 100%;
  height: 100%;
  min-height: 0;
}

.route-map-live__status {
  display: grid;
  min-height: 0;
  place-items: center;
  align-content: center;
  border: 0;
  background:
    linear-gradient(color-mix(in srgb, var(--border) 28%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--border) 28%, transparent) 1px, transparent 1px),
    color-mix(in srgb, var(--muted) 42%, var(--card));
  background-size: 32px 32px;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.4;
  padding: 24px;
  text-align: center;
}

/* Google Maps info window, restyled as an app card. The default header/close
   button is disabled in route_map_controller.js (headerDisabled), so the shell
   collapses to just the content; padding moves to .map-infowindow. Google sets
   its own padding/overflow with high specificity — hence !important. */
.gm-style .gm-style-iw-c {
  background: var(--card);
  border-radius: 10px;
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--border) 80%, transparent),
    0 12px 28px -12px rgb(0 0 0 / 0.4);
  padding: 0 !important;
  max-width: 260px !important;
}

.gm-style .gm-style-iw-d {
  overflow: hidden !important;
  padding: 0 !important;
}

/* The little arrow under the bubble — keep it the card color. */
.gm-style .gm-style-iw-tc::after {
  background: var(--card);
}

.map-infowindow {
  display: grid;
  justify-items: start;
  gap: 3px;
  padding: 10px 14px 11px;
  /* .gm-style resets to Roboto; pull the bubble back onto the app font. */
  font-family:
    Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  min-width: 140px;
}

.map-infowindow__title {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--foreground);
}

.map-infowindow__meta {
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

.map-infowindow__status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  padding: 2px 9px 2px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.5;
}

.map-infowindow__status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: currentcolor;
}

/* Same palette as the customer panel's .route-customer-status badges, so the
   bubble and the sidebar tell the same story. */
.map-infowindow__status--visited {
  background: #d1fae5;
  color: #047857;
}

.map-infowindow__status--in-visit {
  background: #fef3c7;
  color: #b45309;
}

.map-infowindow__status--pending {
  background: var(--muted);
  color: var(--muted-foreground);
}

.route-customer-panel {
  /* Fill the detail row as a min-height:0 grid (header + filter fixed, list
     flexible) so the customer list scrolls inside its own track instead of
     relying on a fixed max-height. Under browser zoom the panel simply gets
     shorter and the list keeps scrolling, rather than overflowing the
     fixed-height board frame and getting clipped by `.routes-panel`.
     The divider from the map is the resize handle's seam, so no border-left. */
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr);
  min-width: 0;
  min-height: 0;
}

.route-customer-panel__header,
.route-customer-row {
  justify-content: space-between;
  gap: 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  padding: 11px 12px;
}

.route-customer-panel__header {
  background: color-mix(in srgb, var(--muted) 38%, var(--card));
  font-size: 12px;
}

.route-customer-panel__header span {
  color: var(--muted-foreground);
}

/* Visit counter + the "Agregar cliente" plus, kept on the header's right edge
   and sized down so the action doesn't grow the row. */
.route-customer-panel__actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.route-customer-panel__actions .icon-button {
  width: 24px;
  height: 24px;
}

/* A customer row plus its remove action. The row itself stays a link, so the ×
   sits beside it and the group takes over the divider to span the full width. */
.route-customer-row-group {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
}

.route-customer-row-group .route-customer-row {
  flex: 1;
  min-width: 0;
  border-bottom: 0;
}

/* Dimmed rather than hover-revealed: on a touch screen there is no hover, and an
   invisible-but-tappable control is worse than a quiet one. */
.route-customer-remove {
  display: grid;
  flex: 0 0 auto;
  place-items: center;
  width: 30px;
  border: 0;
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 120ms ease, color 120ms ease, background-color 120ms ease;
}

.route-customer-row-group:hover .route-customer-remove {
  opacity: 1;
}

.route-customer-remove:hover,
.route-customer-remove:focus-visible {
  background: var(--muted);
  color: var(--destructive);
  opacity: 1;
}

.route-customer-list {
  /* Height of one dense mobile row (7px padding × 2 + the name/code lines + the
     divider). The mobile block caps the list at ten of these; keep the two in
     step if the row's padding or type sizes change. */
  --route-customer-row-height: 49px;
  min-height: 0;
  overflow: auto;
}

/* Client-side filter box for the selected route's customers, mirroring the
   route-list buscador. Fuses flush between the panel header (its bottom border)
   and the scrollable list, sharing borders instead of floating as an inset box. */
.route-customer-filter {
  margin: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
}

.route-customer-filter-empty {
  margin: 0;
  padding: 16px 12px;
  color: var(--muted-foreground);
  font-size: 12px;
  text-align: center;
}

.route-customer-row span {
  display: grid;
  min-width: 0;
  gap: 2px;
}

.route-customer-row strong,
.route-customer-row small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.route-customer-row strong {
  font-size: 12px;
}

.route-customer-row small,
.route-customer-row em {
  color: var(--muted-foreground);
  font-size: 11px;
  font-style: normal;
}

.routes-empty {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 6px;
  min-height: 160px;
  color: var(--muted-foreground);
  padding: 18px;
  text-align: center;
}

.routes-empty strong {
  color: var(--foreground);
}

/* --- Routes screen enhancements ---------------------------------------- */

.routes-panel__actions {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 8px;
}

.routes-panel__actions .button {
  gap: 6px;
}

/* --- "Operar todas" mass-creation launcher ------------------------------ */

/* Registered so --mass-fill can transition: the fill sweep animates smoothly
   between board refreshes instead of jumping. */
@property --mass-fill {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}

.route-mass-launch {
  display: inline-flex;
}

/* Same compact shape as the neighboring header actions, in the app green with
   a darker outline. While the batch runs the button IS the progress bar: a
   slightly diagonal boundary sweeps right-to-left as --mass-fill grows — deep
   green (routes already created) advancing over the button's base green. */
.button--mass {
  --mass-fill: 0%;
  background: var(--success);
  /* A gently darker shade of the green fill, not a near-black outline, so the
     border reads as part of the button instead of a hard dark contour. */
  border-color: color-mix(in srgb, var(--success) 85%, black);
  color: #fff;
}

.button--mass:hover:not(:disabled) {
  background: color-mix(in srgb, var(--success) 86%, black);
}

.button--mass:disabled {
  cursor: default;
}

/* Running is disabled only to block a double launch — it is active work, not
   an unavailable action, so it keeps full color. Doubled class to outrank the
   generic .button:disabled fade declared later in the file. */
.button.button--mass-running:disabled {
  opacity: 1;
  cursor: progress;
}

.button--mass-running {
  background: linear-gradient(
    250deg,
    color-mix(in srgb, var(--success) 48%, black) calc(var(--mass-fill) - 4%),
    var(--success) calc(var(--mass-fill) + 4%)
  );
  transition: --mass-fill 500ms ease;
}

/* --- Mass-creation results (dialog + card badges) ------------------------ */

.route-mass-dialog__body {
  display: grid;
  gap: 8px;
  align-content: start;
}

.route-mass-dialog__note {
  margin: 0;
  font-size: 12.5px;
  color: var(--muted-foreground);
}

/* Count tiles, mirroring the coverage modal's stats grid. */
.route-mass-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 4px;
}

.route-mass-stat {
  display: grid;
  gap: 2px;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 36%, var(--card));
  padding: 12px;
  text-align: center;
}

.route-mass-stat strong {
  font-size: 22px;
  line-height: 1.1;
}

.route-mass-stat span {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 600;
}

.route-mass-stat--ok {
  border-color: color-mix(in srgb, var(--success) 45%, var(--border));
  background: color-mix(in srgb, var(--success) 10%, var(--card));
}

.route-mass-stat--warn {
  border-color: color-mix(in srgb, #f59e0b 55%, var(--border));
  background: color-mix(in srgb, #f59e0b 12%, var(--card));
}

/* One card per route the batch could not create: route + badge, then the why. */
.route-mass-failure {
  display: grid;
  gap: 3px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  padding: 10px 12px;
}

.route-mass-failure__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.route-mass-failure__head strong {
  font-size: 13px;
  font-weight: 600;
}

.route-mass-failure__message {
  font-size: 12px;
  color: var(--muted-foreground);
}

.route-mass-failure__badge {
  flex: none;
  border-radius: 999px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

.route-mass-failure__badge--insufficient_inventory {
  background: color-mix(in srgb, #d97706 16%, var(--card));
  color: color-mix(in srgb, #d97706 80%, var(--foreground));
}

.route-mass-failure__badge--no_load {
  background: var(--muted);
  color: var(--muted-foreground);
}

.route-mass-failure__badge--invalid {
  background: color-mix(in srgb, var(--destructive) 14%, var(--card));
  color: color-mix(in srgb, var(--destructive) 78%, var(--foreground));
}

.route-mass-failure__message {
  overflow-wrap: anywhere;
}

/* The badge doubles as the entry point to the results dialog when it sits on a
   route card. */
.route-card__mass-badge {
  cursor: pointer;
}

.route-card__mass-badge:hover,
.route-card__mass-badge:focus-visible {
  filter: brightness(0.94);
}

.icon-12 {
  width: 12px;
  height: 12px;
}

/* --- Route inventory print view ---------------------------------------- */

.route-inventory-print {
  --print-text: #111827;
  --print-muted: #4b5563;
  --print-line: #9ca3af;
  --print-head: #cbd5e1;
  --print-zebra: #eef2f7;
  width: min(100%, 920px);
  margin: 0 auto;
  padding: 18px 20px 40px;
  color: var(--print-text);
  background: #f3f4f6;
}

.route-inventory-print,
.route-inventory-print * {
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

.route-inventory-print__toolbar {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
}

.route-inventory-sheet {
  min-height: 10in;
  border: 1px solid #d1d5db;
  background: #ffffff;
  box-shadow: 0 12px 28px rgb(15 23 42 / 10%);
  padding: 28px 32px;
}

.route-inventory-sheet + .route-inventory-sheet {
  margin-top: 18px;
}

.route-inventory-sheet--route {
  break-before: page;
  page-break-before: always;
}

.route-inventory-sheet--first-route {
  break-before: auto;
  page-break-before: auto;
}

.route-inventory-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 260px;
  gap: 20px;
  align-items: start;
  border-bottom: 2px solid var(--print-text);
  padding-bottom: 10px;
  margin-bottom: 14px;
}

.route-inventory-header h1,
.route-inventory-header p {
  margin: 0;
}

.route-inventory-header h1 {
  font-size: 22px;
  line-height: 1.1;
}

.route-inventory-header p {
  margin-top: 4px;
  color: var(--print-muted);
  font-size: 12px;
}

.route-inventory-eyebrow {
  margin: 0 0 3px !important;
  color: var(--print-text) !important;
  font-size: 10px !important;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.route-inventory-header__meta {
  display: grid;
  gap: 3px;
  border-left: 1px solid var(--print-line);
  padding-left: 14px;
  color: var(--print-muted);
  font-size: 11px;
  line-height: 1.35;
}

.route-inventory-header__meta strong {
  color: var(--print-text);
}

.route-inventory-kpis {
  display: grid;
  grid-template-columns: minmax(180px, 240px);
  gap: 8px;
  margin-bottom: 12px;
}

.route-inventory-kpis > div {
  border: 1px solid var(--print-line);
  background: #f8fafc;
  padding: 8px 10px;
}

.route-inventory-kpis span {
  display: block;
  color: var(--print-muted);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
}

.route-inventory-kpis strong {
  display: block;
  margin-top: 2px;
  font-size: 18px;
  line-height: 1.1;
}

.route-inventory-empty {
  display: grid;
  gap: 4px;
  border: 1px dashed var(--print-line);
  margin-top: 18px;
  padding: 18px;
  color: var(--print-muted);
  font-size: 13px;
}

.route-inventory-empty strong {
  color: var(--print-text);
}

.route-inventory-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 10.5px;
  line-height: 1.25;
}

.route-inventory-table th,
.route-inventory-table td {
  border-bottom: 1px solid var(--print-line);
  padding: 4px 6px;
  text-align: right;
  vertical-align: top;
}

.route-inventory-table th {
  background: var(--print-head);
  color: var(--print-text);
  font-size: 9.5px;
  font-weight: 800;
  text-transform: uppercase;
}

.route-inventory-table tbody tr:nth-child(even) td {
  background: var(--print-zebra);
}

.route-inventory-table th:nth-child(-n + 2),
.route-inventory-table td:nth-child(-n + 2) {
  text-align: left;
}

.route-inventory-code {
  width: 96px;
  color: var(--print-text);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 9.5px;
  font-weight: 700;
  white-space: nowrap;
}

.route-inventory-table td:nth-child(2) strong,
.route-inventory-table td:nth-child(2) span {
  display: block;
}

.route-inventory-table td:nth-child(2) span {
  margin-top: 1px;
  color: var(--print-muted);
  font-size: 9px;
}

.route-inventory-table tfoot td {
  background: #d1d5db;
  color: var(--print-text);
  font-weight: 800;
}

.route-inventory-check {
  width: 42px;
}

.route-inventory-check::before {
  content: "";
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 1.5px solid var(--print-text);
}

.route-inventory-signatures {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
  margin-top: 30px;
  color: var(--print-muted);
  font-size: 10px;
  font-weight: 700;
  text-align: center;
}

.route-inventory-signatures span {
  border-top: 1px solid var(--print-text);
  padding-top: 5px;
}

@media (max-width: 760px) {
  .route-inventory-print {
    padding: 12px 0 28px;
  }

  .route-inventory-print__toolbar {
    padding: 0 12px;
  }

  .route-inventory-sheet {
    min-height: 0;
    border-right: 0;
    border-left: 0;
    padding: 20px 14px;
  }

  .route-inventory-header {
    grid-template-columns: 1fr;
  }

  .route-inventory-header__meta {
    border-left: 0;
    border-top: 1px solid var(--print-line);
    padding: 8px 0 0;
  }
}

@page {
  size: letter;
  margin: 9mm;
}

@media print {
  * {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  html,
  body {
    background: #ffffff !important;
  }

  body.app-shell {
    display: block;
  }

  .route-inventory-print {
    width: auto;
    margin: 0;
    padding: 0;
    background: #ffffff;
  }

  .route-inventory-print__toolbar,
  .flash {
    display: none !important;
  }

  .route-inventory-sheet {
    min-height: auto;
    border: 0;
    box-shadow: none;
    padding: 0;
  }

  .route-inventory-sheet + .route-inventory-sheet {
    margin-top: 0;
  }

  .route-inventory-header {
    grid-template-columns: minmax(0, 1fr) 245px;
    margin-bottom: 10px;
    padding-bottom: 7px;
  }

  .route-inventory-header h1 {
    font-size: 18px;
  }

  .route-inventory-header p,
  .route-inventory-header__meta {
    font-size: 9.5px;
  }

  .route-inventory-kpis {
    margin-bottom: 8px;
  }

  .route-inventory-kpis > div {
    padding: 5px 8px;
  }

  .route-inventory-kpis strong {
    font-size: 14px;
  }

  .route-inventory-table {
    font-size: 8.7px;
  }

  .route-inventory-table th,
  .route-inventory-table td {
    padding: 2.8px 4px;
  }

  .route-inventory-table th {
    font-size: 8px;
  }

  .route-inventory-code {
    width: 82px;
    font-size: 7.8px;
  }

  .route-inventory-table td:nth-child(2) span {
    font-size: 7.8px;
  }

  .route-inventory-signatures {
    margin-top: 24px;
  }
}

/* On mobile, collapse the top-right rules/coverage actions to icon-only so they
   stay in the corner without crowding the header. */
@media (max-width: 720px) {
  .routes-panel__actions .routes-action-label {
    display: none;
  }

  .routes-panel__actions .button {
    padding: 0 9px;
  }

  .routes-panel__actions .routes-action-icon {
    width: 16px;
    height: 16px;
  }
}

.routes-list-column {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  min-width: 0;
  overflow: hidden;
}

/* The buscador fuses into its column: no inner rounded box, it spans the full
   width/height of the toolbar and shares the toolbar's bottom border as the
   divider. The "+" (nueva ruta) keeps its own slot, split off by a hairline. */
.routes-list-toolbar {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
}

.routes-filter {
  display: flex;
  flex: 1;
  min-width: 0;
  min-height: 40px;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  background: transparent;
  transition: background-color 120ms ease;
}

.routes-filter:focus-within {
  background: color-mix(in srgb, var(--muted) 30%, transparent);
}

.routes-filter__icon {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  color: var(--muted-foreground);
}

.routes-filter input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--foreground);
  font: inherit;
  /* `font: inherit` would pull the browser default 16px here (body sets no
     size); pin it to the compact control size so the placeholder/text match
     the rest of the toolbar instead of looking oversized. */
  font-size: 13px;
  padding: 9px 0;
}

.routes-filter input::placeholder {
  color: var(--muted-foreground);
  font-size: 13px;
  opacity: 1;
}

.routes-filter input:focus {
  outline: none;
}

/* Hide the browser's native search clear so it doesn't double up with ours. */
.routes-filter input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

/* The faint floating "X" that clears the field, right-aligned. Hidden while the
   field is empty (placeholder showing) so it only appears once there's a query. */
.routes-filter__clear {
  /* The slot is ALWAYS reserved (visibility, not display) so revealing the X
     never resizes the input or shifts the "+"; it just fades in on input. */
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: color-mix(in srgb, var(--muted-foreground) 70%, transparent);
  cursor: pointer;
  visibility: hidden;
  pointer-events: none;
  transition: color 120ms ease, background-color 120ms ease;
}

.routes-filter:has(input:not(:placeholder-shown)) .routes-filter__clear {
  visibility: visible;
  pointer-events: auto;
}

.routes-filter__clear:hover {
  color: var(--foreground);
  background: color-mix(in srgb, var(--muted) 55%, transparent);
}

.routes-filter__clear .icon {
  width: 13px;
  height: 13px;
}

/* "+" nueva ruta: a flush, full-height slot fused to the buscador, with a fixed
   width that never changes with the buscador's content. It is the only way to
   create a route from this screen, so it is filled — as a transparent grey "+"
   it read as one more divider and people missed it. */
.routes-new-button {
  flex: 0 0 auto;
  align-self: stretch;
  width: 44px;
  height: auto;
  border: 0;
  border-radius: 0;
  background: var(--primary);
  color: var(--primary-foreground);
}

/* Hover deepens the fill. It has to override .icon-button:hover, which paints a
   light `--accent` background and a `--foreground` icon — and used to recolor
   `border-color`, visible only on this cell's single left hairline (now gone). */
.routes-new-button:hover,
.routes-new-button:focus-visible {
  background: color-mix(in srgb, var(--primary) 85%, var(--card));
  color: var(--primary-foreground);
}

/* A heavier glyph so the "+" holds up against the filled cell. */
.routes-new-button .icon {
  stroke-width: 2.5;
}

/* The list now scrolls inside its column (toolbar above, hint below). */
.routes-list {
  overflow: auto;
}

.routes-filter-empty {
  margin: 0;
  padding: 16px 12px;
  color: var(--muted-foreground);
  font-size: 12px;
  text-align: center;
}

.route-customer-row--link {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease;
}

.route-customer-row--link:hover {
  background: var(--muted);
}

/* Visit progress: a left-edge accent bar (survives the hover background) plus a
   status pill, so it reads which customers were visited on this route-day and
   which are still pending. Colors mirror the route status badges. */
.route-customer-row--visited {
  box-shadow: inset 3px 0 0 var(--success);
}

.route-customer-row--in-visit {
  box-shadow: inset 3px 0 0 #d97706;
}

/* Push the status pill + position number to the right, leaving the name/code on
   the left. Only the first child (the name/code block) gets the auto margin. */
.route-customer-row > span:first-child {
  margin-inline-end: auto;
}

/* More specific than the broad `.route-customer-row span { display: grid }` rule
   above, so the pill stays an inline chip instead of a grid. */
.route-customer-row .route-customer-status {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  gap: 6px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  font-style: normal;
  white-space: nowrap;
}

.route-customer-status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: currentColor;
}

.route-customer-status--visited {
  background: #d1fae5;
  color: #047857;
}

.route-customer-status--in-visit {
  background: #fef3c7;
  color: #b45309;
}

.route-customer-status--pending {
  background: var(--muted);
  color: var(--muted-foreground);
}

.route-config-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.route-days-toggle {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.route-day-toggle {
  min-width: 44px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: 12px;
  font-weight: 700;
  padding: 7px 10px;
}

.route-day-toggle:hover {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  color: var(--foreground);
}

.route-day-toggle--on {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--primary-foreground);
}

.route-coverage-dialog {
  width: min(540px, calc(100vw - 28px));
}

.route-coverage-body {
  display: grid;
  align-content: start;
  gap: 16px;
  /* Reserve the results height up front so the modal opens at its final size and
     does not grow when the coverage audit resolves (no layout shift). */
  min-height: min(400px, 60vh);
  max-height: min(60vh, 520px);
  overflow: auto;
}

/* While loading, the only child is the status note: stretch it to fill the
   reserved height so the "Calculando…" text stays vertically centered. */
.route-coverage-body > .routes-empty:only-child {
  min-height: min(372px, 56vh);
}

.route-coverage-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.route-coverage-stat {
  display: grid;
  gap: 2px;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 36%, var(--card));
  padding: 12px;
  text-align: center;
}

.route-coverage-stat strong {
  font-size: 22px;
  line-height: 1.1;
}

.route-coverage-stat span {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 600;
}

.route-coverage-stat--warn {
  border-color: color-mix(in srgb, #f59e0b 55%, var(--border));
  background: color-mix(in srgb, #f59e0b 12%, var(--card));
}

.route-coverage-pending {
  display: grid;
  gap: 8px;
}

.route-coverage-pending__hint {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12px;
}

.route-coverage-pending__list {
  display: grid;
  gap: 4px;
  max-height: 260px;
  overflow: auto;
}

.route-coverage-pending__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  color: inherit;
  text-decoration: none;
  padding: 8px 10px;
}

.route-coverage-pending__row:hover {
  background: var(--muted);
  border-color: color-mix(in srgb, var(--primary) 40%, var(--border));
}

.route-coverage-pending__row strong {
  font-size: 13px;
  font-weight: 600;
}

.route-coverage-pending__row small {
  color: var(--muted-foreground);
  font-size: 11px;
}

.route-coverage-download {
  gap: 6px;
  margin-right: auto;
}

/* ---- Full-CEDIS route coverage map ---- */

.coverage-map-main {
  width: min(100%, 1500px);
  height: calc(100dvh - var(--app-shell-topbar-height) - var(--app-shell-top-inset));
  margin: 0 auto;
  padding: 12px 24px var(--app-shell-bottom-gutter);
}

.coverage-map-shell {
  display: grid;
  height: 100%;
  min-height: 0;
  grid-template-rows: auto minmax(0, 1fr);
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
}

.coverage-map-header,
.coverage-map-heading,
.coverage-map-header__actions {
  display: flex;
  align-items: center;
}

.coverage-map-header {
  min-height: 64px;
  justify-content: space-between;
  gap: 18px;
  border-bottom: 1px solid var(--border);
  padding: 10px 14px;
}

.coverage-map-heading {
  min-width: 0;
  gap: 10px;
}

.coverage-map-heading h1,
.coverage-map-heading p {
  margin: 0;
}

.coverage-map-heading h1 {
  font-size: 18px;
  line-height: 1.25;
}

.coverage-map-heading p,
.coverage-map-generated {
  color: var(--muted-foreground);
  font-size: 12px;
}

.coverage-map-header__actions {
  gap: 10px;
}

.coverage-map-stage {
  position: relative;
  min-height: 0;
  overflow: hidden;
  background: color-mix(in srgb, var(--muted) 42%, var(--card));
}

.coverage-map-canvas {
  width: 100%;
  height: 100%;
}

.coverage-map-point-layer {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}

.coverage-map-status {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: grid;
  place-items: center;
  background: rgb(255 255 255 / 0.72);
  color: var(--muted-foreground);
  font-size: 13px;
  text-align: center;
  backdrop-filter: blur(2px);
}

.dark .coverage-map-status {
  background: rgb(15 23 42 / 0.72);
}

.coverage-map-status--persistent {
  pointer-events: none;
}

.coverage-map-controls {
  position: absolute;
  z-index: 20;
  top: 12px;
  left: 12px;
  display: grid;
  width: min(360px, calc(100% - 24px));
  max-height: calc(100% - 24px);
  gap: 12px;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 12px;
  background: color-mix(in srgb, var(--card) 94%, transparent);
  box-shadow: 0 14px 34px -18px rgb(0 0 0 / 0.55);
  padding: 12px;
  backdrop-filter: blur(10px);
}

.coverage-map-modes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 3px;
  border-radius: 9px;
  background: var(--muted);
  padding: 3px;
}

.coverage-map-mode {
  min-height: 42px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  padding: 6px;
}

.coverage-map-mode:hover {
  color: var(--foreground);
}

.coverage-map-mode--active {
  background: var(--card);
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.14);
  color: var(--foreground);
}

.coverage-map-filter {
  display: grid;
  gap: 5px;
}

.coverage-map-filter > span,
.coverage-map-legend-heading strong {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.coverage-map-filter .select {
  min-height: 34px;
  font-size: 12px;
}

.coverage-map-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}

.coverage-map-stats > div {
  display: grid;
  gap: 2px;
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--muted) 35%, var(--card));
  padding: 8px;
  text-align: center;
}

.coverage-map-stats strong {
  font-size: 16px;
  font-variant-numeric: tabular-nums;
}

.coverage-map-stats span {
  color: var(--muted-foreground);
  font-size: 9px;
  font-weight: 600;
}

.coverage-map-legend-wrap {
  display: grid;
  min-height: 0;
  gap: 8px;
  overflow: hidden;
}

.coverage-map-legend-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.coverage-map-legend-heading span {
  color: var(--muted-foreground);
  font-size: 9px;
  text-align: right;
}

.coverage-map-legend {
  display: grid;
  min-height: 0;
  gap: 2px;
  overflow: auto;
}

.coverage-map-legend__row {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr) auto;
  align-items: center;
  gap: 7px;
  min-height: 26px;
  border-radius: 6px;
  padding: 3px 5px;
  font-size: 11px;
}

.coverage-map-legend__row:hover {
  background: var(--muted);
}

.coverage-map-legend__row > span:nth-child(2) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.coverage-map-legend__row strong {
  color: var(--muted-foreground);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
}

.coverage-map-legend__swatch {
  width: 10px;
  height: 10px;
  border: 1px solid rgb(255 255 255 / 0.75);
  border-radius: 999px;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--border) 60%, transparent);
}

.coverage-map-infowindow__link {
  margin-top: 5px;
  color: var(--primary);
  font-size: 11px;
  font-weight: 700;
  text-decoration: none;
}

.coverage-map-infowindow__link:hover {
  text-decoration: underline;
}

@media (max-width: 720px) {
  .coverage-map-main {
    padding: 0;
  }

  .coverage-map-shell {
    border: 0;
    border-radius: 0;
  }

  .coverage-map-header {
    min-height: 58px;
    padding: 8px 10px;
  }

  .coverage-map-heading p,
  .coverage-map-generated {
    display: none;
  }

  .coverage-map-controls {
    top: 8px;
    left: 8px;
    width: calc(100% - 16px);
    max-height: min(46%, 360px);
    padding: 9px;
  }

  .coverage-map-mode {
    min-height: 38px;
    font-size: 10px;
  }
}

@media (max-width: 720px) {
  .device-admin-row {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
  }

  /* Grid, not flex + `width: 100%`: grid items stretch by default, so the
     forms fill the row without depending on a percentage width resolving on a
     flex item (which is what the committed baseline shows failing here). */
  .device-admin-device__actions {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }

  .device-admin-device__actions .button {
    width: 100%;
  }

  .device-diagnostic-options,
  .device-diagnostic-options > summary {
    width: 100%;
  }

  .device-diagnostic-options > summary {
    justify-content: center;
  }

  .device-admin-device__release {
    margin-left: 0;
  }

  .device-diagnostic-options form {
    position: static;
    width: 100%;
    margin-top: 8px;
  }

  .device-diagnostic-header .profile-section__header--with-avatar {
    flex-wrap: wrap;
  }

  .profile-section__header--with-avatar .device-diagnostic-header__state {
    flex-basis: 100%;
    justify-items: start;
    margin-left: 0;
    text-align: left;
  }

  .device-diagnostic-facts {
    grid-template-columns: minmax(0, 1fr);
  }

  .user-device-panel {
    margin-top: 18px;
  }

  .user-device-card {
    grid-template-columns: minmax(0, 1fr);
  }

  .user-device-card__actions {
    grid-column: 1;
    grid-row: auto;
  }

  .user-device-card__actions form,
  .user-device-card__actions .button {
    width: 100%;
  }

  .user-device-card__meta {
    grid-template-columns: minmax(0, 1fr);
  }

  .routes-main {
    padding: 8px 0 var(--app-shell-bottom-gutter);
    /* Mobile stacks list over detail; let the page scroll naturally instead of
       the desktop fixed-height frame. */
    height: auto;
    display: block;
  }

  .routes-panel {
    border-right: 0;
    border-left: 0;
    border-radius: 0;
    box-shadow: none;
  }

  .routes-panel__header {
    padding-right: 14px;
    padding-left: 14px;
  }

  .route-mobile-menu {
    display: block;
    border-top: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
    background: var(--card);
  }

  .route-mobile-menu__summary {
    display: flex;
    min-height: 44px;
    padding: 9px 14px;
  }

  .route-mobile-menu[data-open] .route-mobile-menu__summary {
    border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  }

  .route-mobile-menu__panel {
    padding: 10px 14px 12px;
  }

  .route-week-strip,
  .route-filter-bar,
  .routes-list-column {
    display: none;
  }

  .route-detail__actions {
    flex: 1 1 100%;
    order: 0;
    margin: 0;
    padding-left: 0;
    /* Here the group is detached from the bar edges (margin: 0 above), so the
       fused desktop cells would otherwise read as a black stripe glued to two
       loose icons. Frame the whole group instead: one segmented control, with
       the icon cells' existing `border-left` hairlines as its dividers. The
       border colour matches `.route-detail__actions > .icon-button:hover`'s
       `border-left-color` (line 10273) so hover cannot mismatch one edge. */
    border: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
    border-radius: var(--radius);
    overflow: hidden;
  }

  .route-detail__actions .button {
    flex: 1 1 auto;
  }

  .routes-workspace,
  .route-detail__body {
    grid-template-columns: 1fr;
    grid-template-rows: none;
  }

  .route-detail {
    grid-column: 1;
  }

  .route-resize-handle {
    display: none;
  }

  .routes-list,
  .route-customer-panel {
    border-right: 0;
    border-left: 0;
  }

  /* On desktop the panel is a min-height:0 grid inside the board's fixed frame,
     so the list already scrolls in its own track. Mobile drops that frame
     (`.routes-main` above goes `height: auto; display: block`), so a route with
     200 customers printed all 200 down the page. Give the list back a track of
     its own — about ten rows — and let the rest scroll inside it. */
  .route-customer-list {
    max-height: calc(var(--route-customer-row-height) * 10);
  }

  /* Denser rows so those ten fit without the track dominating the screen: the
     name and code are the only things read while scanning. */
  .route-customer-row {
    padding: 7px 12px;
  }

  .route-customer-row span {
    gap: 0;
  }

  .route-map-live,
  .route-map-live__canvas,
  .route-map-live__status {
    min-height: 320px;
  }
}

/* ---- Account settings (Configuración de la cuenta) ---- */

.account-main {
  width: min(100%, 760px);
  margin: 0 auto;
  padding: 24px 20px 56px;
  display: grid;
  gap: 24px;
}

/* The settings form wraps the Datos generales / Preferencias panels, but the
   Suscripción panel sits outside it (it has its own nested billing forms).
   display: contents keeps the form from creating its own grid track — otherwise,
   when Suscripción is active and the form's panels are all hidden, the empty
   form still occupies a row and adds a second 24px gap (nav → empty form →
   panel), pushing the subscription card lower than the other two tabs. */
.account-main > form {
  display: contents;
}

/* Sub-tabs (Datos generales / Preferencias / Suscripción) reuse the top-menu
   tab styling: same outer `.assistant-tabs` centering grid + inner
   `.assistant-tabs__list` pill, just narrower (3 columns, 480px cap instead of
   the header's 4 columns / 600px) since there are only three of them and
   `.account-main` tops out at 760px. */
.settings-tabs {
  grid-template-columns: minmax(0, 1fr) min(100%, 480px) minmax(0, 1fr);
}

/* The header's translucent `.assistant-tabs__list` fill (72% card over
   transparent) leans on the topbar's blur + neighbouring high-contrast chrome
   (search bar, avatar) to read as a distinct control. Floating alone on the
   page here, that translucency barely differs from `--background` and the
   unselected tabs disappear. Use a solid, more contrasty fill + border instead. */
.settings-tabs .assistant-tabs__list {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  background: var(--muted);
  border-color: var(--border);
}

/* Keep each label on one line (the buttons hold raw text, not a <span>, so the
   .tab span ellipsis rule doesn't apply). */
.settings-tabs .tab {
  white-space: nowrap;
}

/* Mobile collapse. `.assistant-tabs` already collapses to a single full-width
   pill under the max-width:900px/640px breakpoints, but this `.settings-tabs`
   override of the outer centering grid lives *after* those media blocks in the
   source, so (media queries adding no specificity) it out-cascades them and the
   3-column desktop grid leaks onto phones — the side tracks collapse to 0 and
   the tab list, placed in track 1, disappears. Re-assert the single-column
   collapse here, after the desktop rule, so source order lets it win. */
@media (max-width: 900px) {
  .settings-tabs {
    grid-template-columns: 1fr;
  }
}

.settings-card {
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 12px;
  background: var(--card);
  box-shadow: var(--shadow);
}

/* Separate stacked cards (e.g. Preferencias / Datos generales) inside the form. */
.settings-card + .settings-card {
  margin-top: 28px;
}

/* A save/status bar placed at the top of a tall card; mirrors the footer but
   sits under the header with a bottom border instead of a top one. */
.settings-card__header-actions {
  border-top: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
}

.settings-card__header {
  padding: 20px 22px 0;
}

.settings-card__header h2 {
  margin: 0;
  /* Undo the generic `.settings-card h2` eyebrow treatment (muted uppercase) —
     these are real card titles, not section labels. */
  color: var(--foreground);
  font-size: 18px;
  line-height: 1.2;
  text-transform: none;
}

.settings-card__header p {
  margin: 6px 0 0;
  color: var(--muted-foreground);
  font-size: 13px;
  line-height: 1.45;
}

.settings-card__body {
  display: grid;
  gap: 28px;
  padding: 18px 22px;
}

.settings-card__footer {
  display: flex;
  flex-direction: column;
  gap: 12px;
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  padding: 16px 22px;
}

.settings-card__footer-actions {
  display: flex;
  gap: 8px;
}

.settings-status {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12px;
}

.settings-status--dirty {
  color: #b45309;
}

/* Deployed build stamp at the bottom of the Configuración screen — a subtle
   tinted pill, informational only. */
.app-version {
  justify-self: center;
  margin: 8px 0 0;
  padding: 3px 10px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 65%, var(--card));
  color: var(--muted-foreground);
  font-size: 11px;
  line-height: 1.6;
  white-space: nowrap;
}

@media (min-width: 640px) {
  .settings-card__footer {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.settings-group h3 {
  margin: 0 0 12px;
  font-size: 13px;
  font-weight: 600;
}

.settings-group__hint {
  margin: 0 0 8px;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.45;
}

.settings-group__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.settings-group__head h3 {
  margin: 0;
}

.settings-group__actions {
  display: flex;
  gap: 6px;
}

.custom-fields-overview {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.custom-fields-overview__item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 11px 12px;
  border: 1px solid color-mix(in srgb, var(--border) 68%, transparent);
  border-radius: calc(var(--radius) - 2px);
  background: color-mix(in srgb, var(--muted) 32%, transparent);
}

.custom-fields-overview__item > span:last-child {
  display: grid;
  min-width: 0;
  gap: 2px;
}

.custom-fields-overview__item strong {
  font-size: 13px;
  line-height: 1.2;
}

.custom-fields-overview__item small {
  color: var(--muted-foreground);
  font-size: 11px;
  line-height: 1.25;
}

.custom-fields-overview__icon {
  display: grid;
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  place-items: center;
  border-radius: 9px;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 11%, transparent);
}

.custom-fields-overview__icon svg {
  width: 16px;
  height: 16px;
}

.custom-fields-dialog {
  width: min(680px, calc(100vw - 28px));
  max-height: min(760px, calc(100dvh - 28px));
  padding: 0;
  overflow: hidden;
}

.custom-fields-dialog__header,
.custom-fields-dialog__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 18px;
}

.custom-fields-dialog__header {
  border-bottom: 1px solid var(--border);
}

.custom-fields-dialog__header > div {
  display: grid;
  gap: 3px;
}

.custom-fields-dialog__header strong {
  font-size: 15px;
}

.custom-fields-dialog__header span,
.custom-fields-dialog__footer > span {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.4;
}

.custom-fields-dialog__body {
  display: grid;
  gap: 16px;
  padding: 18px;
  overflow-y: auto;
}

.custom-fields-dialog__tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 3px;
  padding: 3px;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, var(--muted) 55%, transparent);
}

.custom-fields-dialog__tab {
  min-height: 34px;
  padding: 6px 10px;
  border: 0;
  border-radius: 7px;
  color: var(--muted-foreground);
  background: transparent;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.custom-fields-dialog__tab:hover {
  color: var(--foreground);
}

.custom-fields-dialog__tab.is-active {
  color: var(--foreground);
  background: var(--card);
  box-shadow: 0 1px 3px color-mix(in srgb, var(--foreground) 12%, transparent);
}

.custom-fields-dialog__panel {
  display: grid;
  gap: 10px;
}

.custom-fields-dialog__panel[hidden] {
  display: none;
}

.custom-fields-dialog__panel-head {
  display: grid;
  gap: 2px;
}

.custom-fields-dialog__panel-head strong {
  font-size: 13px;
}

.custom-fields-dialog__panel-head span {
  color: var(--muted-foreground);
  font-size: 11px;
  line-height: 1.4;
}

.custom-fields-dialog__list {
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card);
}

.custom-fields-dialog__field {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
}

.custom-fields-dialog__field + .custom-fields-dialog__field {
  border-top: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
}

.custom-fields-dialog__number {
  display: grid;
  width: 24px;
  height: 24px;
  place-items: center;
  border-radius: 7px;
  color: var(--muted-foreground);
  background: var(--muted);
  font-size: 11px;
  font-weight: 700;
}

.custom-fields-dialog__field input {
  width: 100%;
  min-width: 0;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: 7px;
  color: var(--foreground);
  background: transparent;
  font: inherit;
  font-size: 13px;
  outline: none;
}

.custom-fields-dialog__field input:hover {
  border-color: var(--border);
  background: color-mix(in srgb, var(--muted) 38%, transparent);
}

.custom-fields-dialog__field input:focus {
  border-color: var(--ring);
  background: var(--background);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 14%, transparent);
}

.custom-fields-dialog__footer {
  border-top: 1px solid var(--border);
  background: color-mix(in srgb, var(--muted) 30%, var(--card));
}

.custom-fields-dialog__footer > div {
  display: flex;
  flex: 0 0 auto;
  gap: 8px;
}

.custom-fields-inputs {
  margin-top: 8px;
}

@media (max-width: 640px) {
  .custom-fields-overview {
    grid-template-columns: 1fr;
  }

  .custom-fields-dialog__header,
  .custom-fields-dialog__body,
  .custom-fields-dialog__footer {
    padding-right: 14px;
    padding-left: 14px;
  }

  .custom-fields-dialog__footer {
    justify-content: flex-end;
  }

  .custom-fields-dialog__footer > span {
    display: none;
  }
}

[data-settings-highlight] {
  scroll-margin-top: 112px;
}

.settings-highlight {
  border-radius: var(--radius);
  outline: 2px solid color-mix(in srgb, var(--primary) 58%, transparent);
  outline-offset: 6px;
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--primary) 12%, transparent);
  animation: settings-highlight-pulse 1400ms ease-out 1;
}

/* Inner groups are bare sections with no padding of their own, so the ring
   would otherwise land right against their text. Inflate the highlighted group
   with padding and cancel it with a matching negative margin so the ring gains
   breathing room without shifting the surrounding grid layout. */
.settings-group.settings-highlight {
  padding: 14px;
  margin: -14px;
}

@keyframes settings-highlight-pulse {
  0% {
    outline-color: color-mix(in srgb, var(--primary) 88%, transparent);
    box-shadow: 0 0 0 10px color-mix(in srgb, var(--primary) 24%, transparent);
  }

  100% {
    outline-color: color-mix(in srgb, var(--primary) 58%, transparent);
    box-shadow: 0 0 0 6px color-mix(in srgb, var(--primary) 12%, transparent);
  }
}

/* Buttons: small + secondary variants on top of the existing .button system */
.button--small {
  min-height: 32px;
  padding: 0 10px;
  font-size: 12px;
}

.button--secondary {
  border-color: color-mix(in srgb, var(--border) 78%, transparent);
  background: var(--secondary);
  color: var(--secondary-foreground);
}

.button--secondary:hover:not(:disabled):not(.button--disabled) {
  background: color-mix(in srgb, var(--secondary) 70%, var(--card));
}

.button:disabled,
.button--disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

/* Form fields */
.input,
.select {
  width: 100%;
  min-height: 36px;
  border: 1px solid var(--input);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--foreground);
  padding: 0 10px;
  outline: none;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

textarea.input {
  min-height: auto;
  padding: 8px 10px;
  line-height: 1.45;
  resize: vertical;
}

.input:focus,
.select:focus {
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 18%, transparent);
}

.select {
  cursor: pointer;
}

.input--time {
  width: 120px;
  min-width: 120px;
  font-variant-numeric: tabular-nums;
}

.input--unit {
  width: 96px;
  text-transform: uppercase;
}

.input--num {
  width: 90px;
}

/* Ticket header/footer are printed on a fixed-width thermal roll, so the
   operator counts columns while typing: a monospaced face is what makes the
   line length on screen match the line length on paper. 13px keeps a 48-column
   line inside the 460px dialog (48 × ~7.8px = 375px < the ~398px inner width)
   and a 32-column line inside the mobile dialog. `line-height` is deliberately
   NOT set here: `textarea.input` (line 12609) is 0,1,1 and would win over this
   0,1,0 modifier anyway, and its 1.45 is right for mono. */
.input--mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  tab-size: 4;
}

.field-list {
  display: grid;
}

.field-list > * {
  padding: 16px 0;
}

.field-list > * + * {
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
}

.field-list > *:first-child {
  padding-top: 0;
}

.field-list > *:last-child {
  padding-bottom: 0;
}

.field {
  display: grid;
  gap: 6px;
}

.field > span,
.field__label {
  font-size: 13px;
  font-weight: 500;
}

.field > em,
.field__text em {
  font-style: normal;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.4;
}

.field__text {
  display: grid;
  gap: 4px;
}

.field__text span {
  font-size: 13px;
  font-weight: 500;
}

.field--split {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
}

.field--split .select {
  width: min(100%, 260px);
}

.field--inline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

/* Billing / subscription */
.subscription-panel {
  display: grid;
  gap: 24px;
}

.subscription-panel > .settings-card + .settings-card {
  margin-top: 0;
}

.subscription-panel .settings-card__body {
  gap: 36px;
}

/* Keep the subscription group's blocks (seat summary, facts, actions) from
   sitting flush against each other. */
.subscription-panel .settings-group {
  display: grid;
  gap: 24px;
}

/* Contactos: a deliberately minimal, compact block — the two contacts sit
   close together and each lays its three fields in a single tight row that
   collapses to a stack on narrow screens. */
.subscription-panel .contacts-card .settings-card__body {
  gap: 20px;
}

.contacts-block__title {
  margin: 0 0 8px;
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.contacts-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 10px;
}

.contacts-grid .field {
  gap: 4px;
}

.contacts-grid .input {
  min-height: 34px;
}

@media (max-width: 640px) {
  .contacts-grid {
    grid-template-columns: 1fr;
    gap: 8px;
  }
}

.seat-summary {
  display: grid;
  gap: 14px;
}

.seat-summary__stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.seat-stat {
  display: grid;
  gap: 8px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  padding: 18px 20px;
}

.seat-stat--wide {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
}

.seat-stat__main {
  display: grid;
  gap: 8px;
}

.seat-stat--wide .seat-summary__note {
  margin: 0 0 2px;
  text-align: right;
}

.seat-stat__label {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.seat-stat__value {
  font-size: 36px;
  font-weight: 650;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.seat-summary__note {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 13px;
}

.billing-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  margin: 0;
}

.billing-facts div {
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  padding: 12px;
}

.billing-facts dt {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: uppercase;
}

.billing-facts dd {
  margin: 4px 0 0;
  font-size: 13px;
  font-weight: 600;
}

.billing-warning {
  margin: 0;
  border: 1px solid color-mix(in srgb, #d97706 38%, var(--border));
  border-radius: var(--radius);
  background: color-mix(in srgb, #f59e0b 10%, var(--card));
  color: #92400e;
  padding: 10px 12px;
  font-size: 12px;
  line-height: 1.45;
}

.billing-warning code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

.billing-actions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}

.billing-action {
  display: grid;
  align-content: space-between;
  gap: 12px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  padding: 12px;
}

.billing-action p {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.45;
}

.invoice-list {
  display: grid;
  gap: 10px;
}

.invoice-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  padding: 12px;
}

.invoice-row strong,
.invoice-row span {
  display: block;
}

.invoice-row strong {
  font-size: 13px;
}

.invoice-row span {
  margin-top: 2px;
  color: var(--muted-foreground);
  font-size: 12px;
}

.invoice-row__actions {
  display: flex;
  gap: 8px;
}

@media (max-width: 760px) {
  .seat-summary__stats,
  .billing-facts,
  .billing-actions {
    grid-template-columns: 1fr;
  }

  .seat-stat--wide {
    flex-direction: column;
    align-items: flex-start;
  }

  .seat-stat--wide .seat-summary__note {
    text-align: left;
  }

  .invoice-row {
    align-items: stretch;
    flex-direction: column;
  }
}

/* Preference toggle rows */
.pref-box {
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  padding: 0 14px;
}

.pref-box--divided > .pref-row + .pref-row {
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
}

.pref-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 0;
}

.pref-row--bare {
  padding: 0;
}

.pref-row__text {
  display: grid;
  gap: 4px;
}

.pref-row__text label {
  font-size: 13px;
  font-weight: 500;
}

.pref-row__text p {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.4;
}

.minimum-sale-field {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 600;
}

.minimum-sale-field .input {
  width: 128px;
  color: var(--foreground);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* iOS-style switch built on a checkbox */
.switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  cursor: pointer;
}

.switch--inline {
  gap: 6px;
}

.switch__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
}

.switch__slider {
  position: relative;
  width: 36px;
  height: 20px;
  flex: 0 0 auto;
  border-radius: 999px;
  background: var(--input);
  transition: background 150ms ease;
}

.switch__slider::after {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgb(0 0 0 / 25%);
  transition: transform 150ms ease;
  content: "";
}

.switch__input:checked + .switch__slider {
  background: var(--primary);
}

/* The "on" track is var(--primary), which in dark mode is near-white — a plain
   white knob then vanishes into it. Color the knob with --primary-foreground so
   it contrasts the track in both themes (light: light knob on dark track; dark:
   dark knob on light track). */
.switch__input:checked + .switch__slider::after {
  background: var(--primary-foreground);
  transform: translateX(16px);
}

.switch__input:focus-visible + .switch__slider {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 25%, transparent);
}

.switch__text {
  color: var(--muted-foreground);
  font-size: 12px;
}

/* Ticket list + dialog */
.ticket-list {
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  overflow: hidden;
}

.ticket-row {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  background: var(--card);
  cursor: pointer;
  padding: 10px 14px;
  text-align: left;
}

.ticket-row:last-child {
  border-bottom: 0;
}

.ticket-row:hover {
  background: var(--muted);
}

.ticket-row__main {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.ticket-row__title {
  font-size: 13px;
  font-weight: 500;
}

.ticket-row__sub {
  color: var(--muted-foreground);
  font-weight: 400;
}

.ticket-row__meta {
  color: var(--muted-foreground);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.ticket-row__chevron {
  display: grid;
  width: 22px;
  height: 22px;
  place-items: center;
  flex: 0 0 auto;
  color: var(--muted-foreground);
}

.ticket-row__chevron .icon {
  width: 15px;
  height: 15px;
}

.ticket-dialog {
  width: min(100% - 32px, 460px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--foreground);
  box-shadow: var(--shadow);
  padding: 0;
}

.ticket-dialog::backdrop {
  background: rgb(0 0 0 / 35%);
}

.ticket-dialog__head {
  padding: 18px 20px 0;
}

.ticket-dialog__head h3 {
  margin: 0;
  font-size: 16px;
}

.ticket-dialog__head p {
  margin: 4px 0 0;
  color: var(--muted-foreground);
  font-size: 12px;
}

.ticket-dialog__body {
  display: grid;
  gap: 14px;
  padding: 16px 20px;
}

.ticket-dialog__foot {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  padding: 14px 20px;
}

/* Visit-results catalog editor */
.vr-box {
  display: grid;
  gap: 8px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  padding: 12px 14px;
}

.vr-row__display {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 55%, transparent);
  padding: 6px 8px;
}

.vr-row__label-text {
  overflow: hidden;
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vr-row__edit {
  display: none;
  align-items: center;
  gap: 8px;
}

.vr-row__edit .vr-row__label {
  flex: 1;
  min-height: 32px;
}

.vr-row__remove,
.unit-chip__remove,
.tax-row__remove {
  display: grid;
  width: 22px;
  height: 22px;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
  line-height: 1;
  padding: 0;
  border-radius: 6px;
}

.vr-row__remove:hover,
.unit-chip__remove:hover,
.tax-row__remove:hover {
  background: color-mix(in srgb, var(--danger) 9%, transparent);
  color: var(--danger);
}

.vr-add {
  display: none;
  align-items: center;
  gap: 8px;
  border-top: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  margin-top: 2px;
  padding-top: 10px;
}

.vr-add .input {
  flex: 1;
  min-height: 32px;
}

.vr--editing .vr-row__display {
  display: none;
}

.vr--editing .vr-row__edit {
  display: flex;
}

.vr--editing .vr-add {
  display: flex;
}

/* Units chips editor */
.units-box {
  display: grid;
  gap: 10px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  padding: 12px 14px;
}

.units-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.unit-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 55%, transparent);
  padding: 4px 8px;
  font-size: 12px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.unit-chip__remove {
  display: none;
}

.units--editing .unit-chip__remove {
  display: grid;
}

.units-add {
  display: none;
  align-items: center;
  gap: 8px;
}

.units--editing .units-add {
  display: flex;
}

/* Tax catalog editor */
.tax-box {
  display: grid;
  gap: 8px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: var(--radius);
  padding: 8px;
}

.tax-list {
  display: grid;
  gap: 4px;
}

.tax-row__display {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--muted) 45%, transparent);
  min-height: 34px;
  padding: 6px 8px;
}

.tax-row__main {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
}

.tax-row__main strong {
  overflow: hidden;
  font-size: 13px;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tax-row__main small {
  color: var(--muted-foreground);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tax-row__main small::before {
  content: "· ";
  color: color-mix(in srgb, var(--muted-foreground) 70%, transparent);
}

.tax-row__badges {
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}

.tax-row--inactive .tax-row__display {
  opacity: .62;
}

.tax-row__edit {
  display: none;
  grid-template-columns: minmax(78px, .6fr) minmax(130px, 1.2fr) repeat(2, minmax(88px, .7fr));
  align-items: center;
  gap: 8px;
  border: 1px solid color-mix(in srgb, var(--border) 58%, transparent);
  border-radius: var(--radius);
  padding: 10px;
}

.tax-row__edit .input {
  min-height: 32px;
}

.tax-add {
  display: none;
  grid-template-columns: minmax(78px, .6fr) minmax(130px, 1.2fr) repeat(2, minmax(88px, .7fr));
  align-items: center;
  gap: 8px;
  border-top: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  padding-top: 10px;
}

.tax-catalog--editing .tax-row__display {
  display: none;
}

.tax-catalog--editing .tax-row__edit,
.tax-catalog--editing .tax-add {
  display: grid;
}

.tax-empty {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--muted-foreground);
  font-size: 13px;
  padding: 6px 2px;
}

.sat-catalog-picker {
  margin-top: 2px;
}

.sat-catalog-results .autocomplete-option strong {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.text-warning {
  color: #b45309 !important;
  font-weight: 500;
}

.button.is-active {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  background: color-mix(in srgb, var(--primary) 10%, var(--card));
}

/* Mexico CFDI administration */
.fiscal-status-cluster,
.fiscal-downloads,
.fiscal-filter-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.fiscal-inboxes {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  padding: 0 24px 18px;
}

.fiscal-inbox-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-width: 0;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--card) 94%, var(--muted));
  color: var(--foreground);
  padding: 12px 14px;
  text-decoration: none;
}

.fiscal-inbox-card:hover {
  border-color: color-mix(in srgb, var(--primary) 35%, var(--border));
  background: color-mix(in srgb, var(--primary) 5%, var(--card));
}

.fiscal-inbox-card span {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  color: var(--muted-foreground);
  font-size: 12px;
  font-weight: 650;
}

.fiscal-inbox-card span .icon {
  width: 15px;
  height: 15px;
}

.fiscal-inbox-card > strong {
  font-size: 20px;
  font-variant-numeric: tabular-nums;
}

.fiscal-filters {
  display: grid;
  grid-template-columns: minmax(220px, 1.6fr) repeat(5, minmax(112px, .72fr));
  align-items: end;
  gap: 10px;
  border-block: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  margin-bottom: 8px;
  padding: 16px 24px;
}

.fiscal-filters .field--full {
  grid-column: auto;
}

.admin-table__row--fiscal-documents {
  grid-template-columns: minmax(190px, 1.25fr) minmax(170px, 1.1fr) minmax(100px, .65fr) minmax(105px, .65fr) minmax(130px, .75fr) auto;
}

.admin-table__row--fiscal-documents small {
  overflow-wrap: anywhere;
}

.fiscal-detail-grid,
.fiscal-onboarding-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(280px, .75fr);
  gap: 14px;
  padding: 0 24px 16px;
}

.fiscal-onboarding-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  padding-top: 18px;
}

.fiscal-summary-card,
.fiscal-totals-card,
.fiscal-section-card,
.fiscal-onboarding-grid > .settings-card {
  border: 1px solid color-mix(in srgb, var(--border) 68%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  padding: 16px;
}

.fiscal-summary-card h2,
.fiscal-totals-card h2,
.fiscal-section-card h2,
.fiscal-onboarding-grid h2 {
  margin: 0 0 12px;
  font-size: 15px;
}

.fiscal-section-card {
  margin: 0 24px 16px;
}

.fiscal-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 16px;
  margin: 0;
}

.fiscal-facts div,
.fiscal-total-list div {
  min-width: 0;
}

.fiscal-facts dt,
.fiscal-total-list dt {
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

.fiscal-facts dd,
.fiscal-total-list dd {
  margin: 3px 0 0;
  overflow-wrap: anywhere;
  font-size: 13px;
  font-weight: 600;
}

.fiscal-total-list {
  display: grid;
  gap: 8px;
  margin: 0 0 14px;
}

.fiscal-total-list > div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.fiscal-total-list__grand {
  border-top: 1px solid var(--border);
  margin-top: 4px;
  padding-top: 10px;
}

.fiscal-total-list__grand dd {
  font-size: 16px;
}

.fiscal-source-list,
.fiscal-lines,
.fiscal-timeline {
  display: grid;
  gap: 0;
}

.fiscal-source-list > div,
.fiscal-line {
  display: grid;
  align-items: center;
  gap: 12px;
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  padding: 10px 0;
}

.fiscal-source-list > div {
  grid-template-columns: minmax(0, 1fr) auto;
}

.fiscal-source-list span,
.fiscal-line > div {
  display: grid;
  gap: 2px;
}

.fiscal-source-list small,
.fiscal-line small,
.fiscal-line > span,
.fiscal-timeline {
  color: var(--muted-foreground);
  font-size: 12px;
}

.fiscal-line {
  grid-template-columns: minmax(180px, 1.4fr) minmax(110px, .65fr) minmax(100px, .55fr) auto;
}

.fiscal-actions-grid,
.fiscal-certificate-form {
  display: grid;
  gap: 12px;
}

.fiscal-action-form,
.fiscal-cancellation-form {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
  align-items: end;
  gap: 10px;
}

.fiscal-action-form {
  grid-template-columns: minmax(220px, 1fr) auto;
}

.fiscal-action-form--stacked {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.fiscal-action-form--stacked > .button {
  justify-self: start;
}

.fiscal-readonly-field {
  border: 1px dashed color-mix(in srgb, var(--border) 72%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 35%, transparent);
  padding: 10px 12px;
}

.fiscal-readonly-field strong,
.fiscal-readonly-field small {
  display: block;
}

.fiscal-readonly-field small,
.fiscal-lock-note,
.fiscal-onboarding-grid p {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.45;
}

.fiscal-lock-note {
  display: flex;
  align-items: center;
  gap: 6px;
}

.fiscal-manifest-frame {
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #fff;
  margin-bottom: 12px;
}

.fiscal-manifest-frame iframe {
  display: block;
  width: 100%;
  min-height: 520px;
  border: 0;
}

.fiscal-tabs,
.fiscal-run-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  padding: 0 24px 14px;
}

.fiscal-tabs a {
  border-radius: 999px;
  color: var(--muted-foreground);
  padding: 7px 11px;
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
}

.fiscal-tabs a:hover,
.fiscal-tabs a.is-active {
  background: var(--muted);
  color: var(--foreground);
}

.fiscal-run-filters {
  border-bottom: 0;
  padding-top: 14px;
}

.fiscal-pending-list {
  display: grid;
  gap: 10px;
  padding: 16px 24px 24px;
}

.fiscal-pending-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 16px;
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  padding: 12px 14px;
}

.fiscal-pending-card > div {
  display: grid;
  justify-items: start;
  gap: 3px;
}

.fiscal-pending-card > div:nth-child(2) {
  justify-items: end;
  text-align: right;
}

.fiscal-pending-card__action {
  position: relative;
  z-index: 2;
}

.fiscal-pending-card small,
.fiscal-route-list small {
  color: var(--muted-foreground);
  font-size: 12px;
}

.fiscal-pending-card--link:hover {
  border-color: color-mix(in srgb, var(--primary) 35%, var(--border));
}

.fiscal-run-errors {
  display: grid;
  gap: 8px;
  padding: 0 24px 16px;
}

.fiscal-route-list {
  display: grid;
  gap: 0;
}

.fiscal-route-list > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  padding: 9px 0;
}

.fiscal-route-list > div > span:first-child {
  display: grid;
  gap: 2px;
}

.fiscal-facts--single {
  grid-template-columns: 1fr;
}

.fiscal-resolution-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.fiscal-resolution-card {
  display: grid;
  align-content: start;
  gap: 10px;
  border: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 24%, var(--card));
  padding: 14px;
}

.fiscal-resolution-card > strong {
  font-size: 14px;
}

.fiscal-resolution-card > p {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.45;
}

@media (max-width: 980px) {
  .fiscal-inboxes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .fiscal-filters {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .fiscal-filters .field--full {
    grid-column: span 3;
  }
}

@media (max-width: 760px) {
  .fiscal-inboxes,
  .fiscal-detail-grid,
  .fiscal-onboarding-grid {
    grid-template-columns: 1fr;
    padding-inline: 14px;
  }

  .fiscal-filters {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    padding-inline: 14px;
  }

  .fiscal-filters .field--full {
    grid-column: span 2;
  }

  .fiscal-documents-table .admin-table__head {
    display: none;
  }

  .fiscal-documents-table {
    display: grid;
    gap: 10px;
    padding-inline: 14px;
  }

  .fiscal-documents-table .admin-table__row--fiscal-documents {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px;
  }

  .fiscal-documents-table .admin-table__row--fiscal-documents > div:nth-of-type(2),
  .fiscal-documents-table .admin-table__row--fiscal-documents > div:nth-of-type(3),
  .fiscal-documents-table .admin-table__row--fiscal-documents > div:nth-of-type(5) {
    grid-column: 1 / -1;
  }

  .fiscal-documents-table .admin-table__actions {
    display: none;
  }

  .fiscal-facts,
  .fiscal-line,
  .fiscal-action-form,
  .fiscal-cancellation-form,
  .fiscal-action-form--stacked,
  .fiscal-resolution-grid {
    grid-template-columns: 1fr;
  }

  .fiscal-section-card {
    margin-inline: 14px;
  }

  .fiscal-tabs,
  .fiscal-run-filters,
  .fiscal-pending-list,
  .fiscal-run-errors {
    padding-inline: 14px;
  }

  .fiscal-pending-card {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .fiscal-pending-card > div:nth-child(2) {
    grid-column: 1 / -1;
    justify-items: start;
    text-align: left;
  }

  .fiscal-pending-card__action {
    grid-column: 1 / -1;
    justify-self: stretch;
  }

  .fiscal-pending-card__action .button {
    width: 100%;
  }
}

@media (max-width: 640px) {
  .tax-row__edit,
  .tax-add {
    grid-template-columns: 1fr;
  }

  .account-main:not(.mobile-full-main) {
    padding: 12px 14px 40px;
  }

  .settings-card__header {
    padding: 16px 16px 0;
  }

  .settings-card__body {
    padding: 16px 16px;
  }

  .settings-card__footer {
    padding: 14px 16px;
  }

  .field--split {
    flex-direction: column;
    align-items: stretch;
  }

  .field--split .select {
    width: 100%;
  }

  .pref-row--stack-mobile {
    align-items: stretch;
    flex-direction: column;
  }

  .minimum-sale-field .input {
    flex: 1;
    width: auto;
  }
}

/* --- User administration (roles + field role) --- */
/* The shared catalog toolbar/pagination bring their own side gutters, sized for
   the gutterless .home-panel; inside a padded .profile-section (users roster)
   they double up and misalign with the table edges. */
.profile-section .catalog-toolbar,
.profile-section .catalog-pagination {
  padding-right: 0;
  padding-left: 0;
}

/* Numeric cells lose their column header when tables collapse to cards on
   phones — this hint labels the bare number, mobile only. */
.mobile-count-hint {
  display: none;
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 500;
}

@media (max-width: 720px) {
  .mobile-count-hint {
    display: inline;
  }
}

.users-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.users-table thead th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted-foreground);
  padding: 0 12px 8px;
  border-bottom: 1px solid var(--border);
}

/* Hand the table's leftover width to CEDIS — the column with the longest
   strings — instead of letting auto layout spread it over all four columns,
   which left a ~420px hole between Roles and CEDIS. Usuario and Roles fall
   back to max-content, so the role chips still never wrap. Mirror of the
   `.users-table__actions { width: 1% }` trick already used below. */
.users-table thead th:nth-child(3) {
  width: 100%;
}

.users-table tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  vertical-align: middle;
}

.users-table tbody tr:last-child td {
  border-bottom: none;
}

.users-table__user {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 500;
}

/* Name and handle share one line: two short strings stacked in a narrow
   column is what wasted the row's horizontal space. */
.users-table__identity {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 8px;
  min-width: 0;
}

.users-table__identity strong {
  font-weight: 600;
}

.users-table__identity small {
  font-size: 12px;
  color: var(--muted-foreground);
}

.users-table__muted {
  color: var(--muted-foreground);
}

/* Same for CEDIS: the assigned list and its default sit side by side rather
   than on two lines. */
.users-table__centers {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 10px;
  min-width: 0;
}

.users-table__centers small {
  color: var(--muted-foreground);
}

.users-table__actions {
  width: 1%;
  text-align: right;
  white-space: nowrap;
}

.badge-list {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* Device-bound chip: sits after the role badges; the icon shares the pill's
   muted foreground so it reads as one quiet unit. */
.badge--device {
  margin-left: 4px;
  min-height: 20px;
  padding: 0 6px;
  border-color: transparent;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 500;
}

.badge--device .icon {
  width: 12px;
  height: 12px;
}

.badge-list + .badge--device {
  vertical-align: top;
}

/* Per-row "⋯" actions menu (shadcn row-actions): icon-only ghost trigger +
   the same dropdown panel treatment as the top-bar account menu. */
.row-menu {
  position: relative;
  display: inline-flex;
}

/* Every actions cell sits at z-index 2 (above the stretched row link), so a
   later row's "⋯" trigger would paint over an open panel. Lift the cell that
   currently owns the open menu above its siblings. */
.users-table__actions:has(.row-menu__panel:not([hidden])) {
  z-index: 10;
}

.row-menu__trigger {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: calc(var(--radius) - 2px);
  background: none;
  color: var(--muted-foreground);
  cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease;
}

.row-menu__trigger .icon {
  width: 16px;
  height: 16px;
}

.row-menu__trigger:hover,
.row-menu__trigger[aria-expanded="true"] {
  background: color-mix(in srgb, var(--muted) 70%, var(--card));
  color: var(--foreground);
}

.row-menu__panel {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 30;
  min-width: 200px;
  display: grid;
  gap: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
  padding: 4px;
  text-align: left;
}

.row-menu__panel[hidden] {
  display: none;
}

.row-menu__form {
  margin: 0;
  display: grid;
}

.row-menu__item {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 9px;
  border: 0;
  border-radius: calc(var(--radius) - 2px);
  background: none;
  color: var(--foreground);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  padding: 8px 10px;
  transition: background-color 120ms ease;
}

.row-menu__item .icon {
  width: 15px;
  height: 15px;
  color: var(--muted-foreground);
}

.row-menu__item:hover {
  background: color-mix(in srgb, var(--muted) 55%, var(--card));
}

.row-menu__item--danger,
.row-menu__item--danger .icon {
  color: var(--danger);
}

.row-menu__item--danger:hover {
  background: color-mix(in srgb, var(--danger) 10%, var(--card));
}

.row-menu__separator {
  height: 1px;
  margin: 4px 6px;
  background: color-mix(in srgb, var(--border) 72%, transparent);
}

/* Role chips are secondary metadata in a dense roster, so they read as small
   flat tags, not full-size outlined pills: no border, a 7% neutral wash of
   --foreground (which stays subtle in BOTH themes, unlike the --primary tint
   that went near-white in dark), 20px tall and 500 weight. `.badge--role` sits
   far below the shared `.badge` base (line 2124) at the same specificity, so
   these size overrides win on order. */
.badge--role {
  min-height: 20px;
  padding: 0 6px;
  border-color: transparent;
  border-radius: 4px;
  background: color-mix(in srgb, var(--foreground) 7%, transparent);
  color: color-mix(in srgb, var(--foreground) 78%, var(--muted-foreground));
  font-size: 11px;
  font-weight: 500;
}

.role-form {
  display: grid;
  gap: 16px;
}

.role-fieldset {
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--card) 94%, var(--muted));
  padding: 16px;
  margin: 0;
}

.role-fieldset--identity {
  max-width: 560px;
}

.role-fieldset legend {
  font-size: 13px;
  font-weight: 700;
  padding: 0 6px;
}

.role-fieldset__hint {
  margin: 0 0 12px;
  font-size: 12px;
  color: var(--muted-foreground);
}

/* `.role-fieldset` is a plain block, so consecutive `<label class="field">`
   children had NO separation at all — one field's input sat 4px under the
   next field's label, i.e. tighter than `.field`'s own 6px label→input gap.
   Give the stack the 16px rhythm `.role-form` and `.settings-grid` already
   use. Scoped to a modifier so the users and profile fieldsets that share
   `.role-fieldset` keep their current spacing. */
.role-fieldset--stacked > .field,
.role-fieldset--stacked > .role-option {
  margin-top: 16px;
}

.role-fieldset--stacked > .role-fieldset__hint {
  margin-bottom: 0;
}

.role-fieldset .input + .input {
  margin-top: 10px;
}

.role-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.role-grid--cards {
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}

.role-grid--cedis {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.role-option {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 42px;
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: 8px;
  background: var(--card);
  color: var(--foreground);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  padding: 10px;
  transition: background-color 120ms ease, border-color 120ms ease;
}

/* Inline help inside a role/checkbox option (e.g. the "CEDIS activo" card):
   render it as a regular muted hint instead of inheriting the label's 600. */
.role-option small {
  display: block;
  margin-top: 2px;
  color: var(--muted-foreground);
  font-size: 11px;
  font-weight: 400;
  line-height: 1.35;
}

.role-option input {
  appearance: none;
  display: grid;
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
  place-items: center;
  border: 1px solid var(--input);
  background: var(--card);
  margin: 0;
  padding: 0;
  accent-color: var(--primary);
  cursor: pointer;
}

.role-option input[type="checkbox"] {
  border-radius: 5px;
}

.role-option input[type="radio"] {
  border-radius: 999px;
}

.role-option input::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: inherit;
  background: var(--primary-foreground);
  opacity: 0;
}

.role-option input:checked {
  border-color: var(--primary);
  background: var(--primary);
}

.role-option input:checked::before {
  opacity: 1;
}

.role-option:has(input:checked) {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  background: color-mix(in srgb, var(--primary) 6%, var(--card));
}

.role-form__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-top: 16px;
}

.role-form__pair--passwords {
  margin-top: 0;
}

/* One field that still wants the pair's label treatment and breathing room —
   the CEDIS default select under its membership cards. */
.role-form__pair--single {
  grid-template-columns: minmax(0, 1fr);
  max-width: min(360px, 100%);
}

.role-form__pair label {
  display: grid;
  gap: 6px;
  color: var(--muted-foreground);
  font-size: 12px;
}

.role-form__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

@media (max-width: 720px) {
  .catalog-main .role-form {
    gap: 10px;
  }

  .catalog-main .role-fieldset {
    border-right: 0;
    border-left: 0;
    border-radius: 0;
    background: transparent;
    padding: 14px 0 16px;
  }

  .catalog-main .role-fieldset--identity {
    max-width: none;
  }

  .catalog-main .role-fieldset legend {
    padding-right: 0;
    padding-left: 0;
  }

  .catalog-main .role-grid,
  .catalog-main .role-grid--cards,
  .catalog-main .role-grid--cedis,
  .catalog-main .role-form__pair,
  .catalog-main .role-form__pair--passwords {
    grid-template-columns: minmax(0, 1fr);
  }

  .catalog-main .role-form__actions,
  .profile-main .role-form__actions {
    flex-direction: column-reverse;
  }

  .catalog-main .role-form__actions .button,
  .profile-main .role-form__actions .button {
    width: 100%;
  }
}

/* --- Notification bell (top bar) --- */
.notif {
  position: relative;
  display: flex;
  align-items: center;
}

.notif__bell {
  position: relative;
  display: grid;
  width: 36px;
  height: 36px;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  transition: border-color 120ms ease, background-color 120ms ease;
}

.notif__bell:hover {
  border-color: var(--border);
  background: color-mix(in srgb, var(--muted) 50%, var(--card));
}

.notif__bell svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2;
}

.notif__badge {
  top: -5px;
  right: -5px;
}

.notif__badge-dot {
  min-width: 17px;
  height: 17px;
  display: grid;
  place-items: center;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
}

.notif__badge[hidden] {
  display: none;
}

.notif__panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 50;
  width: min(360px, 92vw);
  max-height: 70vh;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
}

.notif__panel[hidden] {
  display: none;
}

.notif__head,
.notif__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
}

.notif__head {
  border-bottom: 1px solid var(--border);
}

.notif__foot {
  border-top: 1px solid var(--border);
  justify-content: center;
}

.notif__link {
  border: 0;
  background: none;
  color: var(--muted-foreground);
  font-size: 12px;
  cursor: pointer;
}

.notif__link:hover {
  color: var(--foreground);
}

.notif__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.notif__list--page {
  border-top: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  background: var(--card);
  overflow: hidden;
}

.notif__item + .notif__item {
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
}

.notif__item--unread {
  background: color-mix(in srgb, var(--primary) 4%, var(--card));
}

.notif__item-link {
  display: grid;
  gap: 3px;
  padding: 12px 14px;
  text-decoration: none;
  color: inherit;
}

.notif__item-link:hover {
  background: color-mix(in srgb, var(--muted) 55%, var(--card));
}

.notif__item-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--foreground);
}

.notif__item--unread .notif__item-title::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 7px;
  border-radius: 999px;
  /* Neutral (brand) by default — the dot signals "unread", not "error". Per-level
     rules below tint it by severity (e.g. import outcome). */
  background: var(--primary);
  vertical-align: middle;
}

.notif__item--unread.notif__item--level-success .notif__item-title::before {
  background: var(--success);
}

.notif__item--unread.notif__item--level-warning .notif__item-title::before {
  background: #f59e0b;
}

.notif__item--unread.notif__item--level-danger .notif__item-title::before {
  background: var(--danger);
}

.notif__item-body {
  font-size: 12px;
  color: var(--muted-foreground);
}

.notif__item-time {
  font-size: 11px;
  color: color-mix(in srgb, var(--muted-foreground) 80%, transparent);
}

.notif__empty {
  padding: 20px 14px;
  text-align: center;
  color: var(--muted-foreground);
  font-size: 13px;
}

.notif__empty[hidden] {
  display: none;
}

/* ---- Data imports ---- */
.data-import-widget {
  display: flex;
  align-items: center;
}

.data-import-widget__button {
  display: grid;
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--muted-foreground);
  box-shadow: 0 1px 2px rgb(0 0 0 / 3%);
  cursor: pointer;
  transition: border-color 120ms ease, background-color 120ms ease, color 120ms ease;
}

.data-import-widget__button:hover {
  border-color: var(--border);
  background: color-mix(in srgb, var(--muted) 50%, var(--card));
}

.data-import-widget__button svg {
  width: 18px;
  height: 18px;
}

.data-import-widget__button svg,
.data-import-dropzone svg {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.8;
}

.data-import-dropzone svg {
  width: 20px;
  height: 20px;
}

.data-import-dialog {
  width: min(94vw, 560px);
  border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: 0 24px 80px rgb(0 0 0 / 24%);
  color: var(--foreground);
  padding: 0;
}

.data-import-dialog::backdrop {
  background: rgb(0 0 0 / 32%);
}

.data-import-dialog__form {
  display: grid;
  gap: 14px;
  padding: 16px;
}

.data-import-dialog__header {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  justify-content: space-between;
}

/* Keep the close (X) button a fixed 32x32 square. Without this the flex header's
   growing title/description column squeezes it into a narrow sliver on phone
   widths, where it looks nothing like the desktop button. */
.data-import-dialog__header .icon-button {
  flex: 0 0 auto;
}

.data-import-dialog__header h2,
.data-import-dialog__header p {
  margin: 0;
}

.data-import-dialog__header h2 {
  font-size: 18px;
  line-height: 1.2;
}

.data-import-dialog__header p {
  margin-top: 5px;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.45;
}

.data-import-templates {
  position: relative;
}

.data-import-templates__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid color-mix(in srgb, var(--input) 85%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 40%, transparent);
  color: var(--foreground);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: background-color 120ms ease, border-color 120ms ease;
}

.data-import-templates__summary::-webkit-details-marker {
  display: none;
}

.data-import-templates__summary:hover {
  border-color: var(--ring);
  background: color-mix(in srgb, var(--muted) 70%, transparent);
}

.data-import-templates__summary-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.data-import-templates__chevron {
  color: var(--muted-foreground);
  transition: transform 150ms ease;
}

.data-import-templates[open] .data-import-templates__chevron {
  transform: rotate(180deg);
}

.data-import-templates__menu {
  position: absolute;
  z-index: 20;
  left: 0;
  right: 0;
  top: calc(100% + 6px);
  display: grid;
  gap: 2px;
  padding: 6px;
  border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: 0 16px 40px rgb(0 0 0 / 22%);
}

.data-import-templates__row {
  display: flex;
  align-items: center;
  gap: 4px;
}

.data-import-templates__item {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: calc(var(--radius) - 4px);
  color: var(--foreground);
  font-size: 13px;
  text-decoration: none;
  transition: background-color 100ms ease;
}

.data-import-templates__item:hover,
.data-import-templates__item:focus-visible {
  background: color-mix(in srgb, var(--muted) 70%, transparent);
  outline: none;
}

.data-import-templates__item svg {
  color: var(--muted-foreground);
}

/* Secondary action: download the same template pre-filled with current data. */
.data-import-templates__with-data {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
  border-radius: calc(var(--radius) - 4px);
  background: transparent;
  color: var(--muted-foreground);
  font-size: 12px;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 100ms ease, color 100ms ease;
}

.data-import-templates__with-data:hover,
.data-import-templates__with-data:focus-visible {
  background: color-mix(in srgb, var(--muted) 70%, transparent);
  color: var(--foreground);
  outline: none;
}

.data-import-templates__with-data svg {
  color: inherit;
}

.data-import-export {
  display: flex;
  justify-content: flex-end;
}

.data-import-export__download {
  margin-top: 4px;
}

.data-import-dropzone {
  display: grid;
  min-height: 154px;
  place-items: center;
  border: 1px dashed color-mix(in srgb, var(--input) 85%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--muted) 48%, transparent);
  color: var(--foreground);
  cursor: pointer;
  gap: 8px;
  padding: 20px;
  text-align: center;
  transition: background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
}

.data-import-dropzone:hover,
.data-import-dropzone--active {
  border-color: var(--ring);
  background: color-mix(in srgb, var(--muted) 76%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ring) 18%, transparent);
}

/* A file has been chosen/dropped but the import hasn't started — make it clearly
   "ready": a solid brand-tinted border/background and the filename in the accent
   color instead of the same muted prompt text. */
.data-import-dropzone--has-file {
  border-style: solid;
  border-color: color-mix(in srgb, var(--success) 55%, var(--input));
  background: color-mix(in srgb, var(--success) 12%, var(--card));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--success) 22%, transparent);
}

.data-import-dropzone--has-file strong {
  color: color-mix(in srgb, var(--success) 72%, var(--foreground));
}

.data-import-dropzone--has-file svg {
  color: var(--success);
}

.data-import-dropzone.is-error {
  border-color: color-mix(in srgb, var(--danger) 60%, var(--input));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 20%, transparent);
}

.data-import-dropzone:disabled {
  cursor: wait;
  opacity: 0.72;
}

.data-import-dropzone strong {
  font-size: 14px;
}

.data-import-dropzone span {
  max-width: 430px;
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.45;
}

.data-import-dialog__file {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.data-import-progress {
  display: grid;
  gap: 8px;
}

.data-import-progress__head {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  color: var(--muted-foreground);
  font-size: 12px;
}

.data-import-progress__head strong {
  color: var(--foreground);
}

.data-import-progress__bar {
  height: 8px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--muted);
}

.data-import-progress__bar span {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--success);
  transition: width 180ms ease;
}

.data-import-errors {
  display: grid;
  max-height: 210px;
  overflow: auto;
  border: 1px solid color-mix(in srgb, var(--danger) 22%, var(--border));
  border-radius: 10px;
  background: color-mix(in srgb, var(--danger) 7%, var(--card));
  padding: 10px;
  gap: 8px;
}

.data-import-errors p {
  margin: 0;
  color: color-mix(in srgb, var(--danger) 84%, var(--foreground));
  font-size: 12px;
  line-height: 1.45;
}

.data-import-errors strong {
  color: var(--foreground);
}

.data-import-dialog__footer {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}

.data-import-result {
  display: grid;
  gap: 16px;
}

.data-import-result__stats {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 10px;
  margin: 0;
}

.data-import-result__stats div {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  padding: 10px;
}

.data-import-result__stats dt {
  color: var(--muted-foreground);
  font-size: 11px;
}

.data-import-result__stats dd {
  margin: 4px 0 0;
  font-size: 18px;
  font-weight: 700;
}

.data-import-result__errors {
  overflow-x: auto;
}

.data-import-result__errors h3 {
  margin: 0 0 10px;
  font-size: 14px;
}

.data-import-result__errors table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}

.data-import-result__errors th,
.data-import-result__errors td {
  border-bottom: 1px solid var(--border);
  padding: 8px;
  text-align: left;
  vertical-align: top;
}

.data-import-result__errors p {
  color: var(--muted-foreground);
  font-size: 12px;
}

@media (max-width: 720px) {
  .reports-summary,
  .reports-grid,
  .report-list--compact,
  .report-pie-row,
  .settlement-metrics {
    grid-template-columns: 1fr;
  }

  .report-card--wide {
    margin-inline: 14px;
  }

  .report-pie {
    justify-self: center;
  }

  .data-import-dialog__footer .button {
    flex: 1 1 150px;
  }

  .data-import-result__stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .customer-profile__metrics,
  .customer-profile__columns,
  .customer-profile__columns--wide-left {
    grid-template-columns: 1fr;
  }

  .customer-profile__metrics {
    gap: 10px;
    padding-inline: 14px;
  }

  .customer-profile__columns {
    gap: 14px;
  }

  .customer-profile__back {
    padding-inline: 14px;
  }

  .customer-profile__identity .profile-section__header--with-avatar {
    align-items: flex-start;
    flex-wrap: wrap;
  }

  .customer-profile__identity .profile-section__heading {
    flex: 1 1 180px;
  }

  .customer-profile__identity .badge {
    margin-left: 0;
  }

  .customer-profile__identity .profile-section__header-action {
    flex-basis: 100%;
  }

  .customer-profile__product-list li {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .customer-profile__product-list li > :last-child {
    grid-column: 2;
  }
}
