Skip to content
Download

Every window,
in its place.

Every project gets its own workspace: your apps and windows arranged and ready in one click.

Download for Windows

Free and open source. Requirements

Code
checkout.tsx - shop - Code

SHOP

app
checkout
page.tsx
checkout.tsx
components
button.tsx
price.tsx
lib
cart.ts
money.ts
pay.ts
checkout.tsx
cart.ts
pay.ts
app checkout checkout.tsx
1import { useState } from "react"
2import { useRouter } from "next/navigation"
3import { useCart } from "@/lib/cart"
4import { formatPrice } from "@/lib/money"
5
6export function Checkout() {
7 const router = useRouter()
8 const { items, total } = useCart()
9 const [status, setStatus] = useState<"idle" | "paying">("idle")
10
11 async function pay() {
12 setStatus("paying")
13 const res = await fetch("/api/pay", {
14 method: "POST",
15 body: JSON.stringify({ items, total }),
16 })
17 if (!res.ok) throw new Error("Payment failed")
18 router.push("/thanks")
19 }
20
21 return (
22 <button onClick={pay} disabled={status === "paying"}>
23 Pay {formatPrice(total)}
24 </button>
25 )
26}
feat/checkoutLn 17, Col 40    TypeScript React
Code
checkout.tsx - shop - Code

SHOP

app
checkout
page.tsx
checkout.tsx
components
button.tsx
price.tsx
lib
cart.ts
money.ts
pay.ts
checkout.tsx
cart.ts
pay.ts
app checkout checkout.tsx
1import { useState } from "react"
2import { useRouter } from "next/navigation"
3import { useCart } from "@/lib/cart"
4import { formatPrice } from "@/lib/money"
5
6export function Checkout() {
7 const router = useRouter()
8 const { items, total } = useCart()
9 const [status, setStatus] = useState<"idle" | "paying">("idle")
10
11 async function pay() {
12 setStatus("paying")
13 const res = await fetch("/api/pay", {
14 method: "POST",
15 body: JSON.stringify({ items, total }),
16 })
17 if (!res.ok) throw new Error("Payment failed")
18 router.push("/thanks")
19 }
20
21 return (
22 <button onClick={pay} disabled={status === "paying"}>
23 Pay {formatPrice(total)}
24 </button>
25 )
26}
feat/checkoutLn 17, Col 40    TypeScript React
Terminal
>_ PowerShell
Ubuntu
shop on feat/checkout ❯ npm run dev
▲ Next.js 16
- Local: http://localhost:3000
✓ Ready in 842ms
○ Compiling /checkout ...
✓ Compiled /checkout in 311ms
GET /checkout 200 in 38ms
POST /api/pay 200 in 112ms
GET /thanks 200 in 21ms
shop on feat/checkout ❯
Review
Add one-tap checkout #482
git.acme.dev/shop/pull/482/files
S

Add one-tap checkout #482

Openana wants to merge 3 commits into main from feat/checkout
Conversation 4Commits 3Checks 6Files changed 5
lib/cart.ts+14 −3
41 export function total(items: Item[]) {
42- return items.reduce((s, i) => s + i.price, 0)
43+ const sum = items.reduce((s, i) => s + i.price * i.qty, 0)
44+ return Math.round(sum * 100) / 100
45 }
46
47+export const SHIPPING_FREE_OVER = 75
All checks have passed 6 successful checks
Team
Acme - releases

Acme

general

releases

design

random

Direct messages

Ana

Ravi

Mia

releases
M

Mia 09:31

Morning. Checkout copy is in review, feedback welcome.

R

Ravi 09:48

Looks good to me. One nit on the empty cart state.

A

Ana 10:05

Fixed the nit and pushed. CI is running.

M

Mia 10:12

Thanks! Approving once it goes green.

A

Ana 10:42

Staging is green. Merging #482 after lunch.

R

Ravi 10:44

Pay button copy is updated. Can someone check it on mobile?

M

Mia 10:51

On it. Release notes draft is in the doc.

A

Ana 10:58

Thanks both. Tagging v2.4.0 at 3.

Message #releases

Ship the release. Editor, terminal, pull request and team chat, switched as one.

Three ideas that tidy a whole desktop.

Zones give every window a home

Carve the screen into named areas, like Code, Terminal and Review. Drag a window near one and Mosaïk pulls it in. Open a project and everything lands where you left it.

  • Zones belong to the project, not the monitor
  • Every window wears its zone’s colour, so you can tell at a glance
  • Works across multiple displays
Code
checkout.tsx - shop - Code

SHOP

app
checkout
page.tsx
checkout.tsx
components
button.tsx
price.tsx
lib
cart.ts
money.ts
pay.ts
checkout.tsx
cart.ts
pay.ts
app checkout checkout.tsx
1import { useState } from "react"
2import { useRouter } from "next/navigation"
3import { useCart } from "@/lib/cart"
4import { formatPrice } from "@/lib/money"
5
6export function Checkout() {
7 const router = useRouter()
8 const { items, total } = useCart()
9 const [status, setStatus] = useState<"idle" | "paying">("idle")
10
11 async function pay() {
12 setStatus("paying")
13 const res = await fetch("/api/pay", {
14 method: "POST",
15 body: JSON.stringify({ items, total }),
16 })
17 if (!res.ok) throw new Error("Payment failed")
18 router.push("/thanks")
19 }
20
21 return (
22 <button onClick={pay} disabled={status === "paying"}>
23 Pay {formatPrice(total)}
24 </button>
25 )
26}
feat/checkoutLn 17, Col 40    TypeScript React
Terminal
>_ PowerShell
Ubuntu
shop on feat/checkout ❯ npm run dev
▲ Next.js 16
- Local: http://localhost:3000
✓ Ready in 842ms
○ Compiling /checkout ...
✓ Compiled /checkout in 311ms
GET /checkout 200 in 38ms
POST /api/pay 200 in 112ms
GET /thanks 200 in 21ms
shop on feat/checkout ❯

Release to place in Review

Review
Add one-tap checkout #482
git.acme.dev/shop/pull/482/files
S

Add one-tap checkout #482

Openana wants to merge 3 commits into main from feat/checkout
Conversation 4Commits 3Checks 6Files changed 5
lib/cart.ts+14 −3
41 export function total(items: Item[]) {
42- return items.reduce((s, i) => s + i.price, 0)
43+ const sum = items.reduce((s, i) => s + i.price * i.qty, 0)
44+ return Math.round(sum * 100) / 100
45 }
46
47+export const SHIPPING_FREE_OVER = 75
All checks have passed 6 successful checks

Tabs for any app, not only the browser

Stack your editor, terminal and design tool into one frame and flip between them like browser tabs. Tabs dragged out of Chrome or Edge join in too. One window to find instead of twelve.

  • Group any windows into one tab strip
  • Tab order is remembered per workspace
  • Pull a tab out and it becomes a window again
Code
Editor
Terminal
Browser
Design
Drop to add

SHOP

app
checkout
page.tsx
checkout.tsx
components
button.tsx
price.tsx
lib
cart.ts
money.ts
pay.ts
checkout.tsx
cart.ts
pay.ts
app checkout checkout.tsx
1import { useState } from "react"
2import { useRouter } from "next/navigation"
3import { useCart } from "@/lib/cart"
4import { formatPrice } from "@/lib/money"
5
6export function Checkout() {
7 const router = useRouter()
8 const { items, total } = useCart()
9 const [status, setStatus] = useState<"idle" | "paying">("idle")
10
11 async function pay() {
12 setStatus("paying")
13 const res = await fetch("/api/pay", {
14 method: "POST",
15 body: JSON.stringify({ items, total }),
16 })
17 if (!res.ok) throw new Error("Payment failed")
18 router.push("/thanks")
19 }
20
21 return (
22 <button onClick={pay} disabled={status === "paying"}>
23 Pay {formatPrice(total)}
24 </button>
25 )
26}
feat/checkoutLn 17, Col 40    TypeScript React
Team
Acme - releases

Acme

general

releases

design

random

Direct messages

Ana

Ravi

Mia

releases
M

Mia 09:31

Morning. Checkout copy is in review, feedback welcome.

R

Ravi 09:48

Looks good to me. One nit on the empty cart state.

A

Ana 10:05

Fixed the nit and pushed. CI is running.

M

Mia 10:12

Thanks! Approving once it goes green.

A

Ana 10:42

Staging is green. Merging #482 after lunch.

R

Ravi 10:44

Pay button copy is updated. Can someone check it on mobile?

M

Mia 10:51

On it. Release notes draft is in the doc.

A

Ana 10:58

Thanks both. Tagging v2.4.0 at 3.

Message #releases

Switch projects, not just windows

Save a workspace once and bring it back whenever you need it. Positions, sizes and tabs return together, so changing task takes a keystroke instead of ten minutes of rearranging.

  • One workspace per project, role or mood
  • Saved on your computer, never in a cloud
  • Switch from the tray, or press Win+Alt+Space

One desktop, many kinds of work.

A workspace is whatever you need open together. These four are the ones we kept reaching for.

Code
checkout.tsx - shop - Code

SHOP

app
checkout
page.tsx
checkout.tsx
components
button.tsx
price.tsx
lib
cart.ts
money.ts
pay.ts
checkout.tsx
cart.ts
pay.ts
app checkout checkout.tsx
1import { useState } from "react"
2import { useRouter } from "next/navigation"
3import { useCart } from "@/lib/cart"
4import { formatPrice } from "@/lib/money"
5
6export function Checkout() {
7 const router = useRouter()
8 const { items, total } = useCart()
9 const [status, setStatus] = useState<"idle" | "paying">("idle")
10
11 async function pay() {
12 setStatus("paying")
13 const res = await fetch("/api/pay", {
14 method: "POST",
15 body: JSON.stringify({ items, total }),
16 })
17 if (!res.ok) throw new Error("Payment failed")
18 router.push("/thanks")
19 }
20
21 return (
22 <button onClick={pay} disabled={status === "paying"}>
23 Pay {formatPrice(total)}
24 </button>
25 )
26}
feat/checkoutLn 17, Col 40    TypeScript React
Terminal
>_ PowerShell
Ubuntu
shop on feat/checkout ❯ npm run dev
▲ Next.js 16
- Local: http://localhost:3000
✓ Ready in 842ms
○ Compiling /checkout ...
✓ Compiled /checkout in 311ms
GET /checkout 200 in 38ms
POST /api/pay 200 in 112ms
GET /thanks 200 in 21ms
shop on feat/checkout ❯
Review
Add one-tap checkout #482
git.acme.dev/shop/pull/482/files
S

Add one-tap checkout #482

Openana wants to merge 3 commits into main from feat/checkout
Conversation 4Commits 3Checks 6Files changed 5
lib/cart.ts+14 −3
41 export function total(items: Item[]) {
42- return items.reduce((s, i) => s + i.price, 0)
43+ const sum = items.reduce((s, i) => s + i.price * i.qty, 0)
44+ return Math.round(sum * 100) / 100
45 }
46
47+export const SHIPPING_FREE_OVER = 75
All checks have passed 6 successful checks
Team
Acme - releases

Acme

general

releases

design

random

Direct messages

Ana

Ravi

Mia

releases
M

Mia 09:31

Morning. Checkout copy is in review, feedback welcome.

R

Ravi 09:48

Looks good to me. One nit on the empty cart state.

A

Ana 10:05

Fixed the nit and pushed. CI is running.

M

Mia 10:12

Thanks! Approving once it goes green.

A

Ana 10:42

Staging is green. Merging #482 after lunch.

R

Ravi 10:44

Pay button copy is updated. Can someone check it on mobile?

M

Mia 10:51

On it. Release notes draft is in the doc.

A

Ana 10:58

Thanks both. Tagging v2.4.0 at 3.

Message #releases

Ship the release

Developers

Editor, terminal, pull request and team chat, all in place the moment you pick up a task.

Canvas
Logo system - Design
100%Share

Layers

Page 1
Logo lockups
Lockup / dark
Lockup / light
Mark
Colour
Tiles
320 × 200

Design

X 120Y 96W 320H 200

Fill

FFFFFF100%
2B44D9100%
F4B13A100%

Text

Bricolage Grotesque
Bold · 96 · −3.5%

References
Tessellation, references
pinboard.example/brand-refresh
S

Tessellation, references

24 pins

Roman floor, Ostia

Byzantine gold

Glazed ceramics

Tessera study

Lapis & bone

Courtyard pattern

Brief
Brand refresh brief - Notes

Brand refresh brief

In progressDue Oct 17Owner: you

Goals

  • • A mark that works at 16 px and on a billboard
  • • Warm, mineral palette, no gradients

To do

Tighten wordmark spacing

Export lockups for the deck

Colour-blind check

Client
Northwind - Elena Voss
E Elena Voss Northwind

Elena Mon
Hi! Attaching the references we talked about on the call.

You Mon
Got them, thank you. The tessellation direction is great, I will start there.

Elena Mon
Perfect. No rush, we only need it before the pitch.

Elena Tue
Love the tile mark. Could the wordmark sit a little tighter?

You Tue
Yes. Sending a tighter version with the lockups this afternoon.

Elena Wed
Perfect. Approved for the pitch deck.

Message Elena

Brand refresh

Designers

The canvas, your references, the brief and the client thread, side by side instead of buried.

Reading
ocean-heat-2024.pdf - Reader
7 / 24 125%

Upper-ocean heat content and its regional trends

R. Okafor, L. Haugen, M. Tanaka

Abstract

We analyse temperature profiles from 3,900 autonomous floats between 2005 and 2022 and estimate heat content change in the upper 2000 m of the ocean. Regional trends are computed on a one-degree grid and corrected for the sampling bias of the pre-float record.

The warming signal is largest in the subtropical gyres, where surface heat is mixed downward by winter convection and carried below the mixed layer. Between 30°N and 30°S, the upper 700 m gained heat in every basin we examined.

Uncertainty is dominated by sparse sampling in the Southern Ocean before 2007. After the float network reached full coverage, the sampling error falls below the size of the regional signal in all but the highest latitudes.

Draft
Thesis - 3. Results

Chapter 3

Results

3.1 Warming of the upper ocean

Between 1980 and 2020 the global mean sea surface temperature anomaly rose by 0.87 °C (Figure 3.2). The increase was not uniform: the subtropical Atlantic and the Indian Ocean warmed fastest, while the Southern Ocean showed the weakest trend over the same period.

Heat content in the top 700 m followed a similar pattern12. We therefore treat the two series as consistent and report regional estimates in Table 3.1, with uncertainty ranges derived from the float coverage described in Section 2.4.

3.2 Regional differences

Regional trends diverge most strongly after 2005, when the float network reached full global coverage and the sampling bias in the earlier record largely disappears.

2,418 wordsSaved
Data
Sea surface temperature - Data

Sea surface temperature anomaly, global mean

+0.87 °C since 1980

Sources
ocean heat content trend
search.example/?q=ocean+heat+content
S
ocean heat content trend 0-2000 m

About 1,240,000 results

journals.example.org › climate › 2024

Ocean heat content: a regional reassessment

Upper-ocean heat content rose in every basin between 2005 and 2022, with the largest gains in the subtropical Atlantic.

data.example.gov › sst › monthly

Sea surface temperature records, 1980 to today

Monthly gridded anomalies relative to the 1991 to 2020 mean, with uncertainty estimates for each cell.

arxiv.example.org › abs › 2403.01177

Methods for estimating deep-ocean warming

We compare three interpolation schemes for sparse float data and quantify the bias each introduces below 700 m.

Thesis, chapter 3

Researchers

The paper you are reading, the draft you are writing and the data behind both, one switch from the next project.

Broadcast
Broadcast - Scene: Main
LIVE
Stop streaming02:14:07 · 1080p 60 fps · 6,000 kbps

Scenes

Main

Starting soon

Be right back

Sources

Game capture

Webcam

Alerts overlay

Mic
Desktop
Chat
Stream chat
Stream chat 1,247

Kestrel: reminder: be kind in here, new people join every night

tern: first time catching a live run of this boss

dunes_: good luck chat is rooting for u

nova_k: that opener was so smooth

quill: brb snacks

mossy: is this the speedrun route or just vibes

pilotfish: vibes. route is way riskier

tern: lmao the camera

Kestrel: clip that one @quill

dunes_: hiii

Kestrel: welcome in. clips are on, no spoilers pls

quill: ok that last fight was insane

mossy: wait how did u get past phase 2 lmao

tern: he parried it. he PARRIED it

pilotfish: phase 2 is just patience tbh

nova_k: KEKW

mossy: @pilotfish i keep dying to the sweep

pilotfish: roll toward it not away

pilotfish is raiding with 64 viewers

quill: raid gang!!

dunes_: o7

tern: been here since the 5am stream and the soundtrack still slaps

nova_k: who made the overlay, it looks clean

Kestrel: @nova_k its his own, link is in the panel

mossy: ok going in, wish me luck

Send a message
Stats
Stats

Concurrent viewers

1,247 Live

Dashboard
Creator dashboard
studio.example/dashboard
S

Creator dashboard

Followers

18.4K

+212 today

Avg. viewers

912

+8%

Chat / min

148

peak 203

nova_k followed

Kestrel subscribed (Tier 1)

pilotfish raided with 64 viewers

Friday stream

Streamers

Broadcast software, live chat and dashboards, arranged before you go live and again for the next show.

Desktop first, because that’s where windows live.

Only a native app can move other apps’ windows, and each operating system allows a different amount. Here is the plan.

  • Windows

    Available

    Windows 11, and Windows 10 version 22H2. Windows lets one app move, resize and group other apps’ windows, which is all Mosaïk needs.

  • macOS

    Planned

    Next. Mosaïk will ask for the Accessibility permission, then place and group windows the same way.

  • Linux

    Planned, X11 first

    X11 allows the full feature set. Wayland deliberately limits what an app can do to other apps’ windows, so support there depends on the desktop environment.

Put your work back together.

Mosaïk is free and open source, and stays that way. If it earns its place on your desktop, you can support its work on Patreon.