;/*__IIFE_WRAP_START__*/(function(){
/**
 * ============================================================================
 * cenora-bundle-21-hr-extensions.tsx
 * ----------------------------------------------------------------------------
 * HRIS Core extensions (FREE, bundled — not the Workforce Pro add-on).
 *
 * Adds:
 *   - Manual time blocks (Way A — worker self-report)
 *   - Shift Grid (week schedule, Teams-Shifts-style)
 *   - Leave Requests + approval
 *   - Shift Swap / Offer / Claim
 *   - Attendance screen extension (sub-area tabs + Workforce Pro upsell card)
 *
 * Loads AFTER cenora-bundle-3-screens.tsx (which defines HRAttendance) so the
 * override sticks. Patches HRIS section of NAV + extends renderRoute.
 *
 * Mirrors apps/web/components/hr/*.tsx (one file per screen).
 * ============================================================================
 */
})();/*__IIFE_WRAP_END__*/


// ─── apps/web/components/hr/attendance-extended.tsx ───────────────────────────────────────────────

;/*__IIFE_WRAP_START__*/(function(){
/**
 * apps/web/components/hr/attendance-extended.tsx
 * Override of HRAttendance — adds a tab-bar above the existing screen with
 * links to Manual Blocks (Way A, free) + Shift Grid + Leave + Shift Swap,
 * plus a contextual Workforce Pro upsell card when the tenant isn't yet on
 * the add-on. Reuses ATTENDANCE_TODAY / ATTENDANCE_RECENT from bundle-2.
 *
 * Note: the original HRAttendance lives in cenora-bundle-3-screens.tsx; this
 * file replaces the globalThis.HRAttendance binding when loaded after.
 */

function HRAttendanceExtended() {
  const { push } = useRouter()
  const today = (ATTENDANCE_TODAY as any[])
  const recent = (ATTENDANCE_RECENT as any[])
  const totalExpected = today.reduce((s, e) => s + e.expected, 0)
  const totalPresent = today.reduce((s, e) => s + e.present + e.remote, 0)
  const totalAbsent = today.reduce((s, e) => s + e.absent, 0)

  return (
    <>
      <TopBar breadcrumb={[{ label: "HRIS" }, { label: "Attendance" }]} />
      <ActionBar
        title="Attendance & Timekeeping"
        status={`${totalPresent.toLocaleString()} / ${totalExpected.toLocaleString()} present today · Source: Hikvision + Dahua + MS Teams Shifts + Cenora App`}
        secondary={<Button variant="ghost" leadingIcon="download" size="sm">Export DTR</Button>}
        primary={<Button variant="primary" leadingIcon="settings" size="sm">Configure sources</Button>}
      />

      <div className="flex-1 overflow-y-auto bg-app">
        <div className="max-w-[1280px] mx-auto p-6 space-y-4">
          {/* Sub-area pills (the extension) */}
          <div className="flex items-center gap-2 flex-wrap">
            <FilterChip active onClick={() => {}}>Overview</FilterChip>
            <FilterChip active={false} onClick={() => push("/hr/manual-blocks")}>Manual blocks (Way A)</FilterChip>
            <FilterChip active={false} onClick={() => push("/hr/shifts")}>Shift Grid</FilterChip>
            <FilterChip active={false} onClick={() => push("/hr/leave")}>Leave Requests</FilterChip>
            <FilterChip active={false} onClick={() => push("/hr/shift-swap")}>Shift Swap</FilterChip>
            <span className="w-px h-5 bg-divider mx-1" />
            <FilterChip active={false} onClick={() => push("/workforce")}>
              <span className="flex items-center gap-1.5"><span className="size-1.5 rounded-full bg-accent" />Workforce Pro</span>
            </FilterChip>
          </div>

          <div className="grid grid-cols-4 gap-3">
            <KpiTile label="Present" value={totalPresent.toLocaleString()} sub={`${Math.round(totalPresent / totalExpected * 100)}% of expected`} accent="success" />
            <KpiTile label="Remote" value={today.reduce((s, e) => s + e.remote, 0).toString()} sub="GPS-verified WFH" accent="info" />
            <KpiTile label="Late" value={today.reduce((s, e) => s + e.late, 0).toString()} sub="Today" accent="warn" />
            <KpiTile label="Absent" value={totalAbsent.toString()} sub="Unplanned · Need follow-up" accent="danger" />
          </div>

          {/* Entity rollup */}
          <Card>
            <CardHeader>
              <div>
                <div className="text-[10px] uppercase tracking-wider font-bold text-ink-mute">Today by entity</div>
                <div className="font-serif text-[18px] text-ink mt-0.5">Attendance roll-up</div>
              </div>
            </CardHeader>
            <div className="grid grid-cols-[100px_100px_100px_80px_80px_80px_80px_1.5fr] px-4 py-2 bg-cream text-[10px] uppercase tracking-wider font-bold text-ink-mute border-y border-divider">
              <span>Entity</span><span className="text-right">Expected</span><span className="text-right">Present</span><span className="text-right">Remote</span><span className="text-right">Late</span><span className="text-right">Absent</span><span className="text-right">Leave</span><span>Source</span>
            </div>
            {today.map(e => (
              <div key={e.entity} className="grid grid-cols-[100px_100px_100px_80px_80px_80px_80px_1.5fr] px-4 py-2.5 items-center border-t border-divider-soft text-[11.5px] hover:bg-cream/40">
                <span className="font-mono font-bold text-brand-mid">{e.entity}</span>
                <span className="font-mono text-right">{e.expected}</span>
                <span className="font-mono text-right text-success font-bold">{e.present}</span>
                <span className="font-mono text-right">{e.remote}</span>
                <span className={cn("font-mono text-right", e.late > 0 && "text-warn font-bold")}>{e.late}</span>
                <span className={cn("font-mono text-right", e.absent > 0 && "text-danger font-bold")}>{e.absent}</span>
                <span className="font-mono text-right text-ink-mute">{e.onLeave}</span>
                <span className="text-[10.5px] text-ink-mute">{e.source}</span>
              </div>
            ))}
          </Card>

          {/* Workforce Pro contextual upsell */}
          <Card>
            <div className="p-4 flex items-start gap-3">
              <div className="size-10 rounded-md bg-accent/15 text-accent inline-flex items-center justify-center shrink-0">
                <Icon name="sparkle" size={16} />
              </div>
              <div className="flex-1 min-w-0">
                <div className="flex items-center gap-2">
                  <span className="font-serif text-[15px] text-ink">Want activity verification (Way B) on top of these manual blocks?</span>
                  <Badge variant="info">Add-on</Badge>
                </div>
                <p className="text-[11.5px] text-ink-mute mt-1">
                  Cenora Workforce Pro adds desktop-agent intervals, screenshots, A↔B reconciliation, scoring with Article 22 safeguards, contractor portals, and field GPS — native to the ERP. Tenant admin can toggle per entity.
                </p>
              </div>
              <Button variant="primary" size="sm" onClick={() => push("/workforce")}>Open Workforce Pro</Button>
            </div>
          </Card>

          {/* Recent punches */}
          <Card>
            <CardHeader>
              <div>
                <div className="text-[10px] uppercase tracking-wider font-bold text-ink-mute">Recent activity</div>
                <div className="font-serif text-[18px] text-ink mt-0.5">Live feed · Last 30 minutes</div>
              </div>
            </CardHeader>
            <div className="divide-y divide-divider-soft">
              {recent.map((r, i) => (
                <div key={i} className="px-4 py-2.5 flex items-center gap-3 hover:bg-cream/40">
                  <Avatar initials={r.initials} tone="sand" size="sm" />
                  <div className="flex-1 min-w-0">
                    <div className="text-[12px] text-ink font-semibold">{r.who} <span className="font-mono text-[10px] text-ink-mute">· {r.entity}</span></div>
                    <div className="text-[10.5px] text-ink-mute">{r.source}</div>
                  </div>
                  <Badge variant={r.action === "Punch IN" ? "success" : "neutral"}>{r.action}</Badge>
                  <span className="text-[11px] font-mono text-ink-mute w-20 text-right">{r.ts}</span>
                  {r.anomaly && <Badge variant="warn">⚠ GPS off-site</Badge>}
                </div>
              ))}
            </div>
          </Card>
        </div>
      </div>
    </>
  )
}

/* OVERRIDE the existing global. */
;(globalThis as any).HRAttendance = HRAttendanceExtended
})();/*__IIFE_WRAP_END__*/



// ─── apps/web/components/hr/manual-blocks.tsx ───────────────────────────────────────────────

;/*__IIFE_WRAP_START__*/(function(){
/**
 * apps/web/components/hr/manual-blocks.tsx
 * HRIS Core — Way A (worker self-report) manual time blocks at team level.
 * This is the FREE version that ships with HRIS Core; Workforce Pro layers
 * Way B (agent observations) + A↔B reconciliation on top.
 */

function HRManualBlocks() {
  const blocks = [
    { id: "TE-HVPH-118003", worker: "Romulo Bautista",  initials: "RB", entity: "HVPH", date: "2026-05-28", from: "06:00", to: "06:45", project: "Pacific Steel API", customer: "Pacific Steel", billable: true,  status: "approved" },
    { id: "TE-HVPH-118010", worker: "Daniel Reyes",      initials: "DR", entity: "HVPH", date: "2026-05-28", from: "08:00", to: "12:00", project: "Pacific Steel install", customer: "Pacific Steel", billable: false, status: "approved" },
    { id: "TE-HVPH-118011", worker: "Daniel Reyes",      initials: "DR", entity: "HVPH", date: "2026-05-28", from: "13:00", to: "17:30", project: "Pacific Steel install", customer: "Pacific Steel", billable: false, status: "approved" },
    { id: "TE-HVSG-118012", worker: "Priya Anand",       initials: "PA", entity: "HVSG", date: "2026-05-28", from: "09:00", to: "12:00", project: "FP&A — May close",      customer: "—",              billable: true,  status: "submitted" },
    { id: "TE-HVPH-118014", worker: "Maria Antonio",     initials: "MA", entity: "HVPH", date: "2026-05-29", from: "08:30", to: "12:00", project: "Month-end close",       customer: "—",              billable: false, status: "draft" },
    { id: "TE-HVPH-118015", worker: "Maria Antonio",     initials: "MA", entity: "HVPH", date: "2026-05-29", from: "13:00", to: "17:00", project: "AR aging review",        customer: "—",              billable: false, status: "draft" },
  ]

  return (
    <>
      <TopBar breadcrumb={[{ label: "HRIS" }, { label: "Attendance" }, { label: "Manual Blocks" }]} />
      <ActionBar
        title="Manual Time Blocks"
        status={`${blocks.length} entries · Way A (worker self-report) · bundled with HRIS Core`}
        secondary={<Button variant="ghost" size="sm" leadingIcon="download">Export</Button>}
        primary={<Button variant="primary" size="sm" leadingIcon="plus">Add block</Button>}
      />

      <div className="flex-1 overflow-y-auto bg-app">
        <div className="max-w-[1280px] mx-auto p-6 space-y-3">
          <Card>
            <div className="p-3 bg-info-soft border border-info-soft rounded flex items-start gap-3">
              <Icon name="info" size={14} className="text-info mt-0.5 shrink-0" />
              <div className="text-[11.5px] text-ink">
                <span className="font-semibold">Bundled feature.</span> Manual blocks (Way A) ship with HRIS Core. To layer Way B observations from the desktop agent plus A↔B reconciliation timeline, A↔B mismatch flagging, and right-to-challenge workflow — see <span className="font-mono text-brand-mid">Workforce Pro</span> in the Marketplace.
              </div>
            </div>
          </Card>

          <Card>
            <div className="grid grid-cols-[140px_1.5fr_90px_110px_1.4fr_1fr_70px_90px] px-4 py-2 bg-cream text-[10px] uppercase tracking-wider font-bold text-ink-mute border-b border-divider">
              <span>Doc №</span><span>Worker</span><span>Date</span><span>From → To</span><span>Project</span><span>Customer</span><span>Bill.</span><span className="text-right">Status</span>
            </div>
            <div className="divide-y divide-divider-soft">
              {blocks.map(b => (
                <div key={b.id} className="grid grid-cols-[140px_1.5fr_90px_110px_1.4fr_1fr_70px_90px] px-4 py-2.5 items-center text-[11.5px] hover:bg-cream/40">
                  <span className="font-mono text-brand-mid">{b.id}</span>
                  <span className="flex items-center gap-2 min-w-0">
                    <Avatar initials={b.initials} tone="sand" size="sm" />
                    <span className="min-w-0">
                      <span className="block text-ink font-semibold truncate">{b.worker}</span>
                      <span className="block text-[10px] text-ink-mute font-mono">{b.entity}</span>
                    </span>
                  </span>
                  <span className="font-mono text-[10.5px] text-ink-mute">{b.date}</span>
                  <span className="font-mono text-[10.5px]">{b.from} → {b.to}</span>
                  <span className="text-ink truncate">{b.project}</span>
                  <span className="text-ink-mute truncate">{b.customer}</span>
                  <span>{b.billable ? <Badge variant="success">Yes</Badge> : <Badge variant="neutral">No</Badge>}</span>
                  <span className="text-right">
                    {b.status === "draft"     && <Badge variant="neutral">Draft</Badge>}
                    {b.status === "submitted" && <Badge variant="info">Submitted</Badge>}
                    {b.status === "approved"  && <Badge variant="success">Approved</Badge>}
                  </span>
                </div>
              ))}
            </div>
          </Card>
        </div>
      </div>
    </>
  )
}

// SANDBOX
;(globalThis as any).HRManualBlocks = HRManualBlocks
})();/*__IIFE_WRAP_END__*/



// ─── apps/web/components/hr/shift-grid.tsx ───────────────────────────────────────────────

;/*__IIFE_WRAP_START__*/(function(){
/**
 * apps/web/components/hr/shift-grid.tsx
 * HRIS Core (free, bundled) — week-grid shift scheduling.
 * Teams-Shifts-style: rows of workers, cols of days, draggable shift chips.
 */

function HRShiftGrid() {
  const days = ["Mon Jun 02","Tue Jun 03","Wed Jun 04","Thu Jun 05","Fri Jun 06","Sat Jun 07","Sun Jun 08"]
  const rows = [
    { worker: "Romulo Cruz",   initials: "RC", role: "Senior Operator", entity: "HVPH", shifts: [
      { day: 0, from: "06:00", to: "14:00", role: "Floor A" },
      { day: 1, from: "06:00", to: "14:00", role: "Floor A" },
      { day: 2, from: "06:00", to: "14:00", role: "Floor A" },
      { day: 3, off: true },
      { day: 4, from: "06:00", to: "14:00", role: "Floor A" },
    ]},
    { worker: "Daniel Reyes",  initials: "DR", role: "Field Tech",     entity: "HVPH", shifts: [
      { day: 0, from: "07:00", to: "16:00", role: "Field route 1" },
      { day: 1, from: "07:00", to: "16:00", role: "Field route 1" },
      { day: 2, from: "07:00", to: "16:00", role: "Field route 2" },
      { day: 3, from: "07:00", to: "16:00", role: "Field route 1" },
      { day: 4, off: true },
      { day: 5, from: "08:00", to: "14:00", role: "On-call", overtime: true },
    ]},
    { worker: "Carlos Mendoza",initials: "CM", role: "Warehouse",      entity: "HVPH", shifts: [
      { day: 0, from: "06:00", to: "14:00", role: "Receiving" },
      { day: 1, from: "06:00", to: "14:00", role: "Receiving" },
      { day: 2, from: "14:00", to: "22:00", role: "Shipping", swap: true },
      { day: 3, from: "06:00", to: "14:00", role: "Receiving" },
      { day: 4, from: "06:00", to: "14:00", role: "Receiving" },
    ]},
    { worker: "Anna Lim",      initials: "AL", role: "Supervisor",     entity: "HVSG", shifts: [
      { day: 0, from: "09:00", to: "18:00", role: "Site lead" },
      { day: 1, from: "09:00", to: "18:00", role: "Site lead" },
      { day: 2, from: "09:00", to: "18:00", role: "Site lead" },
      { day: 3, off: true, leave: "AL" },
      { day: 4, off: true, leave: "AL" },
    ]},
    { worker: "Open shifts",    initials: "??", role: "Unassigned",     entity: "HVPH", isOpen: true, shifts: [
      { day: 2, from: "22:00", to: "06:00", role: "Night audit" },
      { day: 5, from: "08:00", to: "16:00", role: "Weekend cover" },
    ]},
  ]

  const totalShifts = rows.reduce((s, r) => s + r.shifts.filter((sh: any) => !sh.off).length, 0)
  const openCount = rows.find(r => r.isOpen)?.shifts.length || 0

  return (
    <>
      <TopBar breadcrumb={[{ label: "HRIS" }, { label: "Shift Grid" }]} />
      <ActionBar
        title="Shift Grid"
        status={`Week of Jun 02–08 · ${rows.length-1} scheduled · ${openCount} open shifts · ${totalShifts} total`}
        secondary={<Button variant="ghost" size="sm" leadingIcon="download">Export PDF</Button>}
        primary={<Button variant="primary" size="sm" leadingIcon="plus">Add shift</Button>}
      />

      <div className="flex-1 overflow-y-auto bg-app">
        <div className="max-w-[1400px] mx-auto p-6 space-y-3">
          <Card>
            <div className="overflow-x-auto">
              <div style={{ minWidth: 1000 }}>
                {/* Day header */}
                <div className="grid sticky top-0 z-[1] bg-cream" style={{ gridTemplateColumns: `220px repeat(${days.length}, 1fr)` }}>
                  <div className="px-3 py-2 text-[10px] uppercase tracking-wider font-bold text-ink-mute border-b border-divider">Worker</div>
                  {days.map((d,i) => (
                    <div key={i} className="px-2 py-2 text-[10.5px] font-bold text-ink border-b border-l border-divider text-center">
                      {d}
                    </div>
                  ))}
                </div>
                {rows.map((r,ri) => (
                  <div key={ri} className="grid border-b border-divider-soft hover:bg-cream/30" style={{ gridTemplateColumns: `220px repeat(${days.length}, 1fr)` }}>
                    <div className="px-3 py-2.5 flex items-center gap-2">
                      <Avatar initials={r.initials} tone={r.isOpen ? "ink" : "sand"} size="sm" />
                      <div className="min-w-0">
                        <div className={cn("text-[11.5px] font-semibold truncate", r.isOpen ? "text-ink-mute italic" : "text-ink")}>{r.worker}</div>
                        <div className="text-[10px] font-mono text-ink-mute">{r.role} · {r.entity}</div>
                      </div>
                    </div>
                    {days.map((_, di) => {
                      const sh = r.shifts.find((s: any) => s.day === di)
                      return (
                        <div key={di} className="px-1 py-1.5 border-l border-divider-soft min-h-[58px]">
                          {!sh ? null :
                            sh.off ? (
                              <div className="h-full rounded bg-cream border border-dashed border-divider text-[10px] text-ink-mute flex items-center justify-center">
                                {sh.leave ? <span><Badge variant="info">Leave</Badge></span> : "—"}
                              </div>
                            ) : (
                              <div className={cn(
                                "h-full rounded p-1.5 text-[10px] cursor-pointer",
                                r.isOpen ? "bg-warn-soft border border-dashed border-warn text-warn" :
                                sh.swap ? "bg-info-soft border border-info-soft text-info" :
                                sh.overtime ? "bg-accent/15 border border-accent text-ink" :
                                "bg-brand-soft border border-brand-soft text-brand"
                              )}>
                                <div className="font-mono font-bold">{sh.from}–{sh.to}</div>
                                <div className="truncate mt-0.5">{sh.role}</div>
                                {sh.swap && <Badge variant="info">Swap</Badge>}
                                {sh.overtime && <Badge variant="warn">OT</Badge>}
                                {r.isOpen && <Badge variant="warn">Open · claim</Badge>}
                              </div>
                            )
                          }
                        </div>
                      )
                    })}
                  </div>
                ))}
              </div>
            </div>
          </Card>

          <div className="grid grid-cols-3 gap-3 text-[11px]">
            <Card><div className="p-3"><div className="text-[10px] uppercase tracking-wider font-bold text-ink-mute">Drag to assign</div><p className="mt-1 text-ink">Drop an open shift onto a worker row to assign. Auto-checks max hours, certifications, and leave conflicts.</p></div></Card>
            <Card><div className="p-3"><div className="text-[10px] uppercase tracking-wider font-bold text-ink-mute">Worker self-service</div><p className="mt-1 text-ink">Workers can claim open shifts, offer their shifts, or swap directly from their portal. All routes through Shift Swap approvals.</p></div></Card>
            <Card><div className="p-3"><div className="text-[10px] uppercase tracking-wider font-bold text-ink-mute">Bundled · HRIS Core</div><p className="mt-1 text-ink">Schedule + clock + leave are free. Activity monitoring + scoring + contractor flows live in Workforce Pro.</p></div></Card>
          </div>
        </div>
      </div>
    </>
  )
}

// SANDBOX
;(globalThis as any).HRShiftGrid = HRShiftGrid
})();/*__IIFE_WRAP_END__*/



// ─── apps/web/components/hr/leave-requests.tsx ───────────────────────────────────────────────

;/*__IIFE_WRAP_START__*/(function(){
/**
 * apps/web/components/hr/leave-requests.tsx
 * HRIS Core — leave requests + approval queue.
 * Jurisdiction-aware accruals applied via Payroll.
 */

function HRLeaveRequests() {
  const [tab, setTab] = (React as any).useState<string>("pending")
  const all = [
    { id: "LV-2026-0188", worker: "Anna Lim",        initials: "AL", entity: "HVSG", type: "Annual leave",       from: "2026-06-05", to: "2026-06-09", days: 3, balance: 11, status: "pending",  reason: "Family trip · pre-approved verbally" },
    { id: "LV-2026-0189", worker: "Daniel Reyes",    initials: "DR", entity: "HVPH", type: "Sick leave",         from: "2026-06-02", to: "2026-06-02", days: 1, balance: 8,  status: "pending",  reason: "Medical certificate attached" },
    { id: "LV-2026-0190", worker: "Maria Antonio",   initials: "MA", entity: "HVPH", type: "Bereavement",        from: "2026-06-10", to: "2026-06-12", days: 3, balance: 5,  status: "pending",  reason: "—" },
    { id: "LV-2026-0185", worker: "Carlos Mendoza",  initials: "CM", entity: "HVPH", type: "Annual leave",       from: "2026-05-26", to: "2026-05-30", days: 5, balance: 7,  status: "approved", reason: "—", approvedBy: "Maya C." },
    { id: "LV-2026-0186", worker: "Olivia Park",     initials: "OP", entity: "HVSG", type: "Compensatory",       from: "2026-05-28", to: "2026-05-28", days: 1, balance: 3,  status: "approved", reason: "Weekend coverage on May 24", approvedBy: "Anil V." },
    { id: "LV-2026-0179", worker: "Romulo Cruz",     initials: "RC", entity: "HVPH", type: "Annual leave",       from: "2026-05-20", to: "2026-05-21", days: 2, balance: 9,  status: "rejected", reason: "—", rejectReason: "Overlaps month-end audit window" },
    { id: "LV-2026-0181", worker: "Devon Reyes",     initials: "DR", entity: "HVPH", type: "Parental leave",     from: "2026-07-01", to: "2026-07-31", days: 23,balance: 30, status: "approved", reason: "Statutory entitlement · PH", approvedBy: "Anil V." },
  ]
  const buckets: Record<string, any[]> = {
    pending:  all.filter(l => l.status === "pending"),
    approved: all.filter(l => l.status === "approved"),
    rejected: all.filter(l => l.status === "rejected"),
  }

  return (
    <>
      <TopBar breadcrumb={[{ label: "HRIS" }, { label: "Leave Requests" }]} />
      <ActionBar
        title="Leave Requests"
        status={`${buckets.pending.length} pending · ${buckets.approved.length} approved this quarter · jurisdiction-aware accruals applied via Payroll`}
        primary={<Button variant="primary" size="sm" leadingIcon="plus">Request leave</Button>}
      />

      <div className="flex-1 overflow-y-auto bg-app">
        <div className="max-w-[1200px] mx-auto p-6 space-y-3">
          <div className="flex items-center gap-2">
            {[
              ["pending",  `Pending (${buckets.pending.length})`],
              ["approved", `Approved (${buckets.approved.length})`],
              ["rejected", `Rejected (${buckets.rejected.length})`],
            ].map(([k,lbl]) => (
              <FilterChip key={k as string} active={tab === k} onClick={() => setTab(k as string)}>{lbl}</FilterChip>
            ))}
          </div>

          <Card>
            <div className="grid grid-cols-[130px_1.8fr_140px_180px_60px_70px_1.5fr_140px] px-4 py-2 bg-cream text-[10px] uppercase tracking-wider font-bold text-ink-mute border-b border-divider">
              <span>Doc №</span><span>Worker</span><span>Type</span><span>Period</span>
              <span className="text-right">Days</span><span className="text-right">Bal.</span><span>Reason</span>
              <span className="text-right">Actions</span>
            </div>
            <div className="divide-y divide-divider-soft">
              {buckets[tab].map(l => (
                <div key={l.id} className="grid grid-cols-[130px_1.8fr_140px_180px_60px_70px_1.5fr_140px] px-4 py-2.5 items-center text-[11.5px] hover:bg-cream/40">
                  <span className="font-mono text-brand-mid">{l.id}</span>
                  <span className="flex items-center gap-2 min-w-0">
                    <Avatar initials={l.initials} tone="sand" size="sm" />
                    <span className="min-w-0">
                      <span className="block text-ink font-semibold truncate">{l.worker}</span>
                      <span className="block text-[10px] text-ink-mute font-mono">{l.entity}</span>
                    </span>
                  </span>
                  <span className="text-ink">{l.type}</span>
                  <span className="font-mono text-[10.5px] text-ink-mute">{l.from} → {l.to}</span>
                  <span className="font-mono text-right font-bold">{l.days}</span>
                  <span className="font-mono text-right text-ink-mute">{l.balance}</span>
                  <span className="text-[10.5px] text-ink-mute truncate" title={l.rejectReason || l.reason}>
                    {l.status === "rejected" ? <span className="text-danger">{l.rejectReason}</span> : l.reason}
                    {l.approvedBy && <span className="ml-1">· by {l.approvedBy}</span>}
                  </span>
                  <span className="flex items-center justify-end gap-1">
                    {l.status === "pending" && <>
                      <Button variant="ghost" size="sm">Reject</Button>
                      <Button variant="primary" size="sm">Approve</Button>
                    </>}
                    {l.status === "approved" && <Badge variant="success">Approved</Badge>}
                    {l.status === "rejected" && <Badge variant="danger">Rejected</Badge>}
                  </span>
                </div>
              ))}
            </div>
          </Card>

          <div className="text-[10.5px] text-ink-mute px-1">
            Approved leave creates a Payroll deduction line in the next batch. Accrual policies inherit from the worker's primary entity (PH SSS/PhilHealth/Pag-IBIG, SG MOM, HK MPF, AU FairWork, IN POSH).
          </div>
        </div>
      </div>
    </>
  )
}

// SANDBOX
;(globalThis as any).HRLeaveRequests = HRLeaveRequests
})();/*__IIFE_WRAP_END__*/



// ─── apps/web/components/hr/shift-swap.tsx ───────────────────────────────────────────────

;/*__IIFE_WRAP_START__*/(function(){
/**
 * apps/web/components/hr/shift-swap.tsx
 * HRIS Core — Shift Swap / Offer / Claim workflow.
 * Three tabs: incoming swap requests, my open offers, claimable shifts.
 */

function HRShiftSwap() {
  const [tab, setTab] = (React as any).useState<string>("swap_in")

  const swapIn = [
    { id: "SW-2026-0042", from: "Daniel Reyes",   to: "Carlos Mendoza", shift: "Fri Jun 06 · 06–14 · Field route 1", reason: "Doctor's appointment", status: "pending" },
    { id: "SW-2026-0041", from: "Anna Lim",       to: "Olivia Park",    shift: "Mon Jun 09 · 09–18 · Site lead",      reason: "Trade conflict",        status: "pending" },
  ]
  const offers = [
    { id: "OF-2026-0019", owner: "Carlos Mendoza", shift: "Wed Jun 11 · 14–22 · Shipping",       reason: "Family event", interested: 2, status: "open" },
    { id: "OF-2026-0018", owner: "Romulo Cruz",    shift: "Sat Jun 14 · 06–14 · Floor A",         reason: "—",            interested: 0, status: "open" },
  ]
  const claimable = [
    { id: "OS-2026-0102", role: "Night audit",        when: "Wed Jun 04 · 22–06",  rate: "OT 1.5×",        entity: "HVPH", qualifies: true,  reason: null },
    { id: "OS-2026-0103", role: "Weekend cover",      when: "Sat Jun 07 · 08–16",  rate: "Standard + bonus",entity: "HVPH", qualifies: true,  reason: null },
    { id: "OS-2026-0104", role: "Forklift swap",      when: "Fri Jun 06 · 14–22",  rate: "Standard",       entity: "HVSG", qualifies: false, reason: "Cert. expired 2026-04-30 — renew to claim" },
  ]

  return (
    <>
      <TopBar breadcrumb={[{ label: "HRIS" }, { label: "Shift Swap" }]} />
      <ActionBar
        title="Shift Swap · Offer · Claim"
        status="Workers swap directly · offer to team · or claim open shifts · supervisor co-signs as required"
        primary={<Button variant="primary" size="sm" leadingIcon="plus">Offer my shift</Button>}
      />

      <div className="flex-1 overflow-y-auto bg-app">
        <div className="max-w-[1200px] mx-auto p-6 space-y-3">
          <div className="flex items-center gap-2">
            <FilterChip active={tab === "swap_in"} onClick={() => setTab("swap_in")}>Incoming swaps ({swapIn.length})</FilterChip>
            <FilterChip active={tab === "offers"} onClick={() => setTab("offers")}>Open offers ({offers.length})</FilterChip>
            <FilterChip active={tab === "claim"} onClick={() => setTab("claim")}>Claimable ({claimable.length})</FilterChip>
          </div>

          {tab === "swap_in" && (
            <Card>
              <div className="grid grid-cols-[130px_1fr_1fr_2fr_1fr_180px] px-4 py-2 bg-cream text-[10px] uppercase tracking-wider font-bold text-ink-mute border-b border-divider">
                <span>Doc №</span><span>From</span><span>To</span><span>Shift</span><span>Reason</span><span className="text-right">Actions</span>
              </div>
              <div className="divide-y divide-divider-soft">
                {swapIn.map(s => (
                  <div key={s.id} className="grid grid-cols-[130px_1fr_1fr_2fr_1fr_180px] px-4 py-2.5 items-center text-[11.5px] hover:bg-cream/40">
                    <span className="font-mono text-brand-mid">{s.id}</span>
                    <span className="text-ink">{s.from}</span>
                    <span className="text-ink">{s.to}</span>
                    <span className="text-ink-mute truncate">{s.shift}</span>
                    <span className="text-[10.5px] text-ink-mute">{s.reason}</span>
                    <span className="flex items-center justify-end gap-1">
                      <Button variant="ghost" size="sm">Reject</Button>
                      <Button variant="primary" size="sm">Approve swap</Button>
                    </span>
                  </div>
                ))}
              </div>
            </Card>
          )}

          {tab === "offers" && (
            <Card>
              <div className="grid grid-cols-[130px_1.2fr_2fr_1.2fr_100px_130px] px-4 py-2 bg-cream text-[10px] uppercase tracking-wider font-bold text-ink-mute border-b border-divider">
                <span>Doc №</span><span>Owner</span><span>Shift</span><span>Reason</span><span className="text-right">Interested</span><span className="text-right">Status</span>
              </div>
              <div className="divide-y divide-divider-soft">
                {offers.map(o => (
                  <div key={o.id} className="grid grid-cols-[130px_1.2fr_2fr_1.2fr_100px_130px] px-4 py-2.5 items-center text-[11.5px] hover:bg-cream/40">
                    <span className="font-mono text-brand-mid">{o.id}</span>
                    <span className="text-ink">{o.owner}</span>
                    <span className="text-ink-mute truncate">{o.shift}</span>
                    <span className="text-[10.5px] text-ink-mute">{o.reason || "—"}</span>
                    <span className="font-mono text-right font-bold">{o.interested}</span>
                    <span className="text-right"><Badge variant={o.status === "open" ? "info" : "neutral"}>{o.status}</Badge></span>
                  </div>
                ))}
              </div>
            </Card>
          )}

          {tab === "claim" && (
            <Card>
              <div className="grid grid-cols-[130px_1.2fr_1.5fr_1fr_90px_1.8fr_120px] px-4 py-2 bg-cream text-[10px] uppercase tracking-wider font-bold text-ink-mute border-b border-divider">
                <span>Doc №</span><span>Role</span><span>When</span><span>Rate</span><span>Entity</span><span>Eligibility</span><span className="text-right">Action</span>
              </div>
              <div className="divide-y divide-divider-soft">
                {claimable.map(c => (
                  <div key={c.id} className="grid grid-cols-[130px_1.2fr_1.5fr_1fr_90px_1.8fr_120px] px-4 py-2.5 items-center text-[11.5px] hover:bg-cream/40">
                    <span className="font-mono text-brand-mid">{c.id}</span>
                    <span className="text-ink font-semibold">{c.role}</span>
                    <span className="font-mono text-[10.5px] text-ink-mute">{c.when}</span>
                    <span className="text-ink-mute">{c.rate}</span>
                    <span className="font-mono">{c.entity}</span>
                    <span className="text-[10.5px]">
                      {c.qualifies ? <Badge variant="success">Eligible</Badge> : <span className="text-warn">{c.reason}</span>}
                    </span>
                    <span className="text-right">
                      {c.qualifies ? <Button variant="primary" size="sm">Claim</Button> : <Button variant="ghost" size="sm" disabled>Ineligible</Button>}
                    </span>
                  </div>
                ))}
              </div>
            </Card>
          )}

          <div className="text-[10.5px] text-ink-mute px-1">
            Swaps require co-sign by the receiving worker AND supervisor approval (configurable per entity). Claims auto-check certifications, max-hours, and overlap with leave requests. Audited per HRIS Core audit log.
          </div>
        </div>
      </div>
    </>
  )
}

// SANDBOX
;(globalThis as any).HRShiftSwap = HRShiftSwap
})();/*__IIFE_WRAP_END__*/



// ─── NAV + ROUTE PATCH ─────────────────────────────────────────────────
;/*__IIFE_WRAP_START__*/(function(){
/**
 * Patches the HRIS sidebar section + renderRoute for the four new HRIS Core
 * screens. Manual Blocks lives under /hr/manual-blocks; the three workflow
 * screens get their own NAV entries.
 */

const NAV = (globalThis as any).NAV as any[]
const hris = NAV && NAV.find(s => s && s.key === "hris")
if (hris && !hris.items.find((i: any) => i.key === "wf-shifts")) {
  /* Insert new items right after Attendance for adjacency. */
  const idx = hris.items.findIndex((i: any) => i.key === "attendance")
  const ins = [
    { key: "wf-manual-blocks", href: "/hr/manual-blocks", label: "Manual Blocks (A)", icon: "edit" },
    { key: "wf-shifts",        href: "/hr/shifts",        label: "Shift Grid",        icon: "calendar" },
    { key: "wf-leave",         href: "/hr/leave",         label: "Leave Requests",    icon: "calendar", badge: 3 },
    { key: "wf-shift-swap",    href: "/hr/shift-swap",    label: "Shift Swap",        icon: "git-branch", badge: 2 },
  ]
  hris.items.splice(idx + 1, 0, ...ins)
}

const _prev = (globalThis as any).renderRoute
function hrRoute(route: string): any {
  if (route === "/hr/manual-blocks") return <HRManualBlocks />
  if (route === "/hr/shifts")        return <HRShiftGrid />
  if (route === "/hr/leave")         return <HRLeaveRequests />
  if (route === "/hr/shift-swap")    return <HRShiftSwap />
  return null
}
;(globalThis as any).renderRoute = function(route: string) {
  const r = hrRoute(route)
  if (r) return r
  return _prev ? _prev(route) : null
}

})();/*__IIFE_WRAP_END__*/
