openvibers/openvibe.live Commits
AI Moments and Content: the subtitle stays whole on a phone (#710)
Changes
@@@ -483,7 +483,8 @@ a.cf-recap-band:hover .cf-recap-sub { text-decoration: underline; text-underline.cf-wrap { padding: 12px 12px 40px; --cf-gap: 14px; }.cf-head { margin-bottom: 6px; gap: 8px 12px; align-items: center; }.cf-h1 { font-size: 1.45rem; }-- .cf-sub { font-size: 0.84rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }++ /* Whole, never clamped: on AI Moments the cut-off half was "Everything here is AI-generated", the disclosure. */++ .cf-sub { font-size: 0.84rem; line-height: 1.4; }.cf-crosslink { padding: 5px 10px; font-size: 0.8rem; }.cf-bar { gap: 8px; padding: 8px 0; }.cf-chips {nnew file mode 100644@@@ -0,0 +1,19 @@++'use strict';++/**++ * Content and AI Moments keep their subtitle whole on a phone. A two-line clamp cut AI Moments' "Everything here is++ * AI-generated" (the disclosure) to "Everything here is AI-…" (signed-in sweep, 2026-11-09; pages are short by design,++ * never by hiding).++ *++ * node test/feed-subtitle-whole.test.js++ */++const assert = require('assert');++const fs = require('fs');++const path = require('path');++++const css = fs.readFileSync(path.join(__dirname, '..', 'public/css/features/content.css'), 'utf8');++const rules = css.match(/\.cf-sub\s*\{[^}]*\}/g) || [];++assert.ok(rules.length >= 1, '.cf-sub is styled');++for (const r of rules) assert.ok(!/line-clamp|overflow:\s*hidden|text-overflow/.test(r), `.cf-sub is never clipped: ${r}`);++const html = fs.readFileSync(path.join(__dirname, '..', 'public/fragments/moments.html'), 'utf8');++assert.ok(/class="cf-sub">[^<]*Everything here is AI-generated\./.test(html), 'the AI disclosure is in the subtitle');++console.log('feed subtitles: whole on a phone, the AI disclosure included');
@@ -483,7 +483,8 @@ a.cf-recap-band:hover .cf-recap-sub { text-decoration: underline; text-underline
@@ -483,7 +483,8 @@ a.cf-recap-band:hover .cf-recap-sub { text-decoration: underline; text-underline
.cf-wrap { padding: 12px 12px 40px; --cf-gap: 14px; }
.cf-wrap { padding: 12px 12px 40px; --cf-gap: 14px; }
.cf-head { margin-bottom: 6px; gap: 8px 12px; align-items: center; }
.cf-head { margin-bottom: 6px; gap: 8px 12px; align-items: center; }
.cf-h1 { font-size: 1.45rem; }
.cf-h1 { font-size: 1.45rem; }
- .cf-sub { font-size: 0.84rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
+ /* Whole, never clamped: on AI Moments the cut-off half was "Everything here is AI-generated", the disclosure. */
+ .cf-sub { font-size: 0.84rem; line-height: 1.4; }
.cf-crosslink { padding: 5px 10px; font-size: 0.8rem; }
.cf-crosslink { padding: 5px 10px; font-size: 0.8rem; }
.cf-bar { gap: 8px; padding: 8px 0; }
.cf-bar { gap: 8px; padding: 8px 0; }
.cf-chips {
.cf-chips {
new file mode 100644
new file mode 100644
@@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
+'use strict';
+/**
+ * Content and AI Moments keep their subtitle whole on a phone. A two-line clamp cut AI Moments' "Everything here is
+ * AI-generated" (the disclosure) to "Everything here is AI-…" (signed-in sweep, 2026-11-09; pages are short by design,
+ * never by hiding).
+ *
+ * node test/feed-subtitle-whole.test.js
+ */
+const assert = require('assert');
+const fs = require('fs');
+const path = require('path');
+
+const css = fs.readFileSync(path.join(__dirname, '..', 'public/css/features/content.css'), 'utf8');
+const rules = css.match(/\.cf-sub\s*\{[^}]*\}/g) || [];
+assert.ok(rules.length >= 1, '.cf-sub is styled');
+for (const r of rules) assert.ok(!/line-clamp|overflow:\s*hidden|text-overflow/.test(r), `.cf-sub is never clipped: ${r}`);
+const html = fs.readFileSync(path.join(__dirname, '..', 'public/fragments/moments.html'), 'utf8');
+assert.ok(/class="cf-sub">[^<]*Everything here is AI-generated\./.test(html), 'the AI disclosure is in the subtitle');
+console.log('feed subtitles: whole on a phone, the AI disclosure included');