/* ===== Mi Urbania · Shared UI primitives + component CSS ===== */
window.MU = window.MU || {};
(function (MU) {
  const { useState, useEffect, useRef } = React;

  /* ---------- Icons (line, 24px, currentColor) ---------- */
  const ICONS = {
    dot: '<circle cx="12" cy="12" r="3"/>',
    home: '<path d="M4 11.5 12 4l8 7.5"/><path d="M6 10v9.5h12V10"/>',
    grid: '<rect x="4" y="4" width="7" height="7" rx="1"/><rect x="13" y="4" width="7" height="7" rx="1"/><rect x="4" y="13" width="7" height="7" rx="1"/><rect x="13" y="13" width="7" height="7" rx="1"/>',
    report: '<path d="M12 5v14M5 12h14"/>',
    shield: '<path d="M12 3 5 6v6c0 4 3 6.5 7 9 4-2.5 7-5 7-9V6l-7-3Z"/>',
    help: '<circle cx="12" cy="12" r="9"/><path d="M9.2 9.5a2.8 2.8 0 0 1 5.3 1c0 1.8-2.5 2-2.5 3.5"/><circle cx="12" cy="17.2" r="0.6" fill="currentColor" stroke="none"/>',
    bell: '<path d="M6 9a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6Z"/><path d="M10 20a2 2 0 0 0 4 0"/>',
    globe: '<circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c2.5 2.5 2.5 15 0 18M12 3c-2.5 2.5-2.5 15 0 18"/>',
    chevR: '<path d="m9 6 6 6-6 6"/>',
    chevL: '<path d="m15 6-6 6 6 6"/>',
    chevD: '<path d="m6 9 6 6 6-6"/>',
    chevU: '<path d="m6 15 6-6 6 6"/>',
    search: '<circle cx="11" cy="11" r="7"/><path d="m20 20-3.2-3.2"/>',
    x: '<path d="M6 6l12 12M18 6 6 18"/>',
    check: '<path d="M5 12.5 10 17l9-10"/>',
    plus: '<path d="M12 5v14M5 12h14"/>',
    camera: '<path d="M4 8.5h3l1.5-2h7L17 8.5h3V19H4Z"/><circle cx="12" cy="13" r="3.2"/>',
    calendar: '<rect x="4" y="5.5" width="16" height="15" rx="2"/><path d="M4 9.5h16M8 3.5v4M16 3.5v4"/>',
    clock: '<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3.5 2"/>',
    doc: '<path d="M7 3h7l4 4v14H7Z"/><path d="M14 3v4h4M9.5 12.5h5M9.5 16h5"/>',
    download: '<path d="M12 4v10m0 0 4-4m-4 4-4-4M5 19h14"/>',
    eye: '<path d="M2.5 12S6 6 12 6s9.5 6 9.5 6-3.5 6-9.5 6-9.5-6-9.5-6Z"/><circle cx="12" cy="12" r="2.6"/>',
    alert: '<path d="M12 4 2.5 20h19L12 4Z"/><path d="M12 10v4.5"/><circle cx="12" cy="17.6" r="0.6" fill="currentColor" stroke="none"/>',
    spark: '<path d="M12 3v6M12 15v6M3 12h6M15 12h6"/><path d="m6.5 6.5 3 3M14.5 14.5l3 3M17.5 6.5l-3 3M9.5 14.5l-3 3"/>',
    arrowR: '<path d="M4 12h15m0 0-5-5m5 5-5 5"/>',
    message: '<path d="M4 5h16v11H9l-4 3v-3H4Z"/>',
    whatsapp: '<path d="M5 19l1.3-3.5A7 7 0 1 1 9 18.2L5 19Z"/><path d="M9.3 9.2c.3 2 2.4 4 4.4 4.4.7.1 1.2-.5 1.3-1.1l-1.6-.8-.9.8c-.9-.4-1.5-1-1.9-1.9l.8-.9-.8-1.6c-.6.1-1.2.6-1.1 1.3Z" fill="currentColor" stroke="none"/>',
    sliders: '<path d="M4 8h10M18 8h2M4 16h2M10 16h10"/><circle cx="16" cy="8" r="2"/><circle cx="8" cy="16" r="2"/>',
    pin: '<path d="M12 21s6-5.3 6-10a6 6 0 0 0-12 0c0 4.7 6 10 6 10Z"/><circle cx="12" cy="11" r="2.2"/>',
    info: '<circle cx="12" cy="12" r="9"/><path d="M12 11v5"/><circle cx="12" cy="7.8" r="0.6" fill="currentColor" stroke="none"/>',
    refresh: '<path d="M19 12a7 7 0 1 1-2-4.9M19 4v3.5h-3.5"/>',
    /* categories */
    columns: '<path d="M6 4v16M12 4v16M18 4v16M4 4h16M4 20h16"/>',
    umbrella: '<path d="M3.5 11a8.5 8.5 0 0 1 17 0Z"/><path d="M12 11v7a2.2 2.2 0 0 1-4 0"/>',
    droplets: '<path d="M12 3.5S6.5 9 6.5 13.5a5.5 5.5 0 0 0 11 0C17.5 9 12 3.5 12 3.5Z"/>',
    pipe: '<path d="M5 9h6V5M5 15h6v4M11 9h3a4 4 0 0 1 4 4v2"/>',
    zap: '<path d="M13 3 5 13h6l-1 8 8-10h-6l1-8Z"/>',
    faucet: '<path d="M5 11h6V8a2 2 0 0 1 2-2h2M11 11v3a3 3 0 0 0 3 3M11 11H8M14 6h5"/>',
    door: '<path d="M6 21V4h10v17M6 21h12"/><circle cx="13" cy="12.5" r="0.8" fill="currentColor" stroke="none"/>',
    lock: '<rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/>',
    window: '<rect x="4" y="4" width="16" height="16" rx="1.5"/><path d="M12 4v16M4 12h16"/>',
    roller: '<rect x="5" y="4" width="13" height="5" rx="1.5"/><path d="M11 9v3H6v4M6 16v4"/>',
    crack: '<path d="M11 3 9 8l3 2-2 4 3 2-2 5"/>',
    ceiling: '<path d="M3 6h18M6 6l-1 4M12 6v4M18 6l1 4M4 10h16"/>',
    cabinet: '<rect x="5" y="4" width="14" height="16" rx="1.5"/><path d="M12 4v16M9 9h.01M15 9h.01"/>',
    wind: '<path d="M3 9h10a2.5 2.5 0 1 0-2.5-2.5M3 14h13a2.5 2.5 0 1 1-2.5 2.5"/>',
    appliance: '<rect x="6" y="3" width="12" height="18" rx="2"/><path d="M6 8h12"/><circle cx="12" cy="14" r="3"/><path d="M9 5.5h.01"/>',
    building: '<rect x="5" y="3" width="14" height="18" rx="1.5"/><path d="M9 7h.01M15 7h.01M9 11h.01M15 11h.01M9 15h.01M15 15h.01M10 21v-3h4v3"/>',
    /* rooms */
    kitchen: '<rect x="4" y="4" width="16" height="16" rx="2"/><path d="M9 4v6M7 4c0 2 4 2 4 0M15 4v16M15 11h2"/>',
    bath: '<path d="M4 12h16v2a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4Z"/><path d="M6 12V6a2 2 0 0 1 4 0M7 18l-1 2M18 18l1 2"/>',
    sofa: '<path d="M5 11V8a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v3"/><path d="M3 12a2 2 0 0 1 4 0v2h10v-2a2 2 0 0 1 4 0v5H3Z"/>',
    bed: '<path d="M3 8v11M3 12h18v7M21 12v-1a3 3 0 0 0-3-3H9v4"/>',
    balcony: '<path d="M4 10h16M6 10v10M10 10v10M14 10v10M18 10v10M4 14h16M4 6l8-2 8 2"/>',
  };

  function Icon({ name, size = 22, stroke = 1.7, color, style, className }) {
    return React.createElement("svg", {
      width: size, height: size, viewBox: "0 0 24 24", fill: "none",
      stroke: color || "currentColor", strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round",
      className, style, dangerouslySetInnerHTML: { __html: ICONS[name] || ICONS.dot }, "aria-hidden": true,
    });
  }

  /* ---------- status helpers ---------- */
  const STATUS_COLOR = {
    active: "var(--active)", soon: "var(--soon)", expired: "var(--expired)",
    crack: "var(--gold)", safety: "var(--urgent)", routed: "var(--ink-4)",
  };
  const STATUS_SOFT = {
    active: "var(--active-soft)", soon: "var(--soon-soft)", expired: "var(--expired-soft)",
    crack: "var(--gold-soft)", safety: "var(--urgent-soft)", routed: "var(--expired-soft)",
  };
  MU.STATUS_COLOR = STATUS_COLOR;
  MU.STATUS_SOFT = STATUS_SOFT;

  /* ---------- Ring (animated depletion) ---------- */
  function Ring({ fraction, status, size = 92, sw = 7, children, delay = 0 }) {
    const [on, setOn] = useState(false);
    useEffect(() => { const id = setTimeout(() => setOn(true), 60 + delay); return () => clearTimeout(id); }, [delay]);
    const r = (size - sw) / 2;
    const c = 2 * Math.PI * r;
    const frac = Math.max(0, Math.min(1, fraction == null ? 1 : fraction));
    const target = on ? c * (1 - frac) : c;
    const col = STATUS_COLOR[status] || "var(--active)";
    return (
      React.createElement("div", { style: { position: "relative", width: size, height: size, flex: "0 0 auto" } },
        React.createElement("svg", { width: size, height: size, style: { transform: "rotate(-90deg)" } },
          React.createElement("circle", { cx: size / 2, cy: size / 2, r, fill: "none", stroke: "var(--line)", strokeWidth: sw }),
          React.createElement("circle", {
            cx: size / 2, cy: size / 2, r, fill: "none", stroke: col, strokeWidth: sw, strokeLinecap: "round",
            strokeDasharray: c, strokeDashoffset: target,
            style: { transition: "stroke-dashoffset .9s cubic-bezier(.22,.8,.3,1)" },
          })
        ),
        React.createElement("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column" } }, children)
      )
    );
  }

  /* ---------- CountUp ---------- */
  function CountUp({ to, dur = 900, className, style }) {
    const [v, setV] = useState(0);
    useEffect(() => {
      const motion = getComputedStyle(document.documentElement).getPropertyValue("--motion").trim();
      if (motion === "0" || document.hidden) { setV(to); return; }
      let raf, start, done = false;
      const finish = setTimeout(() => { if (!done) { done = true; setV(to); } }, dur + 140);
      const step = (ts) => {
        if (done) return;
        if (!start) start = ts;
        const p = Math.min(1, (ts - start) / dur);
        const e = 1 - Math.pow(1 - p, 3);
        setV(Math.round(to * e));
        if (p < 1) raf = requestAnimationFrame(step); else done = true;
      };
      raf = requestAnimationFrame(step);
      return () => { cancelAnimationFrame(raf); clearTimeout(finish); };
    }, [to]);
    return React.createElement("span", { className, style }, v);
  }

  /* ---------- StatusPill ---------- */
  function StatusPill({ status, label, small }) {
    return React.createElement("span", {
      className: "mu-pill", style: {
        background: STATUS_SOFT[status], color: STATUS_COLOR[status],
        fontSize: small ? 11 : 12.5, padding: small ? "3px 9px" : "5px 11px",
      }
    },
      React.createElement("span", { style: { width: 7, height: 7, borderRadius: 9, background: STATUS_COLOR[status] } }),
      label
    );
  }

  /* ---------- SeverityBadge ---------- */
  function SeverityBadge({ severity, lang }) {
    const map = {
      cosmetic: { c: "var(--ink-3)", b: "rgba(14,17,22,.06)" },
      functional: { c: "var(--brand)", b: "var(--brand-soft)" },
      urgent: { c: "var(--urgent)", b: "var(--urgent-soft)" },
    };
    const m = map[severity] || map.cosmetic;
    const label = MU.t(lang, "severity_" + severity);
    return React.createElement("span", { className: "mu-pill", style: { background: m.b, color: m.c, fontSize: 11.5, padding: "4px 9px" } },
      severity === "urgent" && React.createElement(Icon, { name: "alert", size: 12, stroke: 2 }),
      label
    );
  }

  /* ---------- Button ---------- */
  function Btn({ variant = "primary", icon, children, onClick, block, style, disabled }) {
    return React.createElement("button", {
      onClick, disabled, className: "mu-btn mu-btn-" + variant,
      style: Object.assign({ width: block ? "100%" : undefined, opacity: disabled ? .45 : 1 }, style),
    },
      icon && React.createElement(Icon, { name: icon, size: 18, stroke: 2 }),
      React.createElement("span", null, children)
    );
  }

  /* ---------- Placeholder (striped, monospace label) ---------- */
  function Placeholder({ label, h = 150, radius = 16, style }) {
    return React.createElement("div", {
      style: Object.assign({
        height: h, borderRadius: radius, display: "flex", alignItems: "center", justifyContent: "center",
        background: "repeating-linear-gradient(135deg, #ECE7DD 0 11px, #E4DECF 11px 22px)",
        border: "1px solid var(--line)", color: "var(--ink-3)",
        fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fontSize: 11.5, letterSpacing: ".02em",
        textTransform: "uppercase", overflow: "hidden",
      }, style)
    }, label);
  }

  /* ---------- Sheet (bottom sheet / centered on desktop) ---------- */
  function Sheet({ open, onClose, title, children, headerRight }) {
    const [show, setShow] = useState(open);
    useEffect(() => { if (open) setShow(true); }, [open]);
    if (!show && !open) return null;
    return (
      React.createElement("div", {
        className: "mu-sheet-backdrop" + (open ? " open" : ""),
        onClick: onClose,
        onTransitionEnd: () => { if (!open) setShow(false); },
      },
        React.createElement("div", { className: "mu-sheet" + (open ? " open" : ""), onClick: (e) => e.stopPropagation() },
          React.createElement("div", { className: "mu-sheet-grip" }),
          React.createElement("div", { className: "mu-sheet-head" },
            React.createElement("h3", { style: { fontSize: 19, fontWeight: 700, flex: 1, paddingRight: 8 } }, title),
            headerRight,
            React.createElement("button", { className: "mu-iconbtn", onClick: onClose, "aria-label": "close" },
              React.createElement(Icon, { name: "x", size: 20 }))
          ),
          React.createElement("div", { className: "mu-sheet-body app-scroll" }, children)
        )
      )
    );
  }

  /* ---------- Segmented ---------- */
  function Segmented({ options, value, onChange }) {
    return React.createElement("div", { className: "mu-seg" },
      options.map((o) =>
        React.createElement("button", {
          key: o.value, onClick: () => onChange(o.value),
          className: "mu-seg-btn" + (value === o.value ? " active" : ""),
        }, o.icon && React.createElement(Icon, { name: o.icon, size: 15, stroke: 2 }), o.label)
      )
    );
  }

  /* ---------- Media thumbnail + uploader (real image/video) ---------- */
  function MediaThumb({ item, size = 96, onRemove }) {
    // Track failure per-url, not as a sticky boolean: thumbnails are index-keyed,
    // so a reused slot (e.g. after removing an item) must not inherit a prior failure.
    const [failedUrl, setFailedUrl] = useState(null);
    const failed = !item.url || failedUrl === item.url;
    const common = { onError: () => setFailedUrl(item.url), style: { width: size, height: size, objectFit: "cover", borderRadius: 14, display: "block", background: "#000" } };
    // If the source can't load (e.g. a video's session blob URL is gone after a
    // reload, or a dropped data-URL), fall back to a tasteful placeholder.
    const media = failed
      ? React.createElement(Placeholder, { label: item.type === "video" ? "video" : "foto", h: size, radius: 14, style: { width: size, fontSize: 9.5 } })
      : item.type === "video"
        ? React.createElement("video", Object.assign({ src: item.url, muted: true, playsInline: true, preload: "metadata" }, common))
        : React.createElement("img", Object.assign({ src: item.url, alt: "" }, common));
    return React.createElement("div", { style: { position: "relative", width: size, height: size, flex: "0 0 auto" } },
      media,
      item.type === "video" && React.createElement("div", { style: { position: "absolute", left: 6, bottom: 6, width: 22, height: 22, borderRadius: 99, background: "rgba(0,0,0,.55)", display: "flex", alignItems: "center", justifyContent: "center", color: "#fff" } }, React.createElement(Icon, { name: "report", size: 12, stroke: 2.4 })),
      item.drive && React.createElement("div", { title: "Guardado en Drive", style: { position: "absolute", right: 6, bottom: 6, width: 20, height: 20, borderRadius: 99, background: "var(--active)", display: "flex", alignItems: "center", justifyContent: "center", color: "#fff", border: "1.5px solid #fff", boxShadow: "0 1px 3px rgba(0,0,0,.3)" } }, React.createElement(Icon, { name: "check", size: 11, stroke: 3 })),
      onRemove && React.createElement("button", { onClick: onRemove, "aria-label": "remove", style: { position: "absolute", top: -6, right: -6, width: 22, height: 22, borderRadius: 99, background: "var(--ink)", color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", boxShadow: "0 2px 6px rgba(0,0,0,.3)" } }, React.createElement(Icon, { name: "x", size: 13, stroke: 2.6 })));
  }

  function MediaUploader({ items, onChange, max = 5, lang }) {
    const inputRef = useRef(null);
    const tt = (k) => (window.MU.t ? window.MU.t(lang || "es", k) : k);
    const addFiles = async (fileList) => {
      const files = Array.from(fileList).slice(0, Math.max(0, max - items.length));
      if (!files.length) return;
      const toItem = (f) => MU.store
        ? MU.store.fileToMedia(f) // image → persistable data-URL, video → session blob
        : Promise.resolve({ url: URL.createObjectURL(f), type: (f.type || "").startsWith("video") ? "video" : "image", name: f.name });
      const added = await Promise.all(files.map(toItem));
      // Functional update + hard cap: rapid successive picks (each awaiting conversion)
      // compose against the latest array and can never push past `max`.
      onChange((prev) => (Array.isArray(prev) ? prev : items).concat(added).slice(0, max));
    };
    const input = React.createElement("input", {
      ref: inputRef, type: "file", accept: "image/*,video/*", multiple: true, capture: "environment",
      style: { display: "none" }, onChange: (ev) => { addFiles(ev.target.files); ev.target.value = ""; },
    });
    if (items.length === 0) {
      return React.createElement("div", null, input,
        React.createElement("button", { onClick: () => inputRef.current && inputRef.current.click(), style: { width: "100%", height: 180, borderRadius: 18, border: "2px dashed var(--line-2)", background: "rgba(14,17,22,.02)", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 10, color: "var(--brand)", cursor: "pointer" } },
          React.createElement("div", { style: { width: 56, height: 56, borderRadius: 99, background: "var(--brand-soft)", display: "flex", alignItems: "center", justifyContent: "center" } }, React.createElement(Icon, { name: "camera", size: 26, color: "var(--brand)" })),
          React.createElement("div", { style: { fontWeight: 700, fontSize: 15 } }, tt("add_media")),
          React.createElement("div", { style: { fontSize: 12, color: "var(--ink-4)", fontWeight: 600 } }, tt("add_media_hint"))));
    }
    return React.createElement("div", null, input,
      React.createElement("div", { style: { display: "flex", gap: 9, flexWrap: "wrap" } },
        items.map((it, i) => React.createElement(MediaThumb, { key: i, item: it, onRemove: () => onChange(items.filter((_, j) => j !== i)) })),
        items.length < max && React.createElement("button", { onClick: () => inputRef.current && inputRef.current.click(), style: { width: 96, height: 96, borderRadius: 16, border: "2px dashed var(--line-2)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--brand)", cursor: "pointer" } }, React.createElement(Icon, { name: "plus", size: 22, stroke: 2.2 }))));
  }

  /* ---------- inject component CSS ---------- */
  const css = `
  .mu-screen{padding:18px 16px 120px;}
  /* min-width:0 lets cards/buttons shrink inside grid & flex tracks instead of
     forcing the track wider than the viewport (the cause of tiles overflowing). */
  .mu-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh-1);min-width:0;}
  .mu-eyebrow{font-size:11.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-4);}
  .mu-h-title{font-size:25px;font-weight:800;letter-spacing:-.025em;}
  .mu-sub{color:var(--ink-3);font-size:14px;line-height:1.5;}
  .mu-pill{display:inline-flex;align-items:center;gap:6px;border-radius:999px;font-weight:600;white-space:nowrap;font-family:var(--text);}
  .mu-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border-radius:14px;font-family:var(--text);
    font-weight:700;font-size:15px;padding:14px 18px;min-width:0;transition:transform .12s ease, background .2s ease, box-shadow .2s;}
  .mu-btn:active{transform:scale(.985);}
  .mu-btn-primary{background:var(--brand);color:#fff;box-shadow:0 6px 18px rgba(31,111,92,.28);}
  .mu-btn-primary:hover{background:var(--brand-deep);}
  .mu-btn-dark{background:var(--ink);color:#fff;}
  .mu-btn-gold{background:var(--gold);color:#2a2208;box-shadow:0 6px 18px rgba(201,162,75,.28);}
  .mu-btn-ghost{background:rgba(14,17,22,.05);color:var(--ink);}
  .mu-btn-ghost:hover{background:rgba(14,17,22,.08);}
  .mu-btn-outline{background:transparent;color:var(--ink);border:1.5px solid var(--line-2);}
  .mu-iconbtn{width:38px;height:38px;border-radius:12px;display:flex;align-items:center;justify-content:center;color:var(--ink-2);transition:background .15s;}
  .mu-iconbtn:hover{background:rgba(14,17,22,.06);}
  .mu-seg{display:inline-flex;background:rgba(14,17,22,.05);border-radius:12px;padding:3px;gap:2px;}
  .mu-seg-btn{display:inline-flex;align-items:center;gap:6px;border-radius:9px;padding:7px 13px;font-size:13px;font-weight:600;color:var(--ink-3);transition:.18s;}
  .mu-seg-btn.active{background:#fff;color:var(--ink);box-shadow:var(--sh-1);}
  .mu-chip{display:inline-flex;align-items:center;gap:6px;padding:8px 13px;border-radius:999px;font-size:13px;font-weight:600;
    background:#fff;border:1px solid var(--line);color:var(--ink-2);transition:.15s;white-space:nowrap;cursor:pointer;}
  .mu-chip.active{background:var(--ink);color:#fff;border-color:var(--ink);}
  .mu-input{width:100%;border:1px solid var(--line-2);border-radius:14px;padding:13px 15px;font-size:15px;background:#fff;color:var(--ink);}
  .mu-input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft);}
  .mu-list-row{display:flex;align-items:center;gap:13px;padding:14px 15px;cursor:pointer;transition:background .15s;}
  .mu-list-row:hover{background:rgba(14,17,22,.025);}
  .mu-cat-ic{width:42px;height:42px;border-radius:12px;display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
  .mu-sheet-backdrop{position:absolute;inset:0;background:rgba(8,14,12,0);display:flex;align-items:flex-end;justify-content:center;
    z-index:60;transition:background .35s ease;pointer-events:none;}
  .mu-sheet-backdrop.open{background:rgba(8,14,12,.42);pointer-events:auto;}
  .mu-sheet{width:100%;max-height:88%;background:var(--paper);border-radius:24px 24px 0 0;transform:translateY(101%);
    transition:transform .42s cubic-bezier(.22,.85,.28,1);display:flex;flex-direction:column;box-shadow:0 -10px 50px rgba(0,0,0,.25);}
  .mu-sheet.open{transform:translateY(0);}
  .mu-sheet-grip{width:38px;height:4px;border-radius:9px;background:var(--line-2);margin:9px auto 2px;flex:0 0 auto;}
  .mu-sheet-head{display:flex;align-items:center;gap:6px;padding:8px 14px 10px;border-bottom:1px solid var(--line);}
  .mu-sheet-body{overflow-y:auto;padding:16px;flex:1;}
  .mu-divider{height:1px;background:var(--line);}
  @media(min-width:560px){
    .mu-sheet-backdrop{align-items:center;}
    .mu-sheet{max-width:460px;border-radius:24px;max-height:84%;transform:translateY(20px) scale(.97);opacity:0;}
    .mu-sheet.open{transform:translateY(0) scale(1);opacity:1;}
  }
  `;
  const styleEl = document.createElement("style");
  styleEl.id = "mu-ui-css";
  styleEl.textContent = css;
  document.head.appendChild(styleEl);

  Object.assign(MU, { Icon, Ring, CountUp, StatusPill, SeverityBadge, Btn, Placeholder, Sheet, Segmented, MediaThumb, MediaUploader });
})(window.MU);
