/* Base CSS for the POC platform — minimal global styles + blueprint chrome.
   Theme tokens use the same names as the existing AbleScript theme so app-level
   CSS can reuse them. */

:root {
  /* Pin the UA color-scheme so native controls (checkboxes, radios, scrollbars,
     date/number/time pickers, native selects) paint LIGHT even when the OS
     prefers dark. Without this, a light page on an OS-dark machine renders dark
     checkboxes + dark scrollbars — the UA follows the OS, not data-theme. */
  color-scheme: light;
  --grey-0:   #ffffff;
  --grey-50:  #fafafa;
  --grey-100: #f8f8f9;
  --grey-200: #f0f1f2;
  --grey-300: #d6d8db;
  --grey-400: #bbbec3;
  --grey-500: #66686b;
  --grey-600: #505151;
  --grey-700: #3f3f46;
  --grey-800: #303236;
  --grey-900: #18191b;

  --accent:   #1e40af;
  --text-primary:      #111111;
  --border-default:    #d6d8db;
  --success:   #15803d;
  --warning:   #b45309;
  --danger:    #b91c1c;
}

/* ── Dark mode ──────────────────────────────────────────────────────────
   theme-base-v2 paints from the raw --grey-* ramp (not the semantic
   --surface / --text semantic layer), and the system dark block only flips the
   semantic tokens — so in dark mode the greys stayed LIGHT here and the app
   read light-on-dark (invisible close button, light health rows, faint grid
   text). Re-map the ramp to dark by ROLE (grey-0 = raised card, grey-100 =
   page base, grey-200 = subtle fill, 300/400 = borders, 500-900 = text
   lightening up), aligned with the system GitHub-dark surfaces. theme-base-v2
   is the cascade leaf, so this :root[data-theme="dark"] (0,2,0) wins. */
:root[data-theme="dark"] {
  color-scheme: dark;    /* native controls (checkbox/scrollbar/pickers) paint dark */
  --grey-0:   #161b22;   /* card / raised surface */
  --grey-50:  #1b212a;
  --grey-100: #0d1117;   /* page background */
  --grey-200: #21262d;   /* subtle fill / table header / hover */
  --grey-300: #30363d;   /* border */
  --grey-400: #484f58;   /* strong border / disabled */
  --grey-500: #6e7681;   /* muted text / icon */
  --grey-600: #8b949e;   /* secondary text */
  --grey-700: #b1bac4;
  --grey-800: #c9d1d9;
  --grey-900: #e6edf3;   /* primary text */

  --accent:         #60a5fa;   /* brand navy (#1e40af) is too dark on dark surfaces */
  --text-primary:   #e6edf3;
  --border-default: #30363d;
  --success:        #3fb950;
  --warning:        #d29922;
  --danger:         #f85149;
}

body {
  margin: 0;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--grey-100);
  color: var(--grey-900);
  font-size: 13px;
  line-height: 1.4;
}

* { box-sizing: border-box; }

button { font-family: inherit; }

/* ---- able-table -------------------------------------------------------- */

.abt {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--grey-0);
  border: 1px solid var(--grey-300);
  border-radius: 8px;
  /* `clip` (NOT `hidden`) — both clip the rounded corners, but `overflow:hidden`
     turns the <table> into a scroll-container, which captures the sticky
     `.abt-thead--sticky` / `.abt-th` headers so they pin to the TABLE (which
     never scrolls) instead of the page's scroll region — i.e. sticky-header
     silently does nothing. `overflow:clip` clips without creating a scroll
     container, so rounded corners stay AND sticky headers pin correctly.
     Verified 2026-05-28 on tasks-v2 / contacts-v2. Do NOT revert to hidden. */
  overflow: clip;
  font-size: 12px;
}
.abt-th {
  position: sticky;
  top: 0;
  background: var(--grey-200);
  padding: 8px 10px;
  text-align: left;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--grey-700);
  border-bottom: 1px solid var(--grey-300);
  cursor: pointer;
  user-select: none;
}
.abt-th[data-sort-field=""] { cursor: default; }
.abt-th.is-asc::after  { content: ' ▲'; color: var(--accent); }
.abt-th.is-desc::after { content: ' ▼'; color: var(--accent); }
.abt-th--check, .abt-th--num { width: 36px; text-align: center; }

.abt-row { transition: background 0.1s ease; }
.abt-row:hover { background: var(--grey-100); }
/* Pointer ONLY on rows that actually act: the directive pass emits data-on-row-click on the
   <able-table> HOST when a page wires @row-click. Read-only grids (e.g. contracts-v2) keep the
   default cursor. Was a blanket cursor:pointer on every grid's rows — user ask 2026-06-10. */
able-table[data-on-row-click] .abt-row:hover { cursor: pointer; }
.abt-td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--grey-200);
  vertical-align: middle;
  font-size: 12px;
}
.abt-td--check, .abt-td--num { text-align: center; color: var(--grey-500); }

.abt-empty {
  padding: 48px 16px;
  text-align: center;
  color: var(--grey-500);
  font-style: italic;
}
.abt-muted { color: var(--grey-400); }
.abt-thead--sticky { position: sticky; top: 0; z-index: 1; }

/* ---- pagination -------------------------------------------------------- */

.abp { display: flex; align-items: center; gap: 8px; }
.abp-range { font-size: 11px; color: var(--grey-600); font-family: 'JetBrains Mono', monospace; }
.abp-btn {
  width: 28px; height: 28px;
  border-radius: 6px; border: 1px solid var(--grey-300);
  background: #fff; font-size: 14px; cursor: pointer;
}
.abp-btn[disabled] { opacity: 0.4; cursor: not-allowed; }
.abp-page { font-size: 11px; color: var(--grey-700); font-family: 'JetBrains Mono', monospace; }
.abp-size {
  height: 28px; padding: 0 8px;
  border-radius: 6px; border: 1px solid var(--grey-300); background: #fff;
  font-size: 11px;
}

/* ---- offcanvas --------------------------------------------------------- */

.aoff {
  position: fixed;
  top: 0; bottom: 0;
  background: #fff;
  z-index: 1000;
  box-shadow: -8px 0 24px rgba(0,0,0,0.15);
  transform: translateX(100%);
  transition: transform 0.2s ease;
  overflow-y: auto;
}
.aoff[data-position="right"] { right: 0; }
.aoff[data-position="left"]  { left: 0; transform: translateX(-100%); }
.aoff--open { transform: translateX(0); }

/* Offcanvas close button: NO app override.
   The system theme (template-system-base) now renders a Mac-style red
   traffic-light dot (top-left, persistent ×) that reads on any panel bg —
   light or dark — so the old white-button workaround here (which existed
   only because the system theme's light-glyph vanished on this app's light
   #fafafa panel) is obsolete. Removed so this app inherits the system Mac
   dot. Re-add a scoped override here ONLY if this app needs a different
   close affordance from the platform default. */

.aoff-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.4);
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s ease;
  z-index: 999;
}
.aoff-backdrop--open { opacity: 1; pointer-events: auto; }

/* ---- KPI card ---------------------------------------------------------- */

.akpi {
  background: var(--grey-0);
  border: 1px solid var(--grey-300);
  border-radius: 8px;
  padding: 14px 16px;
  display: grid;
  gap: 4px;
}
.akpi-label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.5px;
  text-transform: uppercase; color: var(--grey-500);
}
.akpi-value {
  font-size: 22px; font-weight: 700;
  font-family: 'JetBrains Mono', monospace;
  color: var(--grey-900);
}
.akpi[data-tone="good"] .akpi-value { color: var(--success); }
.akpi[data-tone="bad"]  .akpi-value { color: var(--danger); }

/* ---- tabs -------------------------------------------------------------- */

.atabs-bar {
  display: flex; gap: 4px;
  border-bottom: 1px solid var(--grey-300);
  padding: 0 32px;
}
.atabs-tab {
  background: transparent; border: none;
  padding: 12px 16px;
  font-size: 12px; font-weight: 600;
  color: var(--grey-500); cursor: pointer;
  border-bottom: 2px solid transparent;
}
.atabs-tab.is-active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.atabs-panel { padding: 16px 0; }

/* ---- more filters ------------------------------------------------------ */

.amf { position: relative; display: inline-block; }
.amf-pop:not([hidden]) {
  position: absolute; top: 100%; right: 0; margin-top: 4px;
  background: #fff; border: 1px solid var(--grey-300);
  border-radius: 6px; box-shadow: 0 4px 12px rgba(0,0,0,0.08);
  padding: 12px; min-width: 280px; z-index: 50;
  display: grid; gap: 8px;
}
.amf-row { display: grid; gap: 4px; }
.amf-row span { font-size: 10px; font-weight: 700; color: var(--grey-500); text-transform: uppercase; letter-spacing: 0.4px; }
.amf-row input, .amf-row select {
  height: 30px; padding: 0 8px; border: 1px solid var(--grey-300);
  border-radius: 4px; font-size: 12px; background: #fff;
}

/* ---- toasts ------------------------------------------------------------ */

.toast { animation: toast-in 0.15s ease; }
@keyframes toast-in { from { transform: translateY(8px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

/* Toast redesign (2026-05-28) — user: "los toasts están muy oscuros,
   mejora eso". The platform <able-toast-stack> blueprint renders
   near-black toasts (background: var(--surface-inverse) → #18191b here)
   with white text. Override to a LIGHT tinted-by-kind scheme
   (Linear/Stripe pattern): soft coloured surface + dark legible tinted
   text + accent left border + soft shadow.

   Scoped to THIS tenant only (theme.css is global tenant CSS, not
   [data-cmp]-scoped) — the platform blueprint stays dark for every other
   tenant; no able-api deploy needed. Toast-stack lives under .ah-shell,
   so .ah-shell .atst-toast (0,2,0) beats the blueprint's own .atst-toast
   chrome CSS (0,1,0) regardless of inject order; the per-kind rules
   (0,3,0) beat the blueprint's [data-kind] (0,2,0). border-left
   re-declared per kind so the accent stripe survives the full-border
   reset. See memory project_ablecollect_modal_toast_pattern. */
.ah-shell .atst-toast {
  background: var(--surface-card, #ffffff);
  color: var(--text-primary, #1d1c17);
  border: 1px solid var(--border-default, #e5e7eb);
  box-shadow: 0 4px 16px rgba(15, 23, 42, 0.12);
}
.ah-shell .atst-toast .atst-close { opacity: 0.55; }
.ah-shell .atst-toast .atst-close:hover { opacity: 0.9; }

.ah-shell .atst-toast[data-kind="success"] {
  background: #ecfdf5;
  color: #15803d;
  border: 1px solid #a7f3d0;
  border-left: 3px solid #15803d;
}
.ah-shell .atst-toast[data-kind="error"] {
  background: #fef2f2;
  color: #b91c1c;
  border: 1px solid #fecaca;
  border-left: 3px solid #b91c1c;
}
.ah-shell .atst-toast[data-kind="warning"] {
  background: #fffbeb;
  color: #92400e;
  border: 1px solid #fde68a;
  border-left: 3px solid #b45309;
}
.ah-shell .atst-toast[data-kind="info"] {
  background: #eff6ff;
  color: #1e40af;
  border: 1px solid #bfdbfe;
  border-left: 3px solid #1d4ed8;
}

/* able-typeahead */
.aty {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 10px;
  background: #fff;
  border: 1px solid var(--grey-300, #e2e8f0);
  border-radius: 6px;
  /* Default reasonable floor for a standalone typeahead. Tokenized so
     dense filter strips can opt into narrower widths by setting
     --aty-min-width: 0 on the parent <able-typeahead> or container.
     Was hard-coded 180px which ignored parent flex constraints and caused
     the inner .aty (and its .aty-clear X-button) to overflow tight
     wrappers, overlapping adjacent siblings.

     Page-level usage example:
       .ph-header able-typeahead { max-width: 140px; --aty-min-width: 0 }
  */
  min-width: var(--aty-min-width, 180px);
}
.aty:focus-within { outline: 2px solid var(--brand, #1e40af); outline-offset: -1px; }
.aty-icon  { font-size: 12px; color: var(--grey-500, #64748b); }
.aty-input { border: 0; outline: 0; background: transparent; font: inherit; font-size: 12px; color: var(--grey-700, #334155); min-width: 0; width: 100%; }
.aty-input::placeholder { color: var(--grey-400, #94a3b8); }
.aty-clear {
  width: 18px; height: 18px; border: 0; background: var(--grey-200, #f1f5f9);
  border-radius: 50%; cursor: pointer; color: var(--grey-500, #64748b);
  font-size: 12px; line-height: 1; padding: 0; display: grid; place-items: center;
}
.aty-clear:hover { background: var(--grey-300, #cbd5e1); color: var(--grey-700, #334155); }
.aty-pop {
  /* Float anchored to the input's LEFT edge, but sized to the CONTENT (the
     input itself is a narrow 150px chip — results would otherwise be clipped
     with a horizontal scrollbar). min/max keep it readable + on-screen. */
  position: absolute; top: calc(100% + 4px); left: 0;
  min-width: max(100%, 280px); max-width: 440px; width: max-content;
  background: #fff; border: 1px solid var(--grey-200, #e2e8f0);
  border-radius: 8px; box-shadow: 0 10px 30px rgba(15, 23, 42, 0.14), 0 2px 6px rgba(15, 23, 42, 0.08);
  max-height: 340px; overflow-y: auto; overflow-x: hidden;
  z-index: 60; padding: 4px;
}
.aty-row {
  padding: 8px 10px; cursor: pointer; font-size: 12px; border-radius: 5px;
}
.aty-row.is-active, .aty-row:hover { background: var(--grey-100, #f1f5f9); }
.aty-row-label { color: var(--grey-900, #0f172a); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.aty-row-sub   { color: var(--grey-500, #64748b); font-size: 11px; margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.aty-empty     { padding: 12px; color: var(--grey-500, #64748b); font-size: 11px; font-style: italic; }

/* able-multi-select — the blueprint ships only mobile touch sizing, so without
   this the menu renders in-flow as a plain white block that PUSHES page content
   down. Float it as a polished card (shadow + border + rounded), anchored to the
   trigger's LEFT edge so a left-aligned control never clips off the left of the
   viewport. */
.amsel { position: relative; }
.amsel-menu {
  position: absolute; top: calc(100% + 4px); left: 0;
  min-width: max(100%, 220px); max-width: 340px;
  background: #fff; border: 1px solid var(--grey-200, #e2e8f0);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(15, 23, 42, 0.14), 0 2px 6px rgba(15, 23, 42, 0.08);
  max-height: 340px; overflow-y: auto; overflow-x: hidden;
  z-index: 60; padding: 4px;
}
.amsel-title {
  padding: 6px 10px 4px; font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--grey-500, #64748b);
}
.amsel-empty { padding: 12px; color: var(--grey-500, #64748b); font-size: 11px; font-style: italic; }
.amsel-item {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; cursor: pointer; font-size: 12px; border-radius: 5px;
  color: var(--grey-800, #1f2937);
}
.amsel-item:hover, .amsel-item.is-active { background: var(--grey-100, #f1f5f9); }
.amsel-item.is-selected { background: var(--brand-50, #eff6ff); color: var(--brand, #1e40af); font-weight: 600; }
.amsel-item.is-disabled { opacity: 0.45; cursor: not-allowed; }
.amsel-check {
  flex: 0 0 16px; width: 16px; height: 16px; border-radius: 4px;
  border: 1.5px solid var(--grey-300, #cbd5e1);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; line-height: 1; color: #fff; background: #fff;
}
.amsel-item.is-selected .amsel-check { background: var(--brand, #1e40af); border-color: var(--brand, #1e40af); }
.amsel-icon { font-size: 12px; color: var(--grey-500, #64748b); }
.amsel-item-label { flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* leak bar fill width via data-fill (avoids inline-style int+str issue) */
.leak-bar-fill[data-fill]{ width:0; }
.leak-bar-fill[data-fill="0"] { width:0; }
.leak-bar-fill[data-fill="1"] { width:1%; }
.leak-bar-fill[data-fill="2"] { width:2%; }
.leak-bar-fill[data-fill="3"] { width:3%; }
.leak-bar-fill[data-fill="4"] { width:4%; }
.leak-bar-fill[data-fill="5"] { width:5%; }

/* able-spinner */
able-spinner { position: fixed; left: 0; right: 0; top: 0; z-index: 9999; pointer-events: none; }
/* `[hidden]` overrides — the bar/overlay default `display` (block/grid) beats
   the UA stylesheet `[hidden] { display: none }` rule, so we re-assert it
   explicitly. Without this, hidden=""` is visually a no-op. */
.asp-bar[hidden], .asp-overlay[hidden] { display: none !important; }
.asp-bar {
  position: fixed; top: 0; left: 0; right: 0; height: 3px;
  background: rgba(0,0,0,0.05); overflow: hidden;
}
.asp-bar-fill {
  height: 100%; width: 30%; background: linear-gradient(90deg, transparent, #1e40af, #6366f1, transparent);
  animation: asp-slide 1.2s linear infinite;
}
@keyframes asp-slide { 0% { transform: translateX(-100%); } 100% { transform: translateX(400%); } }
.asp-overlay {
  position: fixed; inset: 0; background: rgba(15,23,42,0.4);
  display: grid; place-items: center; pointer-events: auto;
}
.asp-spinner {
  width: 48px; height: 48px;
  border: 4px solid rgba(255,255,255,0.25);
  border-top-color: #fff;
  border-radius: 50%;
  animation: asp-spin 0.8s linear infinite;
}
@keyframes asp-spin { to { transform: rotate(360deg); } }
