diff --git a/cmd/librenotes/web/public/style.css b/cmd/librenotes/web/public/style.css index 4309dee..00bd2a7 100644 --- a/cmd/librenotes/web/public/style.css +++ b/cmd/librenotes/web/public/style.css @@ -1,6 +1,22 @@ -/* librenotes — minimal, mobile-first styles for landing + auth + app shell. - Aim for legibility, no JS dependencies, and a clean dark-mode option - driven by [data-theme="dark"] on . */ +/* librenotes — mobile-first responsive styles. + * + * 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 { --fg: #1a1a1a; @@ -34,17 +50,32 @@ html, body { line-height: 1.5; color: var(--fg); 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:hover { text-decoration: underline; } .wrap { + width: 100%; max-width: 64rem; 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 { font-weight: 700; font-size: 1.15rem; @@ -169,3 +200,61 @@ a:hover { text-decoration: underline; } padding: 1rem; 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; } +}