Overhaul CSS for 320px–2560px viewports

style.css now has explicit breakpoints and primitives covering
the full target range:

- Global: overflow-x: hidden on body, max-width:100% on media,
  fluid typography via clamp() so headings shrink on 320px.
- .wrap: 64rem cap at desktop, 72rem at 1440px, 96rem at 2560px;
  generous side padding at large widths so text doesn't hug the
  edge on huge monitors.
- .app-shell layout primitive (grid: sidebar + content [+ aside
  on ultrawide]) ready for the eventual notes UI:
    * mobile: single column, sidebar hidden behind a toggle
      ([data-sidebar="open"] reveals it).
    * 768px+: 2-column with 16rem sidebar.
    * 1024px+: 18rem sidebar.
    * 1440px+: 20rem sidebar, content max-width 56rem so reading
      lines don't grow unbounded.
    * 2560px+: 3-column (sidebar | content | aside) so the
      editor stays at reading width while the extra real estate
      hosts backlinks/preview.
- .app-resize-handle with touch-action:none so pointer-event
  drag handlers won't conflict with browser scrolling.
- Auth card tightens on viewports under 360px.

Result: no horizontal scroll at any width; content uses ultrawide
space effectively without sacrificing legibility.

Closes #18.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-28 22:28:19 +02:00
co-authored by Claude Opus 4.7
parent 7c3b40c963
commit e6d3893308
+93 -4
View File
@@ -1,6 +1,22 @@
/* librenotes — minimal, mobile-first styles for landing + auth + app shell. /* librenotes — mobile-first responsive styles.
Aim for legibility, no JS dependencies, and a clean dark-mode option *
driven by [data-theme="dark"] on <body>. */ * Breakpoints (matches Phase 3 issue #18):
* - small mobile: 320–479px (default; no media query)
* - large mobile: 480–767px
* - tablet: 768–1023px
* - desktop: 1024–1439px
* - large desktop: 1440–2559px
* - ultrawide: >= 2560px
*
* Design goals:
* - Never horizontal-scroll at any width.
* - Use min(100% - gutter, max-content) sizing so content
* adapts without breaking at the extremes.
* - Reserve a sidebar layout primitive (.app-shell + .app-sidebar
* + .app-content) for the eventual notes UI; on mobile the
* sidebar collapses behind a toggle (display: none until
* [data-sidebar="open"]).
*/
:root { :root {
--fg: #1a1a1a; --fg: #1a1a1a;
@@ -34,17 +50,32 @@ html, body {
line-height: 1.5; line-height: 1.5;
color: var(--fg); color: var(--fg);
background: var(--bg); background: var(--bg);
/* Prevent horizontal scroll at narrow widths even if a child
overflows. Vertical overflow is allowed normally. */
overflow-x: hidden;
} }
img, svg, video, canvas, iframe { max-width: 100%; height: auto; }
/* Fluid typography between mobile and desktop sizes. */
h1 { font-size: clamp(1.5rem, 4vw, 2.5rem); line-height: 1.15; }
h2 { font-size: clamp(1.1rem, 2.5vw, 1.5rem); }
a { color: var(--accent); text-decoration: none; } a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; } a:hover { text-decoration: underline; }
.wrap { .wrap {
width: 100%;
max-width: 64rem; max-width: 64rem;
margin: 0 auto; margin: 0 auto;
padding: 0 1.25rem; padding: 0 1rem;
} }
/* Comfortable reading width that scales up to ultrawide without
stretching paragraphs into uselessly long lines. */
@media (min-width: 1440px) { .wrap { max-width: 72rem; padding: 0 2rem; } }
@media (min-width: 2560px) { .wrap { max-width: 96rem; padding: 0 3rem; } }
.brand { .brand {
font-weight: 700; font-weight: 700;
font-size: 1.15rem; font-size: 1.15rem;
@@ -169,3 +200,61 @@ a:hover { text-decoration: underline; }
padding: 1rem; padding: 1rem;
overflow-x: auto; overflow-x: auto;
} }
/* App shell layout primitive — used by the eventual notes UI.
Mobile-first: sidebar hidden behind a toggle, content fills
the viewport. Tablet+: sidebar visible, fixed width.
Desktop+: sidebar wider, content has reading max-width. */
.app-shell {
display: grid;
grid-template-columns: 1fr;
min-height: calc(100vh - 3.25rem); /* minus header */
}
.app-sidebar {
display: none;
border-right: 1px solid var(--border);
background: var(--card);
padding: 1rem;
overflow-y: auto;
/* Pointer / touch friendliness for the eventual resize handle. */
touch-action: pan-y;
}
.app-shell[data-sidebar="open"] .app-sidebar { display: block; }
.app-content { padding: 1rem; min-width: 0; }
@media (min-width: 768px) {
.app-shell { grid-template-columns: 16rem 1fr; }
.app-sidebar { display: block; }
.app-content { padding: 1.25rem 1.5rem; }
}
@media (min-width: 1024px) {
.app-shell { grid-template-columns: 18rem 1fr; }
}
@media (min-width: 1440px) {
.app-shell { grid-template-columns: 20rem minmax(0, 1fr); }
.app-content { max-width: 56rem; padding: 2rem; }
}
@media (min-width: 2560px) {
/* On ultrawide, reserve a third column for backlinks/preview
so the editor doesn't stretch into illegibility. */
.app-shell { grid-template-columns: 22rem minmax(0, 1fr) 22rem; }
}
/* Sidebar resize handle: pointer events + capture for drag.
Disabled by default; the eventual JS controller will toggle
.resizing on the shell. */
.app-resize-handle {
width: 0.4rem;
cursor: col-resize;
background: transparent;
touch-action: none;
}
.app-resize-handle:hover, .app-shell.resizing .app-resize-handle {
background: var(--accent);
}
/* Ensure inputs in the auth card fit comfortably on 320px. */
@media (max-width: 360px) {
.auth-card { padding: 1.25rem; }
.auth-card h1 { font-size: 1.25rem; }
}