// ── Oasis HMS · Dashboard screen ────────────────────────────────────────────
const Od = window.OASIS;

const KPI_TONE = {
  red: { fg: "#DE4343", border: "#F2B4B4", iconBg: "#FCE5E5", divider: "#F7DADA", footerHover: "#FFF6F6" },
  green: { fg: "#36AC4D", border: "#A8DEB4", iconBg: "#E2F6E7", divider: "#D6EFDC", footerHover: "#F6FCF7" },
  blue: { fg: Od.primary, border: "#AECBF0", iconBg: "#E2EFFC", divider: "#D7E6F8", footerHover: "#F5F9FE" },
  purple: { fg: Od.purple, border: "#C9A6F6", iconBg: "#EEE2FD", divider: "#E3D3FA", footerHover: "#FAF6FE" }
};

function ProfileCard() {
  return (
    <Card flat style={{ flex: "0 0 326px", height: 206, position: "relative", display: "flex", flexDirection: "column", justifyContent: "space-between" }} pad={26}>
      <button style={{ position: "absolute", top: 20, right: 20, border: "none", background: "transparent", cursor: "pointer" }}>
        <Icon name="more-h" size={20} color="#AEB6C4" />
      </button>
      <div style={{ display: "flex", gap: 20, alignItems: "center" }}>
        {/* Avatar - exact CSS crop from the design's portrait sprite (scales at any size) */}
        <div style={{ width: 92, height: 92, borderRadius: 16, flexShrink: 0, backgroundColor: "#cfe2f6",
          backgroundImage: `url(${(window.__resources && window.__resources.avatarFace) || "assets/avatar-face.jpg"})`, backgroundRepeat: "no-repeat",
          backgroundPosition: "center 28%", backgroundSize: "cover" }} />
        <div>
          <div style={{ fontFamily: Od.font, fontSize: 25, color: Od.navy, lineHeight: 1.05, fontWeight: "500" }}>Hi, Sofia!</div>
          <div style={{ fontFamily: Od.font, fontWeight: 500, fontSize: 16, color: Od.primary, marginTop: 6 }}>Hotel Manager</div>
          <div style={{ display: "flex", alignItems: "center", gap: 7, marginTop: 10, color: "#AEB6C4", fontFamily: Od.font, fontSize: 13.5 }}>
            <Icon name="sun" size={16} color="#AEB6C4" /> Morning Shift
          </div>
        </div>
      </div>
      <div style={{ height: 1, background: Od.hairline, margin: "0 -4px" }} />
      <div style={{ display: "flex", alignItems: "stretch", justifyContent: "space-around" }}>
        {[{ n: 6, l: "New Messages", i: "message" }, { n: 11, l: "Notifications", i: "bell" }].map((s, i) =>
        <React.Fragment key={s.l}>
          {i === 1 && <div style={{ width: 1, alignSelf: "stretch", background: Od.hairline }} />}
          <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center", gap: "0px" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
              <span style={{ fontFamily: Od.font, fontWeight: 500, fontSize: 24, color: Od.navy }}>{s.n}</span>
              <span style={{ position: "relative" }}>
                <Icon name={s.i} size={21} color={Od.navy} stroke={1.8} />
                <span style={{ position: "absolute", top: -2, right: -2, borderRadius: "50%", background: Od.red, border: "2px solid #fff", width: "12px", height: "12px" }} />
              </span>
            </div>
            <span style={{ fontFamily: Od.font, fontSize: 13.5, color: "#AEB6C4" }}>{s.l}</span>
          </div>
        </React.Fragment>
        )}
      </div>
    </Card>);

}

function KpiCard({ kpi, onCta }) {
  const [h, setH] = useState(false);
  const t = KPI_TONE[kpi.tone];
  return (
    <div onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)} className="kpi-card"
    style={{ flex: 1, height: 206, background: "#fff", borderRadius: 18, border: `1.5px solid ${t.border}`,
      display: "flex", flexDirection: "column", overflow: "hidden",
      transform: h ? "translateY(-3px)" : "none", transition: "all .18s ease",
      boxShadow: "none" }}>
      <div style={{ flex: 1, padding: "22px 24px", display: "flex", flexDirection: "column" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
          <div style={{ fontFamily: Od.font, fontWeight: 500, fontSize: 17, color: t.fg, maxWidth: 150, lineHeight: 1.25 }}>{kpi.label}</div>
          <div style={{ width: 44, height: 44, borderRadius: 11, background: t.iconBg, display: "flex", alignItems: "center", justifyContent: "center" }}>
            <Icon name={kpi.icon} size={24} color={t.fg} />
          </div>
        </div>
        <div style={{ fontFamily: Od.font, fontWeight: 500, fontSize: 46, color: Od.navy, lineHeight: 1, marginTop: 8 }}>{kpi.value}</div>
        <div style={{ fontFamily: Od.font, fontSize: 13.5, color: "#AEB6C4", marginTop: 8 }}>{kpi.sub}</div>
      </div>
      <button onClick={onCta} onMouseEnter={() => setH(true)}
      style={{ height: 54, borderTop: `1px solid ${t.divider}`, borderLeft: "none", borderRight: "none", borderBottom: "none",
        background: h ? t.footerHover : "#fff", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", gap: 8,
        fontFamily: Od.font, fontWeight: 500, fontSize: 15, color: t.fg, transition: "background .15s ease" }}>
        {kpi.cta} <Icon name="arrow-right" size={16} color={t.fg} />
      </button>
    </div>);

}

function PriorityTabs({ value, onChange, counts }) {
  const tabs = [["all", "All"], ["high", "High"], ["medium", "Medium"], ["low", "Low"]];
  return (
    <div style={{ display: "flex", gap: 4, background: "#fff", borderRadius: 12, padding: 6, marginBottom: 18, border: "1px solid #EEF3F9" }}>
      {tabs.map(([k, l]) => {
        const on = value === k;
        return (
          <button key={k} onClick={() => onChange(k)} style={{
            flex: 1, height: 40, border: "none", borderRadius: 9, cursor: "pointer",
            fontFamily: Od.font, fontWeight: 500, fontSize: 14, whiteSpace: "nowrap",
            background: on ? Od.primary : "transparent", color: on ? "#fff" : "#7C8698",
            boxShadow: on ? "0 4px 12px rgba(74,144,226,.28)" : "none", transition: "all .15s ease"
          }}>{l} ({counts[k]})</button>);

      })}
    </div>);

}

function ActiveAlerts({ alerts, onAdd, onEdit, tab, onTab }) {
  const counts = {
    all: alerts.length,
    high: alerts.filter((a) => a.priority === "high").length,
    medium: alerts.filter((a) => a.priority === "medium").length,
    low: alerts.filter((a) => a.priority === "low").length
  };
  const list = tab === "all" ? alerts : alerts.filter((a) => a.priority === tab);
  return (
    <Card flat style={{ gridColumn: "1", gridRow: "1 / 3", display: "flex", flexDirection: "column", minHeight: 0 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 18 }}>
        <div style={{ fontFamily: Od.font, fontWeight: 500, fontSize: 20, color: Od.navy }}>Active Alerts</div>
        <PillButton tone="blue" variant="solid" icon="plus" onClick={onAdd} style={{ height: 42, fontSize: 15 }}>Add New Alert</PillButton>
      </div>
      <PriorityTabs value={tab} onChange={onTab} counts={counts} />
      <div className="oasis-scroll" style={{ flex: 1, overflowY: "auto", paddingRight: 6, minHeight: 0 }}>
        {list.map((a) => {
          const dep = a.dept ? window.DEPARTMENTS[a.dept] : null;
          const chip = { high: { bg: "#FFE2E2", fg: "#DE4343" }, medium: { bg: "#FFF2D9", fg: "#DB9318" }, low: { bg: "#E7F1FC", fg: "#4A90E2" } }[a.priority];
          return (
            <div key={a.id} style={{ borderBottom: `1px solid ${Od.hairline}`, padding: "16px 4px" }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
                <span style={{ display: "inline-block", padding: "6px 13px", borderRadius: 8, fontFamily: Od.font, fontWeight: 500, fontSize: 15.5,
                  background: chip.bg, color: chip.fg }}>{a.title}</span>
                <button onClick={() => onEdit(a)} style={{ display: "flex", alignItems: "center", gap: 6, height: 34, padding: "0 14px", borderRadius: 9,
                  border: "1px solid #BFD9F5", background: "#fff", cursor: "pointer", color: Od.primary, fontFamily: Od.font, fontWeight: 500, fontSize: 14 }}>
                  <Icon name="edit" size={14} color={Od.primary} /> Edit
                </button>
              </div>
              <div style={{ fontFamily: Od.font, fontSize: 13.5, color: "#AEB6C4", margin: "12px 0 12px 2px" }}>{a.where} • {a.time}</div>
              <div style={{ display: "inline-flex", alignItems: "center", gap: 8, height: 36, padding: "0 14px", borderRadius: 9,
                border: "1px solid #E2EAF4", background: "#fff", marginLeft: 2 }}>
                {dep ? <Icon name={dep.icon} size={17} color={Od.navy} /> : null}
                <span style={{ fontFamily: Od.font, fontSize: 14.5, color: a.dept ? Od.navy : "#AEB6C4" }}>{a.dept || "No Department Assigned"}</span>
              </div>
            </div>);

        })}
      </div>
    </Card>);

}

function OccupancyChart() {
  const weeks = window.OCCUPANCY_WEEKS;
  const [weekId, setWeekId] = useState(weeks[0].id);
  const [open, setOpen] = useState(false);
  const [hi, setHi] = useState(null);
  const weekRef = React.useRef(null);
  window.useOutsideClose(weekRef, open, () => setOpen(false));
  const week = weeks.find((w) => w.id === weekId) || weeks[0];
  const data = week.data;
  const max = 42,ticks = [40, 30, 20, 10, 0];
  return (
    <Card flat style={{ gridColumn: "2", gridRow: "1", display: "flex", flexDirection: "column", minHeight: 0 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 18 }}>
        <div style={{ fontFamily: Od.font, fontWeight: 500, fontSize: 20, color: Od.navy }}>Occupancy Overview</div>
        <div ref={weekRef} style={{ position: "relative" }}>
          <button onClick={() => setOpen((o) => !o)} style={{
            display: "inline-flex", alignItems: "center", gap: 8, height: 44, padding: "0 14px", borderRadius: 10,
            border: `1px solid ${open ? Od.primary : "#DCE7F5"}`, background: "#fff", cursor: "pointer",
            fontFamily: Od.font, fontWeight: 500, fontSize: 15, color: Od.primary, whiteSpace: "nowrap", transition: "border-color .15s ease",
          }}>
            {week.label}
            <span style={{ display: "inline-flex", transform: open ? "rotate(180deg)" : "none", transition: "transform .15s ease" }}>
              <Icon name="chevron-down" size={16} color={Od.primary} />
            </span>
          </button>
          {open && (
            <div style={{ position: "absolute", top: 52, right: 0, minWidth: 188, background: "#fff", borderRadius: 12,
              boxShadow: "0 14px 34px rgba(31,42,68,.16)", border: `1px solid ${Od.hairline}`, zIndex: 30, overflow: "hidden", padding: 6 }}>
              {weeks.map((w) => {
                const sel = w.id === weekId;
                return (
                  <div key={w.id} onMouseDown={() => { setWeekId(w.id); setOpen(false); setHi(null); }} style={{
                    display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12,
                    padding: "11px 12px", borderRadius: 8, cursor: "pointer",
                    fontFamily: Od.font, fontSize: 14.5, fontWeight: sel ? 600 : 400,
                    color: sel ? Od.primary : Od.navy, background: sel ? "#F2F8FF" : "#fff",
                  }}
                    onMouseEnter={(e) => { if (!sel) e.currentTarget.style.background = "#F6FAFF"; }}
                    onMouseLeave={(e) => { e.currentTarget.style.background = sel ? "#F2F8FF" : "#fff"; }}>
                    {w.label}
                    {sel && <Icon name="check" size={15} color={Od.primary} />}
                  </div>
                );
              })}
            </div>
          )}
        </div>
      </div>
      <div style={{ flex: 1, display: "flex", gap: 12, minHeight: 0 }}>
        <div style={{ display: "flex", flexDirection: "column", justifyContent: "space-between", paddingBottom: 26, fontFamily: Od.font, fontSize: 12, color: "#AEB6C4" }}>
          {ticks.map((t) => <span key={t}>{t}</span>)}
        </div>
        <div style={{ flex: 1, display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 10, borderLeft: `1px solid ${Od.hairline}`, paddingLeft: 12 }}>
          {data.map((d, i) => {
          const active = hi === i;
          return (
          <div key={d.day} onMouseEnter={() => setHi(i)} onMouseLeave={() => setHi(null)} className="occ-bar"
            style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", height: "100%", cursor: "default" }}>
              <div style={{ flex: 1, width: "100%", maxWidth: 34, display: "flex", flexDirection: "column", justifyContent: "flex-end", position: "relative" }}>
                {/* Tooltip */}
                <div style={{
                  position: "absolute", left: "50%", bottom: "100%", transform: "translateX(-50%)", marginBottom: 10,
                  background: "#fff", borderRadius: 12, padding: "10px 13px", boxShadow: "0 12px 28px rgba(31,42,68,.16)", border: "1px solid #EDF2F8",
                  opacity: active ? 1 : 0, visibility: active ? "visible" : "hidden",
                  transition: "opacity .14s ease, transform .14s ease", pointerEvents: "none", zIndex: 10,
                  whiteSpace: "nowrap", transformOrigin: "bottom center",
                }}>
                  <div style={{ fontFamily: Od.font, fontWeight: 500, fontSize: 12, color: Od.navy, marginBottom: 7 }}>{d.day}</div>
                  <div style={{ display: "flex", alignItems: "center", gap: 7, fontFamily: Od.font, fontSize: 12, color: "#8A93A3" }}>
                    <span style={{ width: 9, height: 9, borderRadius: 3, background: Od.primary }} /> Occupied <b style={{ color: Od.navy, marginLeft: 2 }}>{d.occ}</b>
                  </div>
                  <div style={{ display: "flex", alignItems: "center", gap: 7, fontFamily: Od.font, fontSize: 12, color: "#8A93A3", marginTop: 4 }}>
                    <span style={{ width: 9, height: 9, borderRadius: 3, background: "#DCEBFF" }} /> Available <b style={{ color: Od.navy, marginLeft: 2 }}>{d.cap - d.occ}</b>
                  </div>
                  <span style={{ position: "absolute", left: "50%", top: "100%", transform: "translateX(-50%) translateY(-1px)", width: 0, height: 0, borderLeft: "7px solid transparent", borderRight: "7px solid transparent", borderTop: "7px solid #fff", filter: "drop-shadow(0 2px 1px rgba(31,42,68,.06))" }} />
                </div>
                <div style={{ height: `${(d.cap - d.occ) / max * 100}%`, background: active ? "#C9E0FB" : "#DCEBFF", borderRadius: "6px 6px 0 0", transition: "background .14s ease" }} />
                <div style={{ height: `${d.occ / max * 100}%`, background: active ? Od.primaryDk : Od.primary, borderRadius: d.occ === d.cap ? "6px 6px 0 0" : 0, transition: "background .14s ease" }} />
              </div>
              <span style={{ fontFamily: Od.font, fontSize: 11.5, color: active ? Od.navy : "#AEB6C4", fontWeight: active ? 600 : 400, marginTop: 8, transition: "color .14s ease" }}>{d.day}</span>
            </div>);

          })}
        </div>
      </div>
      <div style={{ display: "flex", gap: 28, justifyContent: "center", marginTop: 14 }}>
        {[["Occupied", Od.primary], ["Available", "#DCEBFF"]].map(([l, c]) =>
        <div key={l} style={{ display: "flex", alignItems: "center", gap: 8, fontFamily: Od.font, fontSize: 14, color: Od.navy, fontWeight: "500" }}>
            <span style={{ width: 13, height: 13, borderRadius: 4, background: c }} /> {l}
          </div>
        )}
      </div>
    </Card>);

}

function StaffStatus({ onOpen }) {
  return (
    <Card flat style={{ gridColumn: "2", gridRow: "2", display: "flex", flexDirection: "column", minHeight: 0 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
        <div style={{ fontFamily: Od.font, fontWeight: 500, fontSize: 20, color: Od.navy }}>Staff Status</div>
        <button onClick={onOpen} style={{ display: "flex", alignItems: "center", gap: 6, border: "none", background: "transparent", cursor: "pointer", color: Od.primary, fontFamily: Od.font, fontWeight: 500, fontSize: 14 }}>
          View Details <Icon name="arrow-right" size={15} color={Od.primary} />
        </button>
      </div>
      <div style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "space-between" }}>
        {window.STAFF.map((s) => {
          const r = s.on / s.total;
          const col = r === 1 ? "#36AC4D" : r >= 0.6 ? "#E79A1A" : "#E36B6B";
          const track = r === 1 ? "#DDF3E1" : r >= 0.6 ? "#FBEBCF" : "#FBD9D9";
          const dep = window.DEPARTMENTS[s.dept];
          return (
            <div key={s.dept} style={{ display: "flex", alignItems: "center", gap: 14 }}>
              <span style={{ width: 22, display: "flex", justifyContent: "center" }}><Icon name={dep.icon} size={18} color={Od.primary} /></span>
              <span style={{ flex: "0 0 130px", fontFamily: Od.font, fontSize: 15, color: Od.navy }}>{s.dept}</span>
              <span style={{ flex: "0 0 46px", fontFamily: Od.font, fontWeight: 500, fontSize: 15, color: Od.navy }}>{s.on}/{s.total}</span>
              <div style={{ flex: 1, height: 9, borderRadius: 6, background: track, overflow: "hidden" }}>
                <div style={{ width: `${r * 100}%`, height: "100%", background: col, borderRadius: 6 }} />
              </div>
            </div>);

        })}
      </div>
    </Card>);

}

function ArrivalsTable({ onAdd }) {
  const cols = ["Booking ID", "Guest Name", "Room No.", "Room Type", "Status"];
  const [sortKey, setSortKey] = useState(null);
  const [dir, setDir] = useState(1);
  let rows = [...window.ARRIVALS];
  if (sortKey) {
    const keyMap = { "Booking ID": "id", "Guest Name": "guest", "Room No.": "room", "Room Type": "type", "Status": "status" };
    const k = keyMap[sortKey];
    rows.sort((a, b) => (a[k] > b[k] ? 1 : -1) * dir);
  }
  const toggle = (c) => {if (sortKey === c) setDir((d) => -d);else {setSortKey(c);setDir(1);}};
  return (
    <Card flat style={{ gridColumn: "3", gridRow: "1", display: "flex", flexDirection: "column", minHeight: 0 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 18 }}>
        <div style={{ fontFamily: Od.font, fontWeight: 500, fontSize: 20, color: Od.navy }}>Upcoming Arrivals</div>
        <PillButton tone="blue" variant="solid" icon="plus" onClick={onAdd} style={{ height: 42, fontSize: 15 }}>Add New Arrival</PillButton>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1.3fr .8fr 1fr 1fr", gap: 8, paddingBottom: 14, borderBottom: `1px solid ${Od.hairline}` }}>
        {cols.map((c) =>
        <button key={c} onClick={() => toggle(c)} style={{ display: "flex", alignItems: "center", gap: 5, border: "none", background: "transparent", cursor: "pointer", fontFamily: Od.font, fontWeight: 500, fontSize: 14, color: sortKey === c ? Od.primary : "#AEB6C4", justifyContent: "flex-start", padding: 0 }}>
            {c} <Icon name="sort" size={13} color={sortKey === c ? Od.primary : "#C9D2DE"} />
          </button>
        )}
      </div>
      <div className="oasis-scroll" style={{ flex: 1, overflowY: "auto", minHeight: 0 }}>
        {rows.map((r) =>
        <div key={r.id} style={{ display: "grid", gridTemplateColumns: "1fr 1.3fr .8fr 1fr 1fr", gap: 8, alignItems: "center", padding: "16px 0", borderBottom: `1px solid ${Od.hairline}`, fontFamily: Od.font, fontSize: 14.5, color: Od.navy }}>
            <span style={{ fontWeight: 500 }}>{r.id}</span>
            <span>{r.guest}</span>
            <span>{r.room}</span>
            <span>{r.type}</span>
            <span style={{ color: window.OASIS_STATUS[r.status]?.fg }}>{r.status}</span>
          </div>
        )}
      </div>
    </Card>);

}

// Dropdown chip for the Quick Reservations filters
function ResDropdown({ icon, value, options, render, onChange }) {
  const [open, setOpen] = useState(false);
  const ref = React.useRef(null);
  window.useOutsideClose(ref, open, () => setOpen(false));
  return (
    <div ref={ref} style={{ position: "relative" }}>
      <button onClick={() => setOpen((o) => !o)} style={{
        display: "inline-flex", alignItems: "center", gap: 8, height: 44, padding: "0 14px", borderRadius: 10,
        border: `1px solid ${open ? Od.primary : "#DCE7F5"}`, background: "#fff", cursor: "pointer",
        fontFamily: Od.font, fontWeight: 500, fontSize: 15, color: Od.primary, whiteSpace: "nowrap", transition: "border-color .15s ease",
      }}>
        {icon && <Icon name={icon} size={16} color={Od.primary} />}
        <span>{render ? render(value) : value}</span>
        <span style={{ display: "inline-flex", transform: open ? "rotate(180deg)" : "none", transition: "transform .15s ease" }}>
          <Icon name="chevron-down" size={16} color={Od.primary} />
        </span>
      </button>
      {open && (
        <div className="oasis-scroll" style={{ position: "absolute", top: 52, left: 0, minWidth: "100%", maxHeight: 230, overflowY: "auto", background: "#fff", borderRadius: 12, boxShadow: "0 14px 34px rgba(31,42,68,.16)", border: `1px solid ${Od.hairline}`, zIndex: 30, padding: 6 }}>
          {options.map((o) => {
            const sel = o === value;
            return (
              <div key={String(o)} onMouseDown={() => { onChange(o); setOpen(false); }} style={{
                display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, padding: "10px 12px", borderRadius: 8, cursor: "pointer",
                fontFamily: Od.font, fontSize: 14.5, fontWeight: sel ? 500 : 400, color: sel ? Od.primary : Od.navy, background: sel ? "#F2F8FF" : "#fff",
              }}
                onMouseEnter={(e) => { if (!sel) e.currentTarget.style.background = "#F6FAFF"; }}
                onMouseLeave={(e) => { e.currentTarget.style.background = sel ? "#F2F8FF" : "#fff"; }}>
                <span style={{ whiteSpace: "nowrap" }}>{render ? render(o) : o}</span>
                {sel && <Icon name="check" size={15} color={Od.primary} />}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

function QuickReservations() {
  const [venue, setVenue] = useState("Restaurant");
  const [guests, setGuests] = useState(2);
  const [dateIdx, setDateIdx] = useState(0);
  const [sel, setSel] = useState(null);

  const venueIcon = (window.RES_VENUES.find((v) => v.name === venue) || {}).icon || "utensils";
  const slots = window.reservationSlots(venue, dateIdx, guests);
  const totalAvail = Object.values(slots).reduce((n, arr) => n + arr.filter((s) => s.available).length, 0);

  // reset selection whenever filters change
  const resetAnd = (fn) => (v) => { fn(v); setSel(null); };

  return (
    <Card flat style={{ gridColumn: "3", gridRow: "2", display: "flex", flexDirection: "column", minHeight: 0 }}>
      <div style={{ fontFamily: Od.font, fontWeight: 500, fontSize: 20, color: Od.navy, marginBottom: 16 }}>Quick Reservations</div>
      <div style={{ display: "flex", gap: 12, marginBottom: 18, flexWrap: "wrap" }}>
        <ResDropdown icon={venueIcon} value={venue} options={window.RES_VENUES.map((v) => v.name)} onChange={resetAnd(setVenue)} />
        <ResDropdown icon="users" value={guests} options={window.RES_GUESTS} render={(g) => `${g} Guest${g > 1 ? "s" : ""}`} onChange={resetAnd(setGuests)} />
        <ResDropdown icon="calendar" value={dateIdx} options={window.RES_DATES.map((_, i) => i)} render={(i) => window.RES_DATES[i]} onChange={resetAnd(setDateIdx)} />
      </div>
      <div className="oasis-scroll" style={{ flex: 1, overflowY: "auto", minHeight: 0, display: "flex", flexDirection: "column", gap: 14 }}>
        {totalAvail === 0 ? (
          <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 10, textAlign: "center", color: "#AEB6C4", fontFamily: Od.font, fontSize: 14 }}>
            <Icon name="calendar" size={26} color="#C9D2DE" />
            No open slots for {guests} guests on {window.RES_DATES[dateIdx]}. Try another time or party size.
          </div>
        ) : Object.entries(slots).map(([part, times]) =>
        <div key={part}>
            <div style={{ fontFamily: Od.font, fontSize: 14, color: "#AEB6C4", marginBottom: 8 }}>{part}</div>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 10 }}>
              {times.map((slot) => {
              const on = sel === part + slot.time;
              const disabled = !slot.available;
              return (
                <button key={slot.time} disabled={disabled} onClick={() => setSel(on ? null : part + slot.time)} style={{
                  height: 40, padding: "0 16px", borderRadius: 9, cursor: disabled ? "not-allowed" : "pointer", fontFamily: Od.font, fontWeight: 500, fontSize: 14,
                  border: `1px solid ${on ? Od.primary : disabled ? "#EDF1F6" : "#DCE7F5"}`,
                  background: on ? Od.primary : disabled ? "#F4F6F9" : "#fff",
                  color: on ? "#fff" : disabled ? "#C4CCD8" : Od.navy,
                  textDecoration: disabled ? "line-through" : "none", transition: "all .14s ease",
                }}>{slot.time}</button>);

            })}
            </div>
          </div>
        )}
      </div>
      <button style={{ alignSelf: "center", marginTop: 14, display: "flex", alignItems: "center", gap: 8, border: "none", background: "transparent", cursor: "pointer", color: Od.primary, fontFamily: Od.font, fontWeight: 500, fontSize: 15 }}>
        View Full Availability <Icon name="arrow-right" size={16} color={Od.primary} />
      </button>
    </Card>);

}

function Dashboard({ alerts, onAddAlert, onEditAlert, onOpenStaff, onAddArrival, onViewAlerts, onViewArrivals }) {
  const [alertTab, setAlertTab] = useState("all");
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 24, height: "100%" }}>
      <div style={{ display: "flex", gap: 24, flex: "0 0 auto" }}>
        <ProfileCard />
        {window.DASH_KPIS.map((k) =>
        <KpiCard key={k.id} kpi={k} onCta={k.id === "alerts" ? onViewAlerts : k.id === "checkin" ? onViewArrivals : undefined} />
        )}
      </div>
      <div style={{ flex: 1, display: "grid", gridTemplateColumns: "minmax(0,1fr) minmax(0,1fr) minmax(0,1.06fr)", gridTemplateRows: "1fr 1fr", gap: 24, minHeight: 0 }}>
        <ActiveAlerts alerts={alerts} onAdd={onAddAlert} onEdit={onEditAlert} tab={alertTab} onTab={setAlertTab} />
        <OccupancyChart />
        <StaffStatus onOpen={onOpenStaff} />
        <ArrivalsTable onAdd={onAddArrival} />
        <QuickReservations />
      </div>
    </div>);

}
window.Dashboard = Dashboard;