aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AGENTS.md6
-rw-r--r--internal/web/static/blog.css3
-rw-r--r--internal/web/templates/dashboard/design.html7
-rw-r--r--internal/web/templates/dashboard/layout.html4
-rw-r--r--internal/web/theme.go16
-rw-r--r--internal/web/web_test.go6
6 files changed, 12 insertions, 30 deletions
diff --git a/AGENTS.md b/AGENTS.md
index 132e9c2..3a1da81 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -120,8 +120,10 @@ internal/web/ server.go (host router, middleware, render helpers)
index / recent posts when a visible module needs them. A side column is
laid out only when it has modules, or always with `theme.keep_columns`
(`HasLeft/HasRight` → `body.has-*`
- classes, which also lift the `.wrap` max-width so the page goes
- full-width; column widths in the theme CSS under `@media (min-width: 701px)`);
+ classes; column widths in the theme CSS under `@media (min-width: 701px)`).
+ The page is always full width — there is no content max-width; the
+ column percentages divide the page and `keep_columns` is how a blogger
+ gets a narrower, centred main column;
below 700px `.cols` becomes block flow so the order is main → left →
right → footer. Everything is rendered by the `module` template in
`layouts/blog.html`. New blogs get `insertDefaultModules` (title + menu
diff --git a/internal/web/static/blog.css b/internal/web/static/blog.css
index c785ca6..d4465a2 100644
--- a/internal/web/static/blog.css
+++ b/internal/web/static/blog.css
@@ -1,7 +1,7 @@
/* Public blog base styles — colours, fonts and widths come from the inline theme <style>. */
* { box-sizing: border-box; }
img { max-width: 100%; height: auto; }
-.wrap { padding: 0 1em; }
+.wrap { padding: 0 1em; } /* full width; the columns' percentages divide the page */
.site-header { padding: 0; }
.header-image img { display: block; width: 100%; max-height: 320px; object-fit: cover; }
.header-text { padding: 1.4em 1em; }
@@ -56,7 +56,6 @@ img { max-width: 100%; height: auto; }
flexbox puts the left column before it. Widths come from the theme CSS.
Browsers without flexbox see the columns stacked, which still reads fine. */
.cols { display: flex; flex-wrap: wrap; align-items: flex-start; }
-body.has-left .wrap, body.has-right .wrap { max-width: none; } /* side columns: use the whole page */
.col { width: 100%; }
.col-left { order: -1; padding-right: 1.5em; }
.col-right { padding-left: 1.5em; }
diff --git a/internal/web/templates/dashboard/design.html b/internal/web/templates/dashboard/design.html
index 342cabe..4c86c79 100644
--- a/internal/web/templates/dashboard/design.html
+++ b/internal/web/templates/dashboard/design.html
@@ -73,11 +73,6 @@
</select></label>
</div>
<div class="row">
- <label>Width<br><select name="content_width">
- <option value="narrow"{{if eq $t.ContentWidth "narrow"}} selected{{end}}>Narrow</option>
- <option value="medium"{{if eq $t.ContentWidth "medium"}} selected{{end}}>Medium</option>
- <option value="wide"{{if eq $t.ContentWidth "wide"}} selected{{end}}>Wide</option>
- </select></label>
<label>Box style<br><select name="content_style">
<option value="card"{{if eq $t.ContentStyle "card"}} selected{{end}}>Card (shadow, rounded corners)</option>
<option value="flat"{{if eq $t.ContentStyle "flat"}} selected{{end}}>Flat</option>
@@ -88,7 +83,7 @@
<option value="roomy"{{if eq $t.ContentPadding "roomy"}} selected{{end}}>Roomy</option>
</select></label>
</div>
- <p class="muted small">Width only applies while there are no side columns; with a left or right column the blog uses the whole page.</p>
+ <p class="muted small">The content spans the whole page; how much of it the posts get is set by the column widths on the <a href="/b/{{.Blog.Subdomain}}/layout#columns">Layout</a> tab.</p>
</div>
<div class="card" id="header">
diff --git a/internal/web/templates/dashboard/layout.html b/internal/web/templates/dashboard/layout.html
index 7691b1e..229ca0e 100644
--- a/internal/web/templates/dashboard/layout.html
+++ b/internal/web/templates/dashboard/layout.html
@@ -25,8 +25,8 @@
<label>Left column width<br><input type="number" name="left_width" value="{{$t.LeftWidth}}" min="15" max="40" step="5"> %</label>
<label>Right column width<br><input type="number" name="right_width" value="{{$t.RightWidth}}" min="15" max="40" step="5"> %</label>
</div>
- <p class="muted small">Between 15% and 40% each; the main content takes the rest. A column only appears when it has at least one module; as soon as one does, the blog spreads over the whole page. On phones the columns stack: main content first, then the left and right columns, then the footer.</p>
- <label class="check"><input type="checkbox" name="keep_columns"{{if $t.KeepColumns}} checked{{end}}> Always keep the columns' space, even when a column is empty or hidden <span class="muted">(the main content then has the same width on every page)</span></label>
+ <p class="muted small">Between 15% and 40% each; the main content takes the rest. A column only appears when it has at least one module; without columns the posts take the whole width. On phones the columns stack: main content first, then the left and right columns, then the footer.</p>
+ <label class="check"><input type="checkbox" name="keep_columns"{{if $t.KeepColumns}} checked{{end}}> Always keep the columns' space, even when a column is empty or hidden <span class="muted">(the main content then keeps its width and stays centred)</span></label>
<p class="actionrow"><button type="submit">Save columns</button></p>
</form>
</div>
diff --git a/internal/web/theme.go b/internal/web/theme.go
index 46067ba..1ecd832 100644
--- a/internal/web/theme.go
+++ b/internal/web/theme.go
@@ -24,7 +24,6 @@ type Theme struct {
LinkColor string `json:"link_color"`
LinkHover string `json:"link_hover"` // "" = same as LinkColor
LinkUnderline string `json:"link_underline"` // always | hover | never
- ContentWidth string `json:"content_width"` // narrow | medium | wide (no side columns)
ContentStyle string `json:"content_style"` // card | flat
ContentPadding string `json:"content_padding"` // normal | compact | roomy
Font string `json:"font"` // sans | serif | mono
@@ -79,7 +78,7 @@ func DefaultTheme() Theme {
return Theme{
BgColor: "#e9e6df", BgMode: "cover",
ContentBg: "#ffffff", TextColor: "#222222", LinkColor: "#1a5fb4", LinkUnderline: "always",
- ContentWidth: "medium", ContentStyle: "card", ContentPadding: "normal",
+ ContentStyle: "card", ContentPadding: "normal",
Font: "sans", HeadingFont: "same", FontSize: "normal",
HeaderImageHeight: "medium", HeaderAlign: "left", HeaderBg: "#2f3a4a", HeaderText: "#ffffff",
NavAlign: "left", NavStyle: "normal", NavBg: "#ffffff", NavText: "#222222",
@@ -140,7 +139,6 @@ func (t *Theme) normalize() {
t.LinkColor = color(t.LinkColor, d.LinkColor)
t.LinkHover = optColor(t.LinkHover)
t.LinkUnderline = pick(t.LinkUnderline, "always", "hover", "never")
- t.ContentWidth = pick(t.ContentWidth, "medium", "narrow", "wide")
t.ContentStyle = pick(t.ContentStyle, "card", "flat")
t.ContentPadding = pick(t.ContentPadding, "normal", "compact", "roomy")
t.Font = pick(t.Font, "sans", "serif", "mono")
@@ -198,7 +196,6 @@ func ThemeFromForm(cur Theme, f url.Values) Theme {
t.LinkColor = get("link_color")
t.LinkHover = hover("link_hover")
t.LinkUnderline = get("link_underline")
- t.ContentWidth = get("content_width")
t.ContentStyle = get("content_style")
t.ContentPadding = get("content_padding")
t.Font = get("font")
@@ -371,16 +368,6 @@ func (t Theme) FontSizePx() string {
return "17px"
}
-func (t Theme) MaxWidth() string {
- switch t.ContentWidth {
- case "narrow":
- return "640px"
- case "wide":
- return "1100px"
- }
- return "840px"
-}
-
// ContentPaddingCSS returns desktop and phone paddings; "normal" is left to blog.css.
func (t Theme) ContentPaddingCSS() (desktop, phone string) {
switch t.ContentPadding {
@@ -430,7 +417,6 @@ a { color:{{.LinkColor}};{{if eq .LinkUnderline "always"}} text-decoration:under
{{- if or .LinkHover (eq .LinkUnderline "hover")}}
a:hover {{"{"}}{{if .LinkHover}} color:{{.LinkHover}};{{end}}{{if eq .LinkUnderline "hover"}} text-decoration:underline;{{end}} }
{{- end}}
-.wrap { max-width:{{.MaxWidth}}; margin:0 auto; }
.site-header { background:{{.HeaderBg}}; color:{{.HeaderText}}; text-align:{{.HeaderAlign}}; }
.site-header a { color:{{.HeaderText}}; }
.header-image img { max-height:{{.HeaderImageMaxHeight}}; }
diff --git a/internal/web/web_test.go b/internal/web/web_test.go
index b8f761a..a988a23 100644
--- a/internal/web/web_test.go
+++ b/internal/web/web_test.go
@@ -82,18 +82,18 @@ func TestThemeNormalizeAndCSS(t *testing.T) {
if !th.HeaderOn || !th.LeftOn || !th.RightOn || !th.FooterOn || th.LeftWidth != 15 {
t.Errorf("old theme layout defaults: %+v", th)
}
- f := url.Values{"bg_color": {"#ABCDEF"}, "content_width": {"wide"}, "bg_image": {"not-a-uuid"}, "logo_size": {"large"},
+ f := url.Values{"bg_color": {"#ABCDEF"}, "bg_image": {"not-a-uuid"}, "logo_size": {"large"},
"link_hover": {"#ff0000"}, "nav_hover": {"#00ff00"}, "nav_hover_custom": {"on"}, "nav_style": {"uppercase"}, "nav_align": {"center"},
"link_underline": {"hover"}, "heading_font": {"serif"}, "content_style": {"flat"}, "content_padding": {"roomy"}, "date_format": {"iso"}}
th = ThemeFromForm(DefaultTheme(), f)
- if th.BgColor != "#abcdef" || th.ContentWidth != "wide" || th.BgImage != "" || th.LogoSize != "large" {
+ if th.BgColor != "#abcdef" || th.BgImage != "" || th.LogoSize != "large" {
t.Errorf("from form: %+v", th)
}
if th.LinkHover != "" || th.NavHover != "#00ff00" || th.ShowDates || th.DateFormat != "iso" {
t.Errorf("hover checkbox / unticked checkboxes: %+v", th)
}
css := th.CSS()
- for _, want := range []string{"background-color:#abcdef", "max-width:1100px", "text-transform:uppercase", ".site-nav a:hover { color:#00ff00", "a:hover { text-decoration:underline",
+ for _, want := range []string{"background-color:#abcdef", "text-transform:uppercase", ".site-nav a:hover { color:#00ff00", "a:hover { text-decoration:underline",
"h1, h2, h3, h4, h5, h6 { font-family:Georgia", "text-align:center", "border-radius:0", "padding:2.2em 3em", "@media (max-width: 700px)", ".logo { max-height:140px"} {
if !strings.Contains(css, want) {
t.Errorf("css missing %q:\n%s", want, css)