/* ==========================================================================
   DISPONIBILIDAD360 DESIGN SYSTEM · v1.0 · d360.css
   CSS vanilla — sin build, sin bundler, sin dependencias, sin CDN obligatorio.
   --------------------------------------------------------------------------
   Gobernanza (cada valor lleva su etiqueta):
     [LOCKED]     Decisión aprobada por el owner. No modificar.
     [AUDITED]    Medido en producción (CSS en vivo de disponibilidad360.com,
                  16-oct-2026: home, /ecos-del-mar-iii/, /colinas-de-punta-cana/,
                  login.html, landing.html).
     [PROPOSED]   Cubre un gap. Requiere aprobación del owner.
     [DEPRECATED] Residual. Mantener solo como alias hasta la Fase 6.
   --------------------------------------------------------------------------
   Adopción incremental:
     1. <link rel="stylesheet" href="/assets/ds/css/d360.css"> ANTES del CSS de cada página.
     2. Los tokens (:root) solo declaran variables: no cambian nada visible.
     3. Las clases usan el prefijo .ds- y conviven con las clases legacy.
     4. .ds-base en <body> activa tipografía base + focus global (opt-in).
     5. data-density="compact" en <body> (admin) activa la densidad operativa.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */
:root {
  /* 1.1 Marca — [LOCKED] un solo color de acción */
  --brand-primary:        #1b5ef3;
  --brand-primary-hover:  #1550d8;
  --brand-primary-active: #1143b8;
  --brand-primary-soft:   #eaf1fe;
  --brand-primary-border: #c2d7fd;

  /* 1.2 Neutros — [LOCKED] */
  --ink:     #222222;
  --muted:   #6a6a6a;
  --faint:   #c1c1c1;
  --border:  #ebebeb;
  --bg:      #f7f7f7;
  --surface: #ffffff;

  /* 1.3 Disponibilidad — [LOCKED] son DATOS, no branding. Nunca armonizar. */
  --avail:   #16a34a;   /* AVAILABLE */
  --res:     #d97706;   /* RESERVED */
  --unavail: #dc2626;   /* SOLD / UNAVAILABLE */
  --noninv:  #9aa3af;   /* NON_INVENTORY (“Uso común”) */
  --blocked: #8f2d4d;   /* BLOCKED */

  /* 1.4 Tintes de estado — [AUDITED] home .k-avail / .k-res. Solo fondo; texto en --ink. */
  --avail-soft: rgba(22, 163, 74, .09);   /* ≈ #eaf7ef sobre blanco */
  --res-soft:   rgba(217, 119, 6, .09);   /* ≈ #fcf3e9 sobre blanco */

  /* 1.5 Alias semánticos — valores LOCKED · nombres [PROPOSED] */
  --color-action-primary:        var(--brand-primary);
  --color-action-primary-hover:  var(--brand-primary-hover);
  --color-action-primary-active: var(--brand-primary-active);
  --color-link:                  var(--brand-primary);
  --color-focus:                 var(--brand-primary);
  --color-selected-bg:           var(--brand-primary-soft);
  --color-selected-border:       var(--brand-primary);
  --color-selected-text:         var(--brand-primary-active);  /* 7.35:1 sobre soft */
  --color-text-primary:          var(--ink);
  --color-text-secondary:        var(--muted);
  --color-text-disabled:         var(--faint);
  --color-text-on-action:        var(--surface);
  --color-canvas:                var(--bg);
  --color-surface:               var(--surface);
  --color-fill:                  var(--bg);      /* [AUDITED] controles “tonales” (searchbar, ghostbtn, fcard) */
  --color-fill-hover:            var(--border);  /* [AUDITED] rgb(235,235,235) en hover */
  --color-divider:               var(--border);

  --color-status-available:      var(--avail);
  --color-status-reserved:       var(--res);
  --color-status-sold:           var(--unavail);
  --color-status-non-inventory:  var(--noninv);
  --color-status-blocked:        var(--blocked);

  /* Texto accesible SOBRE fondo sólido de estado (ratios WCAG calculados) */
  --color-on-avail:   var(--ink);      /* 4.83:1 · blanco falla (3.30)            */
  --color-on-res:     var(--ink);      /* 4.99:1 · blanco 3.19 y #3a2c00 4.28 fallan */
  --color-on-unavail: var(--surface);  /* 4.83:1 · ink falla (3.29)               */
  --color-on-noninv:  var(--ink);      /* 6.24:1 · blanco falla (2.55)            */
  --color-on-blocked: var(--surface);  /* 7.92:1 · ink falla (2.01)               */

  /* 1.6 Usos con decisión de accesibilidad — [PROPOSED] */
  --color-text-placeholder: var(--muted);   /* AUDITED usa --faint (1.80:1, falla AA) */
  --color-input-border:     var(--border);  /* AUDITED. Ver GAP-07: --border-strong o --muted para WCAG 1.4.11 */
  --border-strong:          #8a8a8a;        /* PROPOSED nuevo neutro, 3.45:1 · no se usa hasta aprobarse */

  /* 1.7 Feedback del sistema — [PROPOSED] formaliza literales AUDITED en login/Colinas */
  --feedback-danger-ink:     #b91c1c;  /* 5.91:1 sobre su fondo */
  --feedback-danger-bg:      #fef2f2;
  --feedback-danger-border:  #fca5a5;
  --feedback-success-ink:    #15803d;  /* 4.79:1 sobre su fondo */
  --feedback-success-bg:     #f0fdf4;
  --feedback-success-border: #bbf7d0;
  --color-danger:            var(--feedback-danger-ink);

  /* 1.8 Overlays — [AUDITED] dentro del rango LOCKED .40–.50 */
  --overlay-backdrop:       rgba(0, 0, 0, .5);   /* modales (home, ECOS) */
  --overlay-backdrop-sheet: rgba(0, 0, 0, .4);   /* bottom sheet (Colinas) */
  --header-bg:              rgba(255, 255, 255, .92);  /* [AUDITED] header sticky translúcido */

  /* 2. Espaciado — [LOCKED] base 4 · índice = valor / 4 · sin intermedios */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-7:  28px;
  --space-8:  32px;
  --space-10: 40px;
  --space-11: 44px;
  --space-12: 48px;

  /* Alias semánticos — nombres [PROPOSED], valores LOCKED */
  --space-inline-xs: var(--space-1);   /* punto ↔ texto en badges */
  --space-inline-sm: var(--space-2);   /* icono ↔ label en botones y chips */
  --space-inline-md: var(--space-3);   /* entre controles de una fila */
  --space-stack-xs:  var(--space-1);   /* título ↔ metadato */
  --space-stack-sm:  var(--space-2);   /* label ↔ campo */
  --space-stack-md:  var(--space-3);   /* entre campos */
  --space-stack-lg:  var(--space-4);   /* entre bloques de una card */
  --space-inset-sm:  var(--space-3);   /* celdas, chips grandes */
  --space-inset-md:  var(--space-4);   /* card móvil, admin */
  --space-inset-lg:  var(--space-5);   /* card / panel público (AUDITED 18 → 20) */
  --space-section:   var(--space-12);

  /* 3. Radios — [LOCKED] por ROL, nunca por página */
  --radius-pill:    999px;  /* CTA primario sólido, search, badges, pills, filtros pill */
  --radius-card:    14px;   /* card, modal                     (AUDITED --r-lg) */
  --radius-panel:   12px;   /* panel, container, banner        (AUDITED --r / --r-md) */
  --radius-control: 8px;    /* input, ghost button, thumbnail  */
  --radius-round:   50%;    /* avatar, icon button circular    */
  --radius-toast:   10px;   /* component-specific locked exception — NO es radio global */
  --radius-sheet:   18px;   /* [AUDITED] radio superior del bottom sheet (ECOS + Colinas) — solo sheet */

  /* Alias por rol */
  --radius-btn-primary: var(--radius-pill);
  --radius-btn-ghost:   var(--radius-control);
  --radius-input:       var(--radius-control);
  --radius-thumb:       var(--radius-control);
  --radius-badge:       var(--radius-pill);
  --radius-chip:        var(--radius-pill);
  --radius-search:      var(--radius-pill);
  --radius-modal:       var(--radius-card);
  --radius-banner:      var(--radius-panel);
  --radius-avatar:      var(--radius-round);

  /* 4. Elevación — [LOCKED] la sombra es altura funcional, nunca decoración */
  --shadow-sm: rgba(0,0,0,.02) 0 0 0 1px, rgba(0,0,0,.04) 0 2px 6px, rgba(0,0,0,.10) 0 4px 8px;
  --shadow-md: 0 6px 20px rgba(0,0,0,.15);
  --shadow-lg: 0 8px 28px rgba(0,0,0,.28);

  --elevation-raised:   var(--shadow-sm);  /* hover de card, search flotante, controles sobre imagen/mapa */
  --elevation-floating: var(--shadow-md);  /* dropdown, popover, panel flotante, toast */
  --elevation-overlay:  var(--shadow-lg);  /* modal, bottom sheet, overlay importante */

  /* 5. Tipografía — familia, pesos y tracking ≥22px [LOCKED]; escala [AUDITED → normalizada] */
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

  --fw-regular:   400;
  --fw-medium:    500;
  --fw-semibold:  600;
  --fw-bold:      700;
  --fw-extrabold: 800;   /* AUDITED: voz de títulos del producto */

  --tracking-tight:    -0.02em;  /* [LOCKED] ≥ 22px */
  --tracking-snug:     -0.01em;  /* [AUDITED] títulos 16–21px */
  --tracking-normal:   0;
  --tracking-overline: 0.03em;   /* [AUDITED] encabezados de tabla en mayúsculas */

  /* Escala móvil (mobile-first). Desktop en @media (min-width: 960px). */
  --text-display:  34px; --lh-display:  40px;
  --text-h1:       26px; --lh-h1:       32px;
  --text-h2:       22px; --lh-h2:       28px;
  --text-h3:       18px; --lh-h3:       24px;
  --text-body-lg:  16px; --lh-body-lg:  24px;
  --text-body:     14px; --lh-body:     20px;
  --text-body-sm:  13px; --lh-body-sm:  20px;
  --text-label:    13px; --lh-label:    16px;
  --text-caption:  12px; --lh-caption:  16px;
  --text-overline: 11px; --lh-overline: 16px;
  --text-input:    16px;  /* nunca < 16px en inputs móviles (evita zoom iOS) */

  /* 6. Controles — [AUDITED] min-height 44 en ghostbtn, cta, inputs, linkrow */
  --control-h-sm: var(--space-8);    /* 32 · admin compacto (táctil → 44) */
  --control-h-md: var(--space-10);   /* 40 · desktop compacto            */
  --control-h-lg: var(--space-11);   /* 44 · público / táctil            */
  --touch-target-min: var(--space-11); /* 44 · [PROPOSED — accessibility requirement] */

  --icon-sm: 16px;      /* [AUDITED] 15px → 16 */
  --icon-md: 18px;      /* [AUDITED] tamaño más usado */
  --icon-lg: 24px;
  --icon-stroke: 2;     /* [AUDITED] mayoría; 2.4 y 3 → DEPRECATED */

  --focus-ring-width:  2px;
  --focus-ring-offset: 2px;
  --focus-ring-input:  0 0 0 3px rgba(27, 94, 243, .16);  /* [AUDITED] login/ECOS (.13–.16) */
  --focus-ring-double: 0 0 0 2px var(--surface), 0 0 0 4px var(--color-focus);  /* sobre foto/mapa */

  /* 7. Densidad — [PROPOSED] comfortable (público) por defecto */
  --density-control-h: var(--control-h-lg);
  --density-row-h:     var(--space-11);
  --density-pad:       var(--space-inset-lg);
  --density-gap:       var(--space-4);
  --density-text:      var(--text-body);
  --density-lh:        var(--lh-body);

  /* 8. Layout — [AUDITED → normalizado] */
  --container-discovery: 960px;    /* home */
  --container-project:   1200px;   /* ECOS 1200 · Colinas 1400 → 1200 */
  --container-reading:   720px;    /* hero home */
  --container-form:      400px;    /* auth, modal home */
  --modal-w-sm:          400px;
  --modal-w-md:          460px;    /* ECOS msgcard */
  --side-panel-w:        336px;    /* ECOS 336 · Colinas 340 → 336 */
  --floating-panel-w:    300px;    /* Colinas ux-floating */
  --header-h:            56px;
  --bottombar-h:         52px;     /* [AUDITED] ECOS .bottombar: 4 + 44 + 4 */
  --sidebar-w:           240px;    /* [PROPOSED] admin */
  --gutter:              var(--space-4);

  /* Breakpoints — [AUDITED] 640 y 960 estables. var() NO funciona en @media:
     usar los literales. 760/520/600/700/720/820/860 → DEPRECATED. */
  --bp-tablet:  640px;
  --bp-desktop: 960px;
  --bp-wide:    1440px;  /* [PROPOSED] solo admin y grilla de discovery */

  /* 9. Capas — [AUDITED → normalizado] (ECOS: modal 60, sheet 61, bottombar 65, banner 70, toast 80) */
  --z-sticky:    10;
  --z-header:    20;
  --z-dropdown:  30;
  --z-modal:     60;
  --z-sheet:     61;
  --z-bottombar: 65;
  --z-banner:    70;
  --z-toast:     80;
  --z-tooltip:   90;

  /* 10. Motion — [AUDITED → normalizado] solo transiciones funcionales */
  --motion-press:   100ms;   /* scale en :active */
  --motion-fast:    150ms;   /* hover de color / fondo (AUDITED .12–.15s) */
  --motion-base:    200ms;   /* elevación, toast, dropdown (AUDITED .18–.2s) */
  --motion-overlay: 220ms;   /* modal y sheet (AUDITED .22s) */
  --ease-standard:  ease;    /* AUDITED */
  --press-scale:    .97;     /* AUDITED .92–.98 → .97 */

  /* 11. Master Plan — [AUDITED → normalizado] */
  --poly-fill-opacity:          .32;  /* polígonos de nivel (Colinas) */
  --poly-fill-opacity-hover:    .48;  /* [PROPOSED] */
  --poly-fill-opacity-selected: .60;  /* AUDITED */
  --marker-fill-opacity:        .90;  /* lotes numerados (ECOS) */
  --mp-dim-opacity:             .18;  /* filtered-out (ECOS .18 · Colinas .30/.35 → .18) */
  --mp-select-width:            3;    /* AUDITED Colinas .lot.selected */
}

@media (min-width: 640px) {
  :root { --gutter: var(--space-5); }
}
@media (min-width: 960px) {
  :root {
    --text-display: 48px; --lh-display: 52px;
    --text-h1:      32px; --lh-h1:      40px;
    --text-h2:      24px; --lh-h2:      32px;
    --gutter:       var(--space-6);
  }
}

/* Densidad operativa (admin) — [PROPOSED] */
[data-density="compact"] {
  --density-control-h: var(--control-h-md);
  --density-row-h:     var(--space-10);
  --density-pad:       var(--space-4);
  --density-gap:       var(--space-3);
  --density-text:      var(--text-body-sm);
  --density-lh:        var(--lh-body-sm);
}
@media (pointer: coarse) {
  [data-density="compact"] { --density-control-h: var(--control-h-lg); --density-row-h: var(--space-11); }
}

/* 1.9 Puente legacy — [DEPRECATED] mantiene vivo el CSS actual mientras migra.
   Eliminar en Fase 6. Ojo: --red vale AZUL en producción (nombre engañoso). */
:root {
  --blue:       var(--brand-primary);
  --brand:      var(--brand-primary);
  --red:        var(--brand-primary);
  --blue-press: var(--brand-primary-hover);
  --brand-ink:  var(--brand-primary-hover);
  --blue-soft:  var(--brand-primary-soft);
  --navy:       var(--ink);
  --line:       var(--border);
  --sold:       var(--unavail);
  --r:          var(--radius-panel);
  --r-md:       var(--radius-panel);
  --r-lg:       var(--radius-card);
  --r-full:     var(--radius-pill);
  --shadow-cap: var(--shadow-sm);
  --sp-1: var(--space-1);  --sp-2: var(--space-2);  --sp-3: var(--space-3);
  --sp-4: var(--space-4);  --sp-5: var(--space-5);  --sp-6: var(--space-6);
  --sp-8: var(--space-8);  --sp-10: var(--space-10); --sp-12: var(--space-12);
  --err-bg:     var(--feedback-danger-bg);
  --err-border: var(--feedback-danger-border);
  --err-ink:    var(--feedback-danger-ink);
}


/* --------------------------------------------------------------------------
   2. BASE (opt-in: <body class="ds-base">)
   -------------------------------------------------------------------------- */
.ds-base {
  margin: 0;
  background: var(--color-canvas);
  color: var(--color-text-primary);
  font-family: var(--font-sans);
  font-size: var(--density-text);
  line-height: var(--density-lh);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
.ds-base *, .ds-base *::before, .ds-base *::after { box-sizing: border-box; }
.ds-base img, .ds-base video { max-width: 100%; }
.ds-base ::selection { background: var(--brand-primary-soft); }
:where(.ds-base) :focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus);
  outline-offset: var(--focus-ring-offset);
}
:where(.ds-base) a { color: var(--color-link); text-underline-offset: 2px; }
:where(.ds-base) a:hover { color: var(--color-action-primary-hover); }

@media (prefers-reduced-motion: reduce) {
  :where(.ds-base) *, :where(.ds-base) *::before, :where(.ds-base) *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* El atributo hidden siempre gana a las clases que fijan display */
[hidden] { display: none !important; }
/* Bloqueo de scroll mientras hay un modal o un sheet expandido (lo pone d360.js) */
.ds-scroll-lock { overflow: hidden; }

/* Utilidades */
.ds-sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* Enlace "Saltar al contenido": invisible hasta recibir foco con teclado — [PROPOSED] */
.ds-skip-link { position: fixed; left: var(--space-2); top: var(--space-2); z-index: var(--z-tooltip); padding: var(--space-2) var(--space-3); border-radius: var(--radius-control); background: var(--ink); color: var(--surface); font-weight: var(--fw-bold); text-decoration: none; transform: translateY(-200%); }
.ds-skip-link:focus { transform: none; color: var(--surface); }
.ds-truncate { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ds-clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ds-num { font-variant-numeric: tabular-nums; }
.ds-break { overflow-wrap: anywhere; }
@media (min-width: 960px) { .ds-only-mobile { display: none !important; } }
@media (max-width: 959.98px) { .ds-only-desktop { display: none !important; } }
.ds-icon { width: var(--icon-md); height: var(--icon-md); flex: none; fill: none; stroke: currentColor; stroke-width: var(--icon-stroke); stroke-linecap: round; stroke-linejoin: round; }
.ds-icon--sm { width: var(--icon-sm); height: var(--icon-sm); }
.ds-icon--lg { width: var(--icon-lg); height: var(--icon-lg); }


/* --------------------------------------------------------------------------
   3. TIPOGRAFÍA
   -------------------------------------------------------------------------- */
.ds-display, .ds-h1, .ds-h2, .ds-h3 { margin: 0; color: var(--ink); font-weight: var(--fw-extrabold); text-wrap: balance; }
.ds-display { font-size: var(--text-display); line-height: var(--lh-display); letter-spacing: var(--tracking-tight); }
.ds-h1      { font-size: var(--text-h1);      line-height: var(--lh-h1);      letter-spacing: var(--tracking-tight); }
.ds-h2      { font-size: var(--text-h2);      line-height: var(--lh-h2);      letter-spacing: var(--tracking-tight); }
.ds-h3      { font-size: var(--text-h3);      line-height: var(--lh-h3);      letter-spacing: var(--tracking-snug); }
.ds-body-lg { font-size: var(--text-body-lg); line-height: var(--lh-body-lg); }
.ds-body    { font-size: var(--text-body);    line-height: var(--lh-body); }
.ds-body-sm { font-size: var(--text-body-sm); line-height: var(--lh-body-sm); }
.ds-label   { font-size: var(--text-label);   line-height: var(--lh-label);   font-weight: var(--fw-bold); }
.ds-caption { font-size: var(--text-caption); line-height: var(--lh-caption); color: var(--muted); }
.ds-overline { font-size: var(--text-overline); line-height: var(--lh-overline); font-weight: var(--fw-semibold); letter-spacing: var(--tracking-overline); text-transform: uppercase; color: var(--muted); }
.ds-title   { font-size: var(--text-body-lg); line-height: var(--lh-body-lg); font-weight: var(--fw-extrabold); letter-spacing: var(--tracking-snug); margin: 0; }
.ds-muted   { color: var(--muted); }


/* --------------------------------------------------------------------------
   4. LAYOUT
   -------------------------------------------------------------------------- */
.ds-container { width: 100%; max-width: calc(var(--container-project) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
.ds-container--discovery { max-width: calc(var(--container-discovery) + 2 * var(--gutter)); }
.ds-container--reading   { max-width: calc(var(--container-reading) + 2 * var(--gutter)); }
.ds-stack { display: flex; flex-direction: column; gap: var(--density-gap); min-width: 0; }
.ds-row   { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-width: 0; }
.ds-grid-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-5); }
@media (min-width: 640px)  { .ds-grid-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1440px) { .ds-grid-cards--wide { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* Master Plan + panel lateral (ECOS .stage) */
.ds-stage { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); align-items: start; }
@media (min-width: 960px) {
  .ds-stage { grid-template-columns: minmax(0, 1fr) var(--side-panel-w); }
  .ds-stage__side { position: sticky; top: calc(var(--header-h) + var(--space-3)); max-height: calc(100vh - var(--header-h) - var(--space-6)); overflow: auto; }
}


/* --------------------------------------------------------------------------
   5. BOTONES
   -------------------------------------------------------------------------- */
.ds-btn {
  --btn-h: var(--density-control-h);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: var(--btn-h); padding: 0 var(--space-4);
  border: 1px solid transparent; border-radius: var(--radius-control);
  background: transparent; color: var(--ink);
  font-family: inherit; font-size: var(--text-label); line-height: var(--lh-label); font-weight: var(--fw-bold);
  text-decoration: none; white-space: nowrap; cursor: pointer; user-select: none;
  transition: background-color var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard), transform var(--motion-press) var(--ease-standard);
}
.ds-btn:active { transform: scale(var(--press-scale)); }
.ds-btn:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }
.ds-btn:disabled, .ds-btn[aria-disabled="true"] { cursor: not-allowed; transform: none; color: var(--faint); background: var(--bg); border-color: transparent; }
.ds-btn--sm { --btn-h: var(--control-h-sm); padding: 0 var(--space-3); font-size: var(--text-caption); }
.ds-btn--md { --btn-h: var(--control-h-md); }
.ds-btn--lg { --btn-h: var(--control-h-lg); padding: 0 var(--space-5); font-size: var(--text-body); line-height: var(--lh-body); }
.ds-btn--block { display: flex; width: 100%; }
.ds-btn .ds-icon { width: var(--icon-sm); height: var(--icon-sm); }
@media (pointer: coarse) { .ds-btn--sm, .ds-btn--md { min-height: var(--touch-target-min); } }

/* Primary — [LOCKED] pill sólido de marca (AUDITED .btn-primary, .cta, .ib-install) */
.ds-btn--primary { border-radius: var(--radius-btn-primary); background: var(--color-action-primary); color: var(--color-text-on-action); }
.ds-btn--primary:hover  { background: var(--color-action-primary-hover); color: var(--color-text-on-action); }
.ds-btn--primary:active { background: var(--color-action-primary-active); }
.ds-btn--primary:disabled, .ds-btn--primary[aria-disabled="true"] { background: var(--faint); color: var(--surface); }

/* Tonal — [AUDITED] pill gris (.ghostbtn, .tb-login, .hburger, .listbtn) */
.ds-btn--tonal { border-radius: var(--radius-pill); background: var(--color-fill); color: var(--ink); }
.ds-btn--tonal:hover { background: var(--color-fill-hover); }
.ds-btn--tonal[aria-pressed="true"] { background: var(--color-action-primary); color: var(--color-text-on-action); }

/* Secondary — [AUDITED] contorno 8px (share-actions, .btn-ghost “Brochure”) */
.ds-btn--secondary { background: var(--surface); border-color: var(--border); color: var(--ink); }
.ds-btn--secondary:hover { background: var(--bg); border-color: var(--faint); }

/* Ghost — [LOCKED radio 8] sin fondo (.engbtn “Me gusta”, “Comentar”) */
.ds-btn--ghost { color: var(--muted); }
.ds-btn--ghost:hover { background: var(--bg); color: var(--ink); }

/* Link — [AUDITED] .card-access a, .back, .linkrow a */
.ds-btn--link { --btn-h: var(--touch-target-min); padding: 0; color: var(--color-link); }
.ds-btn--link:hover { color: var(--color-action-primary-hover); text-decoration: underline; }

/* Danger — [PROPOSED] solo en diálogos de confirmación destructiva */
.ds-btn--danger { border-radius: var(--radius-pill); background: var(--feedback-danger-ink); color: var(--surface); }
.ds-btn--danger:hover { background: var(--unavail); }

/* Icon button — [LOCKED] circular 50% */
.ds-icon-btn {
  --ib: var(--control-h-md);
  position: relative; display: inline-grid; place-items: center; flex: none;
  width: var(--ib); height: var(--ib); padding: 0;
  border: 1px solid transparent; border-radius: var(--radius-round);
  background: transparent; color: var(--ink); cursor: pointer;
  transition: background-color var(--motion-fast) var(--ease-standard), transform var(--motion-press) var(--ease-standard);
}
.ds-icon-btn::before { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, var(--touch-target-min)); height: max(100%, var(--touch-target-min)); transform: translate(-50%, -50%); }
.ds-icon-btn:hover { background: var(--bg); }
.ds-icon-btn:active { transform: scale(var(--press-scale)); }
.ds-icon-btn:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }
.ds-icon-btn:disabled { color: var(--faint); background: transparent; cursor: not-allowed; }
.ds-icon-btn--sm { --ib: var(--control-h-sm); }
.ds-icon-btn--tonal { background: var(--color-fill); color: var(--muted); }
.ds-icon-btn--tonal:hover { background: var(--color-fill-hover); color: var(--ink); }
.ds-icon-btn--outline { border-color: var(--border); background: var(--surface); }
/* Sobre imagen o Master Plan: superficie + shadow-sm (sustituye al círculo oscuro translúcido) */
.ds-icon-btn--float { background: var(--surface); border-color: var(--border); box-shadow: var(--elevation-raised); }
.ds-icon-btn--float:hover { background: var(--surface); box-shadow: var(--elevation-floating); }
.ds-icon-btn--float:focus-visible { outline: none; box-shadow: var(--focus-ring-double); }
.ds-icon-btn[aria-pressed="true"] { color: var(--color-action-primary); }

/* Google — [LOCKED exception] logo “G” multicolor oficial, nunca monocromo */
.ds-btn-google {
  display: flex; align-items: center; justify-content: center; gap: var(--space-3);
  width: 100%; min-height: var(--control-h-lg); padding: 0 var(--space-5);
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--surface); color: var(--ink);
  font-family: inherit; font-size: var(--text-body); font-weight: var(--fw-bold); cursor: pointer;
  transition: background-color var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard);
}
.ds-btn-google:hover { background: var(--bg); border-color: var(--faint); }
.ds-btn-google:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }
.ds-btn-google svg { width: var(--icon-md); height: var(--icon-md); flex: none; }


/* --------------------------------------------------------------------------
   6. FORMULARIOS
   -------------------------------------------------------------------------- */
.ds-field { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-stack-sm); min-width: 0; }
.ds-field__label { font-size: var(--text-caption); line-height: var(--lh-caption); font-weight: var(--fw-bold); color: var(--ink); }
.ds-field__hint  { font-size: var(--text-caption); line-height: var(--lh-caption); color: var(--muted); }
.ds-field__error { display: flex; gap: var(--space-1); align-items: center; font-size: var(--text-caption); line-height: var(--lh-caption); font-weight: var(--fw-semibold); color: var(--color-danger); }

.ds-input, .ds-select, .ds-textarea {
  width: 100%; min-height: var(--density-control-h); padding: 0 var(--space-3);
  border: 1px solid var(--color-input-border); border-radius: var(--radius-input);
  background: var(--surface); color: var(--ink);
  font-family: inherit; font-size: var(--text-input); line-height: var(--lh-body-lg);
  appearance: none;
  transition: border-color var(--motion-fast) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard);
}
.ds-input::placeholder, .ds-textarea::placeholder { color: var(--color-text-placeholder); opacity: 1; }
.ds-input:hover, .ds-select:hover, .ds-textarea:hover { border-color: var(--faint); }
.ds-input:focus, .ds-select:focus, .ds-textarea:focus { outline: none; border-color: var(--color-focus); box-shadow: var(--focus-ring-input); }
.ds-input[aria-invalid="true"], .ds-textarea[aria-invalid="true"] { border-color: var(--color-danger); }
.ds-input:disabled, .ds-select:disabled, .ds-textarea:disabled { background: var(--bg); color: var(--faint); cursor: not-allowed; }
.ds-textarea { padding: var(--space-3); resize: vertical; }
@media (min-width: 960px) {
  [data-density="compact"] .ds-input, [data-density="compact"] .ds-select, [data-density="compact"] .ds-textarea { font-size: var(--text-body); line-height: var(--lh-body); }
}

/* Input tonal de búsqueda — [AUDITED] .searchbar / .searchbar2 / .search */
.ds-searchfield { display: flex; align-items: center; gap: var(--space-2); min-height: var(--control-h-lg); padding: 0 var(--space-4); border-radius: var(--radius-pill); background: var(--color-fill); color: var(--muted); }
.ds-searchfield input { flex: 1; min-width: 0; border: 0; padding: 0; background: transparent; color: var(--ink); font: inherit; font-size: var(--text-input); outline: none; }
.ds-searchfield input::placeholder { color: var(--color-text-placeholder); opacity: 1; }
.ds-searchfield:focus-within { box-shadow: inset 0 0 0 2px var(--color-focus); }
/* Sobre el canvas gris (admin, .ds-app) el relleno #f7f7f7 desaparece: superficie blanca + borde de input — [PROPOSED]
   El borde sigue la decisión pendiente --color-input-border (--border hoy · --border-strong si se aprueba). */
.ds-searchfield--surface { background: var(--surface); box-shadow: inset 0 0 0 1px var(--color-input-border); }
.ds-searchfield--surface:focus-within { box-shadow: inset 0 0 0 2px var(--color-focus); }

.ds-select-wrap { position: relative; }
.ds-select-wrap::after { content: ""; position: absolute; right: var(--space-4); top: 50%; width: 8px; height: 8px; border-right: 2px solid var(--ink); border-bottom: 2px solid var(--ink); transform: translateY(-75%) rotate(45deg); pointer-events: none; }
.ds-select { padding-right: var(--space-10); cursor: pointer; }

.ds-check { display: inline-flex; align-items: flex-start; gap: var(--space-3); min-height: var(--space-6); font-size: var(--text-body); line-height: var(--lh-body); cursor: pointer; }
.ds-check input { width: 20px; height: 20px; margin: 2px 0 0; flex: none; accent-color: var(--color-action-primary); cursor: pointer; }
.ds-check input:disabled + span { color: var(--faint); }
@media (pointer: coarse) { .ds-check { padding-block: var(--space-2); } }

.ds-toggle { position: relative; display: inline-flex; align-items: center; gap: var(--space-3); min-height: var(--touch-target-min); cursor: pointer; font-size: var(--text-body); }
.ds-toggle__input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.ds-toggle__track { position: relative; flex: none; width: var(--space-11); height: var(--space-6); border-radius: var(--radius-pill); background: var(--faint); transition: background-color var(--motion-base) var(--ease-standard); }
.ds-toggle__track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: var(--surface); transition: transform var(--motion-base) var(--ease-standard); }
.ds-toggle__input:checked + .ds-toggle__track { background: var(--color-action-primary); }
.ds-toggle__input:checked + .ds-toggle__track::after { transform: translateX(20px); }
.ds-toggle__input:focus-visible + .ds-toggle__track { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }
.ds-toggle__input:disabled + .ds-toggle__track { background: var(--border); }
.ds-toggle__input:disabled ~ .ds-toggle__label { color: var(--faint); }

.ds-inline-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3); }
.ds-inline-form > .ds-field { flex: 1 1 200px; }
.ds-inline-form > .ds-btn { flex: none; }
@media (max-width: 639.98px) { .ds-inline-form > .ds-btn { flex: 1 1 100%; } }

/* Stepper de onboarding — [AUDITED] .pub-progress (3px, gap 5 → 4) */
.ds-stepper { display: flex; gap: var(--space-1); }
.ds-stepper i { flex: 1; height: 3px; border-radius: var(--radius-pill); background: var(--border); transition: background-color var(--motion-base) var(--ease-standard); }
.ds-stepper i.is-done, .ds-stepper i[aria-current="step"] { background: var(--color-action-primary); }

/* Lista de opciones (onboarding “¿Dónde operas?”) — [AUDITED] */
.ds-option { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); width: 100%; min-height: var(--touch-target-min); padding: 0 var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-control); background: var(--surface); color: var(--ink); font: inherit; font-size: var(--text-body); font-weight: var(--fw-bold); text-align: left; cursor: pointer; }
.ds-option:hover { border-color: var(--faint); background: var(--bg); }
.ds-option[aria-selected="true"] { border-color: var(--color-selected-border); background: var(--color-selected-bg); }


/* --------------------------------------------------------------------------
   7. SEARCH CAPSULE — [AUDITED] home .searchcap
   -------------------------------------------------------------------------- */
.ds-search { display: flex; align-items: stretch; gap: 0; width: 100%; max-width: 640px; margin-inline: auto; padding: var(--space-2); background: var(--surface); border-radius: var(--radius-search); box-shadow: var(--elevation-raised); transition: box-shadow var(--motion-base) var(--ease-standard); }
.ds-search:hover { box-shadow: var(--elevation-floating); }
.ds-search__field { position: relative; flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: center; padding: var(--space-1) var(--space-5); border-radius: var(--radius-pill); cursor: pointer; transition: background-color var(--motion-fast) var(--ease-standard); }
.ds-search__field + .ds-search__field::before { content: ""; position: absolute; left: 0; top: var(--space-2); bottom: var(--space-2); width: 1px; background: var(--border); }
button.ds-search__field { border: 0; background: transparent; color: inherit; font: inherit; text-align: left; }
.ds-search__field:hover { background: var(--bg); }
.ds-search__field:focus-within { background: var(--bg); box-shadow: inset 0 0 0 2px var(--color-focus); }
.ds-search__label { font-size: var(--text-overline); line-height: var(--lh-overline); font-weight: var(--fw-bold); color: var(--ink); }
.ds-search__input { width: 100%; min-width: 0; padding: 0; border: 0; background: transparent; color: var(--ink); font: inherit; font-size: var(--text-body); line-height: var(--lh-body); outline: none; appearance: none; text-overflow: ellipsis; }
.ds-search__input::placeholder { color: var(--color-text-placeholder); opacity: 1; }
.ds-search__submit { flex: none; display: grid; place-items: center; width: var(--control-h-lg); height: var(--control-h-lg); margin-left: var(--space-1); border: 0; border-radius: var(--radius-round); background: var(--color-action-primary); color: var(--surface); cursor: pointer; transition: background-color var(--motion-fast) var(--ease-standard), transform var(--motion-press) var(--ease-standard); }
.ds-search__submit:hover { background: var(--color-action-primary-hover); }
.ds-search__submit:active { background: var(--color-action-primary-active); transform: scale(var(--press-scale)); }
.ds-search__submit:focus-visible { outline: none; box-shadow: var(--focus-ring-double); }
@media (max-width: 639.98px) {
  .ds-search { flex-wrap: wrap; border-radius: var(--radius-card); }
  .ds-search__field { flex: 1 1 40%; padding: var(--space-2) var(--space-4); }
  .ds-search__field + .ds-search__field::before { display: none; }
  .ds-search__field--full { flex-basis: 100%; border-top: 1px solid var(--border); border-radius: 0; }
  .ds-search__submit { margin-left: auto; }
}


/* --------------------------------------------------------------------------
   8. CHIPS, BADGES, TAGS
   -------------------------------------------------------------------------- */
/* Filter chip — control interactivo */
.ds-chip { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--control-h-md); padding: 0 var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-chip); background: var(--surface); color: var(--ink); font: inherit; font-size: var(--text-label); line-height: var(--lh-label); font-weight: var(--fw-semibold); white-space: nowrap; cursor: pointer; transition: border-color var(--motion-fast) var(--ease-standard), background-color var(--motion-fast) var(--ease-standard); }
.ds-chip:hover { border-color: var(--ink); }
.ds-chip:active { background: var(--bg); }
.ds-chip:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }
.ds-chip[aria-pressed="true"] { border-color: var(--color-selected-border); background: var(--color-selected-bg); color: var(--color-selected-text); }
.ds-chip:disabled { color: var(--faint); border-color: var(--border); background: var(--surface); cursor: not-allowed; }
.ds-chip__check { display: none; }
.ds-chip[aria-pressed="true"] .ds-chip__check { display: block; }
@media (pointer: coarse) { .ds-chip { min-height: var(--touch-target-min); } }
/* Chip de estado — conserva el color semántico; NUNCA azul de marca */
.ds-chip--status::before { content: ""; width: 8px; height: 8px; flex: none; border-radius: 50%; background: var(--chip-status, var(--noninv)); }
.ds-chip--status[aria-pressed="true"] { border-color: var(--chip-status); background: var(--surface); color: var(--ink); box-shadow: inset 0 0 0 1px var(--chip-status); }
.ds-chip--avail   { --chip-status: var(--avail); }
.ds-chip--res     { --chip-status: var(--res); }
.ds-chip--unavail { --chip-status: var(--unavail); }
.ds-chip--blocked { --chip-status: var(--blocked); }
.ds-chip--noninv  { --chip-status: var(--noninv); }

/* Status badge — estado informativo (pill). Default “soft”: punto de color + texto ink */
.ds-badge { --badge-color: var(--noninv); --badge-on: var(--ink); display: inline-flex; align-items: center; gap: var(--space-1); min-height: var(--space-6); padding: 0 var(--space-2); border: 1px solid var(--border); border-radius: var(--radius-badge); background: var(--surface); color: var(--ink); font-size: var(--text-caption); line-height: var(--lh-caption); font-weight: var(--fw-bold); white-space: nowrap; }
.ds-badge::before { content: ""; width: 8px; height: 8px; flex: none; border-radius: 50%; background: var(--badge-color); }
.ds-badge--solid { border-color: transparent; background: var(--badge-color); color: var(--badge-on); }
.ds-badge--solid::before { display: none; }
.ds-badge--avail   { --badge-color: var(--avail);   --badge-on: var(--color-on-avail); }
.ds-badge--res     { --badge-color: var(--res);     --badge-on: var(--color-on-res); }
.ds-badge--unavail { --badge-color: var(--unavail); --badge-on: var(--color-on-unavail); }
.ds-badge--blocked { --badge-color: var(--blocked); --badge-on: var(--color-on-blocked); }
.ds-badge--noninv  { --badge-color: var(--noninv);  --badge-on: var(--color-on-noninv); }
/* Trust badge (Verificado) — sobre imagen: superficie + shadow-sm — [AUDITED] .badge-verified */
.ds-badge--trust { border-color: transparent; box-shadow: var(--elevation-raised); }
.ds-badge--trust::before { display: none; }
.ds-badge--trust svg { width: var(--icon-sm); height: var(--icon-sm); color: var(--color-action-primary); }

/* Tag — metadato (no estado, no control) — [PROPOSED] */
.ds-tag { display: inline-flex; align-items: center; min-height: var(--space-6); padding: 0 var(--space-2); border-radius: var(--radius-control); background: var(--bg); color: var(--muted); font-size: var(--text-caption); line-height: var(--lh-caption); font-weight: var(--fw-semibold); }

/* Punto de estado */
.ds-dot { display: inline-block; width: 8px; height: 8px; flex: none; border-radius: 50%; background: var(--noninv); }
.ds-dot--avail { background: var(--avail); } .ds-dot--res { background: var(--res); } .ds-dot--unavail { background: var(--unavail); }
.ds-dot--blocked { background: var(--blocked); } .ds-dot--noninv { background: var(--noninv); }


/* --------------------------------------------------------------------------
   9. CARDS Y PANELES
   -------------------------------------------------------------------------- */
.ds-card  { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card); padding: var(--density-pad); }
.ds-panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel); padding: var(--density-pad); }
.ds-card--interactive { position: relative; cursor: pointer; transition: box-shadow var(--motion-base) var(--ease-standard), border-color var(--motion-base) var(--ease-standard); }
.ds-card--interactive:hover { box-shadow: var(--elevation-raised); }
.ds-card--interactive[aria-current="true"], .ds-card--interactive.is-selected { border-color: var(--color-selected-border); background: var(--color-selected-bg); }
@media (max-width: 959.98px) {
  .ds-panel--bleed { border-radius: 0; border-inline: 0; }   /* [AUDITED] paneles a sangre en móvil */
}
/* Enlace que cubre toda la card (stretched link) */
.ds-cover-link { color: inherit; text-decoration: none; }
.ds-cover-link::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.ds-cover-link:focus-visible { outline: none; }
.ds-cover-link:focus-visible::after { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }

/* Project listing card — [AUDITED] home .card */
.ds-project-card { position: relative; display: flex; flex-direction: column; overflow: hidden; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card); transition: box-shadow var(--motion-base) var(--ease-standard), transform var(--motion-base) var(--ease-standard); }
@media (hover: hover) { .ds-project-card:hover { box-shadow: var(--elevation-raised); transform: translateY(-2px); } }
.ds-project-card__head { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-4) var(--space-3); min-width: 0; }
.ds-project-card__logo { width: 36px; height: 36px; flex: none; padding: var(--space-1); object-fit: contain; border: 1px solid var(--border); border-radius: var(--radius-thumb); background: var(--bg); }
.ds-project-card__title { display: block; margin: 0; font-size: var(--text-body-lg); line-height: var(--lh-body-lg); font-weight: var(--fw-extrabold); letter-spacing: var(--tracking-snug); }
.ds-project-card__meta { font-size: var(--text-caption); line-height: var(--lh-caption); color: var(--muted); }
.ds-project-card__media { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--bg); }
.ds-project-card__media img { display: block; width: 100%; height: 100%; object-fit: contain; }
.ds-project-card__overlay-tl { position: absolute; left: var(--space-3); top: var(--space-3); z-index: 2; }   /* [PROPOSED] “Verificado” arriba-izq (hoy abajo-izq) */
.ds-project-card__overlay-tr { position: absolute; right: var(--space-3); top: var(--space-3); z-index: 2; }
.ds-project-card__kpis { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); padding: var(--space-3) var(--space-4) 0; }
.ds-project-card__actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--space-2); padding: var(--space-4); margin-top: auto; position: relative; z-index: 2; }
@media (max-width: 639.98px) { .ds-project-card { border-radius: 0; border-inline: 0; } }

/* Mini KPI (card de proyecto) — [AUDITED] .card-kpis */
.ds-minikpi { display: grid; justify-items: center; gap: 0; padding: var(--space-1) var(--space-1) var(--space-2); border-radius: var(--radius-control); background: var(--bg); text-align: center; }
.ds-minikpi b { font-size: var(--text-body-lg); line-height: var(--lh-body-lg); font-weight: var(--fw-extrabold); font-variant-numeric: tabular-nums; color: var(--ink); }
.ds-minikpi span { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--text-overline); line-height: var(--lh-overline); font-weight: var(--fw-semibold); letter-spacing: var(--tracking-overline); text-transform: uppercase; color: var(--muted); }
.ds-minikpi--avail { background: var(--avail-soft); }
.ds-minikpi--res   { background: var(--res-soft); }

/* Lot / Unit detail card — [AUDITED] ECOS .lotcard, Colinas .fieldrow */
.ds-unit-card { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
.ds-unit-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.ds-unit-card__code { margin: 0; font-size: var(--text-h3); line-height: var(--lh-h3); font-weight: var(--fw-extrabold); letter-spacing: var(--tracking-snug); }
.ds-unit-card__context { font-size: var(--text-body-sm); line-height: var(--lh-body-sm); color: var(--muted); }
.ds-unit-card__price { font-size: var(--text-h2); line-height: var(--lh-h2); font-weight: var(--fw-extrabold); letter-spacing: var(--tracking-tight); font-variant-numeric: tabular-nums; }
.ds-unit-card__price small { font-size: var(--text-caption); font-weight: var(--fw-semibold); color: var(--muted); letter-spacing: 0; }
.ds-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--space-4); margin: 0; }
.ds-facts > div { display: flex; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--border); font-size: var(--text-body); line-height: var(--lh-body); }
.ds-facts dt { color: var(--muted); }
.ds-facts dd { margin: 0; font-weight: var(--fw-bold); text-align: right; font-variant-numeric: tabular-nums; }
.ds-unit-card__actions { display: flex; gap: var(--space-2); align-items: center; }
.ds-unit-card__actions .ds-btn--primary { flex: 1; }

/* Unit row (lista de inventario) — [AUDITED] .availUnitRow / .unitrow */
.ds-unit-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); width: 100%; min-height: var(--touch-target-min); padding: var(--space-2) var(--space-3); border: 0; border-radius: var(--radius-control); background: transparent; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
a.ds-unit-row { text-decoration: none; }
.ds-unit-row:hover { background: var(--surface); color: var(--ink); }
.ds-unit-row[aria-current="true"] { background: var(--color-selected-bg); }
.ds-unit-row__line { display: flex; align-items: baseline; gap: var(--space-2); flex: 1; min-width: 0; overflow-x: auto; white-space: nowrap; scrollbar-width: none; }
.ds-unit-row__code { flex: none; font-size: var(--text-body); font-weight: var(--fw-bold); }
.ds-unit-row__spec { flex: none; font-size: var(--text-caption); color: var(--muted); }
.ds-unit-row__price { flex: none; font-size: var(--text-body-sm); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }

/* Grupo de inventario (acordeón) — [AUDITED] .availGroup */
.ds-group { border-radius: var(--radius-panel); background: var(--bg); overflow: hidden; }
.ds-group + .ds-group { margin-top: var(--space-2); }
.ds-group__btn { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); width: 100%; min-height: var(--touch-target-min); padding: var(--space-3) var(--space-4); border: 0; background: transparent; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.ds-group__btn:hover { background: var(--color-fill-hover); }
.ds-group__title { font-size: var(--text-body); font-weight: var(--fw-extrabold); }
.ds-group__count { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--text-caption); font-weight: var(--fw-bold); color: var(--ink); }
.ds-group__chev { color: var(--muted); transition: transform var(--motion-fast) var(--ease-standard); }
.ds-group__btn[aria-expanded="true"] .ds-group__chev { transform: rotate(90deg); }
.ds-group__body { padding: 0 var(--space-2) var(--space-2); }

/* KPI / metric card — [PROPOSED] admin */
.ds-kpi { display: grid; gap: var(--space-1); padding: var(--space-4); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card); }
.ds-kpi__label { font-size: var(--text-caption); line-height: var(--lh-caption); font-weight: var(--fw-semibold); color: var(--muted); }
.ds-kpi__value { font-size: var(--text-h2); line-height: var(--lh-h2); font-weight: var(--fw-extrabold); letter-spacing: var(--tracking-tight); font-variant-numeric: tabular-nums; }
.ds-kpi__meta  { font-size: var(--text-caption); line-height: var(--lh-caption); color: var(--muted); }

/* Barra de distribución de disponibilidad — [AUDITED] .mbar (6px) */
.ds-availbar { display: flex; height: 6px; overflow: hidden; border-radius: var(--radius-pill); background: var(--bg); }
.ds-availbar i { display: block; height: 100%; }
.ds-availbar .is-avail { background: var(--avail); } .ds-availbar .is-res { background: var(--res); }
.ds-availbar .is-unavail { background: var(--unavail); } .ds-availbar .is-blocked { background: var(--blocked); }
.ds-availbar .is-noninv { background: var(--noninv); }

/* Resumen de disponibilidad — [AUDITED] .metricsMain */
.ds-availsum { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }
.ds-availsum__big { font-size: var(--text-h2); line-height: var(--lh-h2); font-weight: var(--fw-extrabold); letter-spacing: var(--tracking-tight); color: var(--avail); font-variant-numeric: tabular-nums; }   /* [AUDITED] texto grande ≥18.7px bold: 3.30:1 cumple */
.ds-availsum__lbl { font-size: var(--text-body-sm); color: var(--muted); }
.ds-availsum__lbl b { color: var(--ink); }

/* Building card / Level card — [AUDITED] Colinas .grid .card y .tab */
.ds-bcard { position: relative; display: grid; gap: var(--space-1); flex: 0 0 192px; padding: var(--space-3) var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-card); background: var(--surface); color: var(--ink); font: inherit; text-align: left; cursor: pointer; scroll-snap-align: start; transition: border-color var(--motion-fast) var(--ease-standard), background-color var(--motion-fast) var(--ease-standard); }
.ds-bcard:hover { border-color: var(--color-selected-border); }
.ds-bcard[aria-pressed="true"] { border-color: var(--color-selected-border); background: var(--color-selected-bg); }
.ds-bcard__title { font-size: var(--text-body); font-weight: var(--fw-bold); }
.ds-bcard__status { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--text-caption); font-weight: var(--fw-bold); color: var(--ink); }
.ds-bcard__meta { font-size: var(--text-caption); color: var(--muted); }
.ds-bcard__chev { position: absolute; top: var(--space-3); right: var(--space-3); color: var(--muted); }
.ds-hscroll { display: flex; gap: var(--space-3); overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); padding-bottom: var(--space-2); scrollbar-width: thin; }
.ds-level { flex: none; display: grid; gap: 0; min-width: 96px; min-height: var(--touch-target-min); padding: var(--space-3) var(--space-4); border: 1px solid var(--border); border-top: 4px solid var(--level-status, var(--noninv)); border-radius: var(--radius-panel); background: var(--surface); color: var(--ink); font: inherit; text-align: center; cursor: pointer; }
.ds-level b { font-size: var(--text-body); }
.ds-level span { font-size: var(--text-caption); color: var(--muted); }
.ds-level[aria-selected="true"] { border-color: var(--color-selected-border); border-top-color: var(--level-status, var(--noninv)); background: var(--color-selected-bg); }


/* --------------------------------------------------------------------------
   10. FILTROS DE ESTADO DEL MASTER PLAN — [AUDITED] ECOS/Colinas .fcard
   -------------------------------------------------------------------------- */
.ds-statgroup { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); }
.ds-statgroup--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 640px) {
  .ds-statgroup { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .ds-statgroup--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.ds-statcard { --stat: var(--color-action-primary); display: flex; flex-direction: column; align-items: center; gap: var(--space-1); min-width: 0; min-height: var(--touch-target-min); padding: var(--space-2) var(--space-1); border: 1px solid transparent; border-radius: var(--radius-control); background: var(--color-fill); color: var(--ink); font: inherit; text-align: center; cursor: pointer; transition: background-color var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard); }
.ds-statcard:hover { background: var(--color-fill-hover); }
.ds-statcard:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }
.ds-statcard__n { font-size: var(--text-h3); line-height: var(--lh-h3); font-weight: var(--fw-extrabold); font-variant-numeric: tabular-nums; color: var(--ink); }
.ds-statcard__l { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1); max-width: 100%; font-size: var(--text-overline); line-height: var(--lh-overline); font-weight: var(--fw-semibold); color: var(--muted); }
.ds-statcard__l::before { content: ""; width: 8px; height: 8px; flex: none; border-radius: 50%; background: var(--stat); }
.ds-statcard--all .ds-statcard__l::before { display: none; }
.ds-statcard[aria-pressed="true"] { background: var(--surface); border-color: var(--stat); box-shadow: inset 0 0 0 1px var(--stat); }
.ds-statcard[aria-pressed="true"] .ds-statcard__l { color: var(--ink); }
.ds-statcard:disabled { cursor: not-allowed; opacity: .5; }
.ds-statcard--all     { --stat: var(--color-action-primary); }
.ds-statcard--avail   { --stat: var(--avail); }
.ds-statcard--res     { --stat: var(--res); }
.ds-statcard--unavail { --stat: var(--unavail); }
.ds-statcard--blocked { --stat: var(--blocked); }
.ds-statcard--noninv  { --stat: var(--noninv); }


/* --------------------------------------------------------------------------
   11. MASTER PLAN
   -------------------------------------------------------------------------- */
.ds-mp { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-panel); background: var(--bg); }
/* Los controles flotantes se anclan a la fila 1 (el mapa), nunca encima de la leyenda (fila 2) */
.ds-mp > .ds-mp-share, .ds-mp > .ds-mp-zoom { grid-row: 1; grid-column: 1; }
.ds-mp__viewport { position: relative; width: 100%; overflow: auto; touch-action: pan-x pan-y; overscroll-behavior: contain; }
.ds-mp__stage { position: relative; width: calc(100% * var(--z, 1)); transition: width var(--motion-base) var(--ease-standard); }
.ds-mp__image { display: block; width: 100%; height: auto; user-select: none; -webkit-user-drag: none; }
.ds-mp__overlay { position: absolute; inset: 0; width: 100%; height: 100%; }
/* Lote / unidad: fill = estado comercial · stroke = selección */
.ds-poly { --poly: var(--noninv); fill: var(--poly); fill-opacity: var(--poly-fill-opacity); stroke: var(--surface); stroke-width: 2; cursor: pointer; transition: fill-opacity var(--motion-fast) var(--ease-standard), opacity var(--motion-base) var(--ease-standard); }
.ds-poly--marker { fill-opacity: var(--marker-fill-opacity); }
.ds-poly[data-status="AVAILABLE"]     { --poly: var(--avail); }
.ds-poly[data-status="RESERVED"]      { --poly: var(--res); }
.ds-poly[data-status="SOLD"], .ds-poly[data-status="UNAVAILABLE"] { --poly: var(--unavail); }
.ds-poly[data-status="BLOCKED"]       { --poly: var(--blocked); }
.ds-poly[data-status="NON_INVENTORY"] { --poly: var(--noninv); cursor: default; }
.ds-poly:hover, .ds-poly.is-hover { fill-opacity: var(--poly-fill-opacity-hover); }
.ds-poly--marker:hover, .ds-poly--marker.is-hover { fill-opacity: 1; }
.ds-poly.is-selected { fill-opacity: var(--poly-fill-opacity-selected); }
.ds-poly--marker.is-selected { fill-opacity: 1; }
.ds-poly.is-filtered { opacity: var(--mp-dim-opacity); pointer-events: none; }
.ds-poly.is-disabled { fill: none; stroke: var(--faint); stroke-dasharray: 4 4; cursor: not-allowed; }
.ds-poly:focus-visible { outline: none; stroke: var(--ink); stroke-width: 3; stroke-dasharray: 6 3; }
/* Grupo de lote enfocable: <g class="ds-lot" data-lot data-status role="button" tabindex="0" aria-label> */
.ds-lot { cursor: pointer; outline: none; transition: opacity var(--motion-base) var(--ease-standard); }
.ds-lot:hover .ds-poly--marker { fill-opacity: 1; }
.ds-lot:hover .ds-poly:not(.ds-poly--marker) { fill-opacity: var(--poly-fill-opacity-hover); }
.ds-lot.is-filtered { opacity: var(--mp-dim-opacity); pointer-events: none; }
.ds-lot:focus-visible .ds-poly { stroke: var(--ink); stroke-width: 3; stroke-dasharray: 6 3; }
/* Contorno de selección doble (halo blanco + marca): se dibuja como elemento hermano */
.ds-sel-halo { fill: none; stroke: var(--surface); stroke-width: 7; pointer-events: none; }
.ds-sel-ring { fill: none; stroke: var(--color-selected-border); stroke-width: var(--mp-select-width); pointer-events: none; }
/* Etiqueta numérica del lote: ink sobre avail/res/noninv, blanco sobre unavail/blocked */
.ds-poly-label { font-family: var(--font-sans); font-weight: var(--fw-extrabold); text-anchor: middle; dominant-baseline: central; pointer-events: none; fill: var(--ink); }
.ds-poly-label--on-dark { fill: var(--surface); }
/* Building marker — [AUDITED] Colinas .bmark */
.ds-bmark { cursor: pointer; transition: opacity var(--motion-base) var(--ease-standard); }
.ds-bmark rect { stroke: var(--surface); stroke-width: 2; }
.ds-bmark.is-filtered { opacity: var(--mp-dim-opacity); }
.ds-bmark-count { fill: var(--surface); stroke: var(--ink); stroke-width: 1.5; }
.ds-bmark-count-text { fill: var(--ink); font-weight: var(--fw-extrabold); text-anchor: middle; dominant-baseline: central; pointer-events: none; }
/* Controles flotantes del mapa */
.ds-mp-share { position: absolute; top: var(--space-3); right: var(--space-3); z-index: 6; }
.ds-mp-zoom { position: absolute; right: var(--space-3); bottom: var(--space-3); z-index: 6; display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-control); background: var(--surface); box-shadow: var(--elevation-raised); }
.ds-mp-zoom button { display: grid; place-items: center; width: var(--control-h-md); height: var(--control-h-md); padding: 0; border: 0; background: var(--surface); color: var(--ink); cursor: pointer; }
.ds-mp-zoom button + button { border-top: 1px solid var(--border); }
.ds-mp-zoom button:hover { background: var(--bg); }
.ds-mp-zoom button:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: -2px; }
.ds-mp-zoom button:disabled { color: var(--faint); cursor: not-allowed; }
@media (pointer: coarse) { .ds-mp-zoom button { width: var(--touch-target-min); height: var(--touch-target-min); } }
.ds-mp-legend { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border); font-size: var(--text-caption); line-height: var(--lh-caption); color: var(--muted); }
.ds-mp-legend span { display: inline-flex; align-items: center; gap: var(--space-2); }
.ds-mp-legend b { color: var(--ink); font-variant-numeric: tabular-nums; }


/* --------------------------------------------------------------------------
   12. NAVEGACIÓN
   -------------------------------------------------------------------------- */
/* Header de plataforma — [AUDITED] home header sticky translúcido */
.ds-header { position: sticky; top: 0; z-index: var(--z-header); background: var(--header-bg); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); border-bottom: 1px solid transparent; transition: border-color var(--motion-base) var(--ease-standard), box-shadow var(--motion-base) var(--ease-standard); }
.ds-header.is-scrolled { border-bottom-color: var(--border); box-shadow: var(--elevation-raised); }
.ds-header__in { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); min-height: var(--header-h); max-width: calc(var(--container-discovery) + 2 * var(--gutter)); margin-inline: auto; padding: var(--space-2) var(--gutter); }
.ds-header__logo { display: block; height: var(--space-7); width: auto; flex: none; }

/* Project brand header — [AUDITED] .topbar */
.ds-project-header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); min-width: 0; }
.ds-project-header__id { display: flex; flex: 1 1 auto; align-items: center; gap: var(--space-3); min-width: 0; }
/* Las acciones nunca se encogen: el que cede espacio (y trunca) es el nombre/meta */
.ds-project-header__actions, .ds-project-header > :not(.ds-project-header__id) { display: flex; flex: none; align-items: center; gap: var(--space-2); }
.ds-project-header__logo { width: var(--space-12); height: var(--space-12); flex: none; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-avatar); background: var(--surface); object-fit: cover; }
.ds-project-header__name { display: flex; align-items: center; gap: var(--space-1); min-width: 0; margin: 0; font-size: var(--text-h3); line-height: var(--lh-h3); font-weight: var(--fw-extrabold); letter-spacing: var(--tracking-snug); }
.ds-project-header__name span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ds-project-header__meta { font-size: var(--text-caption); line-height: var(--lh-caption); color: var(--muted); }
@media (min-width: 960px) { .ds-project-header__logo { width: 64px; height: 64px; } .ds-project-header__name { font-size: var(--text-h2); line-height: var(--lh-h2); letter-spacing: var(--tracking-tight); } }

/* Barra de navegación inferior móvil — [AUDITED] ECOS .bottombar (≤959) */
.ds-bottombar { position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-bottombar); display: flex; padding: var(--space-1) var(--space-1) calc(var(--space-1) + env(safe-area-inset-bottom)); background: var(--surface); border-top: 1px solid var(--border); }
.ds-bottombar__item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-width: var(--touch-target-min); min-height: var(--touch-target-min); padding: var(--space-1); border: 0; border-radius: var(--radius-control); background: transparent; color: var(--muted); font: inherit; font-size: var(--text-overline); line-height: var(--lh-overline); font-weight: var(--fw-bold); text-decoration: none; cursor: pointer; }
.ds-bottombar__item:hover { color: var(--ink); }
.ds-bottombar__item[aria-current="page"] { color: var(--color-action-primary); }
@media (min-width: 960px) { .ds-bottombar { display: none; } }
/* Página con bottombar móvil: <body class="ds-base ds-has-bottombar"> — [PROPOSED]
   Reserva el alto de la barra para que no tape contenido y sube sheet y toast por encima. */
@media (max-width: 959.98px) {
  .ds-has-bottombar { padding-bottom: calc(var(--bottombar-h) + env(safe-area-inset-bottom)); }
  .ds-has-bottombar .ds-sheet { bottom: calc(var(--bottombar-h) + env(safe-area-inset-bottom)); padding-bottom: 0; }
  .ds-has-bottombar .ds-sheet:not([data-height="peek"]) { max-height: calc(86vh - var(--bottombar-h)); }
  .ds-has-bottombar .ds-sheet[data-height="expanded"] { height: calc(86vh - var(--bottombar-h)); }
  .ds-has-bottombar .ds-toast { bottom: calc(var(--bottombar-h) + var(--space-4) + env(safe-area-inset-bottom)); }
}

/* Admin: top bar + sidebar — [PROPOSED] */
.ds-topbar { position: sticky; top: 0; z-index: var(--z-header); display: flex; align-items: center; gap: var(--space-3); min-height: var(--header-h); padding: 0 var(--space-4); background: var(--surface); border-bottom: 1px solid var(--border); }
.ds-sidebar { display: none; flex-direction: column; gap: var(--space-1); width: var(--sidebar-w); padding: var(--space-4) var(--space-3); background: var(--surface); border-right: 1px solid var(--border); }
.ds-sidebar.is-open { display: flex; position: fixed; inset: 0 auto 0 0; z-index: var(--z-modal); width: min(320px, 85vw); box-shadow: var(--elevation-overlay); overflow-y: auto; }
@media (min-width: 960px) { .ds-sidebar { display: flex; position: sticky; top: 0; height: 100vh; overflow-y: auto; flex: none; } .ds-sidebar.is-open { position: sticky; box-shadow: none; width: var(--sidebar-w); } }
.ds-sidebar__heading { margin: var(--space-4) 0 var(--space-1); padding: 0 var(--space-3); font-size: var(--text-overline); line-height: var(--lh-overline); font-weight: var(--fw-semibold); letter-spacing: var(--tracking-overline); text-transform: uppercase; color: var(--muted); }
.ds-nav-item { display: flex; align-items: center; gap: var(--space-3); min-height: var(--control-h-md); padding: 0 var(--space-3); border-radius: var(--radius-control); color: var(--ink); font-size: var(--text-body-sm); font-weight: var(--fw-semibold); text-decoration: none; }
.ds-nav-item svg { width: var(--icon-md); height: var(--icon-md); color: var(--muted); }
.ds-nav-item:hover { background: var(--bg); color: var(--ink); }
.ds-nav-item[aria-current="page"] { background: var(--color-selected-bg); color: var(--color-selected-text); }
.ds-nav-item[aria-current="page"] svg { color: var(--color-action-primary); }
.ds-nav-item__count { margin-left: auto; font-size: var(--text-caption); color: var(--muted); font-variant-numeric: tabular-nums; }
@media (pointer: coarse) { .ds-nav-item { min-height: var(--touch-target-min); } }

/* Breadcrumb */
.ds-breadcrumb ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; padding: 0; list-style: none; font-size: var(--text-body-sm); line-height: var(--lh-body-sm); color: var(--muted); }
.ds-breadcrumb li { display: inline-flex; align-items: center; gap: var(--space-2); }
.ds-breadcrumb li + li::before { content: "/"; color: var(--faint); }
.ds-breadcrumb a { color: var(--muted); text-decoration: none; }
.ds-breadcrumb a:hover { color: var(--ink); text-decoration: underline; }
.ds-breadcrumb [aria-current="page"] { color: var(--ink); font-weight: var(--fw-semibold); }
@media (max-width: 639.98px) { .ds-breadcrumb li:not(:nth-last-child(-n+2)) { display: none; } }

/* Tabs (subrayado) */
.ds-tabs { display: flex; gap: var(--space-6); overflow-x: auto; border-bottom: 1px solid var(--border); scrollbar-width: none; }
.ds-tab { position: relative; flex: none; display: inline-flex; align-items: center; min-height: var(--touch-target-min); padding: 0; border: 0; background: none; color: var(--muted); font: inherit; font-size: var(--text-label); font-weight: var(--fw-bold); cursor: pointer; }
.ds-tab:hover { color: var(--ink); }
.ds-tab[aria-selected="true"] { color: var(--ink); }
.ds-tab[aria-selected="true"]::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; border-radius: var(--radius-pill); background: var(--color-action-primary); }

/* Segmented control — [AUDITED] login .tabsrow (contenedor 12, segmento 8) */
.ds-seg { display: flex; gap: var(--space-1); padding: var(--space-1); border-radius: var(--radius-panel); background: var(--bg); }
.ds-seg__btn { flex: 1; min-height: var(--control-h-md); padding: 0 var(--space-3); border: 1px solid transparent; border-radius: var(--radius-control); background: transparent; color: var(--muted); font: inherit; font-size: var(--text-label); font-weight: var(--fw-bold); cursor: pointer; transition: background-color var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard); }
.ds-seg__btn:hover { color: var(--ink); }
.ds-seg__btn[aria-checked="true"], .ds-seg__btn[aria-selected="true"] { background: var(--surface); border-color: var(--border); color: var(--ink); }

/* Paginación */
.ds-pagination { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); }
.ds-pagination__item { display: inline-grid; place-items: center; min-width: var(--control-h-md); height: var(--control-h-md); padding: 0 var(--space-2); border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--ink); font: inherit; font-size: var(--text-label); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; text-decoration: none; cursor: pointer; }
.ds-pagination__item:hover { background: var(--bg); }
.ds-pagination__item[aria-current="page"] { background: var(--color-selected-bg); color: var(--color-selected-text); }
.ds-pagination__item:disabled { color: var(--faint); cursor: not-allowed; }

/* Menú / dropdown / action menu — [AUDITED] Colinas .menupanel */
.ds-menu-wrap { position: relative; display: inline-block; }
.ds-menu-wrap > .ds-menu { position: absolute; top: calc(100% + var(--space-1)); right: 0; }
.ds-menu-wrap--start > .ds-menu { right: auto; left: 0; }
.ds-menu { min-width: 200px; padding: var(--space-1); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel); box-shadow: var(--elevation-floating); z-index: var(--z-dropdown); }
.ds-menu__item { display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: var(--control-h-md); padding: 0 var(--space-3); border: 0; border-radius: var(--radius-control); background: transparent; color: var(--ink); font: inherit; font-size: var(--text-body); font-weight: var(--fw-semibold); text-align: left; text-decoration: none; cursor: pointer; }
.ds-menu__item:hover { background: var(--bg); }
.ds-menu__item:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: -2px; }
.ds-menu__item svg { width: var(--icon-md); height: var(--icon-md); color: var(--muted); flex: none; }
.ds-menu__item--danger { color: var(--color-danger); }
.ds-menu__sep { height: 1px; margin: var(--space-1) 0; background: var(--border); }
@media (pointer: coarse) { .ds-menu__item { min-height: var(--touch-target-min); } }

/* Tooltip */
.ds-tooltip { position: absolute; z-index: var(--z-tooltip); max-width: 240px; padding: var(--space-2) var(--space-3); border-radius: var(--radius-control); background: var(--ink); color: var(--surface); font-size: var(--text-caption); line-height: var(--lh-caption); font-weight: var(--fw-semibold); box-shadow: var(--elevation-floating); pointer-events: none; }


/* --------------------------------------------------------------------------
   13. OVERLAYS Y FEEDBACK
   -------------------------------------------------------------------------- */
/* Modal: <dialog class="ds-modal"> + showModal(). Móvil = sheet inferior (AUDITED ECOS) */
.ds-modal { width: 100%; max-width: 100%; max-height: 90vh; margin: auto 0 0; padding: 0; border: 0; border-radius: var(--radius-sheet) var(--radius-sheet) 0 0; background: var(--surface); color: var(--ink); box-shadow: var(--elevation-overlay); overflow: hidden; }
.ds-modal[open] { display: flex; flex-direction: column; animation: ds-rise var(--motion-overlay) var(--ease-standard); }
.ds-modal::backdrop { background: var(--overlay-backdrop); }
@media (min-width: 640px) {
  .ds-modal { width: calc(100% - 2 * var(--space-4)); max-width: var(--modal-w-md); margin: auto; border-radius: var(--radius-modal); }
  .ds-modal--sm { max-width: var(--modal-w-sm); }
}
.ds-modal__header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-3) var(--space-3) var(--space-3) var(--space-5); border-bottom: 1px solid var(--border); }
.ds-modal__title { margin: 0; font-size: var(--text-body-lg); line-height: var(--lh-body-lg); font-weight: var(--fw-extrabold); letter-spacing: var(--tracking-snug); }
.ds-modal__body { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; padding: var(--space-4) var(--space-5); }
.ds-modal__footer { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4) var(--space-5) calc(var(--space-4) + env(safe-area-inset-bottom)); border-top: 1px solid var(--border); }
@media (min-width: 640px) { .ds-modal__footer--row { flex-direction: row; justify-content: flex-end; } }
/* Un <form> que envuelve body + footer participa del layout flex del modal — [PROPOSED] */
.ds-modal > form { display: contents; }
@keyframes ds-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Bottom sheet — [AUDITED] Colinas #buildingPanel (ux-sheet) */
.ds-sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-sheet); display: flex; flex-direction: column; max-height: 86vh; background: var(--surface); border-radius: var(--radius-sheet) var(--radius-sheet) 0 0; box-shadow: var(--elevation-overlay); padding-bottom: env(safe-area-inset-bottom); transform: translateY(100%); transition: transform var(--motion-overlay) var(--ease-standard); }
.ds-sheet:not(.is-open) { visibility: hidden; transition: transform var(--motion-overlay) var(--ease-standard), visibility 0s linear var(--motion-overlay); }
.ds-sheet.is-open { transform: translateY(0); }
.ds-sheet[data-height="expanded"] { height: 86vh; }
.ds-sheet[data-height="peek"] { max-height: max(40vh, 220px); }   /* 220 [PROPOSED]: en horizontal el peek aún muestra título + CTA */
.ds-sheet__handle { display: grid; place-items: center; flex: none; width: 100%; height: var(--space-7); padding: 0; border: 0; background: transparent; cursor: grab; touch-action: none; }
.ds-sheet__handle::before { content: ""; width: var(--space-10); height: 4px; border-radius: var(--radius-pill); background: var(--faint); }
.ds-sheet__header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: 0 var(--space-4) var(--space-3); border-bottom: 1px solid var(--border); }
.ds-sheet__body { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; padding: var(--space-4); }
.ds-sheet__footer { padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border); background: var(--surface); }
.ds-sheet-backdrop { position: fixed; inset: 0; z-index: calc(var(--z-sheet) - 1); background: var(--overlay-backdrop-sheet); }

/* Toast — [LOCKED] ink + blanco + radio 10 (excepción) */
.ds-toast { position: fixed; left: 50%; bottom: calc(var(--space-6) + env(safe-area-inset-bottom)); z-index: var(--z-toast); display: flex; align-items: center; gap: var(--space-3); max-width: min(400px, calc(100vw - 2 * var(--space-4))); padding: var(--space-3) var(--space-4); border-radius: var(--radius-toast); background: var(--ink); color: var(--surface); font-size: var(--text-body); line-height: var(--lh-body); font-weight: var(--fw-semibold); box-shadow: var(--elevation-floating); opacity: 0; transform: translate(-50%, var(--space-5)); transition: opacity var(--motion-base) var(--ease-standard), transform var(--motion-base) var(--ease-standard); pointer-events: none; }
.ds-toast.is-visible { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.ds-toast__action { margin-left: auto; padding: 0; border: 0; background: none; color: var(--surface); font: inherit; font-weight: var(--fw-extrabold); text-decoration: underline; cursor: pointer; }
.ds-toast__action:focus-visible { outline: var(--focus-ring-width) solid var(--surface); outline-offset: var(--focus-ring-offset); }

/* Banner (info / error / éxito / instalar app) */
.ds-banner { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-banner); background: var(--surface); font-size: var(--text-body); line-height: var(--lh-body); }
.ds-banner--info    { border-color: var(--brand-primary-border); background: var(--brand-primary-soft); }
.ds-banner--danger  { border-color: var(--feedback-danger-border); background: var(--feedback-danger-bg); color: var(--feedback-danger-ink); font-weight: var(--fw-semibold); }
.ds-banner--success { border-color: var(--feedback-success-border); background: var(--feedback-success-bg); color: var(--feedback-success-ink); font-weight: var(--fw-semibold); }

/* Estados vacío / error — [AUDITED] .empty (borde punteado) */
.ds-state { display: grid; justify-items: center; gap: var(--space-2); padding: var(--space-8) var(--space-5); border: 1px dashed var(--border); border-radius: var(--radius-panel); background: var(--surface); text-align: center; color: var(--muted); font-size: var(--text-body); line-height: var(--lh-body); }
.ds-state__icon { display: grid; place-items: center; width: var(--space-12); height: var(--space-12); border-radius: 50%; background: var(--bg); color: var(--muted); }
.ds-state__title { margin: 0; color: var(--ink); font-size: var(--text-body-lg); line-height: var(--lh-body-lg); font-weight: var(--fw-extrabold); }
.ds-state--error { border-style: solid; border-color: var(--feedback-danger-border); }
.ds-state--error .ds-state__icon { background: var(--feedback-danger-bg); color: var(--feedback-danger-ink); }

/* Skeleton — [AUDITED] pulse 1.3s / shimmer 1.4s → pulse 1.4s */
.ds-skeleton { display: block; border-radius: var(--radius-control); background: var(--border); animation: ds-pulse 1.4s ease-in-out infinite; }
.ds-skeleton--text  { height: var(--space-3); }
.ds-skeleton--title { height: var(--space-5); width: 60%; }
.ds-skeleton--media { aspect-ratio: 16 / 10; border-radius: 0; }
.ds-skeleton--round { border-radius: 50%; }
@keyframes ds-pulse { 50% { opacity: .5; } }

/* Spinner (botones en carga) — [AUDITED] .spin */
.ds-spinner { display: inline-block; width: var(--icon-sm); height: var(--icon-sm); border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: ds-spin .7s linear infinite; }
@keyframes ds-spin { to { transform: rotate(360deg); } }


/* --------------------------------------------------------------------------
   14. TABLA DENSA — [AUDITED] ECOS #lotTable
   -------------------------------------------------------------------------- */
.ds-table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--border); border-radius: var(--radius-panel); background: var(--surface); }
.ds-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--text-body); line-height: var(--lh-body); font-variant-numeric: tabular-nums; }
.ds-table th { position: sticky; top: 0; z-index: 1; height: var(--control-h-md); padding: 0 var(--space-4); background: var(--surface); border-bottom: 1px solid var(--border); color: var(--muted); font-size: var(--text-overline); line-height: var(--lh-overline); font-weight: var(--fw-semibold); letter-spacing: var(--tracking-overline); text-transform: uppercase; text-align: left; white-space: nowrap; }
.ds-table td { height: var(--density-row-h); padding: 0 var(--space-4); border-bottom: 1px solid var(--border); color: var(--ink); white-space: nowrap; }
.ds-table tbody tr:last-child td { border-bottom: 0; }
.ds-table tbody tr:hover td { background: var(--bg); }
.ds-table tbody tr[aria-selected="true"] td, .ds-table tbody tr[aria-current="true"] td { background: var(--color-selected-bg); }
.ds-table .is-num { text-align: right; }
.ds-table--min { min-width: 640px; }
.ds-table--sticky-first th:first-child, .ds-table--sticky-first td:first-child { position: sticky; left: 0; z-index: 2; background: var(--surface); }
@media (max-width: 639.98px) {
  .ds-table--stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .ds-table--stack, .ds-table--stack tbody, .ds-table--stack tr, .ds-table--stack td { display: block; width: 100%; }
  .ds-table--stack tr { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); }
  .ds-table--stack td { display: flex; justify-content: space-between; gap: var(--space-4); height: auto; padding: var(--space-1) 0; border: 0; white-space: normal; }
  .ds-table--stack td::before { content: attr(data-label); color: var(--muted); font-size: var(--text-caption); }
}


/* --------------------------------------------------------------------------
   15. AVATAR Y MENSAJERÍA
   -------------------------------------------------------------------------- */
.ds-avatar { --av: var(--control-h-md); display: inline-grid; place-items: center; flex: none; width: var(--av); height: var(--av); overflow: hidden; border-radius: var(--radius-avatar); background: var(--bg); color: var(--ink); font-size: var(--text-body-sm); font-weight: var(--fw-bold); }
.ds-avatar img { width: 100%; height: 100%; object-fit: cover; }
.ds-avatar--sm { --av: var(--control-h-sm); font-size: var(--text-caption); }
.ds-avatar--lg { --av: var(--space-12); font-size: var(--text-body); }
/* Color por usuario — [LOCKED exception] solo en mensajería. Inyectar inline: style="--user-color:…; --user-on:…" */
.ds-avatar--user { background: var(--user-color, var(--bg)); color: var(--user-on, var(--ink)); }

.ds-thread { display: flex; flex-direction: column; gap: var(--space-2); }
.ds-bubble { max-width: 82%; padding: var(--space-2) var(--space-3); border-radius: var(--radius-card); font-size: var(--text-body); line-height: var(--lh-body); white-space: pre-wrap; overflow-wrap: anywhere; }
.ds-bubble--out { align-self: flex-end; background: var(--color-action-primary); color: var(--surface); border-bottom-right-radius: var(--space-1); }
.ds-bubble--in  { align-self: flex-start; background: var(--bg); border: 1px solid var(--border); border-bottom-left-radius: var(--space-1); }
.ds-bubble__who { display: block; margin-bottom: 2px; font-size: var(--text-caption); line-height: var(--lh-caption); font-weight: var(--fw-semibold); }


/* --------------------------------------------------------------------------
   16. SHELLS DE PÁGINA — [PROPOSED] (público y admin)
   -------------------------------------------------------------------------- */
/* Público */
.ds-hero { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-5); max-width: calc(var(--container-reading) + 2 * var(--gutter)); margin: 0 auto; padding: var(--space-8) var(--gutter) var(--space-6); text-align: center; }
.ds-public { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); align-content: start; width: 100%; max-width: calc(var(--container-project) + 2 * var(--gutter)); margin: 0 auto; padding: var(--space-4) var(--gutter) var(--space-12); }
.ds-public--discovery { max-width: calc(var(--container-discovery) + 2 * var(--gutter)); }
@media (max-width: 959.98px) {
  .ds-public { padding-inline: 0; }
  .ds-public > .ds-pad { padding-inline: var(--gutter); }
}
/* Superficie del proyecto — [AUDITED] ECOS .feedpost (16-oct-2026): blanco sobre el canvas #f7f7f7,
   radio panel + shadow-sm; ≤959 a sangre (sin radio ni sombra). Padding 14/16/18 normalizado a 16/16/20.
   Los controles de relleno (--color-fill: statcards, searchfield, segmented) se diseñaron para ir SOBRE esta superficie. */
.ds-surface { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); align-content: start; padding: var(--space-4) var(--space-4) var(--space-5); background: var(--surface); border-radius: var(--radius-panel); box-shadow: var(--elevation-raised); }
@media (max-width: 959.98px) { .ds-surface { border-radius: 0; box-shadow: none; } }
.ds-footer { display: grid; justify-items: center; gap: var(--space-2); max-width: calc(var(--container-discovery) + 2 * var(--gutter)); margin: var(--space-6) auto 0; padding: var(--space-6) var(--gutter) var(--space-10); border-top: 1px solid var(--border); text-align: center; color: var(--muted); font-size: var(--text-caption); line-height: var(--lh-caption); }
.ds-engage { display: flex; gap: var(--space-1); padding-top: var(--space-3); border-top: 1px solid var(--border); }

/* Auth: login, registro, recuperar, verificación — [AUDITED] login.html (card 400, franja ink/brand) */
.ds-auth { min-height: 100vh; display: grid; place-items: center; align-content: center; gap: var(--space-4); padding: var(--space-8) var(--gutter); }
.ds-auth__card { position: relative; width: 100%; max-width: var(--container-form); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); padding: var(--space-6); overflow: hidden; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card); }
.ds-auth__card::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 4px; background: linear-gradient(90deg, var(--ink) 50%, var(--brand-primary) 50%); }
.ds-divider { display: flex; align-items: center; gap: var(--space-3); color: var(--muted); font-size: var(--text-caption); line-height: var(--lh-caption); }
.ds-divider::before, .ds-divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* Admin */
.ds-app { display: flex; min-height: 100vh; background: var(--bg); }
.ds-app__main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.ds-env-strip { height: 4px; background: var(--ink); }   /* entorno Plataforma360 */
.ds-page { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); align-content: start; width: 100%; max-width: 1440px; margin: 0 auto; padding: var(--space-5) var(--gutter) var(--space-12); }
.ds-page-header { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-3); }
.ds-page-header__title { margin: var(--space-1) 0 0; font-size: var(--text-h2); line-height: var(--lh-h2); font-weight: var(--fw-extrabold); letter-spacing: var(--tracking-tight); }
.ds-page-header__meta { font-size: var(--text-body-sm); line-height: var(--lh-body-sm); color: var(--muted); }
.ds-page-header__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ds-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.ds-toolbar > .ds-searchfield { flex: 1 1 240px; max-width: 360px; }
.ds-bulkbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--radius-panel); background: var(--ink); color: var(--surface); font-size: var(--text-body-sm); font-weight: var(--fw-semibold); }
.ds-bulkbar .ds-btn { color: var(--surface); border-color: var(--muted); }
.ds-bulkbar .ds-btn:hover { background: transparent; text-decoration: underline; }
.ds-section-title { margin: 0; font-size: var(--text-body-lg); line-height: var(--lh-body-lg); font-weight: var(--fw-extrabold); letter-spacing: var(--tracking-snug); }
.ds-cols { display: grid; gap: var(--space-4); grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 960px) {
  .ds-cols--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ds-cols--main-side { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
  .ds-cols--list-detail { grid-template-columns: 320px minmax(0, 1fr); }
}
.ds-kpis { display: grid; gap: var(--space-3); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 960px) {
  .ds-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .ds-kpis--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
.ds-panel--flush { padding: 0; overflow: hidden; }
.ds-panel__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); }
.ds-listrow { display: flex; align-items: center; gap: var(--space-3); min-height: var(--density-row-h); padding: var(--space-2) var(--space-4); border-bottom: 1px solid var(--border); color: var(--ink); font-size: var(--density-text); line-height: var(--density-lh); text-decoration: none; }
.ds-listrow:last-child { border-bottom: 0; }
button.ds-listrow { width: 100%; border: 0; border-bottom: 1px solid var(--border); background: transparent; font: inherit; text-align: left; cursor: pointer; }
a.ds-listrow:hover, button.ds-listrow:hover { background: var(--bg); }
.ds-listrow[aria-current="true"] { background: var(--color-selected-bg); }
.ds-listrow__main { flex: 1; min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; }
.ds-listrow__meta { font-size: var(--text-caption); line-height: var(--lh-caption); color: var(--muted); }
