Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
21f023d
Auto migrate with `@tailwindcss/upgrade`
ItsEeleeya Apr 2, 2026
0e1cfbf
Upgrade desktop app to Tailwind 4 + Format
ItsEeleeya Apr 17, 2026
552bc43
Use data- attributes instead of ui-
ItsEeleeya Apr 29, 2026
f8838e2
Use antialiased font smoothing
ItsEeleeya Apr 29, 2026
3ab5cda
Update ConfigSidebar.tsx
ItsEeleeya Apr 29, 2026
4b86478
Merge branch 'main' into desktop-tailwind-v4
ItsEeleeya May 1, 2026
da9ce12
Fix for remaining `ui-` classes to `data-`
ItsEeleeya May 1, 2026
542216f
format
ItsEeleeya May 1, 2026
7e1f217
Merge branch 'main' into desktop-tailwind-v4
ItsEeleeya May 5, 2026
93c11ef
Merge branch 'main' into desktop-tailwind-v4
ItsEeleeya May 6, 2026
44938bc
Merge branch 'main' into desktop-tailwind-v4
ItsEeleeya May 7, 2026
6b9751a
Bump Tailwind version
ItsEeleeya May 7, 2026
939e8e3
Update tauri.ts
ItsEeleeya May 7, 2026
06359b1
Merge branch 'main' into desktop-tailwind-v4
ItsEeleeya May 8, 2026
d2fe08c
Merge branch 'main' into desktop-tailwind-v4
ItsEeleeya May 9, 2026
451c78d
Fix missing shimmer animation
ItsEeleeya May 9, 2026
13fffe3
Merge remote-tracking branch 'upstream/main' into desktop-tailwind-v4
ItsEeleeya May 12, 2026
cb990a0
Merge branch 'main' into pr/1771
richiemcilroy May 12, 2026
c07b615
Bump tailwind to 4.0, default font weight 500
ItsEeleeya May 12, 2026
a75caba
Merge remote-tracking branch 'upstream/main' into desktop-tailwind-v4
ItsEeleeya May 13, 2026
4c7e7fb
Merge remote-tracking branch 'upstream/main' into desktop-tailwind-v4
ItsEeleeya May 14, 2026
7cb2b4d
Merge remote-tracking branch 'upstream/main' into desktop-tailwind-v4
ItsEeleeya May 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"@cap/utils": "workspace:*",
"@cap/web-api-contract": "workspace:*",
"@corvu/tooltip": "^0.2.1",
"@kobalte/core": "^0.13.7",
"@kobalte/core": "^0.13.11",
"@radix-ui/colors": "^3.0.0",
"@rive-app/canvas": "^2.32.2",
"@solid-primitives/bounds": "^0.0.122",
Expand Down Expand Up @@ -75,13 +75,16 @@
},
"devDependencies": {
"@fontsource/geist-sans": "^5.0.3",
"@webgpu/types": "^0.1.44",
"@iconify/json": "^2.2.239",
"@tailwindcss/postcss": "^4.2.2",
"@tailwindcss/typography": "^0.5.9",
"@tauri-apps/cli": ">=2.1.0",
"@total-typescript/ts-reset": "^0.6.1",
"@types/dom-webcodecs": "^0.1.11",
"@types/uuid": "^9.0.8",
"@webgpu/types": "^0.1.44",
"cross-env": "^7.0.3",
"tailwind-scrollbar": "^3.1.0",
"typescript": "^5.8.3",
"vite": "^6.3.5",
"vite-plugin-top-level-await": "^1.4.4",
Expand Down
7 changes: 6 additions & 1 deletion apps/desktop/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
module.exports = require("@cap/ui/postcss");
module.exports = {
plugins: {
"@tailwindcss/postcss": {},
autoprefixer: {},
},
};
4 changes: 2 additions & 2 deletions apps/desktop/src/components/CapErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export function CapErrorBoundary(props: ParentProps) {
fallback={(e: Error) => {
console.error(e);
return (
<div class="w-full h-full flex flex-col justify-center items-center bg-gray-2 border-gray-3 max-h-screen overflow-hidden transition-[border-radius] duration-200 text-[--text-secondary] gap-y-4 max-sm:gap-y-2 px-8 text-center">
<div class="w-full h-full flex flex-col justify-center items-center bg-gray-2 border-gray-3 max-h-screen overflow-hidden transition-[border-radius] duration-200 text-(--text-secondary) gap-y-4 max-sm:gap-y-2 px-8 text-center">
<IconCapLogo class="max-sm:size-16" />
<h1 class="text-[--text-primary] text-3xl max-sm:text-xl font-bold">
<h1 class="text-(--text-primary) text-3xl max-sm:text-xl font-bold">
An Error Occured
</h1>
<p class="mb-2 max-sm:text-sm">
Expand Down
16 changes: 8 additions & 8 deletions apps/desktop/src/components/Cropper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1018,7 +1018,7 @@ export function Cropper(
return (
<div
ref={containerRef}
class="relative w-full h-full select-none overscroll-contain focus:outline-none touch-none"
class="relative w-full h-full select-none overscroll-contain focus:outline-hidden touch-none"
style={{
cursor: cursorStyle() ?? (props.aspectRatio ? "default" : "crosshair"),
}}
Expand All @@ -1031,11 +1031,11 @@ export function Cropper(
<Transition
appear
enterActiveClass="transition-opacity duration-300 ease-in-out"
enterClass="opacity-0 blur-sm"
enterClass="opacity-0 blur-xs"
enterToClass="opacity-100 blur-none"
exitActiveClass="transition-opacity duration-300 ease-in-out"
exitClass="opacity-100 blur-none"
exitToClass="opacity-0 blur-sm"
exitToClass="opacity-0 blur-xs"
>
<Show when={props.showBounds && labelTransform()}>
{(transform) => (
Expand Down Expand Up @@ -1110,7 +1110,7 @@ export function Cropper(
handle.isCorner ? (
<button
type="button"
class="fixed z-50 flex h-[30px] w-[30px] focus:ring-0 outline-none"
class="fixed z-50 flex h-[30px] w-[30px] focus:ring-0 outline-hidden"
tabIndex={-1}
classList={{ "opacity-0": mouseState.drag === "overlay" }}
style={{
Expand All @@ -1136,7 +1136,7 @@ export function Cropper(
>
<svg
aria-hidden="true"
class="absolute pointer-events-none drop-shadow-sm shadow-black"
class="absolute pointer-events-none drop-shadow-xs shadow-black"
classList={{
"size-1": boundsTooSmall(),
"size-6": !boundsTooSmall(),
Expand Down Expand Up @@ -1172,7 +1172,7 @@ export function Cropper(
) : (
<button
type="button"
class="absolute focus:outline-none focus:ring-0 outline-none"
class="absolute focus:outline-hidden focus:ring-0 outline-hidden"
tabIndex={-1}
style={{
visibility:
Expand Down Expand Up @@ -1239,9 +1239,9 @@ export function Cropper(
aria-live="polite"
>
<div
class="h-[18px] w-11 rounded-full text-center text-xs text-gray-12 border border-white/70 dark:border-white/20 drop-shadow-md outline-1 outline outline-black/80"
class="h-[18px] w-11 rounded-full text-center text-xs text-gray-12 border border-white/70 dark:border-white/20 drop-shadow-md outline-1 outline-solid outline-black/80"
classList={{
"backdrop-blur-sm bg-white/50 dark:bg-black/50 dark:backdrop-brightness-90 backdrop-brightness-200":
"backdrop-blur-xs bg-white/50 dark:bg-black/50 dark:backdrop-brightness-90 backdrop-brightness-200":
props.useBackdropFilter,
"bg-gray-3 opacity-80": !props.useBackdropFilter,
}}
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/components/Loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export function AbsoluteInsetLoader() {
return (
<div class="w-full h-full flex items-center justify-center">
<div class="animate-spin">
<IconCapLogo class="size-[4rem]" />
<IconCapLogo class="size-16" />
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/components/SignInButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function SignInButton(
return (
<Button
size="md"
class="flex flex-grow justify-center items-center"
class="flex grow justify-center items-center"
{...props}
variant={signIn.isPending ? "gray" : "primary"}
onClick={() => {
Expand Down
16 changes: 8 additions & 8 deletions apps/desktop/src/components/Toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { cva } from "cva";
import { type ComponentProps, splitProps } from "solid-js";

const toggleControlStyles = cva(
"rounded-full bg-gray-6 ui-disabled:bg-gray-3 ui-checked:bg-blue-500 transition-colors outline-2 outline-offset-2 outline-blue-300",
"rounded-full bg-gray-6 data-disabled:bg-gray-3 data-checked:bg-blue-500 transition-colors",
{
Comment thread
ItsEeleeya marked this conversation as resolved.
variants: {
size: {
sm: "w-9 h-[1.25rem] p-[0.125rem]",
md: "w-11 h-[1.5rem] p-[0.125rem]",
lg: "w-14 h-[1.75rem] p-[0.1875rem]",
sm: "w-9 h-5 p-0.5",
md: "w-11 h-6 p-0.5",
lg: "w-14 h-7 p-0.75",
},
},
defaultVariants: {
Expand All @@ -19,13 +19,13 @@ const toggleControlStyles = cva(
);

const toggleThumbStyles = cva(
"bg-white rounded-full transition-transform ui-checked:translate-x-[calc(100%)]",
"bg-white rounded-full transition-transform data-checked:translate-x-[calc(100%)]",
{
variants: {
size: {
sm: "size-[1rem]",
md: "size-[1.25rem]",
lg: "size-[1.5rem]",
sm: "size-4",
md: "size-5",
lg: "size-6",
},
},
defaultVariants: {
Expand Down
6 changes: 3 additions & 3 deletions apps/desktop/src/components/titlebar/Titlebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ export default function Titlebar() {
>
{left() ? (
<>
<WindowControls class="!ml-0" />
<div class="!ml-auto">{titlebarState.items}</div>
<WindowControls class="ml-0!" />
<div class="ml-auto!">{titlebarState.items}</div>
</>
) : (
<>
{titlebarState.items}
<WindowControls class="!ml-auto" />
<WindowControls class="ml-auto!" />
</>
)}
</header>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default function (
return (
<div
class={cx(
"flex flex-row items-stretch h-full align-baseline cursor-default rounded-none select-none *:outline-none *:transition-all *:duration-200",
"flex flex-row items-stretch h-full align-baseline cursor-default rounded-none select-none *:outline-hidden *:transition-all *:duration-200",
local.class,
focused()
? "*:text-black-transparent-80"
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/entry-server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default createHandler(() => (
{assets}
</head>
<body class="w-screen h-screen cursor-default select-none">
<div id="app" class="h-full text-[--text-primary]">
<div id="app" class="h-full text-(--text-primary)">
{children}
</div>
{scripts}
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/routes/(window-chrome).tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ function Header() {
data-tauri-drag-region
>
{ctx.state()?.items}
{isWindows && <CaptionControlsWindows11 class="!ml-auto" />}
{isWindows && <CaptionControlsWindows11 class="ml-auto!" />}
{isMacOS && (
<CaptionControlsMacOS
class="!mr-auto ml-3"
class="mr-auto! ml-3"
showMinimize={false}
showZoom={false}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export default function CameraSelect(props: {
const isDisabled = () => !!currentRecording.data || props.disabled;

return (
<div class="flex flex-col items-stretch text-[--text-primary]">
<div class="flex flex-col items-stretch text-(--text-primary)">
<button
type="button"
disabled={isDisabled()}
Expand Down Expand Up @@ -262,7 +262,7 @@ export function CameraSelectBase(props: {
!props.hidePreviewButton;

return (
<div class="flex flex-col gap-[0.25rem] items-stretch text-[--text-primary]">
<div class="flex flex-col gap-1 items-stretch text-(--text-primary)">
<button
type="button"
disabled={!!currentRecording.data || props.disabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export default function DeviceSelectOverlay<T>(
placeholder="Search..."
value={searchQuery()}
onInput={(e) => setSearchQuery(e.currentTarget.value)}
class="w-full px-3 py-1.5 text-sm rounded-lg outline-none placeholder:text-white/40 text-white"
class="w-full px-3 py-1.5 text-sm rounded-lg outline-hidden placeholder:text-white/40 text-white"
style={{
"background-color": "rgba(255, 255, 255, 0.1)",
border: "1px solid rgba(255, 255, 255, 0.1)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default function MicrophoneSelect(props: {
const isDisabled = () => !!currentRecording.data || props.disabled;

return (
<div class="flex flex-col items-stretch text-[--text-primary]">
<div class="flex flex-col items-stretch text-(--text-primary)">
<button
type="button"
disabled={isDisabled()}
Expand Down Expand Up @@ -181,7 +181,7 @@ export function MicrophoneSelectBase(props: {
(1 - Math.max((dbs() ?? 0) + DB_SCALE, 0) / DB_SCALE) ** 0.5;

return (
<div class="flex flex-col gap-[0.25rem] items-stretch text-[--text-primary]">
<div class="flex flex-col gap-1 items-stretch text-(--text-primary)">
<button
type="button"
disabled={!!currentRecording.data || props.disabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function ModeInfoPanel(props: ModeInfoPanelProps) {
onClick={() => props.onBack()}
class="flex gap-1 items-center rounded-md px-1.5 text-xs cursor-pointer
text-gray-11 transition-opacity hover:opacity-70 hover:text-gray-12
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-9 focus-visible:ring-offset-2 focus-visible:ring-offset-gray-1"
focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-blue-9 focus-visible:ring-offset-2 focus-visible:ring-offset-gray-1"
>
<IconLucideArrowLeft class="size-3 text-gray-11" />
<span class="font-medium text-gray-12">Back</span>
Expand Down Expand Up @@ -89,7 +89,7 @@ export default function ModeInfoPanel(props: ModeInfoPanelProps) {
</div>
)}

<div class="flex-shrink-0">
<div class="shrink-0">
<option.icon
class={cx(
"size-5 invert dark:invert-0",
Expand Down
34 changes: 17 additions & 17 deletions apps/desktop/src/routes/(window-chrome)/new-main/TargetCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export default function TargetCard(props: TargetCardProps) {
return parts.map((part) => {
if (part.toLowerCase() === lowercaseQuery) {
return (
<span class="rounded bg-blue-9/20 px-[1px] text-gray-12">{part}</span>
<span class="rounded-sm bg-blue-9/20 px-px text-gray-12">{part}</span>
);
}
return part;
Expand Down Expand Up @@ -314,12 +314,12 @@ export default function TargetCard(props: TargetCardProps) {
disabled={local.disabled}
data-variant={local.variant}
class={cx(
"group flex flex-col overflow-hidden rounded-lg border border-transparent bg-gray-3 text-left outline-none transition-colors duration-100 hover:bg-gray-4 focus-visible:ring-2 focus-visible:ring-blue-9 focus-visible:ring-offset-2 focus-visible:ring-offset-gray-1",
"group flex flex-col overflow-hidden rounded-lg border border-transparent bg-gray-3 text-left outline-hidden transition-colors duration-100 hover:bg-gray-4 focus-visible:ring-2 focus-visible:ring-blue-9 focus-visible:ring-offset-2 focus-visible:ring-offset-gray-1",
local.disabled && "pointer-events-none opacity-60",
local.class,
)}
>
<div class="relative h-[4.75rem] w-full overflow-hidden bg-gray-4/40">
<div class="relative h-19 w-full overflow-hidden bg-gray-4/40">
<Show
when={imageExists() ? thumbnailSrc() : undefined}
fallback={
Expand Down Expand Up @@ -354,10 +354,10 @@ export default function TargetCard(props: TargetCardProps) {
)}
</Show>
<div class="absolute inset-0 border opacity-60 pointer-events-none border-black/5" />
<div class="absolute inset-x-0 bottom-0 h-10 bg-gradient-to-t to-transparent pointer-events-none from-black/40" />
<div class="absolute inset-x-0 bottom-0 h-10 bg-linear-to-t to-transparent pointer-events-none from-black/40" />
<Show when={recordingFailed() || recordingUploadFailed()}>
<div class="absolute inset-0 flex items-center justify-center bg-black/75">
<div class="flex items-center gap-1 px-1.5 py-0.5 rounded bg-red-9/20 text-red-11">
<div class="flex items-center gap-1 px-1.5 py-0.5 rounded-sm bg-red-9/20 text-red-11">
<IconPhWarningBold class="size-2.5" />
<span class="text-[10px] font-medium">
{recordingFailed() ? "Recording failed" : "Upload failed"}
Expand Down Expand Up @@ -391,7 +391,7 @@ export default function TargetCard(props: TargetCardProps) {
role="button"
tabIndex={-1}
onClick={handleOpenEditor}
class="flex-1 flex items-center justify-center p-1 rounded hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
class="flex-1 flex items-center justify-center p-1 rounded-sm hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
>
<IconLucideEdit class="size-3.5" />
</div>
Expand All @@ -401,7 +401,7 @@ export default function TargetCard(props: TargetCardProps) {
role="button"
tabIndex={-1}
onClick={handleCopy}
class="flex-1 flex items-center justify-center p-1 rounded hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
class="flex-1 flex items-center justify-center p-1 rounded-sm hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
>
<IconLucideCopy class="size-3.5" />
</div>
Expand All @@ -411,7 +411,7 @@ export default function TargetCard(props: TargetCardProps) {
role="button"
tabIndex={-1}
onClick={handleSave}
class="flex-1 flex items-center justify-center p-1 rounded hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
class="flex-1 flex items-center justify-center p-1 rounded-sm hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
>
<IconLucideSave class="size-3.5" />
</div>
Expand All @@ -436,7 +436,7 @@ export default function TargetCard(props: TargetCardProps) {
role="button"
tabIndex={-1}
onClick={handleOpenRecordingEditor}
class="flex-1 flex items-center justify-center p-1 rounded hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
class="flex-1 flex items-center justify-center p-1 rounded-sm hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
>
<IconLucideEdit class="size-3.5" />
</div>
Expand All @@ -453,7 +453,7 @@ export default function TargetCard(props: TargetCardProps) {
role="button"
tabIndex={-1}
onClick={handleReupload}
class="flex-1 flex items-center justify-center p-1 rounded hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
class="flex-1 flex items-center justify-center p-1 rounded-sm hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
>
<IconLucideRotateCcw class="size-3.5" />
</div>
Expand All @@ -475,7 +475,7 @@ export default function TargetCard(props: TargetCardProps) {
role="button"
tabIndex={-1}
onClick={handleOpenRecordingLink}
class="flex-1 flex items-center justify-center p-1 rounded hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
class="flex-1 flex items-center justify-center p-1 rounded-sm hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
>
<IconCapLink class="size-3.5" />
</div>
Expand All @@ -486,7 +486,7 @@ export default function TargetCard(props: TargetCardProps) {
role="button"
tabIndex={-1}
onClick={handleOpenRecordingFolder}
class="flex-1 flex items-center justify-center p-1 rounded hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
class="flex-1 flex items-center justify-center p-1 rounded-sm hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
>
<IconLucideFolder class="size-3.5" />
</div>
Expand All @@ -496,7 +496,7 @@ export default function TargetCard(props: TargetCardProps) {
role="button"
tabIndex={-1}
onClick={handleDeleteRecording}
class="flex-1 flex items-center justify-center p-1 rounded hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
class="flex-1 flex items-center justify-center p-1 rounded-sm hover:bg-gray-5 text-gray-11 hover:text-gray-12 transition-colors"
>
<IconCapTrash class="size-3.5" />
</div>
Expand All @@ -522,12 +522,12 @@ export function TargetCardSkeleton(props: { class?: string }) {
props.class,
)}
>
<div class="h-[4.75rem] w-full animate-pulse bg-gray-4" />
<div class="h-19 w-full animate-pulse bg-gray-4" />
<div class="flex flex-row items-start gap-2 px-2 py-1.5">
<div class="flex-1 space-y-1">
<div class="w-3/4 h-3 rounded bg-gray-4" />
<div class="h-2.5 w-1/2 rounded bg-gray-4" />
<div class="h-2.5 w-2/5 rounded bg-gray-4" />
<div class="w-3/4 h-3 rounded-sm bg-gray-4" />
<div class="h-2.5 w-1/2 rounded-sm bg-gray-4" />
<div class="h-2.5 w-2/5 rounded-sm bg-gray-4" />
</div>
</div>
</div>
Expand Down
Loading
Loading