Toby Chui 5 дней назад
Родитель
Сommit
3e2b8e9ce3

+ 21 - 0
src/web/Arozcast/index.html

@@ -264,6 +264,27 @@
             height: 100%; background: var(--accent);
             height: 100%; background: var(--accent);
             transition: width .5s linear;
             transition: width .5s linear;
         }
         }
+
+        /* ── Mobile / responsive ─────────────────────────────────────── */
+        @media (max-width: 600px) {
+            .waiting-screen { padding: 24px; }
+            .brand-logo { margin-bottom: 28px; gap: 10px; }
+            .brand-name { font-size: 22px; }
+            .brand-logo .cast-icon { width: 48px !important; }
+            .code-label { font-size: 12px; margin-bottom: 12px; }
+            .code-display { gap: 8px; margin-bottom: 24px; }
+            /* Shrink the code tiles so three of them never overflow a phone screen */
+            .code-digit { width: 18vw; max-width: 64px; height: 24vw; max-height: 80px; font-size: 11vw; border-radius: 11px; }
+            .waiting-hint { font-size: 13px; }
+            .track-name { font-size: 18px; max-width: 80vw; }
+            .track-artist { font-size: 13px; }
+            /* Toolbar hugs the screen width with a small inset on each side */
+            .toolbar { bottom: 16px; gap: 6px; padding: 7px 12px; min-width: 0; max-width: none; width: calc(100vw - 24px); }
+            .tb-btn { width: 34px; height: 34px; }
+            .tb-filename { font-size: 12px; }
+            .disconnected-banner { font-size: 10px; padding: 5px 14px; max-width: calc(100vw - 24px); white-space: normal; text-align: center; }
+            .disconnected-notice { max-width: calc(100vw - 48px); }
+        }
     </style>
     </style>
 </head>
 </head>
 <body>
 <body>

+ 11 - 0
src/web/Arozcast/screenshare.html

@@ -118,6 +118,17 @@
         #codeInput{
         #codeInput{
             width: 100%;
             width: 100%;
         }
         }
+
+        /* ── Mobile / responsive ─────────────────────────────────────── */
+        @media (max-width: 420px) {
+            html, body { padding: 16px; }
+            .header { margin-bottom: 24px; gap: 12px; }
+            .card { padding: 18px; }
+            .code-input { font-size: 24px; padding: 11px 12px; }
+            /* Stack the share controls so the labels never get clipped */
+            .controls-row { flex-wrap: wrap; }
+            .controls-row .btn { flex: 1 1 100%; }
+        }
     </style>
     </style>
 </head>
 </head>
 <body>
 <body>

+ 51 - 3
src/web/Calendar/index.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 <head>
 <head>
 <meta charset="UTF-8">
 <meta charset="UTF-8">
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=resizes-content">
 <title>Calendar</title>
 <title>Calendar</title>
 <script src="../script/jquery.min.js"></script>
 <script src="../script/jquery.min.js"></script>
 <script src="../script/ao_module.js"></script>
 <script src="../script/ao_module.js"></script>
@@ -31,7 +31,11 @@ body.dark{
   --ev-purple-bg:rgba(168,85,247,.18);--ev-purple-bd:#c084fc;--ev-purple-tx:#d8b4fe;
   --ev-purple-bg:rgba(168,85,247,.18);--ev-purple-bd:#c084fc;--ev-purple-tx:#d8b4fe;
   --ev-teal-bg:rgba(20,184,166,.18);--ev-teal-bd:#2dd4bf;--ev-teal-tx:#5eead4;
   --ev-teal-bg:rgba(20,184,166,.18);--ev-teal-bd:#2dd4bf;--ev-teal-tx:#5eead4;
 }
 }
-body{font-family:-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI',sans-serif;background:var(--bg);color:var(--text);height:100vh;overflow:hidden;display:grid;grid-template-rows:52px 1fr}
+body{font-family:-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI',sans-serif;background:var(--bg);color:var(--text);height:100vh;height:100dvh;overflow:hidden;display:grid;grid-template-rows:52px 1fr}
+
+/* HAMBURGER — only shown on narrow screens (see media query) */
+.menu-btn{display:none;background:none;border:none;cursor:pointer;padding:5px 6px;border-radius:var(--r3);color:var(--accent);line-height:1;align-items:center}
+.menu-btn:hover{background:var(--hover2)}
 
 
 /* TOOLBAR */
 /* TOOLBAR */
 #toolbar{display:flex;align-items:center;gap:6px;padding:0 14px;border-bottom:1px solid var(--border);background:var(--bg2);user-select:none;flex-shrink:0}
 #toolbar{display:flex;align-items:center;gap:6px;padding:0 14px;border-bottom:1px solid var(--border);background:var(--bg2);user-select:none;flex-shrink:0}
@@ -209,11 +213,45 @@ body{font-family:-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI',sa
 /* SNACKBAR */
 /* SNACKBAR */
 #snackbar{position:fixed;bottom:24px;left:50%;transform:translateX(-50%) translateY(12px);padding:8px 18px;border-radius:10px;font-size:13px;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;z-index:9999;background:var(--text);color:var(--bg);white-space:nowrap}
 #snackbar{position:fixed;bottom:24px;left:50%;transform:translateX(-50%) translateY(12px);padding:8px 18px;border-radius:10px;font-size:13px;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;z-index:9999;background:var(--text);color:var(--bg);white-space:nowrap}
 #snackbar.show{opacity:1;transform:translateX(-50%) translateY(0)}
 #snackbar.show{opacity:1;transform:translateX(-50%) translateY(0)}
+
+/* SIDEBAR BACKDROP (mobile off-canvas) */
+#sidebarScrim{display:none}
+
+/* ── MOBILE / RESPONSIVE ─────────────────────────────────────────────── */
+@media (max-width:768px){
+  /* Toolbar: drop the title, let it wrap so the view switcher gets its own row */
+  body{grid-template-rows:auto 1fr}
+  #toolbar{flex-wrap:wrap;padding:6px 10px;gap:5px 6px}
+  .app-title{display:none}
+  .menu-btn{display:inline-flex}
+  .period-label{flex:1;min-width:0;font-size:14px;text-align:left}
+  .tb-spacer{display:none}
+  /* The view switcher wraps to a full-width second row */
+  .view-switcher{order:1;flex:1 1 100%}
+  .view-btn{flex:1;text-align:center}
+  .tb-btn{font-size:21px;padding:5px 6px}
+
+  /* Main area becomes single-column; sidebar slides in over the content */
+  #main{grid-template-columns:1fr}
+  #sidebar{position:fixed;top:0;left:0;z-index:40;height:100vh;height:100dvh;width:80vw;max-width:280px;transform:translateX(-100%);transition:transform .22s ease;box-shadow:var(--shadow)}
+  #sidebar.open{transform:translateX(0)}
+  #sidebarScrim{display:block;position:fixed;inset:0;z-index:39;background:rgba(0,0,0,.5);opacity:0;pointer-events:none;transition:opacity .2s}
+  #sidebarScrim.open{opacity:1;pointer-events:auto}
+
+  /* Roomier cells / tap targets */
+  .month-cell{min-height:0;padding:3px}
+  .wk-dd{font-size:18px}
+  .sb-btn{padding:9px 8px}
+  .modal{width:100%;max-width:calc(100vw - 24px)}
+}
 </style>
 </style>
 </head>
 </head>
 <body>
 <body>
 
 
 <header id="toolbar">
 <header id="toolbar">
+  <button class="menu-btn" title="Menu" onclick="toggleSidebar()">
+    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
+  </button>
   <span class="app-title" locale="calendar/app/title">Calendar</span>
   <span class="app-title" locale="calendar/app/title">Calendar</span>
   <button class="today-btn" onclick="goToday()" locale="calendar/btn/today">Today</button>
   <button class="today-btn" onclick="goToday()" locale="calendar/btn/today">Today</button>
   <button class="tb-btn" onclick="navPrev()">&#8249;</button>
   <button class="tb-btn" onclick="navPrev()">&#8249;</button>
@@ -254,6 +292,9 @@ body{font-family:-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI',sa
   <div id="viewArea"></div>
   <div id="viewArea"></div>
 </div>
 </div>
 
 
+<!-- Backdrop for the mobile off-canvas sidebar -->
+<div id="sidebarScrim" onclick="closeSidebar()"></div>
+
 <!-- Event Modal -->
 <!-- Event Modal -->
 <div class="modal-back hidden" id="eventModal">
 <div class="modal-back hidden" id="eventModal">
   <div class="modal">
   <div class="modal">
@@ -464,6 +505,10 @@ function applyDark(dark){
 }
 }
 function toggleDark(){ applyDark(!S.dark); }
 function toggleDark(){ applyDark(!S.dark); }
 
 
+// ── Mobile off-canvas sidebar (no-op on desktop where it's a static column) ──
+function toggleSidebar(){ document.getElementById('sidebar').classList.toggle('open'); document.getElementById('sidebarScrim').classList.toggle('open'); }
+function closeSidebar(){ document.getElementById('sidebar').classList.remove('open'); document.getElementById('sidebarScrim').classList.remove('open'); }
+
 // ── Mini calendar ─────────────────────────────────────────────────────
 // ── Mini calendar ─────────────────────────────────────────────────────
 function renderMiniCal(){
 function renderMiniCal(){
   var a=S.miniCalAnchor, y=a.getFullYear(), mo=a.getMonth();
   var a=S.miniCalAnchor, y=a.getFullYear(), mo=a.getMonth();
@@ -493,7 +538,7 @@ function getViewDays(){
 }
 }
 function mcPrev(){ S.miniCalAnchor=new Date(S.miniCalAnchor.getFullYear(),S.miniCalAnchor.getMonth()-1,1); renderMiniCal(); }
 function mcPrev(){ S.miniCalAnchor=new Date(S.miniCalAnchor.getFullYear(),S.miniCalAnchor.getMonth()-1,1); renderMiniCal(); }
 function mcNext(){ S.miniCalAnchor=new Date(S.miniCalAnchor.getFullYear(),S.miniCalAnchor.getMonth()+1,1); renderMiniCal(); }
 function mcNext(){ S.miniCalAnchor=new Date(S.miniCalAnchor.getFullYear(),S.miniCalAnchor.getMonth()+1,1); renderMiniCal(); }
-function mcDayClick(y,mo,day){ S.anchor=new Date(y,mo,day); S.miniCalAnchor=new Date(y,mo,1); render(); }
+function mcDayClick(y,mo,day){ S.anchor=new Date(y,mo,day); S.miniCalAnchor=new Date(y,mo,1); render(); closeSidebar(); }
 
 
 // ── Navigation ────────────────────────────────────────────────────────
 // ── Navigation ────────────────────────────────────────────────────────
 function goToday(){ S.anchor=new Date(); S.miniCalAnchor=new Date(S.anchor.getFullYear(),S.anchor.getMonth(),1); render(); }
 function goToday(){ S.anchor=new Date(); S.miniCalAnchor=new Date(S.anchor.getFullYear(),S.anchor.getMonth(),1); render(); }
@@ -1146,6 +1191,7 @@ function exportICS(){
     lines.push('END:VEVENT');
     lines.push('END:VEVENT');
   });
   });
   lines.push('END:VCALENDAR');
   lines.push('END:VCALENDAR');
+  closeSidebar();
   var blob=new Blob([lines.join('\r\n')],{type:'text/calendar;charset=utf-8'});
   var blob=new Blob([lines.join('\r\n')],{type:'text/calendar;charset=utf-8'});
   var url=URL.createObjectURL(blob), a=document.createElement('a');
   var url=URL.createObjectURL(blob), a=document.createElement('a');
   a.href=url; a.download='calendar.ics'; document.body.appendChild(a); a.click();
   a.href=url; a.download='calendar.ics'; document.body.appendChild(a); a.click();
@@ -1153,12 +1199,14 @@ function exportICS(){
   snack(L('calendar/snack/exported-n','Exported {n} event(s)').replace('{n}',S.events.length));
   snack(L('calendar/snack/exported-n','Exported {n} event(s)').replace('{n}',S.events.length));
 }
 }
 function importFromComputer(){
 function importFromComputer(){
+  closeSidebar();
   ao_module_selectFiles(function(files){
   ao_module_selectFiles(function(files){
     if(!files||!files.length) return;
     if(!files||!files.length) return;
     var r=new FileReader(); r.onload=function(ev){ processICSText(ev.target.result); }; r.readAsText(files[0]);
     var r=new FileReader(); r.onload=function(ev){ processICSText(ev.target.result); }; r.readAsText(files[0]);
   },'file','.ics',false);
   },'file','.ics',false);
 }
 }
 function importFromFiles(){
 function importFromFiles(){
+  closeSidebar();
   ao_module_openFileSelector(function(sel){
   ao_module_openFileSelector(function(sel){
     if(!sel||!sel.length) return;
     if(!sel||!sel.length) return;
     apiImportIcs(sel[0].filepath||sel[0],function(resp){
     apiImportIcs(sel[0].filepath||sel[0],function(resp){

+ 2 - 0
src/web/SystemAO/advance/agi_runtime.html

@@ -19,6 +19,7 @@
                 white-space: nowrap;
                 white-space: nowrap;
             }
             }
             th.sortable:hover { background: rgba(0,0,0,0.04) !important; }
             th.sortable:hover { background: rgba(0,0,0,0.04) !important; }
+            body.dark th.sortable:hover { background: rgba(255,255,255,0.06) !important; }
             th.sortable .sort-icon {
             th.sortable .sort-icon {
                 display: inline-block;
                 display: inline-block;
                 margin-left: 4px;
                 margin-left: 4px;
@@ -42,6 +43,7 @@
                 font-size: 0.82em;
                 font-size: 0.82em;
                 color: #555;
                 color: #555;
             }
             }
+            body.dark .execid-cell { color: #9b9b9b; }
 
 
             /* ── Refresh bar ──────────────────────────────── */
             /* ── Refresh bar ──────────────────────────────── */
             .refresh-bar {
             .refresh-bar {

+ 3 - 6
src/web/SystemAO/info/license.html

@@ -13,7 +13,7 @@
 </head>
 </head>
 
 
 <body>
 <body>
-    <div class="ui container" id="sys-setting-page">
+    <div id="sys-setting-page">
         <div class="ui basic segment">
         <div class="ui basic segment">
             <div class="ui header">
             <div class="ui header">
                 Open Source Licenses
                 Open Source Licenses
@@ -21,12 +21,9 @@
             </div>
             </div>
         </div>
         </div>
         <div class="ui divider"></div>
         <div class="ui divider"></div>
+        <div id="mainarea"></div>
+        <br><br>
     </div>
     </div>
-    
-    <div id="mainarea" class="ui container">
-       
-    </div>
-    <br><br>
 </body>
 </body>
 <script>
 <script>
     $.get("../../system/info/license", function(data){
     $.get("../../system/info/license", function(data){

+ 3 - 2
src/web/SystemAO/iot/info.html

@@ -13,15 +13,16 @@
     </style>
     </style>
 </head>
 </head>
 <body>
 <body>
-    <div class="ui container" id="sys-setting-page">
+    <div id="sys-setting-page">
         <div class="ui basic segment">
         <div class="ui basic segment">
             <h3 class="ui header">
             <h3 class="ui header">
                 <span locale="locale/iot-hub-title">IoT Hub</span>
                 <span locale="locale/iot-hub-title">IoT Hub</span>
                 <div class="sub header" locale="locale/iot-hub-description">List of supported IoT protocol scanners for this Host</div>
                 <div class="sub header" locale="locale/iot-hub-description">List of supported IoT protocol scanners for this Host</div>
             </h3>
             </h3>
         </div>
         </div>
+        <div class="ui divider"></div>
         <div>
         <div>
-            <table class="ui celled  very basic compact table">
+            <table class="ui celled very basic compact table">
                 <thead>
                 <thead>
                   <tr>
                   <tr>
                     <th locale="locale/protocol-name">Protocol Name</th>
                     <th locale="locale/protocol-name">Protocol Name</th>