theseus/bundled-addons/screenshot/editor.css

171 lines
8 KiB
CSS
Raw Normal View History

feat(theseus/screenshot): 0.5.0 — sidebar-first editor, direct save/copy, sounds Two problems the old editor kept hitting: - __pending drain race: opening the editor a second time (refresh, back-and- forth navigation) found the storage entry already consumed and bailed to a blank canvas silently. - Cross-origin img loading: editor.html at file:///…/addons/screenshot/ loading a scratch PNG at file:///…/addons-data/ counts as cross-origin under Chromium's file-URL policy; setting crossOrigin="anonymous" made the load fail outright. Rebuilt editor v2: - Load path is idempotent: silentmode.invoke("getBytes", {name}) → addon reads the scratch file and returns a data URL. No __pending drain, no cross-origin trickery — data: URLs are same-origin and never taint the canvas, so getImageData / toBlob keep working. - Two-canvas model (#base + #over, over is pointer-events:none) so live previews don't cost a full re-composite per mousemove. - Tools: cursor, arrow, rect, ellipse, pen, text. 6 swatches, 3 widths, undo / redo (25-deep). Copy + Save at the top bar. Back and Maximize buttons in the same top bar so navigation controls stay reachable when the toolbar wraps at narrow widths. - Keyboard: A/R/O/P/T select tool, Esc = cursor, Ctrl+Z/Shift+Z undo/redo, Ctrl+S save, Ctrl+C copy. - Toast surface for save/copy/error feedback. Sidebar panel gains a direct raw-save path so the user can copy or save the capture without entering the editor: - Two-row actions: [Copy] [Save] on top, [Discard] [Edit] below. - Copy uses navigator.clipboard.write(ClipboardItem); Save uses <a download> with a Blob URL — same path Chromium's will-download tracker already handles, so the file lands in Downloads and the chip updates like any other save. Inline "clear all" confirmation replaces the native confirm() — the old system-modal opened over the tab area (out of the sidebar's visual context) and looked like Windows 95. Now a compact red strip appears under the Recent header with Cancel / Delete buttons. Sounds + a sound-on/off toggle in both surfaces: - Web Audio oscillator-synthesized (no .wav shipped): shutter click on capture, two-tone bloop on copy, descending pair on discard/back, ascending triad on save. - Preference stored in silentmode.storage under "soundOn" (default on), shared between the panel and the editor. Simplifications: - Dropped the addon's "arm" onMessage handler (superseded by getBytes). - Manifest capabilities: sidebar-panel + capture-tab (no open-tab, no toolbar-menu). Bundled but not shipped — parent session handles the OTA sign + push.
2026-09-09 00:56:41 +02:00
/* Screenshot editor v2 sidebar-embedded. Compact but not cramped; scales
the canvas to fit whatever width the sidebar has, up to full window when
the user hits the maximize button in the topbar. */
:root { color-scheme: light dark;
--bg:#0e131c; --panel:#141a24; --panel2:#191f2b; --line:rgba(255,255,255,.09);
--ink:#e7eaf1; --mut:#8b98a9; --dim:#5e6678; --acid:#d6ff3d;
--danger:#ff5b5b; --board:#0a0d13; }
@media (prefers-color-scheme: light) {
:root { --bg:#f8faff; --panel:#ffffff; --panel2:#eff3fb; --line:rgba(0,0,0,.10);
--ink:#1a1f2b; --mut:#5c6577; --dim:#8a93a5; --acid:#0AC18E;
--board:#dde3ee; }
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body { background: var(--bg); color: var(--ink);
font: 13px/1.5 system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
display: flex; flex-direction: column; overflow: hidden; }
/* Author styles set `display: flex` on .empty/.stage plain [hidden]
loses the cascade fight and the "Loading capture" pill stayed visible
over the drawn image. Force-hide takes it out for real. */
[hidden] { display: none !important; }
feat(theseus/screenshot): 0.5.0 — sidebar-first editor, direct save/copy, sounds Two problems the old editor kept hitting: - __pending drain race: opening the editor a second time (refresh, back-and- forth navigation) found the storage entry already consumed and bailed to a blank canvas silently. - Cross-origin img loading: editor.html at file:///…/addons/screenshot/ loading a scratch PNG at file:///…/addons-data/ counts as cross-origin under Chromium's file-URL policy; setting crossOrigin="anonymous" made the load fail outright. Rebuilt editor v2: - Load path is idempotent: silentmode.invoke("getBytes", {name}) → addon reads the scratch file and returns a data URL. No __pending drain, no cross-origin trickery — data: URLs are same-origin and never taint the canvas, so getImageData / toBlob keep working. - Two-canvas model (#base + #over, over is pointer-events:none) so live previews don't cost a full re-composite per mousemove. - Tools: cursor, arrow, rect, ellipse, pen, text. 6 swatches, 3 widths, undo / redo (25-deep). Copy + Save at the top bar. Back and Maximize buttons in the same top bar so navigation controls stay reachable when the toolbar wraps at narrow widths. - Keyboard: A/R/O/P/T select tool, Esc = cursor, Ctrl+Z/Shift+Z undo/redo, Ctrl+S save, Ctrl+C copy. - Toast surface for save/copy/error feedback. Sidebar panel gains a direct raw-save path so the user can copy or save the capture without entering the editor: - Two-row actions: [Copy] [Save] on top, [Discard] [Edit] below. - Copy uses navigator.clipboard.write(ClipboardItem); Save uses <a download> with a Blob URL — same path Chromium's will-download tracker already handles, so the file lands in Downloads and the chip updates like any other save. Inline "clear all" confirmation replaces the native confirm() — the old system-modal opened over the tab area (out of the sidebar's visual context) and looked like Windows 95. Now a compact red strip appears under the Recent header with Cancel / Delete buttons. Sounds + a sound-on/off toggle in both surfaces: - Web Audio oscillator-synthesized (no .wav shipped): shutter click on capture, two-tone bloop on copy, descending pair on discard/back, ascending triad on save. - Preference stored in silentmode.storage under "soundOn" (default on), shared between the panel and the editor. Simplifications: - Dropped the addon's "arm" onMessage handler (superseded by getBytes). - Manifest capabilities: sidebar-panel + capture-tab (no open-tab, no toolbar-menu). Bundled but not shipped — parent session handles the OTA sign + push.
2026-09-09 00:56:41 +02:00
.topbar, .toolbar { display: flex; align-items: center; gap: 4px; padding: 6px 8px;
border-bottom: 1px solid var(--line); background: var(--panel);
user-select: none; flex-wrap: wrap; }
feat(theseus/screenshot): 0.6.4 — Polaroid sounds, trash icon, centred cluster, filename footer + open-in-folder Rolling every user report from the 0.6.3 rollout into one bundle: Sounds — the Web-Audio synth palette matches the metaphor now: - Screenshot: Polaroid shutter — sharp metallic tick + curtain-close click chained to a film-advance whir (band-passed noise sweeping 900→400 Hz). - Copy: printer "chika-chika-chika" — three descending percussive noise bursts pinned by short sine ticks. Reads as a print-head sweep. - Discard: paper crumple — three overlapping band-limited noise beds with per-sample random-amplitude crackle, descending centre freq. No more descending sine "boop". - Save: soft "photo dispensing" hiss (Polaroid ejects) + a small click. - Both the panel and editor share the design so nothing sounds different depending on which surface fired it. UI polish: - Discard button now carries a trash-can icon so it's obviously not the same as the close-sidebar X (they both used to be plain X's). - Toolbar drawing tools centre themselves via a new .tool-cluster wrapper (flex:1 1 auto, justify-content:center); the Copy/Save actions stay right-anchored via margin-left:auto on their own tgroup. Fixes the maximized-sidebar case where the drawing groups all crowded the left with a big empty gap before Copy/Save on the right. - Filename moves out of the topbar into a dedicated footer strip under the canvas board, alongside a new "Open in folder" button. The topbar is now flex-wrap:nowrap and holds only fixed-width window controls, so a long filename can never push discard / sound / max / close onto a second row (the filename ellipsises instead). - "Open in folder" invokes a new "openFolder" addon message that calls Electron's shell.showItemInFolder() to open the OS file explorer with the specific scratch PNG highlighted (falls back to shell.openPath() on the scratch dir when no capture is named). Version bump so the OTA update endpoint picks it up on the next tick.
2026-09-09 22:34:47 +02:00
/* The topbar has fixed-size window controls only; no reason to ever wrap
its row. Filename lives in the footer now, so nothing can grow the row
past what the icons need. */
.topbar { flex-wrap: nowrap; }
/* Toolbar layout: drawing tools live inside `.tool-cluster` which is a
flex-grow container centring its own contents. Copy/Save (`.tgroup
.actions`) sit outside it and pin to the right edge. On a maximized
sidebar the cluster centres in the empty space between name-area and
the actions; at narrow widths the whole cluster shrinks and wraps by
category, and the actions can wrap to their own row on the right. */
.toolbar { align-items: flex-start; gap: 8px; row-gap: 6px; }
.tool-cluster {
display: flex; flex-wrap: wrap; align-items: center;
gap: 10px; row-gap: 6px;
flex: 1 1 auto; justify-content: center;
}
feat(theseus/screenshot): 0.6.1 — text tool fix, category wrap, sidebar close X Four user reports from the 0.6.0 rollout: - Text tool never committed. openTextInput placed the box correctly but a couple of Chromium quirks stopped a normal type-Enter cycle: focus() called synchronously right after appendChild lost the race in some builds, and the input's own mousedown / click was bubbling through to #base and re-firing openTextInput on every subsequent keystroke click-through, so what looked like "nothing happens" was actually "a new empty box spawned on top of the last one every time". Now: focus after requestAnimationFrame, contain pointerdown / mousedown / click inside the input so they don't bubble to the canvas, track the font size on the state so commit uses the same one openTextInput measured against, and preventDefault on the base pointerdown so Chromium doesn't reset focus back to <body>. - Toolbar wrapped one dot at a time when the sidebar was narrow (a lonely thin/medium/thick width would jump to a second row while the swatches stayed above it). Toolbar items are now wrapped in `<div class="tgroup">` per category — tools / swatches / widths / undo-redo — with `flex: 0 0 auto`, so a whole row wraps as a unit and lands cleanly under the previous one. `gap: 10px / row-gap: 6px` keeps the visual grouping obvious. - No way to close the sidebar without hunting for the dock icon. Added an X button in the top-right of both the sidebar panel and the editor toolbar. Both wire through a new `silentmode.sidebar.close()` preload method that calls the existing `sidebar-close` IPC. - Tightened the pointerdown text branch so preventDefault + explicit focus-after-frame make the click-through races impossible. Bundled but not shipped separately — parent session signs and pushes.
2026-09-09 10:55:21 +02:00
.tgroup { display: inline-flex; align-items: center; gap: 4px; flex: 0 0 auto; }
feat(theseus/screenshot): 0.6.4 — Polaroid sounds, trash icon, centred cluster, filename footer + open-in-folder Rolling every user report from the 0.6.3 rollout into one bundle: Sounds — the Web-Audio synth palette matches the metaphor now: - Screenshot: Polaroid shutter — sharp metallic tick + curtain-close click chained to a film-advance whir (band-passed noise sweeping 900→400 Hz). - Copy: printer "chika-chika-chika" — three descending percussive noise bursts pinned by short sine ticks. Reads as a print-head sweep. - Discard: paper crumple — three overlapping band-limited noise beds with per-sample random-amplitude crackle, descending centre freq. No more descending sine "boop". - Save: soft "photo dispensing" hiss (Polaroid ejects) + a small click. - Both the panel and editor share the design so nothing sounds different depending on which surface fired it. UI polish: - Discard button now carries a trash-can icon so it's obviously not the same as the close-sidebar X (they both used to be plain X's). - Toolbar drawing tools centre themselves via a new .tool-cluster wrapper (flex:1 1 auto, justify-content:center); the Copy/Save actions stay right-anchored via margin-left:auto on their own tgroup. Fixes the maximized-sidebar case where the drawing groups all crowded the left with a big empty gap before Copy/Save on the right. - Filename moves out of the topbar into a dedicated footer strip under the canvas board, alongside a new "Open in folder" button. The topbar is now flex-wrap:nowrap and holds only fixed-width window controls, so a long filename can never push discard / sound / max / close onto a second row (the filename ellipsises instead). - "Open in folder" invokes a new "openFolder" addon message that calls Electron's shell.showItemInFolder() to open the OS file explorer with the specific scratch PNG highlighted (falls back to shell.openPath() on the scratch dir when no capture is named). Version bump so the OTA update endpoint picks it up on the next tick.
2026-09-09 22:34:47 +02:00
.tgroup.actions { flex: 0 0 auto; align-self: center; }
feat(theseus/screenshot): 0.6.1 — text tool fix, category wrap, sidebar close X Four user reports from the 0.6.0 rollout: - Text tool never committed. openTextInput placed the box correctly but a couple of Chromium quirks stopped a normal type-Enter cycle: focus() called synchronously right after appendChild lost the race in some builds, and the input's own mousedown / click was bubbling through to #base and re-firing openTextInput on every subsequent keystroke click-through, so what looked like "nothing happens" was actually "a new empty box spawned on top of the last one every time". Now: focus after requestAnimationFrame, contain pointerdown / mousedown / click inside the input so they don't bubble to the canvas, track the font size on the state so commit uses the same one openTextInput measured against, and preventDefault on the base pointerdown so Chromium doesn't reset focus back to <body>. - Toolbar wrapped one dot at a time when the sidebar was narrow (a lonely thin/medium/thick width would jump to a second row while the swatches stayed above it). Toolbar items are now wrapped in `<div class="tgroup">` per category — tools / swatches / widths / undo-redo — with `flex: 0 0 auto`, so a whole row wraps as a unit and lands cleanly under the previous one. `gap: 10px / row-gap: 6px` keeps the visual grouping obvious. - No way to close the sidebar without hunting for the dock icon. Added an X button in the top-right of both the sidebar panel and the editor toolbar. Both wire through a new `silentmode.sidebar.close()` preload method that calls the existing `sidebar-close` IPC. - Tightened the pointerdown text branch so preventDefault + explicit focus-after-frame make the click-through races impossible. Bundled but not shipped separately — parent session signs and pushes.
2026-09-09 10:55:21 +02:00
/* Close-sidebar button — reads as danger without shouting. */
#close-sidebar:hover,
#discard:hover { border-color: rgba(255,91,91,.55); color: var(--danger); }
.btn.danger { color: var(--danger); }
.btn.danger:hover { border-color: rgba(255,91,91,.55); }
feat(theseus/screenshot): 0.5.0 — sidebar-first editor, direct save/copy, sounds Two problems the old editor kept hitting: - __pending drain race: opening the editor a second time (refresh, back-and- forth navigation) found the storage entry already consumed and bailed to a blank canvas silently. - Cross-origin img loading: editor.html at file:///…/addons/screenshot/ loading a scratch PNG at file:///…/addons-data/ counts as cross-origin under Chromium's file-URL policy; setting crossOrigin="anonymous" made the load fail outright. Rebuilt editor v2: - Load path is idempotent: silentmode.invoke("getBytes", {name}) → addon reads the scratch file and returns a data URL. No __pending drain, no cross-origin trickery — data: URLs are same-origin and never taint the canvas, so getImageData / toBlob keep working. - Two-canvas model (#base + #over, over is pointer-events:none) so live previews don't cost a full re-composite per mousemove. - Tools: cursor, arrow, rect, ellipse, pen, text. 6 swatches, 3 widths, undo / redo (25-deep). Copy + Save at the top bar. Back and Maximize buttons in the same top bar so navigation controls stay reachable when the toolbar wraps at narrow widths. - Keyboard: A/R/O/P/T select tool, Esc = cursor, Ctrl+Z/Shift+Z undo/redo, Ctrl+S save, Ctrl+C copy. - Toast surface for save/copy/error feedback. Sidebar panel gains a direct raw-save path so the user can copy or save the capture without entering the editor: - Two-row actions: [Copy] [Save] on top, [Discard] [Edit] below. - Copy uses navigator.clipboard.write(ClipboardItem); Save uses <a download> with a Blob URL — same path Chromium's will-download tracker already handles, so the file lands in Downloads and the chip updates like any other save. Inline "clear all" confirmation replaces the native confirm() — the old system-modal opened over the tab area (out of the sidebar's visual context) and looked like Windows 95. Now a compact red strip appears under the Recent header with Cancel / Delete buttons. Sounds + a sound-on/off toggle in both surfaces: - Web Audio oscillator-synthesized (no .wav shipped): shutter click on capture, two-tone bloop on copy, descending pair on discard/back, ascending triad on save. - Preference stored in silentmode.storage under "soundOn" (default on), shared between the panel and the editor. Simplifications: - Dropped the addon's "arm" onMessage handler (superseded by getBytes). - Manifest capabilities: sidebar-panel + capture-tab (no open-tab, no toolbar-menu). Bundled but not shipped — parent session handles the OTA sign + push.
2026-09-09 00:56:41 +02:00
.topbar .name { color: var(--dim); font-size: 11.5px; overflow: hidden;
text-overflow: ellipsis; white-space: nowrap; max-width: 200px; margin: 0 4px; }
feat(theseus/screenshot): 0.6.4 — Polaroid sounds, trash icon, centred cluster, filename footer + open-in-folder Rolling every user report from the 0.6.3 rollout into one bundle: Sounds — the Web-Audio synth palette matches the metaphor now: - Screenshot: Polaroid shutter — sharp metallic tick + curtain-close click chained to a film-advance whir (band-passed noise sweeping 900→400 Hz). - Copy: printer "chika-chika-chika" — three descending percussive noise bursts pinned by short sine ticks. Reads as a print-head sweep. - Discard: paper crumple — three overlapping band-limited noise beds with per-sample random-amplitude crackle, descending centre freq. No more descending sine "boop". - Save: soft "photo dispensing" hiss (Polaroid ejects) + a small click. - Both the panel and editor share the design so nothing sounds different depending on which surface fired it. UI polish: - Discard button now carries a trash-can icon so it's obviously not the same as the close-sidebar X (they both used to be plain X's). - Toolbar drawing tools centre themselves via a new .tool-cluster wrapper (flex:1 1 auto, justify-content:center); the Copy/Save actions stay right-anchored via margin-left:auto on their own tgroup. Fixes the maximized-sidebar case where the drawing groups all crowded the left with a big empty gap before Copy/Save on the right. - Filename moves out of the topbar into a dedicated footer strip under the canvas board, alongside a new "Open in folder" button. The topbar is now flex-wrap:nowrap and holds only fixed-width window controls, so a long filename can never push discard / sound / max / close onto a second row (the filename ellipsises instead). - "Open in folder" invokes a new "openFolder" addon message that calls Electron's shell.showItemInFolder() to open the OS file explorer with the specific scratch PNG highlighted (falls back to shell.openPath() on the scratch dir when no capture is named). Version bump so the OTA update endpoint picks it up on the next tick.
2026-09-09 22:34:47 +02:00
/* Footer strip that carries the filename + "Open in folder" affordance,
sitting under the canvas board. The filename truncates first so the
button never falls off the edge; the button never wraps. */
.footer { display: flex; align-items: center; gap: 8px;
padding: 6px 10px; border-top: 1px solid var(--line);
background: var(--panel); font-size: 11.5px; }
.footer .fname { color: var(--dim); flex: 1 1 auto; min-width: 0;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.footer .fbtn { border: 1px solid var(--line); background: var(--panel2);
color: var(--ink); border-radius: 6px; cursor: pointer;
padding: 4px 8px; display: inline-flex; gap: 6px; align-items: center;
flex: 0 0 auto; font: inherit; line-height: 1; }
.footer .fbtn svg { width: 14px; height: 14px; display: block; }
.footer .fbtn:hover { border-color: rgb(from var(--acid) r g b / .55); }
feat(theseus/screenshot): 0.5.0 — sidebar-first editor, direct save/copy, sounds Two problems the old editor kept hitting: - __pending drain race: opening the editor a second time (refresh, back-and- forth navigation) found the storage entry already consumed and bailed to a blank canvas silently. - Cross-origin img loading: editor.html at file:///…/addons/screenshot/ loading a scratch PNG at file:///…/addons-data/ counts as cross-origin under Chromium's file-URL policy; setting crossOrigin="anonymous" made the load fail outright. Rebuilt editor v2: - Load path is idempotent: silentmode.invoke("getBytes", {name}) → addon reads the scratch file and returns a data URL. No __pending drain, no cross-origin trickery — data: URLs are same-origin and never taint the canvas, so getImageData / toBlob keep working. - Two-canvas model (#base + #over, over is pointer-events:none) so live previews don't cost a full re-composite per mousemove. - Tools: cursor, arrow, rect, ellipse, pen, text. 6 swatches, 3 widths, undo / redo (25-deep). Copy + Save at the top bar. Back and Maximize buttons in the same top bar so navigation controls stay reachable when the toolbar wraps at narrow widths. - Keyboard: A/R/O/P/T select tool, Esc = cursor, Ctrl+Z/Shift+Z undo/redo, Ctrl+S save, Ctrl+C copy. - Toast surface for save/copy/error feedback. Sidebar panel gains a direct raw-save path so the user can copy or save the capture without entering the editor: - Two-row actions: [Copy] [Save] on top, [Discard] [Edit] below. - Copy uses navigator.clipboard.write(ClipboardItem); Save uses <a download> with a Blob URL — same path Chromium's will-download tracker already handles, so the file lands in Downloads and the chip updates like any other save. Inline "clear all" confirmation replaces the native confirm() — the old system-modal opened over the tab area (out of the sidebar's visual context) and looked like Windows 95. Now a compact red strip appears under the Recent header with Cancel / Delete buttons. Sounds + a sound-on/off toggle in both surfaces: - Web Audio oscillator-synthesized (no .wav shipped): shutter click on capture, two-tone bloop on copy, descending pair on discard/back, ascending triad on save. - Preference stored in silentmode.storage under "soundOn" (default on), shared between the panel and the editor. Simplifications: - Dropped the addon's "arm" onMessage handler (superseded by getBytes). - Manifest capabilities: sidebar-panel + capture-tab (no open-tab, no toolbar-menu). Bundled but not shipped — parent session handles the OTA sign + push.
2026-09-09 00:56:41 +02:00
.topbar .spacer, .toolbar .spacer { flex: 1; }
.btn, .tool {
border: 1px solid var(--line); background: var(--panel2); color: var(--ink);
width: 30px; height: 30px; border-radius: 6px; cursor: pointer;
display: inline-flex; align-items: center; justify-content: center;
padding: 0; transition: background 100ms, border-color 100ms;
font: inherit; line-height: 0;
}
.btn:hover, .tool:hover { border-color: rgb(from var(--acid) r g b / .5); }
.btn:disabled, .tool:disabled { opacity: .4; cursor: default; }
.btn:disabled:hover, .tool:disabled:hover { border-color: var(--line); }
.tool.active {
background: rgb(from var(--acid) r g b / .15);
border-color: rgb(from var(--acid) r g b / .7);
color: var(--acid);
}
.btn svg, .tool svg { width: 16px; height: 16px; display: block; }
.btn.wide {
width: auto; padding: 0 10px; gap: 6px; line-height: 1;
}
.btn.wide span { font-size: 12px; }
.btn.primary {
background: var(--acid); color: #101418; border-color: transparent; font-weight: 600;
}
.btn.primary:hover { filter: brightness(1.06); border-color: transparent; }
.sep { width: 1px; height: 20px; background: var(--line); margin: 0 3px; }
.swatch {
width: 22px; height: 22px; border-radius: 50%; padding: 0;
border: 2px solid var(--line); cursor: pointer;
}
.swatch.active {
border-color: var(--acid);
outline: 1px solid rgb(from var(--acid) r g b / .35); outline-offset: 1px;
}
.width {
border: 1px solid var(--line); background: var(--panel2); color: var(--ink);
width: 30px; height: 30px; border-radius: 6px; cursor: pointer;
display: inline-flex; align-items: center; justify-content: center; padding: 0;
}
.width.active {
border-color: rgb(from var(--acid) r g b / .7);
background: rgb(from var(--acid) r g b / .15);
}
.width .dot { border-radius: 50%; background: currentColor; color: var(--ink); }
.width.active .dot { color: var(--acid); }
/* Canvas board -------------------------------------------------------- */
.board {
flex: 1; overflow: auto; background: var(--board);
display: flex; align-items: flex-start; justify-content: center;
padding: 12px;
}
.empty { color: var(--dim); font-size: 13px; padding: 40px 20px; text-align: center;
display: flex; align-items: center; justify-content: center; height: 100%; }
.empty.err { color: var(--danger); }
.stage { position: relative; transform-origin: top left;
box-shadow: 0 2px 12px rgba(0,0,0,.35); background: #fff; }
.stage canvas { display: block; position: absolute; left: 0; top: 0; }
.stage #base { position: static; }
.stage #over { pointer-events: none; }
.stage[data-tool="arrow"] { cursor: crosshair; }
.stage[data-tool="line"] { cursor: crosshair; }
feat(theseus/screenshot): 0.5.0 — sidebar-first editor, direct save/copy, sounds Two problems the old editor kept hitting: - __pending drain race: opening the editor a second time (refresh, back-and- forth navigation) found the storage entry already consumed and bailed to a blank canvas silently. - Cross-origin img loading: editor.html at file:///…/addons/screenshot/ loading a scratch PNG at file:///…/addons-data/ counts as cross-origin under Chromium's file-URL policy; setting crossOrigin="anonymous" made the load fail outright. Rebuilt editor v2: - Load path is idempotent: silentmode.invoke("getBytes", {name}) → addon reads the scratch file and returns a data URL. No __pending drain, no cross-origin trickery — data: URLs are same-origin and never taint the canvas, so getImageData / toBlob keep working. - Two-canvas model (#base + #over, over is pointer-events:none) so live previews don't cost a full re-composite per mousemove. - Tools: cursor, arrow, rect, ellipse, pen, text. 6 swatches, 3 widths, undo / redo (25-deep). Copy + Save at the top bar. Back and Maximize buttons in the same top bar so navigation controls stay reachable when the toolbar wraps at narrow widths. - Keyboard: A/R/O/P/T select tool, Esc = cursor, Ctrl+Z/Shift+Z undo/redo, Ctrl+S save, Ctrl+C copy. - Toast surface for save/copy/error feedback. Sidebar panel gains a direct raw-save path so the user can copy or save the capture without entering the editor: - Two-row actions: [Copy] [Save] on top, [Discard] [Edit] below. - Copy uses navigator.clipboard.write(ClipboardItem); Save uses <a download> with a Blob URL — same path Chromium's will-download tracker already handles, so the file lands in Downloads and the chip updates like any other save. Inline "clear all" confirmation replaces the native confirm() — the old system-modal opened over the tab area (out of the sidebar's visual context) and looked like Windows 95. Now a compact red strip appears under the Recent header with Cancel / Delete buttons. Sounds + a sound-on/off toggle in both surfaces: - Web Audio oscillator-synthesized (no .wav shipped): shutter click on capture, two-tone bloop on copy, descending pair on discard/back, ascending triad on save. - Preference stored in silentmode.storage under "soundOn" (default on), shared between the panel and the editor. Simplifications: - Dropped the addon's "arm" onMessage handler (superseded by getBytes). - Manifest capabilities: sidebar-panel + capture-tab (no open-tab, no toolbar-menu). Bundled but not shipped — parent session handles the OTA sign + push.
2026-09-09 00:56:41 +02:00
.stage[data-tool="rect"] { cursor: crosshair; }
.stage[data-tool="ellipse"]{ cursor: crosshair; }
.stage[data-tool="pen"] { cursor: crosshair; }
.stage[data-tool="text"] { cursor: text; }
feat(theseus/screenshot): 0.6.0 — crop + mosaic redaction, right-anchored sidebar controls, real shutter+print sounds Editor: - Crop tool restored — drag to select, marquee sits with a dashed acid border and a dimmed backdrop for the area you'll discard, then the topbar shows Apply crop / Cancel. Applying trims #base to the rect, resets undo (dimensions changed), and drops back into the select tool. Enter / Esc keyboard shortcuts while a crop is pending. - Blur / mosaic redaction tool back — drag a rectangle, editor downsamples that region of #base to ~12-block granularity and paints the blocks back nearest-neighbour. Commits directly (no confirm step). - Sidebar-window controls (Back, name, Copy, Save, Sound, Maximize) reflow: Back + name on the left, Copy + Save + Sound + Maximize on the right so the "put the sidebar back to normal size" affordance lives where users expect it. Toolbar's drawing tools stay centred. - Back arrow icon swapped from a chevron to a proper flat arrow (line + arrowhead), matching the new browser back/forward glyphs. Sounds — modeled on Firefox Screenshots' feedback rather than beeps: - Shutter is now a real photoshoot click: two mirror-slaps built from a band-passed noise burst (metallic ping) plus a very short square-wave thud each. Sounds like a camera, not a beep. - Copy is a two-chirp "printer feed" — filtered noise burst on top of a sine chirp per beat, staccato ascending pair. Same shape Firefox Easy Screenshot uses for "copied to clipboard". - Save keeps its ascending triad; Discard keeps its descending pair; new small ascending pair for Apply crop. Chrome: - Browser Back / Forward chevrons (M10 3 L5 8 L10 13 — two segments meeting at a point, no shaft) replaced with straight-arrow glyphs (line + arrowhead). Reads as a navigation arrow, not an angle bracket. Bundled but not shipped separately — parent session OTA-signs and pushes.
2026-09-09 10:24:03 +02:00
.stage[data-tool="crop"] { cursor: crosshair; }
.stage[data-tool="blur"] { cursor: crosshair; }
/* Apply-crop is the primary action while a crop marquee is up. */
#apply-crop {
background: var(--acid); color: #101418; border-color: transparent; font-weight: 600;
}
#apply-crop:hover { filter: brightness(1.06); background: var(--acid); border-color: transparent; }
#cancel-crop:hover { border-color: rgba(255,91,91,.5); color: var(--danger); }
feat(theseus/screenshot): 0.5.0 — sidebar-first editor, direct save/copy, sounds Two problems the old editor kept hitting: - __pending drain race: opening the editor a second time (refresh, back-and- forth navigation) found the storage entry already consumed and bailed to a blank canvas silently. - Cross-origin img loading: editor.html at file:///…/addons/screenshot/ loading a scratch PNG at file:///…/addons-data/ counts as cross-origin under Chromium's file-URL policy; setting crossOrigin="anonymous" made the load fail outright. Rebuilt editor v2: - Load path is idempotent: silentmode.invoke("getBytes", {name}) → addon reads the scratch file and returns a data URL. No __pending drain, no cross-origin trickery — data: URLs are same-origin and never taint the canvas, so getImageData / toBlob keep working. - Two-canvas model (#base + #over, over is pointer-events:none) so live previews don't cost a full re-composite per mousemove. - Tools: cursor, arrow, rect, ellipse, pen, text. 6 swatches, 3 widths, undo / redo (25-deep). Copy + Save at the top bar. Back and Maximize buttons in the same top bar so navigation controls stay reachable when the toolbar wraps at narrow widths. - Keyboard: A/R/O/P/T select tool, Esc = cursor, Ctrl+Z/Shift+Z undo/redo, Ctrl+S save, Ctrl+C copy. - Toast surface for save/copy/error feedback. Sidebar panel gains a direct raw-save path so the user can copy or save the capture without entering the editor: - Two-row actions: [Copy] [Save] on top, [Discard] [Edit] below. - Copy uses navigator.clipboard.write(ClipboardItem); Save uses <a download> with a Blob URL — same path Chromium's will-download tracker already handles, so the file lands in Downloads and the chip updates like any other save. Inline "clear all" confirmation replaces the native confirm() — the old system-modal opened over the tab area (out of the sidebar's visual context) and looked like Windows 95. Now a compact red strip appears under the Recent header with Cancel / Delete buttons. Sounds + a sound-on/off toggle in both surfaces: - Web Audio oscillator-synthesized (no .wav shipped): shutter click on capture, two-tone bloop on copy, descending pair on discard/back, ascending triad on save. - Preference stored in silentmode.storage under "soundOn" (default on), shared between the panel and the editor. Simplifications: - Dropped the addon's "arm" onMessage handler (superseded by getBytes). - Manifest capabilities: sidebar-panel + capture-tab (no open-tab, no toolbar-menu). Bundled but not shipped — parent session handles the OTA sign + push.
2026-09-09 00:56:41 +02:00
.text-input {
position: absolute; z-index: 10;
background: rgba(20,26,36,.92); color: var(--ink);
border: 1px solid var(--acid); padding: 2px 6px;
font: 15px/1.2 system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
outline: none; border-radius: 3px;
/* Textarea variant corner drag-to-resize is on (see resize:both in
JS). These floors keep the box visible even if the user resizes it
down to almost nothing. */
min-width: 80px; min-height: 24px;
overflow: auto;
feat(theseus/screenshot): 0.5.0 — sidebar-first editor, direct save/copy, sounds Two problems the old editor kept hitting: - __pending drain race: opening the editor a second time (refresh, back-and- forth navigation) found the storage entry already consumed and bailed to a blank canvas silently. - Cross-origin img loading: editor.html at file:///…/addons/screenshot/ loading a scratch PNG at file:///…/addons-data/ counts as cross-origin under Chromium's file-URL policy; setting crossOrigin="anonymous" made the load fail outright. Rebuilt editor v2: - Load path is idempotent: silentmode.invoke("getBytes", {name}) → addon reads the scratch file and returns a data URL. No __pending drain, no cross-origin trickery — data: URLs are same-origin and never taint the canvas, so getImageData / toBlob keep working. - Two-canvas model (#base + #over, over is pointer-events:none) so live previews don't cost a full re-composite per mousemove. - Tools: cursor, arrow, rect, ellipse, pen, text. 6 swatches, 3 widths, undo / redo (25-deep). Copy + Save at the top bar. Back and Maximize buttons in the same top bar so navigation controls stay reachable when the toolbar wraps at narrow widths. - Keyboard: A/R/O/P/T select tool, Esc = cursor, Ctrl+Z/Shift+Z undo/redo, Ctrl+S save, Ctrl+C copy. - Toast surface for save/copy/error feedback. Sidebar panel gains a direct raw-save path so the user can copy or save the capture without entering the editor: - Two-row actions: [Copy] [Save] on top, [Discard] [Edit] below. - Copy uses navigator.clipboard.write(ClipboardItem); Save uses <a download> with a Blob URL — same path Chromium's will-download tracker already handles, so the file lands in Downloads and the chip updates like any other save. Inline "clear all" confirmation replaces the native confirm() — the old system-modal opened over the tab area (out of the sidebar's visual context) and looked like Windows 95. Now a compact red strip appears under the Recent header with Cancel / Delete buttons. Sounds + a sound-on/off toggle in both surfaces: - Web Audio oscillator-synthesized (no .wav shipped): shutter click on capture, two-tone bloop on copy, descending pair on discard/back, ascending triad on save. - Preference stored in silentmode.storage under "soundOn" (default on), shared between the panel and the editor. Simplifications: - Dropped the addon's "arm" onMessage handler (superseded by getBytes). - Manifest capabilities: sidebar-panel + capture-tab (no open-tab, no toolbar-menu). Bundled but not shipped — parent session handles the OTA sign + push.
2026-09-09 00:56:41 +02:00
}
.toast {
position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%) translateY(20px);
padding: 8px 14px; border-radius: 6px; background: rgba(11,14,20,.94);
color: var(--ink); font-size: 12.5px; border: 1px solid var(--line);
opacity: 0; pointer-events: none; transition: opacity 180ms, transform 180ms;
z-index: 100; max-width: 80vw; text-align: center;
}
.toast.on { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.err { border-color: rgba(255,91,91,.5); color: var(--danger); }
</style>