Root cause per QA on palette-dev (merge d402113): splitLines() joined
.codeline spans with '\n'; under white-space:pre-wrap each newline text
node between display:block spans rendered as its own extra visual row,
while renumber() counted gutter rows only from span heights — numbers
drifted up one row per wrapped line. Join with '' (spans are blocks).
Also: in the <=640px media query, .gutter { font-size: 15px } overrode
the paste-view gutter size while .code switched to 13px, so gutline rows
were ~36.7px vs 22.1px code rows at narrow widths — every number below
line 1 drifted. Scope the paste-view gutter to the code font size.
Verified with headless Chromium DOM geometry (desktop 1400x900 and
mobile 375x812): gutter number tops equal their .codeline tops for
lines wrapping to 2-3 rows, wrap OFF numbering unchanged
('1\n2\n3\n4\n5'), no horizontal scroll.
- splitLines(): join .codeline blocks with "" not "\n" — newline text
nodes under pre-wrap rendered an extra line box per logical line, so
every gutter number drifted one row per line
- renumber(): geometry-driven placement — one gutline per visual row of
the code body, each number assigned to the row matching its line's
measured offsetTop; verified second pass re-runs if a partially-filled
last wrapped row reflows after the gutter rebuild
- app.css: mobile media query gives .code .gutter the same 13px font as
.code so gutter rows and code rows share one line box at 375px
Verified in local build with headless chromium (long unbroken token on
line 5, wrap ON): all numbers align with line starts, no misalignment,
no horizontal scroll at 1400x900 and 375x812.
Image files render fitted into the editor area (editor and gutter
hidden); the title auto-fills with the file name. Text files always
load their content into the editor, replacing any text already there,
instead of only filling an empty editor. Title auto-fill still only
applies when the title is blank; a typed title is never overwritten.
Drawing and cropping tools are noted in the issue as possible future
work and are intentionally not implemented here.
The divider between the stats dropdown head and body lived on
.stats-body's border-top, so it vanished when collapsed and only the
hover background hinted at the boundary (flicker). Move it to
.stats-head border-bottom so it is always present and spans the full
pill width.
QA on dev showed .codeline spans wrap correctly but gutter .gutline spans
rendered inline (all at the same top), so numbers 6+ fell off with wrap on.
Add .gutter .gutline { display: block; } so each gutter number occupies its
own visual row, matching the one-number-per-visual-row contract of
paste-lines.js. Verified rendered output in a local build at 1400x900 and
375x812 with a long unbroken token on line 5 and wrap ON.
- Pill now reads only 'Paste Created' (no combined 'Paste Created - Link Copied')
- Copy fallback toast now says 'Link Copied'
- Pill shrunk (smaller padding/font) and anchored tighter to the right side
Fixes#168
QA of PR #179 found paste-lines.js creates .gutline spans but no CSS rule
existed, so all gutter numbers rendered inline on one visual row. Stack
them one per row under .code .gutter; blank fill spans inherit it.
- Pill now reads only 'Paste Created' (no combined 'Paste Created - Link Copied')
- Copy fallback toast now says 'Link Copied'
- Pill shrunk (smaller padding/font) and anchored tighter to the right side
Fixes#168
#139 removed inline display:block from paste.html's created banner and
compensated with a global .created-banner { display:block } override.
That override also hit the hidden placeholder banner on /new, whose
base rule is display:none, making an empty padded bar render above the
action bar. Scope the override to .created-banner.show and mark only
the paste-view banner with the show class.
- images render fitted into the editor area (object-fit contain), editor hidden
- text files load content into the editor; title placeholder convention (Python.py, Text.txt fallback)
- title auto-fills only when blank; never overwrites a typed title
- external JS + CSS classes only, CSP-safe (no inline styles/scripts)
Missing or expired paste IDs (and unknown routes) now render the main
UI chrome with a 'Paste ID not found' message in a color-coded result
card instead of a bare text/JSON 404. HTTP status stays 404. No inline
scripts or styles; new CSS uses existing --err token and pill radii.
Missing/expired/burned paste IDs and unknown routes now render the main
UI (topbar + centered result card) with a 'Paste ID not found' message,
returning HTTP 404 status for correctness.
wrap button on the new paste page looked identical whether wrap was on
or off because the btn base is already accent filled. give the toggle a
neutral off state so the accent on state is visible, matching the icon
button toggles on the paste view.
also remove the accent border on the whole language settings pill when
any child has focus. individual controls already show their own focus
rings, so the pill highlight made no sense.
Give the custom expiry and readable N times submenus a shared boxed
container with proper padding, indent them under their parent option,
and style the number inputs and unit select with palette vars, the
existing radius scale, and the select chevron. No em dashes, no hard
coded colors in new rules.
Add word-break: normal; overflow-wrap: anywhere to .paste-title-bar h1 so
a >120-char unbroken title wraps inside the title card at mobile width
instead of producing an internal + page-level horizontal scrollbar.
- Move all inline <script> blocks (layout head/theme, topbar dark toggle,
foot, paste, new, history, mine, settings, admin, unlock) to external
files under internal/web/static/. Page data reaches scripts via data-*
attributes (data-paste-id, data-default-dark) instead of template vars.
- Replace inline onclick handlers (copy, delete, stats toggle) with
addEventListener wiring.
- Convert inline style="" attributes to CSS utility classes; swatch
colors are now set via CSSOM/DOM APIs instead of innerHTML strings.
- script-src/style-src are now plain 'self'; img-src data: stays for the
SVG data-URI backgrounds. Verified with headless chromium: zero CSP
violations on all pages in dark and light presets, theme swatches,
admin lock, tables and paste view render correctly.
- codebody/editor: overflow-wrap anywhere + word-break break-all + overflow-x hidden under html[data-wrap]
- code container and mobile .float also hidden overflow with wrap on
- topbar mobile: tighten gap/padding/nav link padding so nothing overflows at 375px
Fixes#152