copilotoffice 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -148598,6 +148598,7 @@ WARNING: This link could potentially be dangerous`)) {
148598
148598
  this.historyPopover = null;
148599
148599
  this.isFullWidth = false;
148600
148600
  this.fullscreenBtn = null;
148601
+ this.mobileKeyboardBtn = null;
148601
148602
  this.isFocused = false;
148602
148603
  this.resizeHandler = null;
148603
148604
  this.resizeObserver = null;
@@ -148605,6 +148606,7 @@ WARNING: This link could potentially be dangerous`)) {
148605
148606
  this.attachedOfficeId = null;
148606
148607
  this.isReadOnly = false;
148607
148608
  this.isReplaying = false;
148609
+ this.launchMode = "copilot";
148608
148610
  this.scene = scene;
148609
148611
  this.inputManager = inputManager;
148610
148612
  this.getOfficeId = getOfficeId;
@@ -148648,6 +148650,7 @@ WARNING: This link could potentially be dangerous`)) {
148648
148650
  parseSessionId(_data) {
148649
148651
  }
148650
148652
  acknowledgeCompletedWork(officeId, agentId) {
148653
+ if (agentId === "pc-terminal") return;
148651
148654
  if (officeManager.acknowledgeAgentCompletion(officeId, agentId)) {
148652
148655
  this.scene.game.events.emit("agent:status:changed", agentId);
148653
148656
  }
@@ -148669,6 +148672,7 @@ WARNING: This link could potentially be dangerous`)) {
148669
148672
  this.currentAgentId = agent.id;
148670
148673
  this.onCloseCallback = onClose;
148671
148674
  this.isReadOnly = options?.readOnly ?? false;
148675
+ this.launchMode = options?.launchMode ?? "copilot";
148672
148676
  this.attachedOfficeId = this.getOfficeId();
148673
148677
  this.currentAgent = agent;
148674
148678
  if (!this.container) {
@@ -148713,6 +148717,8 @@ WARNING: This link could potentially be dangerous`)) {
148713
148717
  if (this.spriteCardElement) {
148714
148718
  this.spriteCardElement.style.display = "flex";
148715
148719
  }
148720
+ this.applySpriteCardResponsiveStyles();
148721
+ this.updateMobileKeyboardButtonVisibility();
148716
148722
  this.applyPanelLayout();
148717
148723
  this.updateFullscreenButton();
148718
148724
  const colorHex = "#" + agent.color.toString(16).padStart(6, "0");
@@ -148810,7 +148816,21 @@ WARNING: This link could potentially be dangerous`)) {
148810
148816
  this.fitAddon?.fit();
148811
148817
  const dims = this.fitAddon?.proposeDimensions();
148812
148818
  const result = await withTimeout(
148813
- window.copilotBridge.terminalStart(this.getOfficeId(), agentId, workingDir, dims?.cols, dims?.rows),
148819
+ this.launchMode === "shell" ? window.copilotBridge.terminalStart(
148820
+ this.getOfficeId(),
148821
+ agentId,
148822
+ workingDir,
148823
+ dims?.cols,
148824
+ dims?.rows,
148825
+ void 0,
148826
+ "shell"
148827
+ ) : window.copilotBridge.terminalStart(
148828
+ this.getOfficeId(),
148829
+ agentId,
148830
+ workingDir,
148831
+ dims?.cols,
148832
+ dims?.rows
148833
+ ),
148814
148834
  IPC_TIMEOUT,
148815
148835
  "terminalStart"
148816
148836
  );
@@ -148934,6 +148954,13 @@ WARNING: This link could potentially be dangerous`)) {
148934
148954
  </div>
148935
148955
  `;
148936
148956
  this.spriteCardElement.appendChild(agentDisplay);
148957
+ const controlsColumn = document.createElement("div");
148958
+ controlsColumn.style.cssText = `
148959
+ display: flex;
148960
+ flex-direction: column;
148961
+ gap: 10px;
148962
+ align-items: stretch;
148963
+ `;
148937
148964
  const buttonGrid = document.createElement("div");
148938
148965
  buttonGrid.style.cssText = `
148939
148966
  display: grid;
@@ -149007,7 +149034,30 @@ WARNING: This link could potentially be dangerous`)) {
149007
149034
  refreshFocusBtn.onclick = () => this.focusTerminal();
149008
149035
  refreshFocusBtn.title = "Re-focus terminal input when typing stops working";
149009
149036
  buttonGrid.appendChild(refreshFocusBtn);
149010
- this.spriteCardElement.appendChild(buttonGrid);
149037
+ this.mobileKeyboardBtn = document.createElement("button");
149038
+ this.mobileKeyboardBtn.textContent = "\u2328 Open Keyboard";
149039
+ this.mobileKeyboardBtn.style.cssText = `
149040
+ ${btnStyle}
149041
+ width: 100%;
149042
+ min-height: 56px;
149043
+ font-size: 20px;
149044
+ font-weight: bold;
149045
+ color: #ffffff;
149046
+ background: #3a4f8f;
149047
+ border: 2px solid #6f86d8;
149048
+ `;
149049
+ this.mobileKeyboardBtn.onmouseover = () => {
149050
+ if (this.mobileKeyboardBtn) this.mobileKeyboardBtn.style.background = "#4a63b0";
149051
+ };
149052
+ this.mobileKeyboardBtn.onmouseout = () => {
149053
+ if (this.mobileKeyboardBtn) this.mobileKeyboardBtn.style.background = "#3a4f8f";
149054
+ };
149055
+ this.mobileKeyboardBtn.onclick = () => this.focusTerminal();
149056
+ this.mobileKeyboardBtn.title = "Tap to open the device keyboard for terminal input";
149057
+ controlsColumn.appendChild(this.mobileKeyboardBtn);
149058
+ controlsColumn.appendChild(buttonGrid);
149059
+ this.spriteCardElement.appendChild(controlsColumn);
149060
+ this.updateMobileKeyboardButtonVisibility();
149011
149061
  const gameContainer = document.getElementById("game-container");
149012
149062
  if (gameContainer) {
149013
149063
  gameContainer.appendChild(this.spriteCardElement);
@@ -149050,7 +149100,21 @@ WARNING: This link could potentially be dangerous`)) {
149050
149100
  this.fitAddon?.fit();
149051
149101
  const dims = this.fitAddon?.proposeDimensions();
149052
149102
  const result = await withTimeout(
149053
- window.copilotBridge.terminalStart(officeId, this.currentAgentId, this.currentAgent.workingDir || officeManager.getCurrentWorkingDirectory(), dims?.cols, dims?.rows),
149103
+ this.launchMode === "shell" ? window.copilotBridge.terminalStart(
149104
+ officeId,
149105
+ this.currentAgentId,
149106
+ this.currentAgent.workingDir || officeManager.getCurrentWorkingDirectory(),
149107
+ dims?.cols,
149108
+ dims?.rows,
149109
+ void 0,
149110
+ "shell"
149111
+ ) : window.copilotBridge.terminalStart(
149112
+ officeId,
149113
+ this.currentAgentId,
149114
+ this.currentAgent.workingDir || officeManager.getCurrentWorkingDirectory(),
149115
+ dims?.cols,
149116
+ dims?.rows
149117
+ ),
149054
149118
  IPC_TIMEOUT,
149055
149119
  "terminalStart"
149056
149120
  );
@@ -149243,12 +149307,16 @@ WARNING: This link could potentially be dangerous`)) {
149243
149307
  });
149244
149308
  this.resizeHandler = () => {
149245
149309
  if (this.isVisible) {
149310
+ this.applySpriteCardResponsiveStyles();
149311
+ this.updateMobileKeyboardButtonVisibility();
149246
149312
  this.debouncedRefit();
149247
149313
  }
149248
149314
  };
149249
149315
  window.addEventListener("resize", this.resizeHandler);
149250
149316
  this.resizeObserver = new ResizeObserver(() => {
149251
149317
  if (this.isVisible) {
149318
+ this.applySpriteCardResponsiveStyles();
149319
+ this.updateMobileKeyboardButtonVisibility();
149252
149320
  this.debouncedRefit();
149253
149321
  }
149254
149322
  });
@@ -149258,6 +149326,13 @@ WARNING: This link could potentially be dangerous`)) {
149258
149326
  }
149259
149327
  /** Toggle between half-width and full-width terminal panel. */
149260
149328
  toggleFullWidth() {
149329
+ if (window.__copilotOfficeMobileModeActive?.() === true) {
149330
+ this.isFullWidth = true;
149331
+ this.applyPanelLayout();
149332
+ this.updateFullscreenButton();
149333
+ this.debouncedRefit();
149334
+ return;
149335
+ }
149261
149336
  this.isFullWidth = !this.isFullWidth;
149262
149337
  localStorage.setItem(_TerminalOverlay.STORAGE_KEY, String(this.isFullWidth));
149263
149338
  console.log(`[TerminalOverlay] toggleFullWidth() \u2014 now ${this.isFullWidth ? "full" : "half"}`);
@@ -149270,6 +149345,12 @@ WARNING: This link could potentially be dangerous`)) {
149270
149345
  const officePanel = document.getElementById("office-panel");
149271
149346
  const terminalPanel = document.getElementById("terminal-panel");
149272
149347
  if (!officePanel || !terminalPanel) return;
149348
+ if (window.__copilotOfficeMobileModeActive?.() === true) {
149349
+ officePanel.style.display = "none";
149350
+ terminalPanel.style.width = "100%";
149351
+ terminalPanel.style.borderLeft = "none";
149352
+ return;
149353
+ }
149273
149354
  if (this.isFullWidth) {
149274
149355
  officePanel.style.display = "none";
149275
149356
  terminalPanel.style.width = "100%";
@@ -149281,6 +149362,7 @@ WARNING: This link could potentially be dangerous`)) {
149281
149362
  }
149282
149363
  /** Restore half-width layout (used when hiding terminal). */
149283
149364
  restorePanelLayout() {
149365
+ if (window.__copilotOfficeMobileModeActive?.() === true) return;
149284
149366
  const officePanel = document.getElementById("office-panel");
149285
149367
  const terminalPanel = document.getElementById("terminal-panel");
149286
149368
  if (!officePanel || !terminalPanel) return;
@@ -149312,8 +149394,29 @@ WARNING: This link could potentially be dangerous`)) {
149312
149394
  /** Update the fullscreen toggle button label. */
149313
149395
  updateFullscreenButton() {
149314
149396
  if (this.fullscreenBtn) {
149397
+ if (window.__copilotOfficeMobileModeActive?.() === true) {
149398
+ this.fullscreenBtn.textContent = "\u26F6 Locked";
149399
+ this.fullscreenBtn.title = "Fullscreen is locked in mobile mode";
149400
+ return;
149401
+ }
149315
149402
  this.fullscreenBtn.textContent = this.isFullWidth ? "\u26F6 Half" : "\u26F6 Fullscreen";
149403
+ this.fullscreenBtn.title = "";
149404
+ }
149405
+ }
149406
+ applySpriteCardResponsiveStyles() {
149407
+ if (!this.spriteCardElement) return;
149408
+ const isMobile = window.__copilotOfficeMobileModeActive?.() === true;
149409
+ if (isMobile) {
149410
+ this.spriteCardElement.style.minHeight = "416px";
149411
+ this.spriteCardElement.style.padding = "39px";
149412
+ return;
149316
149413
  }
149414
+ this.spriteCardElement.style.minHeight = "";
149415
+ this.spriteCardElement.style.padding = "15px 30px";
149416
+ }
149417
+ updateMobileKeyboardButtonVisibility() {
149418
+ if (!this.mobileKeyboardBtn) return;
149419
+ this.mobileKeyboardBtn.style.display = "none";
149317
149420
  }
149318
149421
  /** Give keyboard focus to the terminal. Safe to call when already focused. */
149319
149422
  focusTerminal() {
@@ -149323,6 +149426,9 @@ WARNING: This link could potentially be dangerous`)) {
149323
149426
  () => this.handleNewSession(),
149324
149427
  () => this.toggleFullWidth()
149325
149428
  );
149429
+ if (window.__copilotOfficeMobileModeActive?.() === true) {
149430
+ this.terminal?.focus();
149431
+ }
149326
149432
  this.inputManager.focusTerminalXterm(this.terminal);
149327
149433
  if (this.currentAgent) {
149328
149434
  this.scene.game.events.emit("npc:highlight", this.currentAgent.id);
@@ -149338,7 +149444,12 @@ WARNING: This link could potentially be dangerous`)) {
149338
149444
  /** Give keyboard focus back to the game canvas. Safe to call when already blurred. */
149339
149445
  blurTerminal() {
149340
149446
  console.log("[TerminalOverlay] blurTerminal() \u2014 delegating to InputManager");
149341
- this.inputManager.switchToGame("TerminalOverlay.blurTerminal()");
149447
+ const mobileLocked = window.__copilotOfficeMobileModeActive?.() === true;
149448
+ if (mobileLocked) {
149449
+ this.inputManager.switchToNone("TerminalOverlay.blurTerminal() mobile lock");
149450
+ } else {
149451
+ this.inputManager.switchToGame("TerminalOverlay.blurTerminal()");
149452
+ }
149342
149453
  this.inputManager.blurTerminalXterm(this.terminal);
149343
149454
  if (this.currentAgentId) {
149344
149455
  const officeId = this.attachedOfficeId ?? this.getOfficeId();
@@ -149369,6 +149480,7 @@ WARNING: This link could potentially be dangerous`)) {
149369
149480
  if (this.spriteCardElement) {
149370
149481
  this.spriteCardElement.style.display = "none";
149371
149482
  }
149483
+ this.updateMobileKeyboardButtonVisibility();
149372
149484
  this.isVisible = false;
149373
149485
  this.isReadOnly = false;
149374
149486
  this.closeHistoryPopover();
@@ -149390,7 +149502,9 @@ WARNING: This link could potentially be dangerous`)) {
149390
149502
  if (this.onCloseCallback) {
149391
149503
  this.onCloseCallback();
149392
149504
  }
149393
- this.scene.game.canvas.focus();
149505
+ if (window.__copilotOfficeMobileModeActive?.() !== true) {
149506
+ this.scene.game.canvas.focus();
149507
+ }
149394
149508
  }
149395
149509
  getIsVisible() {
149396
149510
  return this.isVisible;
@@ -150352,15 +150466,102 @@ WARNING: This link could potentially be dangerous`)) {
150352
150466
  }
150353
150467
  });
150354
150468
 
150469
+ // src/layouts/types.ts
150470
+ function getDashboardTypography() {
150471
+ const isMobile = typeof window !== "undefined" && window.__copilotOfficeMobileModeActive?.() === true;
150472
+ return isMobile ? MOBILE_DASHBOARD_TYPOGRAPHY : DESKTOP_DASHBOARD_TYPOGRAPHY;
150473
+ }
150474
+ var DESKTOP_DASHBOARD_TYPOGRAPHY, MOBILE_DASHBOARD_TYPOGRAPHY;
150475
+ var init_types = __esm({
150476
+ "src/layouts/types.ts"() {
150477
+ "use strict";
150478
+ DESKTOP_DASHBOARD_TYPOGRAPHY = {
150479
+ cardTitle: "15px",
150480
+ cardDescription: "11px",
150481
+ statusText: "11px",
150482
+ statusDot: "8px",
150483
+ elapsed: "10px",
150484
+ badge: "10px",
150485
+ queue: "9px",
150486
+ toolRow: "10px",
150487
+ sectionLabel: "9px",
150488
+ activityRow: "10px",
150489
+ taskSummary: "10px",
150490
+ sessionLabel: "9px",
150491
+ sessionTitle: "13px",
150492
+ sessionButton: "11px",
150493
+ emptyState: "11px",
150494
+ arthurHint: "10px"
150495
+ };
150496
+ MOBILE_DASHBOARD_TYPOGRAPHY = {
150497
+ cardTitle: "19px",
150498
+ cardDescription: "15px",
150499
+ statusText: "16px",
150500
+ statusDot: "11px",
150501
+ elapsed: "14px",
150502
+ badge: "13px",
150503
+ queue: "13px",
150504
+ toolRow: "14px",
150505
+ sectionLabel: "13px",
150506
+ activityRow: "14px",
150507
+ taskSummary: "14px",
150508
+ sessionLabel: "13px",
150509
+ sessionTitle: "17px",
150510
+ sessionButton: "14px",
150511
+ emptyState: "14px",
150512
+ arthurHint: "14px"
150513
+ };
150514
+ }
150515
+ });
150516
+
150355
150517
  // src/layouts/default/DefaultDashboard.ts
150356
150518
  var defaultDashboard;
150357
150519
  var init_DefaultDashboard = __esm({
150358
150520
  "src/layouts/default/DefaultDashboard.ts"() {
150359
150521
  "use strict";
150522
+ init_types();
150360
150523
  defaultDashboard = {
150361
150524
  renderCards(ctx) {
150362
150525
  const { agents, office, selectedAgentId, cachedSessionMeta, agentTools, formatElapsed, formatRelativeTime } = ctx;
150526
+ const t = getDashboardTypography();
150363
150527
  let html = "";
150528
+ const pcCardSelected = selectedAgentId === "pc-terminal";
150529
+ html += `
150530
+ <div class="agent-card" data-agent="pc-terminal" style="
150531
+ background: ${pcCardSelected ? "#1e1e3a" : "#13131f"};
150532
+ border: 1.5px solid ${pcCardSelected ? "#6677ff" : "#252540"};
150533
+ border-radius: 10px;
150534
+ padding: 14px 16px;
150535
+ margin-bottom: 10px;
150536
+ cursor: pointer;
150537
+ transition: border-color 0.15s;
150538
+ display: flex;
150539
+ align-items: center;
150540
+ gap: 12px;
150541
+ ">
150542
+ <div style="
150543
+ width: 64px;
150544
+ background: #5da9ff22;
150545
+ border: 1px solid #5da9ff44;
150546
+ border-radius: 8px;
150547
+ display: flex;
150548
+ align-items: center;
150549
+ justify-content: center;
150550
+ overflow: hidden;
150551
+ flex-shrink: 0;
150552
+ ">
150553
+ <canvas
150554
+ id="overview-sprite-pc-terminal"
150555
+ width="32" height="32"
150556
+ style="image-rendering: pixelated; width: 48px; height: 48px; display: block;"
150557
+ ></canvas>
150558
+ </div>
150559
+ <div style="min-width: 0;">
150560
+ <div style="font-weight: bold; color: #dde; font-size: ${t.cardTitle};">PC TERMINAL</div>
150561
+ <div style="color: #778; font-size: ${t.cardDescription}; margin-top: 2px;">Local shell</div>
150562
+ </div>
150563
+ </div>
150564
+ `;
150364
150565
  for (const agent of agents) {
150365
150566
  const liveStatus = office?.agents.get(agent.id);
150366
150567
  const tools = agentTools.get(agent.id) || [];
@@ -150418,27 +150619,27 @@ WARNING: This link could potentially be dangerous`)) {
150418
150619
  <div style="
150419
150620
  position: absolute; top: -4px; right: -4px;
150420
150621
  background: #e55; color: #fff;
150421
- font-size: 10px; font-weight: bold;
150622
+ font-size: ${t.badge}; font-weight: bold;
150422
150623
  min-width: 18px; height: 18px;
150423
150624
  border-radius: 9px;
150424
150625
  display: flex; align-items: center; justify-content: center;
150425
150626
  padding: 0 4px;
150426
150627
  box-shadow: 0 1px 4px rgba(0,0,0,0.4);
150427
150628
  ">${unread}</div>` : "";
150428
- const elapsedHtml = elapsed ? `<span data-elapsed-agent="${agent.id}" style="color: #8a8; font-size: 10px; margin-left: 8px;">\u23F1 ${elapsed}</span>` : "";
150629
+ const elapsedHtml = elapsed ? `<span data-elapsed-agent="${agent.id}" style="color: #8a8; font-size: ${t.elapsed}; margin-left: 8px;">\u23F1 ${elapsed}</span>` : "";
150429
150630
  const queueHtml = toolCount > 1 ? `<span style="
150430
- background: #334; color: #aac; font-size: 9px;
150631
+ background: #334; color: #aac; font-size: ${t.queue};
150431
150632
  padding: 1px 6px; border-radius: 8px; margin-left: 6px;
150432
150633
  ">${toolCount} tools</span>` : "";
150433
150634
  let toolPipelineHtml = "";
150434
150635
  if (tools.length > 0) {
150435
- const toolRows = tools.map((t, i) => {
150636
+ const toolRows = tools.map((t2, i) => {
150436
150637
  const isLast = i === tools.length - 1;
150437
150638
  const icon = isLast ? "\u25B8" : "\u25E6";
150438
150639
  const color = isLast ? "#8af" : "#556";
150439
- const statusText = isLast ? t.status : "(queued)";
150440
- return `<div style="font-size: 10px; color: ${color}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 1px 0;">
150441
- ${icon} <span style="color: #9ab;">${t.name}</span> <span style="color: #556;">\u2014 ${statusText}</span>
150640
+ const statusText = isLast ? t2.status : "(queued)";
150641
+ return `<div style="font-size: ${t2.toolRow}; color: ${color}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 1px 0;">
150642
+ ${icon} <span style="color: #9ab;">${t2.name}</span> <span style="color: #556;">\u2014 ${statusText}</span>
150442
150643
  </div>`;
150443
150644
  }).join("");
150444
150645
  toolPipelineHtml = `
@@ -150451,24 +150652,24 @@ WARNING: This link could potentially be dangerous`)) {
150451
150652
  if (completedActions.length > 0) {
150452
150653
  const rows = completedActions.map((a) => {
150453
150654
  const relTime = formatRelativeTime(a.timestamp);
150454
- return `<div style="display: flex; gap: 8px; font-size: 10px; padding: 1px 0;" data-action-ts="${a.timestamp}">
150655
+ return `<div style="display: flex; gap: 8px; font-size: ${t.activityRow}; padding: 1px 0;" data-action-ts="${a.timestamp}">
150455
150656
  <span style="color: #445; flex-shrink: 0; min-width: 48px; text-align: right;">${relTime}</span>
150456
150657
  <span style="color: #5a5a7a;">\u2713 ${a.action}</span>
150457
150658
  </div>`;
150458
150659
  }).join("");
150459
150660
  activityLogHtml = `
150460
150661
  <div style="margin-top: 6px; padding-top: 6px; border-top: 1px solid #1a1a30;">
150461
- <div style="font-size: 9px; color: #3a3a5a; margin-bottom: 3px; text-transform: uppercase; letter-spacing: 0.5px;">Recent Activity</div>
150662
+ <div style="font-size: ${t.sectionLabel}; color: #3a3a5a; margin-bottom: 3px; text-transform: uppercase; letter-spacing: 0.5px;">Recent Activity</div>
150462
150663
  ${rows}
150463
150664
  </div>`;
150464
150665
  } else if (liveStatus?.state !== "slacking") {
150465
150666
  activityLogHtml = `
150466
150667
  <div style="margin-top: 6px; padding-top: 6px; border-top: 1px solid #1a1a30;">
150467
- <div style="font-size: 10px; color: #333; font-style: italic;">No recent activity</div>
150668
+ <div style="font-size: ${t.emptyState}; color: #333; font-style: italic;">No recent activity</div>
150468
150669
  </div>`;
150469
150670
  }
150470
150671
  const taskSummaryHtml = taskSummary && isActive ? `
150471
- <div style="font-size: 10px; color: #667; margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
150672
+ <div style="font-size: ${t.taskSummary}; color: #667; margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
150472
150673
  \u{1F4CB} ${taskSummary}
150473
150674
  </div>` : "";
150474
150675
  const meta = cachedSessionMeta[agent.id];
@@ -150483,9 +150684,9 @@ WARNING: This link could potentially be dangerous`)) {
150483
150684
  align-self: stretch;
150484
150685
  justify-content: center;
150485
150686
  ">
150486
- <div style="font-size: 9px; color: #3a3a5a; text-transform: uppercase; letter-spacing: 0.5px;">Session Info</div>
150687
+ <div style="font-size: ${t.sessionLabel}; color: #3a3a5a; text-transform: uppercase; letter-spacing: 0.5px;">Session Info</div>
150487
150688
  <div class="session-title-display" data-agent="${agent.id}" style="
150488
- font-weight: bold; color: ${metaTitle ? "#ccd" : "#444"}; font-size: 13px;
150689
+ font-weight: bold; color: ${metaTitle ? "#ccd" : "#444"}; font-size: ${t.sessionTitle};
150489
150690
  cursor: text; min-height: 18px; line-height: 1.4;
150490
150691
  overflow: hidden; text-overflow: ellipsis;
150491
150692
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
@@ -150493,7 +150694,7 @@ WARNING: This link could potentially be dangerous`)) {
150493
150694
  <div style="display: flex; justify-content: flex-end; margin-top: 2px;">
150494
150695
  <button class="session-edit-btn" data-agent="${agent.id}" style="
150495
150696
  background: none; border: 1px solid #333; color: #667;
150496
- font-size: 11px; padding: 2px 8px; border-radius: 4px;
150697
+ font-size: ${t.sessionButton}; padding: 2px 8px; border-radius: 4px;
150497
150698
  cursor: pointer; transition: color 0.15s, border-color 0.15s;
150498
150699
  " title="Edit session title">\u270F\uFE0F</button>
150499
150700
  </div>
@@ -150508,7 +150709,7 @@ WARNING: This link could potentially be dangerous`)) {
150508
150709
  justify-content: center;
150509
150710
  opacity: 0.4;
150510
150711
  ">
150511
- <div style="font-size: 11px; color: #444; font-style: italic;">No active session</div>
150712
+ <div style="font-size: ${t.emptyState}; color: #444; font-style: italic;">No active session</div>
150512
150713
  </div>
150513
150714
  `;
150514
150715
  html += `
@@ -150548,17 +150749,17 @@ WARNING: This link could potentially be dangerous`)) {
150548
150749
  </div>
150549
150750
  <div style="flex: 3; min-width: 0; display: flex; flex-direction: column; gap: 4px;">
150550
150751
  <div>
150551
- <div style="font-weight: bold; color: #dde; font-size: 15px;">${agent.name}</div>
150552
- <div style="color: #778; font-size: 11px; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;">${agent.description}</div>
150752
+ <div style="font-weight: bold; color: #dde; font-size: ${t.cardTitle};">${agent.name}</div>
150753
+ <div style="color: #778; font-size: ${t.cardDescription}; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;">${agent.description}</div>
150553
150754
  </div>
150554
150755
  <div>
150555
150756
  <div style="display: flex; align-items: center; flex-wrap: wrap; margin-top: 4px;">
150556
150757
  <div style="
150557
- font-size: 11px;
150758
+ font-size: ${t.statusText};
150558
150759
  color: ${statusDot};
150559
150760
  display: flex; align-items: center; gap: 4px;
150560
150761
  ">
150561
- <span style="font-size: 8px;">\u25CF</span>
150762
+ <span style="font-size: ${t.statusDot};">\u25CF</span>
150562
150763
  <span>${statusIcon} ${statusLabel}</span>
150563
150764
  </div>
150564
150765
  ${elapsedHtml}
@@ -150587,7 +150788,9 @@ WARNING: This link could potentially be dangerous`)) {
150587
150788
  defaultClickHandler = {
150588
150789
  handleCardClick(agentId, context) {
150589
150790
  context.setSelectedAgent(agentId);
150590
- context.clearUnread(agentId);
150791
+ if (agentId !== "pc-terminal") {
150792
+ context.clearUnread(agentId);
150793
+ }
150591
150794
  context.updateContent();
150592
150795
  context.emitOpenTerminal(agentId);
150593
150796
  },
@@ -150605,9 +150808,11 @@ WARNING: This link could potentially be dangerous`)) {
150605
150808
  var init_FleetDashboard = __esm({
150606
150809
  "src/layouts/fleet/FleetDashboard.ts"() {
150607
150810
  "use strict";
150811
+ init_types();
150608
150812
  fleetDashboard = {
150609
150813
  renderCards(ctx) {
150610
150814
  const { agents, office, selectedAgentId, formatElapsed, formatRelativeTime } = ctx;
150815
+ const t = getDashboardTypography();
150611
150816
  let html = "";
150612
150817
  for (const agent of agents) {
150613
150818
  const liveStatus = office?.agents.get(agent.id);
@@ -150661,29 +150866,29 @@ WARNING: This link could potentially be dangerous`)) {
150661
150866
  const recentActions = liveStatus?.recentActions || [];
150662
150867
  const taskSummary = liveStatus?.taskSummary || "";
150663
150868
  const isActive = liveStatus?.state === "active" && liveStatus?.subState !== "ready" && liveStatus?.subState !== "error";
150664
- const elapsedHtml = elapsed ? `<span data-elapsed-agent="${agent.id}" style="color: #8a8; font-size: 10px; margin-left: 8px;">\u23F1 ${elapsed}</span>` : "";
150869
+ const elapsedHtml = elapsed ? `<span data-elapsed-agent="${agent.id}" style="color: #8a8; font-size: ${t.elapsed}; margin-left: 8px;">\u23F1 ${elapsed}</span>` : "";
150665
150870
  let activityLogHtml = "";
150666
150871
  const completedActions = recentActions.filter((a) => a.type === "completed").slice(-3).reverse();
150667
150872
  if (completedActions.length > 0) {
150668
150873
  const rows = completedActions.map((a) => {
150669
150874
  const relTime = formatRelativeTime(a.timestamp);
150670
- return `<div style="display: flex; gap: 8px; font-size: 10px; padding: 1px 0;" data-action-ts="${a.timestamp}">
150875
+ return `<div style="display: flex; gap: 8px; font-size: ${t.activityRow}; padding: 1px 0;" data-action-ts="${a.timestamp}">
150671
150876
  <span style="color: #445; flex-shrink: 0; min-width: 48px; text-align: right;">${relTime}</span>
150672
150877
  <span style="color: #5a5a7a;">\u2713 ${a.action}</span>
150673
150878
  </div>`;
150674
150879
  }).join("");
150675
150880
  activityLogHtml = `
150676
150881
  <div style="margin-top: 6px; padding-top: 6px; border-top: 1px solid #1a1a30;">
150677
- <div style="font-size: 9px; color: #3a3a5a; margin-bottom: 3px; text-transform: uppercase; letter-spacing: 0.5px;">Recent Activity</div>
150882
+ <div style="font-size: ${t.sectionLabel}; color: #3a3a5a; margin-bottom: 3px; text-transform: uppercase; letter-spacing: 0.5px;">Recent Activity</div>
150678
150883
  ${rows}
150679
150884
  </div>`;
150680
150885
  }
150681
150886
  const taskSummaryHtml = taskSummary && isActive ? `
150682
- <div style="font-size: 10px; color: #667; margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
150887
+ <div style="font-size: ${t.taskSummary}; color: #667; margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
150683
150888
  \u{1F4CB} ${taskSummary}
150684
150889
  </div>` : "";
150685
150890
  const arthurHint = isArthur ? `
150686
- <div style="font-size: 10px; color: #4af; margin-top: 4px; display: flex; align-items: center; gap: 4px;">
150891
+ <div style="font-size: ${t.arthurHint}; color: #4af; margin-top: 4px; display: flex; align-items: center; gap: 4px;">
150687
150892
  \u{1F4AC} Open Arthur's terminal
150688
150893
  </div>` : "";
150689
150894
  html += `
@@ -150721,17 +150926,17 @@ WARNING: This link could potentially be dangerous`)) {
150721
150926
  </div>
150722
150927
  <div style="flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px;">
150723
150928
  <div>
150724
- <div style="font-weight: bold; color: #dde; font-size: 14px;">${agent.name}</div>
150725
- <div style="color: #778; font-size: 10px; margin-top: 2px;">${agent.description}</div>
150929
+ <div style="font-weight: bold; color: #dde; font-size: ${t.cardTitle};">${agent.name}</div>
150930
+ <div style="color: #778; font-size: ${t.cardDescription}; margin-top: 2px;">${agent.description}</div>
150726
150931
  </div>
150727
150932
  <div>
150728
150933
  <div style="display: flex; align-items: center; flex-wrap: wrap; margin-top: 3px;">
150729
150934
  <div style="
150730
- font-size: 11px;
150935
+ font-size: ${t.statusText};
150731
150936
  color: ${statusDot};
150732
150937
  display: flex; align-items: center; gap: 4px;
150733
150938
  ">
150734
- <span style="font-size: 8px;">\u25CF</span>
150939
+ <span style="font-size: ${t.statusDot};">\u25CF</span>
150735
150940
  <span>${statusIcon} ${statusLabel}</span>
150736
150941
  </div>
150737
150942
  ${elapsedHtml}
@@ -151101,6 +151306,25 @@ WARNING: This link could potentially be dangerous`)) {
151101
151306
  this.currentFocus = "terminal";
151102
151307
  console.log("[InputManager] \u2500\u2500 switchToTerminal() complete \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
151103
151308
  }
151309
+ /**
151310
+ * Switch focus to a neutral dashboard mode.
151311
+ * - Deactivates Phaser keyboard
151312
+ * - Deactivates terminal shortcut intercepts
151313
+ * - Leaves global listener in 'none' mode
151314
+ */
151315
+ switchToNone(reason) {
151316
+ console.log(
151317
+ `[InputManager] \u2500\u2500 switchToNone() \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
151318
+ reason : "${reason}"
151319
+ from : "${this.currentFocus}"
151320
+ time : ${Date.now()}`
151321
+ );
151322
+ this.terminal.deactivateShortcuts();
151323
+ this.game.deactivate(reason);
151324
+ this.global.setMode("none");
151325
+ this.currentFocus = "none";
151326
+ console.log("[InputManager] \u2500\u2500 switchToNone() complete \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
151327
+ }
151104
151328
  /**
151105
151329
  * Install the F10-to-close handler. Should be called whenever a terminal
151106
151330
  * becomes visible (regardless of which side has keyboard focus — F10 always
@@ -151803,7 +152027,7 @@ WARNING: This link could potentially be dangerous`)) {
151803
152027
  function debugLog(scene, ...args) {
151804
152028
  if (scene.physics.world.drawDebug) console.log("[Debug]", ...args);
151805
152029
  }
151806
- var import_phaser8, ENABLE_DECORATIONS, ENABLE_BASKETBALL, ENABLE_GALAXIAN, ENABLE_ZOOM_BAR, OfficeScene;
152030
+ var import_phaser8, ENABLE_DECORATIONS, ENABLE_BASKETBALL, ENABLE_GALAXIAN, ENABLE_ZOOM_BAR, PC_TERMINAL_ID, OfficeScene;
151807
152031
  var init_OfficeScene = __esm({
151808
152032
  "src/scenes/OfficeScene.ts"() {
151809
152033
  "use strict";
@@ -151826,6 +152050,7 @@ WARNING: This link could potentially be dangerous`)) {
151826
152050
  ENABLE_BASKETBALL = false;
151827
152051
  ENABLE_GALAXIAN = true;
151828
152052
  ENABLE_ZOOM_BAR = true;
152053
+ PC_TERMINAL_ID = "pc-terminal";
151829
152054
  OfficeScene = class extends import_phaser8.default.Scene {
151830
152055
  constructor() {
151831
152056
  super({ key: "OfficeScene" });
@@ -151859,11 +152084,32 @@ WARNING: This link could potentially be dangerous`)) {
151859
152084
  this.walkInTimers = [];
151860
152085
  this.walkInAgents = [];
151861
152086
  this.skipButton = null;
152087
+ this.isPortraitDashboardMode = false;
151862
152088
  }
151863
152089
  setAnimating(value) {
151864
152090
  this.animating = value;
151865
152091
  this.game.registry.set("animating", value);
151866
152092
  }
152093
+ handleLayoutChange(payload) {
152094
+ const next = payload?.layoutKey === "portrait-dashboard";
152095
+ if (next === this.isPortraitDashboardMode) return;
152096
+ this.isPortraitDashboardMode = next;
152097
+ if (next) {
152098
+ this.player.disableMovement();
152099
+ this.playerMovementEnabled = false;
152100
+ this.inputManager.switchToNone("layout:portrait-dashboard");
152101
+ this.physics.world.pause();
152102
+ this.anims.pauseAll();
152103
+ return;
152104
+ }
152105
+ this.physics.world.resume();
152106
+ this.anims.resumeAll();
152107
+ if (!this.terminalOverlay.getIsVisible() && this.playerInScene) {
152108
+ this.player.enableMovement();
152109
+ this.playerMovementEnabled = true;
152110
+ this.inputManager.switchToGame("layout:default");
152111
+ }
152112
+ }
151867
152113
  create() {
151868
152114
  const screenWidth = this.cameras.main.width;
151869
152115
  const screenHeight = this.cameras.main.height;
@@ -152042,6 +152288,10 @@ WARNING: This link could potentially be dangerous`)) {
152042
152288
  this.instructionText.setOrigin(0.5, 1);
152043
152289
  this.instructionText.setDepth(Depths.UI_OVERLAY);
152044
152290
  this.game.events.on("open:agent:terminal", (agentId) => {
152291
+ if (agentId === PC_TERMINAL_ID) {
152292
+ this.openPlayerPcTerminal();
152293
+ return;
152294
+ }
152045
152295
  if (this.currentLayout === "fleet-vteam" && agentId !== "architect") return;
152046
152296
  const agents = getLayout(this.currentLayout).agents;
152047
152297
  const agent = agents.find((a) => a.id === agentId);
@@ -152129,6 +152379,10 @@ WARNING: This link could potentially be dangerous`)) {
152129
152379
  console.log("[OfficeScene] Fleet complete!");
152130
152380
  }, this);
152131
152381
  this.game.events.on("game:panel:clicked", () => {
152382
+ if (this.isPortraitDashboardMode) {
152383
+ this.inputManager.switchToNone("game:panel:clicked mobile lock");
152384
+ return;
152385
+ }
152132
152386
  debugLog(this, `game:panel:clicked \u2014 blurring terminal`);
152133
152387
  this.terminalOverlay.blurTerminal();
152134
152388
  if (this.playerInScene) {
@@ -152149,6 +152403,7 @@ WARNING: This link could potentially be dangerous`)) {
152149
152403
  this.playerMovementEnabled = true;
152150
152404
  }
152151
152405
  }, this);
152406
+ this.game.events.on("layout:change", this.handleLayoutChange, this);
152152
152407
  this.input.on("pointerup", (_pointer, currentlyOver) => {
152153
152408
  if (this.cameraDrag?.wasDragging()) return;
152154
152409
  const clickedNPC = currentlyOver.find((go) => go instanceof NPC);
@@ -152156,6 +152411,13 @@ WARNING: This link could potentially be dangerous`)) {
152156
152411
  this.startConversation(clickedNPC.config);
152157
152412
  return;
152158
152413
  }
152414
+ const clickedPcTerminal = this.desks.some(
152415
+ (desk) => desk.agentId === PC_TERMINAL_ID && currentlyOver.includes(desk.sprite)
152416
+ );
152417
+ if (clickedPcTerminal) {
152418
+ this.openPlayerPcTerminal();
152419
+ return;
152420
+ }
152159
152421
  if (this.currentLayout === "default") {
152160
152422
  for (const desk of this.desks) {
152161
152423
  if (!desk.agentId.startsWith("unassigned-")) continue;
@@ -152220,6 +152482,7 @@ WARNING: This link could potentially be dangerous`)) {
152220
152482
  this.bgMusic?.stop();
152221
152483
  this.game.events.off("bgm:volume");
152222
152484
  this.game.events.off("bgm:mute");
152485
+ this.game.events.off("layout:change", this.handleLayoutChange, this);
152223
152486
  this.disposeFleetPipeline();
152224
152487
  this.game.events.off("zoom:change");
152225
152488
  this.cameraDrag?.destroy();
@@ -152427,6 +152690,13 @@ WARNING: This link could potentially be dangerous`)) {
152427
152690
  }
152428
152691
  const bossPC = addDecor(bossDeskX, bossDeskY - 2 * scale, "desktop_pc");
152429
152692
  bossPC.setDepth(ySortDepth(bossDeskY, worldH) + 0.1);
152693
+ bossPC.setInteractive({ useHandCursor: true, pixelPerfect: false });
152694
+ this.desks.push({
152695
+ sprite: bossPC,
152696
+ agentId: PC_TERMINAL_ID,
152697
+ x: bossDeskX,
152698
+ y: bossDeskY - 2 * scale
152699
+ });
152430
152700
  addDecor(bossDeskX, bossDeskY + this.tileSize, "chair").setDepth(ySortDepth(bossDeskY + this.tileSize + 16 * scale, worldH));
152431
152701
  if (ENABLE_DECORATIONS) {
152432
152702
  addDecor(2 * this.tileSize + this.tileSize / 2, 2 * this.tileSize + this.tileSize / 2, "plant");
@@ -153326,6 +153596,9 @@ WARNING: This link could potentially be dangerous`)) {
153326
153596
  }
153327
153597
  }
153328
153598
  update() {
153599
+ if (this.isPortraitDashboardMode) {
153600
+ return;
153601
+ }
153329
153602
  if (!this.playerInScene || this.basketballGame.getIsVisible() || this.galaxianGame.getIsVisible() || !this.playerMovementEnabled) {
153330
153603
  return;
153331
153604
  }
@@ -153345,6 +153618,10 @@ WARNING: This link could potentially be dangerous`)) {
153345
153618
  this.updateExitDoorProximity();
153346
153619
  if (import_phaser8.default.Input.Keyboard.JustDown(this.interactKey)) {
153347
153620
  if (this.terminalOverlay.getIsVisible()) {
153621
+ if (this.nearestDesk?.agentId === PC_TERMINAL_ID) {
153622
+ this.openPlayerPcTerminal();
153623
+ return;
153624
+ }
153348
153625
  const targetAgent = this.nearestNPC?.config ?? (this.nearestDesk ? AGENTS.find((a) => a.id === this.nearestDesk.agentId) : null) ?? null;
153349
153626
  if (targetAgent) {
153350
153627
  this.startConversation(targetAgent);
@@ -153358,6 +153635,10 @@ WARNING: This link could potentially be dangerous`)) {
153358
153635
  } else if (this.nearestNPC) {
153359
153636
  this.startConversation(this.nearestNPC.config);
153360
153637
  } else if (this.nearestDesk) {
153638
+ if (this.nearestDesk.agentId === PC_TERMINAL_ID) {
153639
+ this.openPlayerPcTerminal();
153640
+ return;
153641
+ }
153361
153642
  const agent = AGENTS.find((a) => a.id === this.nearestDesk.agentId);
153362
153643
  if (agent) {
153363
153644
  this.startConversation(agent);
@@ -153592,6 +153873,37 @@ WARNING: This link could potentially be dangerous`)) {
153592
153873
  }
153593
153874
  );
153594
153875
  }
153876
+ openPlayerPcTerminal() {
153877
+ if (this.currentLayout !== "default") return;
153878
+ const workingDir = officeManager.getCurrentWorkingDirectory();
153879
+ const pcTerminalConfig = {
153880
+ id: PC_TERMINAL_ID,
153881
+ name: "PC TERMINAL",
153882
+ skill: "general",
153883
+ sprite: "desktop_pc",
153884
+ color: 6138367,
153885
+ position: { x: 10, y: 2 },
153886
+ greeting: "PC terminal ready.",
153887
+ description: "Local Shell",
153888
+ workingDir
153889
+ };
153890
+ this.playerMovementEnabled = false;
153891
+ if (this.playerInScene) {
153892
+ this.player.disableMovement();
153893
+ }
153894
+ this.cameraDrag?.disable();
153895
+ this.terminalOverlay.show(
153896
+ pcTerminalConfig,
153897
+ () => {
153898
+ this.playerMovementEnabled = true;
153899
+ if (this.playerInScene) {
153900
+ this.player.enableMovement();
153901
+ }
153902
+ this.applyZoom(this.cameras.main.zoom);
153903
+ },
153904
+ { launchMode: "shell" }
153905
+ );
153906
+ }
153595
153907
  enterMeeting() {
153596
153908
  this.playerMovementEnabled = false;
153597
153909
  if (this.playerInScene) {
@@ -154261,6 +154573,21 @@ WARNING: This link could potentially be dangerous`)) {
154261
154573
  }
154262
154574
  });
154263
154575
 
154576
+ // src/config/responsiveLayout.ts
154577
+ function computeResponsiveLayout(width, height) {
154578
+ const safeHeight = Math.max(1, height);
154579
+ const ratio = width / safeHeight;
154580
+ return ratio <= PORTRAIT_RATIO_THRESHOLD || width <= PORTRAIT_WIDTH_THRESHOLD_PX ? "portrait-dashboard" : "default";
154581
+ }
154582
+ var PORTRAIT_RATIO_THRESHOLD, PORTRAIT_WIDTH_THRESHOLD_PX;
154583
+ var init_responsiveLayout = __esm({
154584
+ "src/config/responsiveLayout.ts"() {
154585
+ "use strict";
154586
+ PORTRAIT_RATIO_THRESHOLD = 0.9;
154587
+ PORTRAIT_WIDTH_THRESHOLD_PX = 600;
154588
+ }
154589
+ });
154590
+
154264
154591
  // src/ui/ToastNotification.ts
154265
154592
  var MAX_VISIBLE, AUTO_DISMISS_MS, ANIMATION_MS, RATE_LIMIT_WINDOW_MS, RATE_LIMIT_MAX, ToastNotificationManager;
154266
154593
  var init_ToastNotification = __esm({
@@ -155125,6 +155452,7 @@ WARNING: This link could potentially be dangerous`)) {
155125
155452
  init_MeetingScene();
155126
155453
  init_officeManager();
155127
155454
  init_agents();
155455
+ init_responsiveLayout();
155128
155456
  init_layouts();
155129
155457
  init_ToastNotification();
155130
155458
  init_NotificationService();
@@ -155158,6 +155486,7 @@ WARNING: This link could potentially be dangerous`)) {
155158
155486
  var debugMode = false;
155159
155487
  var currentZoom = parseFloat(localStorage.getItem("agencyOffice:zoomLevel") ?? "0.8");
155160
155488
  currentZoom = isNaN(currentZoom) || currentZoom < 0.5 || currentZoom > 2 ? 0.8 : currentZoom;
155489
+ var RESIZE_DEBOUNCE_MS = 200;
155161
155490
  var agentPreloadStatus = /* @__PURE__ */ new Map();
155162
155491
  var pendingStatusBarUpdate = false;
155163
155492
  var pendingTerminalContentUpdate = false;
@@ -155223,6 +155552,61 @@ WARNING: This link could potentially be dangerous`)) {
155223
155552
  position: relative;
155224
155553
  `;
155225
155554
  mainContent.appendChild(terminalPanel);
155555
+ var currentResponsiveLayout = "default";
155556
+ var resizeDebounceTimer = null;
155557
+ function isMobileModeActive() {
155558
+ return currentResponsiveLayout === "portrait-dashboard";
155559
+ }
155560
+ function applyMobileTopBarVisibility() {
155561
+ const hidden = isMobileModeActive();
155562
+ const ids = ["zoom-bar", "sprite-customizer-btn", "debug-toggle-btn"];
155563
+ for (const id of ids) {
155564
+ const el = document.getElementById(id);
155565
+ if (!el) continue;
155566
+ el.style.display = hidden ? "none" : "";
155567
+ }
155568
+ }
155569
+ function applyResponsiveLayout(layoutKey) {
155570
+ if (layoutKey === currentResponsiveLayout) return;
155571
+ currentResponsiveLayout = layoutKey;
155572
+ if (layoutKey === "portrait-dashboard") {
155573
+ officePanel.style.display = "none";
155574
+ terminalPanel.style.width = "100%";
155575
+ terminalPanel.style.borderLeft = "none";
155576
+ } else {
155577
+ officePanel.style.display = "";
155578
+ terminalPanel.style.width = "50%";
155579
+ terminalPanel.style.borderLeft = "2px solid #333";
155580
+ }
155581
+ if (phaserGameRef) {
155582
+ phaserGameRef.events.emit("layout:change", { layoutKey });
155583
+ if (layoutKey === "default") {
155584
+ const width = officePanel.clientWidth || window.innerWidth / 2;
155585
+ const height = officePanel.clientHeight || window.innerHeight;
155586
+ phaserGameRef.scale.resize(width, height);
155587
+ }
155588
+ }
155589
+ applyMobileTopBarVisibility();
155590
+ }
155591
+ function onWindowResize() {
155592
+ if (resizeDebounceTimer !== null) {
155593
+ window.clearTimeout(resizeDebounceTimer);
155594
+ }
155595
+ resizeDebounceTimer = window.setTimeout(() => {
155596
+ const next = computeResponsiveLayout(window.innerWidth, window.innerHeight);
155597
+ applyResponsiveLayout(next);
155598
+ if (phaserGameRef && currentResponsiveLayout === "default") {
155599
+ const width = officePanel.clientWidth || window.innerWidth / 2;
155600
+ const height = officePanel.clientHeight || window.innerHeight;
155601
+ phaserGameRef.scale.resize(width, height);
155602
+ }
155603
+ }, RESIZE_DEBOUNCE_MS);
155604
+ }
155605
+ applyResponsiveLayout(computeResponsiveLayout(window.innerWidth, window.innerHeight));
155606
+ window.addEventListener("resize", onWindowResize);
155607
+ if (typeof window !== "undefined") {
155608
+ window.__copilotOfficeMobileModeActive = isMobileModeActive;
155609
+ }
155226
155610
  function renderOfficeTabs() {
155227
155611
  const offices = officeManager.getAllOffices();
155228
155612
  const currentId = officeManager.currentOfficeId;
@@ -155369,7 +155753,9 @@ WARNING: This link could potentially be dangerous`)) {
155369
155753
  debugMode = !debugMode;
155370
155754
  phaserGame?.events.emit("debug:toggle", debugMode);
155371
155755
  renderOfficeTabs();
155372
- phaserGame?.events.emit("game:panel:clicked");
155756
+ if (!isMobileModeActive()) {
155757
+ phaserGame?.events.emit("game:panel:clicked");
155758
+ }
155373
155759
  console.log(`[Debug] Debug mode ${debugMode ? "ON" : "OFF"}`);
155374
155760
  });
155375
155761
  const zoomSlider = document.getElementById("zoom-slider");
@@ -155405,6 +155791,7 @@ WARNING: This link could potentially be dangerous`)) {
155405
155791
  spriteCustomizerPanel.updatePreview(base64);
155406
155792
  }
155407
155793
  });
155794
+ applyMobileTopBarVisibility();
155408
155795
  }
155409
155796
  function switchToOffice(officeId) {
155410
155797
  if (phaserGame?.registry.get("animating")) {
@@ -155830,6 +156217,19 @@ WARNING: This link could potentially be dangerous`)) {
155830
156217
  ctx.drawImage(source, 0, 0);
155831
156218
  }
155832
156219
  }
156220
+ const pcCanvas = document.getElementById("overview-sprite-pc-terminal");
156221
+ if (pcCanvas) {
156222
+ const ctx = pcCanvas.getContext("2d");
156223
+ if (!ctx) return;
156224
+ const texture = phaserGameRef.textures.get("desktop_pc");
156225
+ if (!texture || texture.key === "__MISSING") return;
156226
+ const source = texture.getSourceImage();
156227
+ if (source) {
156228
+ ctx.imageSmoothingEnabled = false;
156229
+ ctx.clearRect(0, 0, pcCanvas.width, pcCanvas.height);
156230
+ ctx.drawImage(source, 0, 0);
156231
+ }
156232
+ }
155833
156233
  }, 50);
155834
156234
  }
155835
156235
  function setupTerminalClickHandler() {
@@ -156250,11 +156650,13 @@ WARNING: This link could potentially be dangerous`)) {
156250
156650
  canvas?.focus();
156251
156651
  });
156252
156652
  officePanel.addEventListener("mousedown", () => {
156653
+ if (isMobileModeActive()) return;
156253
156654
  console.log("[main] game panel mousedown \u2014 emitting game:panel:clicked");
156254
156655
  phaserGame?.events.emit("game:panel:clicked");
156255
156656
  });
156256
156657
  phaserGame.events.once("ready", () => {
156257
156658
  drawOverviewSprites();
156659
+ phaserGame.events.emit("layout:change", { layoutKey: currentResponsiveLayout });
156258
156660
  });
156259
156661
  window.addEventListener("focus", () => {
156260
156662
  catchUpStatusViews("window focus");