From c3864287cfd55799ebef23f646450532c199cba6 Mon Sep 17 00:00:00 2001 From: randogoth Date: Tue, 6 Oct 2026 08:45:13 +0300 Subject: [PATCH] fix: make randogoth.com's bbs theme readable on narrow viewports --- randogoth.com/bbs/static/bbs.css | 46 ++++++++++++++++++++- randogoth.com/bbs/templates/404.html | 10 +++++ randogoth.com/bbs/templates/archives.html | 12 ++++++ randogoth.com/bbs/templates/article.html | 10 ++++- randogoth.com/bbs/templates/base.html | 2 +- randogoth.com/bbs/templates/categories.html | 10 +++++ randogoth.com/bbs/templates/category.html | 14 ++++++- randogoth.com/bbs/templates/index.html | 32 ++++++++++++++ randogoth.com/bbs/templates/page.html | 2 +- randogoth.com/bbs/templates/tag.html | 14 ++++++- randogoth.com/bbs/templates/tags.html | 6 ++- 11 files changed, 150 insertions(+), 8 deletions(-) diff --git a/randogoth.com/bbs/static/bbs.css b/randogoth.com/bbs/static/bbs.css index c21f5dd..84f7d34 100644 --- a/randogoth.com/bbs/static/bbs.css +++ b/randogoth.com/bbs/static/bbs.css @@ -69,7 +69,8 @@ body { color: var(--grey); font-family: 'Classic Console', ui-monospace, monospace; /* clamp so 80ch always fits the viewport, phone to desktop */ - font-size: clamp(7px, 2.32vw, 17px); + --cell: clamp(7px, 2.32vw, 17px); + font-size: var(--cell); /* Exactly one cell per row. Each box row is its own
, so any leading at
      all opens a gap between them and the vertical box-drawing characters stop
      meeting. Prose gets its leading back on .msgbody below. */
@@ -180,6 +181,49 @@ a:visited { color: var(--lcyan); }
 .msgbody hr { border: 0; border-top: 1px solid var(--blue); margin: 1.4em 0; }
 .msgbody a { text-decoration: underline; }
 
+/* ── mobile: read content is one size, not two ───────────────────────────
+ * 80 real characters cannot be legible and fit a phone's width at the same
+ * time, so below this breakpoint every piece of actual content (prose,
+ * the message header, the listing tables) renders at one fixed size
+ * instead of inheriting --cell. Box-drawn tables that packed two columns
+ * into 80 characters get a second, narrower rendering built for this
+ * width instead: see .desktop-only/.mobile-only below, toggled by the
+ * matching (min-width: 601px) block further down. The masthead logo and
+ * the plain ──── rule dividers are graphics, not content, and are left on
+ * --cell exactly as before.
+ */
+@media (max-width: 600px) {
+  .msgbody,
+  .cloud,
+  .pagehdr,
+  .sysline,
+  .tagline,
+  .prompt,
+  .mobile-only { font-size: 1rem; }
+
+  /* The desktop article header packs two fields per row with hand-counted
+     padding; the mobile rows (and a page's single Subj row) are one field
+     each, so they just need to wrap like normal text instead of running
+     off the edge under white-space: pre. The sysline, tagline and the
+     bottom command bar are actual words, not a repeating-character rule,
+     so they wrap too. */
+  .msghdr.mobile-only,
+  .pagehdr,
+  .sysline,
+  .tagline,
+  .prompt { white-space: normal; }
+
+  /* Box drawing embedded in prose (a pull-quote box, if one is ever used)
+     is a rigid character grid and must stay at the chrome size or its
+     columns stop lining up against their own border characters. */
+  .msgbody .box, .msgbody .gb-rule, .msgbody .rule { font-size: var(--cell); }
+
+  .desktop-only { display: none; }
+}
+@media (min-width: 601px) {
+  .mobile-only { display: none; }
+}
+
 /* the Fidonet tagline that closed every message */
 .tagline { color: var(--dgrey); margin-top: 1.6em; }
 .tagline .origin { color: var(--green); }
diff --git a/randogoth.com/bbs/templates/404.html b/randogoth.com/bbs/templates/404.html
index 073c2d7..61cb043 100644
--- a/randogoth.com/bbs/templates/404.html
+++ b/randogoth.com/bbs/templates/404.html
@@ -1,8 +1,18 @@
 {% extends "base.html" %}
 {% block title %}NO CARRIER · {{ SITENAME }}{% endblock %}
 {% block content %}
+
┌─ ERROR ──────────────────────────────────────────────────────────────────────┐
│ {{ "%-76s"|format("NO CARRIER") }} │
│ {{ "%-76s"|format("That message does not exist on this board.") }} │
└──────────────────────────────────────────────────────────────────────────────┘
+
+ +
+
┌─ ERROR ──────────────────────────────┐
+
│ {{ "%-36s"|format("NO CARRIER") }} │
+
│ {{ "%-36s"|format("That message does not exist") }} │
+
│ {{ "%-36s"|format("on this board.") }} │
+
└──────────────────────────────────────┘
+
{% endblock %} diff --git a/randogoth.com/bbs/templates/archives.html b/randogoth.com/bbs/templates/archives.html index cf77645..8f74774 100644 --- a/randogoth.com/bbs/templates/archives.html +++ b/randogoth.com/bbs/templates/archives.html @@ -1,10 +1,22 @@ {% extends "base.html" %} {% block title %}Message Index · {{ SITENAME }}{% endblock %} {% block content %} +
┌─ MESSAGE INDEX ──────────────────────────────────────────────────────────────┐
{%- for a in dates %} {%- set n = loop.index %}
│ [{{ "%2d"|format(n) }}] {{ a.date.strftime('%d %b %y')|lower }} {{ "%-8s"|format(a.category|string) }} {{ "%-52s"|format(a.title|striptags|truncate(52, true, '')) }} │
{%- endfor %}
└──────────────────────────────────────────────────────────────────────────────┘
+
+ +
+
┌─ MESSAGE INDEX ──────────────────────┐
+{%- for a in dates %} +{%- set n = loop.index %} +
│ [{{ "%2d"|format(n) }}] {{ "%-31s"|format(a.title|striptags|truncate(31, true, '', 0)) }} │
+
│      {{ a.date.strftime('%d %b %y')|lower }} · {{ "%-8s"|format(a.category|string) }}            │
+{%- endfor %} +
└──────────────────────────────────────┘
+
{% endblock %} diff --git a/randogoth.com/bbs/templates/article.html b/randogoth.com/bbs/templates/article.html index 977d623..a96a24f 100644 --- a/randogoth.com/bbs/templates/article.html +++ b/randogoth.com/bbs/templates/article.html @@ -2,10 +2,18 @@ {% block title %}{{ article.title|striptags }} · {{ SITENAME }}{% endblock %} {% block content %}
════════════════════════════════════════════════════════════════════════════════
-
 Msg  : {{ "%-44s"|format(article.slug) }} Area : {{ article.category }}
+
 Msg  : {{ "%-44s"|format(article.slug) }} Area : {{ article.category }}
  From : {{ "%-44s"|format(article.author|default(AUTHOR, true)|string) }} Date : {{ article.date.strftime('%d %b %Y') }}
  Subj : {{ article.title|striptags }}{% if article.tags %}
  Keys : {% for t in article.tags %}{{ t }}{% if not loop.last %}, {% endif %}{% endfor %}{% endif %}
+
 Msg  : {{ article.slug }}
+
 Area : {{ article.category }}
+
 From : {{ article.author|default(AUTHOR, true)|string }}
+
 Date : {{ article.date.strftime('%d %b %Y') }}
+
 Subj : {{ article.title|striptags }}
+{%- if article.tags %} +
 Keys : {% for t in article.tags %}{{ t }}{% if not loop.last %}, {% endif %}{% endfor %}
+{%- endif %}
════════════════════════════════════════════════════════════════════════════════
{{ article.content }}
diff --git a/randogoth.com/bbs/templates/base.html b/randogoth.com/bbs/templates/base.html index 4977ed3..30e3ad6 100644 --- a/randogoth.com/bbs/templates/base.html +++ b/randogoth.com/bbs/templates/base.html @@ -29,7 +29,7 @@ {% block content %}{% endblock %}
────────────────────────────────────────────────────────────────────────────────
-
 [I]ndex   [K]eywords   [F]eed   Main [M]enu   
+
 [I]ndex   [K]eywords   [F]eed   Main [M]enu   
Command:
diff --git a/randogoth.com/bbs/templates/categories.html b/randogoth.com/bbs/templates/categories.html index 0f956e1..be57a97 100644 --- a/randogoth.com/bbs/templates/categories.html +++ b/randogoth.com/bbs/templates/categories.html @@ -5,10 +5,20 @@ {%- for cat, arts in categories %}{% set _ = rows.append((BBS_AREAS.get(cat|string, 99), cat, arts)) %}{% endfor %} {%- set ordered = rows|sort(attribute='0') %} {%- set half = (ordered|length + 1) // 2 %} +
┌─ MESSAGE AREAS ───────────────────────┬──────────────────────────────────────┐
{%- for i in range(half) %} {%- set a = ordered[i] %}
│ [{{ a[0] }}] {{ "%-9s"|format(a[1]|string) }}                     {{ "%3d"|format(a[2]|length) }} │ {% if ordered|length > i + half %}{% set b = ordered[i + half] %}[{{ b[0] }}] {{ "%-9s"|format(b[1]|string) }}                    {{ "%3d"|format(b[2]|length) }}{% else %}                                    {% endif %} │
{%- endfor %}
└───────────────────────────────────────┴──────────────────────────────────────┘
+
+ +
+
┌─ MESSAGE AREAS ──────────────────────┐
+{%- for a in ordered %} +
│ [{{ "%2d"|format(a[0]) }}] {{ "%-28s"|format(a[1]|string) }}{{ "%3d"|format(a[2]|length) }} │
+{%- endfor %} +
└──────────────────────────────────────┘
+
{% endblock %} diff --git a/randogoth.com/bbs/templates/category.html b/randogoth.com/bbs/templates/category.html index ce77f98..3cfabac 100644 --- a/randogoth.com/bbs/templates/category.html +++ b/randogoth.com/bbs/templates/category.html @@ -3,13 +3,25 @@ {% block content %} {% set info = BBS_AREAS.get(category|string, 0) %} {% set t = "AREA " ~ info ~ ": " ~ category %} +{%- set total = articles_paginator.object_list|length %} +
┌─ {{ t }} {{ "─" * (75 - t|length) }}┐
├──────────────────────────────────────────────────────────────────────────────┤
-{%- set total = articles_paginator.object_list|length %} {%- for a in articles_page.object_list %} {%- set n = total - (loop.index0 + (articles_page.number - 1) * articles_paginator.per_page) %}
│ [{{ "%3d"|format(n) }}] {{ a.date.strftime('%d %b %y')|lower }} {{ "%-60s"|format(a.title|striptags|truncate(60, true, '')) }} │
{%- endfor %}
└──────────────────────────────────────────────────────────────────────────────┘
+
+ +
+
┌─ {{ t }} {{ "─" * (35 - t|length) }}┐
+{%- for a in articles_page.object_list %} +{%- set n = total - (loop.index0 + (articles_page.number - 1) * articles_paginator.per_page) %} +
│ [{{ "%2d"|format(n) }}] {{ "%-31s"|format(a.title|striptags|truncate(31, true, '', 0)) }} │
+
│      {{ a.date.strftime('%d %b %y')|lower }}                       │
+{%- endfor %} +
└──────────────────────────────────────┘
+
{% include 'pagination.html' %} {% endblock %} diff --git a/randogoth.com/bbs/templates/index.html b/randogoth.com/bbs/templates/index.html index 4c75a40..f0554ae 100644 --- a/randogoth.com/bbs/templates/index.html +++ b/randogoth.com/bbs/templates/index.html @@ -4,20 +4,40 @@ {%- for cat, arts in categories %}{% set _ = rows.append((BBS_AREAS.get(cat|string, 99), cat, arts)) %}{% endfor %} {%- set ordered = rows|sort(attribute='0') %} {%- set half = (ordered|length + 1) // 2 %} +
┌─ MESSAGE AREAS ───────────────────────┬──────────────────────────────────────┐
{%- for i in range(half) %} {%- set a = ordered[i] %}
│ [{{ a[0] }}] {{ "%-9s"|format(a[1]|string) }}                     {{ "%3d"|format(a[2]|length) }} │ {% if ordered|length > i + half %}{% set b = ordered[i + half] %}[{{ b[0] }}] {{ "%-9s"|format(b[1]|string) }}                    {{ "%3d"|format(b[2]|length) }}{% else %}                                    {% endif %} │
{%- endfor %}
└───────────────────────────────────────┴──────────────────────────────────────┘
+
+ +
+
┌─ MESSAGE AREAS ──────────────────────┐
+{%- for a in ordered %} +
│ [{{ "%2d"|format(a[0]) }}] {{ "%-28s"|format(a[1]|string) }}{{ "%3d"|format(a[2]|length) }} │
+{%- endfor %} +
└──────────────────────────────────────┘
+
{# GUESTBOOK is commented out of the menu until it is built; the page and its mockup stay in the tree. Restoring it means a third column here and dropping Status: draft from content/pages/guestbook.md. #} +
┌─ SYSTEM ──────────────────────────────┬──────────────────────────────────────┐
│ [A] ABOUT                             │ [C] CONNECT                          │
└───────────────────────────────────────┴──────────────────────────────────────┘
+
+
+
┌─ SYSTEM ─────────────────────────────┐
+
│ [A] {{ "%-32s"|format("ABOUT") }} │
+
│ [C] {{ "%-32s"|format("CONNECT") }} │
+
└──────────────────────────────────────┘
+
+ +
┌─ LATEST ─────────────────────────────────────────────────────────────────────┐
{%- set base = BBS_AREAS|length %} {%- for article in articles_page.object_list %} @@ -25,5 +45,17 @@
│ [{{ "%2d"|format(n) }}] {{ article.date.strftime('%d %b %y')|lower }} {{ "%-8s"|format(article.category|string) }} {{ "%-52s"|format(article.title|striptags|truncate(52, true, '')) }} │
{%- endfor %}
└──────────────────────────────────────────────────────────────────────────────┘
+
+ +
+
┌─ LATEST ─────────────────────────────┐
+{%- set base = BBS_AREAS|length %} +{%- for article in articles_page.object_list %} +{%- set n = base + loop.index %} +
│ [{{ "%2d"|format(n) }}] {{ "%-31s"|format(article.title|striptags|truncate(31, true, '', 0)) }} │
+
│      {{ article.date.strftime('%d %b %y')|lower }} · {{ "%-8s"|format(article.category|string) }}            │
+{%- endfor %} +
└──────────────────────────────────────┘
+
{% include 'pagination.html' %} {% endblock %} diff --git a/randogoth.com/bbs/templates/page.html b/randogoth.com/bbs/templates/page.html index 0f18588..fcabcf8 100644 --- a/randogoth.com/bbs/templates/page.html +++ b/randogoth.com/bbs/templates/page.html @@ -2,7 +2,7 @@ {% block title %}{{ page.title|striptags }} · {{ SITENAME }}{% endblock %} {% block content %}
════════════════════════════════════════════════════════════════════════════════
-
 Subj : {{ page.title|striptags }}
+
 Subj : {{ page.title|striptags }}
════════════════════════════════════════════════════════════════════════════════
{{ page.content }}
{% endblock %} diff --git a/randogoth.com/bbs/templates/tag.html b/randogoth.com/bbs/templates/tag.html index 7d427e8..f4488bf 100644 --- a/randogoth.com/bbs/templates/tag.html +++ b/randogoth.com/bbs/templates/tag.html @@ -2,12 +2,24 @@ {% block title %}{{ tag }} · {{ SITENAME }}{% endblock %} {% block content %} {% set t = "KEYWORD: " ~ tag %} -
┌─ {{ t }} {{ "─" * (75 - t|length) }}┐
{%- set total = articles_paginator.object_list|length %} +
+
┌─ {{ t }} {{ "─" * (75 - t|length) }}┐
{%- for a in articles_page.object_list %} {%- set n = loop.index0 + 1 + (articles_page.number - 1) * articles_paginator.per_page %}
│ [{{ "%2d"|format(n) }}] {{ a.date.strftime('%d %b %y')|lower }} {{ "%-8s"|format(a.category|string) }} {{ "%-52s"|format(a.title|striptags|truncate(52, true, '')) }} │
{%- endfor %}
└──────────────────────────────────────────────────────────────────────────────┘
+
+ +
+
┌─ {{ t }} {{ "─" * (35 - t|length) }}┐
+{%- for a in articles_page.object_list %} +{%- set n = loop.index0 + 1 + (articles_page.number - 1) * articles_paginator.per_page %} +
│ [{{ "%2d"|format(n) }}] {{ "%-31s"|format(a.title|striptags|truncate(31, true, '', 0)) }} │
+
│      {{ a.date.strftime('%d %b %y')|lower }} · {{ "%-8s"|format(a.category|string) }}            │
+{%- endfor %} +
└──────────────────────────────────────┘
+
{% include 'pagination.html' %} {% endblock %} diff --git a/randogoth.com/bbs/templates/tags.html b/randogoth.com/bbs/templates/tags.html index 326b4e3..6e62eb9 100644 --- a/randogoth.com/bbs/templates/tags.html +++ b/randogoth.com/bbs/templates/tags.html @@ -2,7 +2,9 @@ {% block title %}Keywords · {{ SITENAME }}{% endblock %} {% block content %} {% set t = "KEYWORDS" %} -
┌─ {{ t }} {{ "─" * (75 - t|length) }}┐
+
┌─ {{ t }} {{ "─" * (75 - t|length) }}┐
+
┌─ {{ t }} {{ "─" * (35 - t|length) }}┐
{% for tg, arts in tags|sort %}[{{ loop.index }}]{{ tg }}({{ arts|length }}) {% endfor %}
-
└──────────────────────────────────────────────────────────────────────────────┘
+
└──────────────────────────────────────────────────────────────────────────────┘
+
└──────────────────────────────────────┘
{% endblock %}