diff --git a/modules/cal/components/folk-calendar-view.ts b/modules/cal/components/folk-calendar-view.ts
index e6bce27..1344e47 100644
--- a/modules/cal/components/folk-calendar-view.ts
+++ b/modules/cal/components/folk-calendar-view.ts
@@ -186,7 +186,9 @@ class FolkCalendarView extends HTMLElement {
.moon { font-size: 10px; opacity: 0.7; }
.event-dot { width: 6px; height: 6px; border-radius: 50%; display: inline-block; margin: 1px; }
.event-dots { display: flex; flex-wrap: wrap; gap: 1px; }
- .event-label { font-size: 9px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #aaa; line-height: 1.4; }
+ .event-label { font-size: 9px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #aaa; line-height: 1.4; padding: 1px 3px; border-radius: 3px; cursor: pointer; }
+ .event-label:hover { background: rgba(255,255,255,0.08); }
+ .event-time { color: #666; font-size: 8px; margin-right: 2px; }
.event-modal {
position: fixed; top: 0; left: 0; right: 0; bottom: 0;
@@ -199,12 +201,30 @@ class FolkCalendarView extends HTMLElement {
.sources { display: flex; gap: 6px; margin-bottom: 12px; flex-wrap: wrap; }
.source-badge { font-size: 10px; padding: 3px 8px; border-radius: 10px; border: 1px solid #333; }
+
+ @media (max-width: 768px) {
+ .day { min-height: 56px; padding: 4px; }
+ .day-num { font-size: 11px; }
+ .event-label { display: none; }
+ .event-dot { width: 5px; height: 5px; }
+ .moon { font-size: 8px; }
+ .rapp-nav__title { font-size: 13px; }
+ }
+ @media (max-width: 480px) {
+ .day { min-height: 44px; padding: 3px; }
+ .day-num { font-size: 10px; }
+ .weekday { font-size: 9px; padding: 2px; }
+ .rapp-nav { gap: 4px; }
+ .toggle-btn { padding: 3px 6px; font-size: 10px; }
+ .source-badge { font-size: 8px; padding: 2px 6px; }
+ }
${this.error ? `
${this.esc(this.error)}
` : ""}
+
${monthName} ${year}
@@ -255,7 +275,11 @@ class FolkCalendarView extends HTMLElement {
${dayEvents.slice(0, 3).map(e => ``).join("")}
${dayEvents.length > 3 ? `+${dayEvents.length - 3}` : ""}
- ${dayEvents.slice(0, 2).map(e => `${this.esc(e.title)}
`).join("")}
+ ${dayEvents.slice(0, 2).map(e => {
+ const t = new Date(e.start_time);
+ const timeStr = `${t.getHours()}:${String(t.getMinutes()).padStart(2, "0")}`;
+ return `${timeStr}${this.esc(e.title)}
`;
+ }).join("")}
` : ""}
`;
}
@@ -290,6 +314,10 @@ class FolkCalendarView extends HTMLElement {
private attachListeners() {
this.shadow.getElementById("prev")?.addEventListener("click", () => this.navigate(-1));
this.shadow.getElementById("next")?.addEventListener("click", () => this.navigate(1));
+ this.shadow.getElementById("today")?.addEventListener("click", () => {
+ this.currentDate = new Date();
+ if (this.space === "demo") { this.loadDemoData(); } else { this.loadMonth(); }
+ });
this.shadow.getElementById("toggle-lunar")?.addEventListener("click", () => {
this.showLunar = !this.showLunar;
this.render();
diff --git a/modules/pubs/components/folk-pubs-editor.ts b/modules/pubs/components/folk-pubs-editor.ts
index 1c226fd..bd7edcc 100644
--- a/modules/pubs/components/folk-pubs-editor.ts
+++ b/modules/pubs/components/folk-pubs-editor.ts
@@ -481,14 +481,27 @@ export class FolkPubsEditor extends HTMLElement {
.format-detail .pages { color: #60a5fa; }
@media (max-width: 768px) {
- .editor-layout { flex-direction: column; }
+ :host { height: auto; min-height: calc(100vh - 92px); }
+ .editor-layout { flex-direction: column; height: auto; }
+ .editor-main { min-height: 0; }
.sidebar {
width: 100%;
border-left: none;
border-top: 1px solid #1e293b;
- max-height: 50vh;
+ max-height: none;
+ padding: 0.75rem;
}
- .content-area { min-height: 40vh; }
+ .content-area { min-height: 45vh; }
+ .toolbar-left { flex-direction: column; gap: 0.375rem; }
+ .title-input, .author-input { max-width: 100%; flex: 1; }
+ .editor-toolbar { gap: 0.5rem; }
+ .format-grid { grid-template-columns: repeat(3, 1fr); }
+ .btn-generate { font-size: 0.8rem; padding: 0.5rem; }
+ }
+ @media (max-width: 480px) {
+ .format-grid { grid-template-columns: 1fr 1fr; }
+ .toolbar-right { width: 100%; }
+ .btn-sample, .btn-upload { flex: 1; text-align: center; }
}
`;
}
diff --git a/modules/tube/components/folk-video-player.ts b/modules/tube/components/folk-video-player.ts
index f7efac0..ba1017d 100644
--- a/modules/tube/components/folk-video-player.ts
+++ b/modules/tube/components/folk-video-player.ts
@@ -8,7 +8,7 @@
class FolkVideoPlayer extends HTMLElement {
private shadow: ShadowRoot;
private space = "demo";
- private videos: Array<{ name: string; size: number }> = [];
+ private videos: Array<{ name: string; size: number; duration?: string; date?: string }> = [];
private currentVideo: string | null = null;
private mode: "library" | "live" = "library";
private streamKey = "";
@@ -29,13 +29,14 @@ class FolkVideoPlayer extends HTMLElement {
private loadDemoData() {
this.isDemo = true;
this.videos = [
- { name: "community-meeting-2026-02-15.mp4", size: 524288000 },
- { name: "rspace-demo-walkthrough.mp4", size: 157286400 },
- { name: "design-sprint-day1.webm", size: 892108800 },
- { name: "interview-cosmolocal-founders.mp4", size: 1073741824 },
- { name: "workshop-local-first-data.mp4", size: 734003200 },
- { name: "lightning-talks-feb2026.webm", size: 445644800 },
+ { name: "community-meeting-2026-02-15.mp4", size: 524288000, duration: "1:23:45", date: "Feb 15, 2026" },
+ { name: "rspace-demo-walkthrough.mp4", size: 157286400, duration: "18:32", date: "Feb 12, 2026" },
+ { name: "design-sprint-day1.webm", size: 892108800, duration: "2:45:10", date: "Feb 10, 2026" },
+ { name: "interview-cosmolocal-founders.mp4", size: 1073741824, duration: "52:18", date: "Feb 7, 2026" },
+ { name: "workshop-local-first-data.mp4", size: 734003200, duration: "1:35:42", date: "Feb 3, 2026" },
+ { name: "lightning-talks-feb2026.webm", size: 445644800, duration: "42:15", date: "Jan 28, 2026" },
];
+ this.currentVideo = this.videos[0].name;
this.render();
}
@@ -72,7 +73,7 @@ class FolkVideoPlayer extends HTMLElement {
:host { display: block; min-height: 60vh; font-family: system-ui, sans-serif; color: #e2e8f0; }
.container { max-width: 1200px; margin: 0 auto; }
.rapp-nav { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; min-height: 36px; }
- .rapp-nav__title { font-size: 15px; font-weight: 600; color: #e2e8f0; flex: 1; }
+ .rapp-nav__title { font-size: 13px; font-weight: 500; color: #64748b; flex: 1; text-align: right; }
.tab { padding: 0.5rem 1.25rem; border-radius: 8px; border: 1px solid #334155; background: transparent; color: #94a3b8; cursor: pointer; font-size: 0.875rem; }
.tab.active { background: #ef4444; color: white; border-color: #ef4444; }
.layout { display: grid; grid-template-columns: 300px 1fr; gap: 1.5rem; }
@@ -109,7 +110,8 @@ class FolkVideoPlayer extends HTMLElement {
-
+ ${!this.isDemo ? `` : ""}
+ ${this.isDemo ? `${this.videos.length} recordings` : ""}
${this.mode === "library" ? this.renderLibrary() : this.renderLive()}
@@ -129,7 +131,7 @@ class FolkVideoPlayer extends HTMLElement {
: filteredVideos.map((v) => `
${v.name}
-
${this.getExtension(v.name).toUpperCase()} · ${this.formatSize(v.size)}
+
${this.getExtension(v.name).toUpperCase()} · ${this.formatSize(v.size)}${v.duration ? ` · ${v.duration}` : ""}${v.date ? `
${v.date}` : ""}
`).join("");
@@ -141,7 +143,16 @@ class FolkVideoPlayer extends HTMLElement {
} else if (this.isDemo) {
const selectedVideo = this.videos.find(v => v.name === this.currentVideo);
const sizeStr = selectedVideo ? this.formatSize(selectedVideo.size) : "";
- player = `🎦
${this.currentVideo}
${this.getExtension(this.currentVideo).toUpperCase()} · ${sizeStr}
Demo mode — no actual video file
`;
+ const durStr = selectedVideo?.duration || "";
+ player = `
+
+
${this.currentVideo}
+
${this.getExtension(this.currentVideo).toUpperCase()} · ${sizeStr}${durStr ? ` · ${durStr}` : ""}
+ ${selectedVideo?.date ? `
Recorded ${selectedVideo.date}
` : ""}
+
Demo preview — connect rTube to stream real video
+
`;
} else if (!this.isPlayable(this.currentVideo)) {
player = `⚠️
${this.getExtension(this.currentVideo).toUpperCase()} files cannot play in browsers
Download to play locally
`;
} else {