Compare commits
25 Commits
revert-724
...
worktree-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1ee19f13f | ||
|
|
fa535b1898 | ||
|
|
d9b78958aa | ||
|
|
cbbc9f3391 | ||
|
|
b043f0ae92 | ||
|
|
598292d9bf | ||
|
|
a5d130f5da | ||
|
|
f289ef7fbd | ||
|
|
58a7ef07d8 | ||
|
|
b7eb508cce | ||
|
|
7cccdad1ba | ||
|
|
60fa9bbbcb | ||
|
|
3862c48123 | ||
|
|
4362e4c9ff | ||
|
|
676778b027 | ||
|
|
112e3b73ee | ||
|
|
6e4d3f7869 | ||
|
|
89d89b89c3 | ||
|
|
0bcec82523 | ||
|
|
9199903ca7 | ||
|
|
82cb89caa5 | ||
|
|
59ce349b6b | ||
|
|
5cbc972a7a | ||
|
|
7396f12be6 | ||
|
|
012b0d4984 |
6
.github/workflows/build.yml
vendored
@@ -84,7 +84,7 @@ jobs:
|
||||
cli:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Set up environment
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@@ -96,12 +96,12 @@ jobs:
|
||||
- name: Prepare bundle stats artifact
|
||||
run: cp packages/cli/dist/stats.json cli-stats.json
|
||||
- name: Upload Build
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
with:
|
||||
name: actual-cli
|
||||
path: packages/cli/actual-cli.tgz
|
||||
- name: Upload CLI bundle stats
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
with:
|
||||
name: cli-build-stats
|
||||
path: cli-stats.json
|
||||
|
||||
4
.github/workflows/size-compare.yml
vendored
@@ -130,7 +130,7 @@ jobs:
|
||||
path: head
|
||||
allow_forks: true
|
||||
- name: Download CLI build artifact from ${{github.base_ref}}
|
||||
uses: dawidd6/action-download-artifact@1f8785ff7a5130826f848e7f72725c85d241860f # v18
|
||||
uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11
|
||||
with:
|
||||
branch: ${{github.base_ref}}
|
||||
workflow: build.yml
|
||||
@@ -138,7 +138,7 @@ jobs:
|
||||
name: cli-build-stats
|
||||
path: base
|
||||
- name: Download CLI stats from PR
|
||||
uses: dawidd6/action-download-artifact@1f8785ff7a5130826f848e7f72725c85d241860f # v18
|
||||
uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11
|
||||
with:
|
||||
pr: ${{github.event.pull_request.number}}
|
||||
workflow: build.yml
|
||||
|
||||
7
my-video/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
node_modules/
|
||||
out/
|
||||
.playwright-cli/
|
||||
.superpowers/
|
||||
# Temp screenshots from playwright-cli
|
||||
*.png
|
||||
!public/screenshots/*.png
|
||||
1349
my-video/docs/superpowers/plans/2026-04-02-release-video.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# Actual Budget v26.4.0 Release Video — Design Spec
|
||||
|
||||
## Overview
|
||||
|
||||
A 52-second social media teaser video showcasing the most important features in Actual Budget v26.4.0. Built with Remotion (React), using real screen recordings captured via Playwright and synced to a music track at ~139 BPM.
|
||||
|
||||
**Format:** 1280x720, 30fps, ~52 seconds
|
||||
**Style:** Branded & colorful — Actual brand colors, energetic transitions, playful feel
|
||||
**Music:** `public/music.mp3` — upbeat tech track, 139 BPM. Using first 52 seconds only.
|
||||
**Content:** Real screen recordings with bold text overlays (feature name + tagline)
|
||||
|
||||
## Music Analysis
|
||||
|
||||
- **BPM:** ~139 (beat interval: ~0.43s = ~13 frames at 30fps)
|
||||
- **0–4s:** Quiet intro build-up (energy rises from silence to medium)
|
||||
- **4s+:** Full energy drop, sustained loud level throughout
|
||||
- **Track total:** 4:24, but we only use 0–52s
|
||||
|
||||
## Video Timeline
|
||||
|
||||
### Scene 1: Title Card (0.0s – 4.0s | frames 0–120)
|
||||
|
||||
- Actual Budget logo animates in during quiet intro
|
||||
- "v26.4.0" and subtitle fade in on rising energy
|
||||
- Beat drop at 4.0s triggers transition to first feature
|
||||
- Background: dark gradient with brand colors
|
||||
|
||||
### Tier 1: Hero Features (4.0s – 20.0s | frames 120–600)
|
||||
|
||||
Each feature gets ~5.3s (160 frames / 12 beats). Screen recording fills most of the frame in a styled browser mockup. Text overlay appears on the first beat.
|
||||
|
||||
**Feature 1: Drag & Drop Transaction Reordering (4.0s – 9.3s)**
|
||||
- Screen recording: user dragging transactions to reorder within the same day
|
||||
- Text: "Reorder transactions — your way"
|
||||
- Playwright scenario: open an account, drag a transaction up/down within same-day group
|
||||
|
||||
**Feature 2: Concentric Donut Chart (9.3s – 14.7s)**
|
||||
- Screen recording: custom reports page showing the new donut chart visualization
|
||||
- Text: "Beautiful category breakdowns"
|
||||
- Playwright scenario: navigate to custom reports, show a donut chart with category data
|
||||
|
||||
**Feature 3: Payee Locations MVP (14.7s – 20.0s)**
|
||||
- Screen recording: payee management showing location data
|
||||
- Text: "Know where you spend"
|
||||
- Playwright scenario: open payees section, show payee with location info
|
||||
|
||||
### Tier 2: Quick Highlights (20.0s – 44.0s | frames 600–1320)
|
||||
|
||||
Each feature gets ~6s (180 frames / 14 beats). Same layout but slightly faster-paced transitions.
|
||||
|
||||
**Feature 4: Monthly Budget Cell Notes (20.0s – 26.0s)**
|
||||
- Screen recording: adding a note to a monthly budget cell
|
||||
- Text: "Annotate your budget"
|
||||
- Playwright scenario: click a budget cell, add a note, show the note indicator
|
||||
|
||||
**Feature 5: Actual CLI Tool (26.0s – 32.0s)**
|
||||
- Screen recording: terminal showing CLI commands querying budget data
|
||||
- Text: "Your budget, from the command line"
|
||||
- Note: This will be a terminal recording/mockup rather than Playwright, since it's a CLI tool
|
||||
|
||||
**Feature 6: Custom Theme Improvements (32.0s – 38.0s)**
|
||||
- Screen recording: switching themes, showing custom fonts and light/dark options
|
||||
- Text: "Make it yours"
|
||||
- Playwright scenario: open settings, switch between themes, toggle light/dark
|
||||
|
||||
**Feature 7: Import Improvements (38.0s – 44.0s)**
|
||||
- Screen recording: import dialog showing new options
|
||||
- Text: "Smarter imports"
|
||||
- Playwright scenario: open import dialog, show "import since" date filter, swap payee/memo toggle
|
||||
|
||||
### Scene 9: Outro (44.0s – 52.0s | frames 1320–1560)
|
||||
|
||||
- Stats flash in sequence: "4 features · 45 enhancements · 32 bugfixes"
|
||||
- CTA: "Update now — actualbudget.org"
|
||||
- Logo + version badge fade out
|
||||
- Music continues to natural phrase ending
|
||||
|
||||
## Visual Design
|
||||
|
||||
### Color Palette
|
||||
|
||||
- **Background:** Dark (#1a1a2e / #16213e gradient)
|
||||
- **Tier 1 accent:** Cyan (#00d2ff)
|
||||
- **Tier 2 accent:** Coral/Red (#e94560)
|
||||
- **Outro accent:** Gold (#ffd700)
|
||||
- **Text:** White (#ffffff) with subtle shadows
|
||||
- **Brand purple:** Used for logo and accent elements
|
||||
|
||||
### Typography
|
||||
|
||||
- Feature names: Bold, large sans-serif
|
||||
- Taglines: Regular weight, slightly smaller
|
||||
- Stats/CTA: Bold, emphasized with accent color
|
||||
|
||||
### Transitions
|
||||
|
||||
- Scene transitions: slide/zoom synced to beat hits
|
||||
- Screen recordings slide in from right
|
||||
- Text overlays pop in with spring animation on beat
|
||||
- Slight zoom-in on screen recordings during playback for energy
|
||||
|
||||
### Screen Recording Frame
|
||||
|
||||
- Styled browser mockup wrapper (rounded corners, subtle shadow)
|
||||
- Dark chrome to match overall aesthetic
|
||||
- Fills ~80% of frame width, centered
|
||||
|
||||
## Remotion Architecture
|
||||
|
||||
### Composition Structure
|
||||
|
||||
```
|
||||
<MyComposition> (1560 frames, 30fps, 1280x720)
|
||||
<Audio src="music.mp3" />
|
||||
<TitleCard /> {frames 0-120}
|
||||
<FeatureScene /> {frames 120-280} -- Drag & Drop
|
||||
<FeatureScene /> {frames 280-440} -- Donut Chart
|
||||
<FeatureScene /> {frames 440-600} -- Payee Locations
|
||||
<FeatureScene /> {frames 600-780} -- Budget Notes
|
||||
<FeatureScene /> {frames 780-960} -- CLI Tool
|
||||
<FeatureScene /> {frames 960-1140} -- Themes
|
||||
<FeatureScene /> {frames 1140-1320} -- Imports
|
||||
<OutroCard /> {frames 1320-1560}
|
||||
</MyComposition>
|
||||
```
|
||||
|
||||
### Key Components
|
||||
|
||||
- **TitleCard:** Animated logo + version text with fade/scale entrance
|
||||
- **FeatureScene:** Reusable component accepting screen recording source, title, tagline, accent color, and frame range. Handles slide-in animation, text overlay timing, and zoom effect.
|
||||
- **OutroCard:** Sequential stat counter animations + CTA
|
||||
- **BrowserFrame:** Decorative wrapper around screen recordings
|
||||
|
||||
### Screen Recordings
|
||||
|
||||
Captured as video files via Playwright (webm/mp4) and placed in `public/recordings/`. Each recording is pre-trimmed to show the key interaction for that feature.
|
||||
|
||||
## Playwright Recording Plan
|
||||
|
||||
Each recording captures a specific user interaction in the running Actual Budget app:
|
||||
|
||||
1. **drag-drop.webm** — Open checking account, drag transaction to reorder
|
||||
2. **donut-chart.webm** — Navigate to reports, create/view donut chart
|
||||
3. **payee-locations.webm** — Open payees, show payee with location
|
||||
4. **budget-notes.webm** — Click budget cell, type a note, save
|
||||
5. **cli-tool.webm** — (Terminal recording, not Playwright)
|
||||
6. **themes.webm** — Settings > Themes, switch themes, toggle dark/light
|
||||
7. **imports.webm** — File > Import, show new import options
|
||||
|
||||
The app needs to be running with demo data (`yarn start` + "View demo" setup) before capturing.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Remotion 4.0.443** (already installed)
|
||||
- **@remotion/player** — for preview
|
||||
- **Tailwind CSS 4** (already installed)
|
||||
- **Playwright** — for screen recordings (project dependency)
|
||||
- **ffmpeg** — for audio trimming if needed
|
||||
3
my-video/eslint.config.mjs
Normal file
@@ -0,0 +1,3 @@
|
||||
import { config } from "@remotion/eslint-config-flat";
|
||||
|
||||
export default config;
|
||||
4989
my-video/package-lock.json
generated
Normal file
38
my-video/package.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "my-video",
|
||||
"version": "1.0.0",
|
||||
"description": "My Remotion video",
|
||||
"repository": {},
|
||||
"license": "UNLICENSED",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@remotion/cli": "4.0.443",
|
||||
"@remotion/google-fonts": "^4.0.443",
|
||||
"@remotion/media": "^4.0.443",
|
||||
"@remotion/tailwind-v4": "4.0.443",
|
||||
"@remotion/transitions": "^4.0.443",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"remotion": "4.0.443",
|
||||
"tailwindcss": "4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.59.1",
|
||||
"@remotion/eslint-config-flat": "4.0.443",
|
||||
"@types/react": "19.2.7",
|
||||
"@types/web": "0.0.166",
|
||||
"eslint": "9.19.0",
|
||||
"playwright": "^1.59.1",
|
||||
"prettier": "3.8.1",
|
||||
"typescript": "5.9.3"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "remotion studio",
|
||||
"build": "remotion bundle",
|
||||
"upgrade": "remotion upgrade",
|
||||
"lint": "eslint src && tsc"
|
||||
},
|
||||
"sideEffects": [
|
||||
"*.css"
|
||||
]
|
||||
}
|
||||
4
my-video/public/logo.svg
Executable file
@@ -0,0 +1,4 @@
|
||||
<svg width="30" height="32" viewBox="0 0 30 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.13785 30.4226L14.9372 1.11397C14.99 1.00184 15.1027 0.930283 15.2267 0.930283H15.8318C15.9542 0.930283 16.0659 1.00015 16.1195 1.11023L25.0219 19.3999L27.8131 18.3264C27.978 18.2629 28.1632 18.3452 28.2266 18.5102L28.9695 20.4417C29.033 20.6067 28.9507 20.7918 28.7857 20.8553L26.2121 21.8452L29.3875 28.3689C29.4648 28.5278 29.3987 28.7193 29.2398 28.7967L27.379 29.7024C27.2201 29.7798 27.0286 29.7136 26.9512 29.5547L23.6739 22.8215L1.6943 31.2754C1.52935 31.3389 1.3442 31.2566 1.28075 31.0916C1.28006 31.0898 1.27938 31.088 1.27872 31.0862L1.12666 30.6684C1.09749 30.5883 1.10152 30.4998 1.13785 30.4226ZM15.56 6.1518L5.85065 26.7737L22.4837 20.3762L15.56 6.1518Z" fill="white"/>
|
||||
<path d="M21.7768 14.5682L22.7095 17.1121L1.50597 24.8867C1.34004 24.9476 1.1562 24.8624 1.09536 24.6964L0.382928 22.7534C0.322087 22.5875 0.407278 22.4037 0.573207 22.3428L21.7768 14.5682Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1006 B |
BIN
my-video/public/recordings/budget-notes.webm
Normal file
BIN
my-video/public/recordings/cli-tool.webm
Normal file
BIN
my-video/public/recordings/donut-chart.webm
Normal file
BIN
my-video/public/recordings/drag-drop.webm
Normal file
BIN
my-video/public/recordings/imports.webm
Normal file
BIN
my-video/public/recordings/payee-locations.webm
Normal file
BIN
my-video/public/recordings/themes.webm
Normal file
BIN
my-video/public/screenshots/budget-notes.png
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
my-video/public/screenshots/cli-tool.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
my-video/public/screenshots/donut-chart.png
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
my-video/public/screenshots/drag-drop.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
my-video/public/screenshots/imports.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
my-video/public/screenshots/payee-locations.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
my-video/public/screenshots/themes.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
13
my-video/remotion.config.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Note: When using the Node.JS APIs, the config file
|
||||
* doesn't apply. Instead, pass options directly to the APIs.
|
||||
*
|
||||
* All configuration options: https://remotion.dev/docs/config
|
||||
*/
|
||||
|
||||
import { Config } from "@remotion/cli/config";
|
||||
import { enableTailwind } from '@remotion/tailwind-v4';
|
||||
|
||||
Config.setVideoImageFormat("jpeg");
|
||||
Config.setOverwriteOutput(true);
|
||||
Config.overrideWebpackConfig(enableTailwind);
|
||||
42
my-video/scripts/cli-mockup.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
background: #1e1e2e;
|
||||
color: #f8f8f2;
|
||||
padding: 40px;
|
||||
width: 1024px;
|
||||
height: 576px;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
line-height: 1.7;
|
||||
white-space: pre;
|
||||
}
|
||||
.prompt { color: #50fa7b; }
|
||||
.dim { color: #6272a4; }
|
||||
.red { color: #ff5555; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<span class="prompt">$</span> actual-cli accounts list --format table
|
||||
|
||||
<span class="dim"> id name offBudget closed balance_current</span>
|
||||
99e8f789-c982-4618-b686-3b331985374b Bank of America false false 6,929.07
|
||||
cbcec281-9899-4595-9ef3-5e33725555bb Ally Savings false false 3,425.74
|
||||
5f8e1bc3-136a-4669-9e00-6e36088eebc3 Capital One false false 1,388.56
|
||||
713d293e-ec6b-4813-aafd-6c9e63579375 HSBC false false <span class="red">-531.05</span>
|
||||
2ce33e0b-0517-458c-98d6-796c7ede90f7 Vanguard 401k true false 4,399.38
|
||||
6f6d9cb2-25ea-4b62-a6f6-0a4f2bb167ad Mortgage true false <span class="red">-301,380.72</span>
|
||||
7f3ff788-9af8-4109-aef5-b0b2971097df House Asset true false 341,300.00
|
||||
59aec8a4-0c61-4a4a-932e-4ae927f1adb6 Roth IRA true false 3,439.18
|
||||
|
||||
<span class="prompt">$</span> <span style="opacity:0.7">_</span>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
89
my-video/src/Composition.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import React from "react";
|
||||
import { AbsoluteFill, interpolate, useCurrentFrame, useVideoConfig } from "remotion";
|
||||
import { Audio } from "@remotion/media";
|
||||
import { TransitionSeries, linearTiming } from "@remotion/transitions";
|
||||
import { slide } from "@remotion/transitions/slide";
|
||||
import { fade } from "@remotion/transitions/fade";
|
||||
import { staticFile } from "remotion";
|
||||
import {
|
||||
FPS,
|
||||
TITLE_DURATION,
|
||||
TIER1_SCENE_DURATION,
|
||||
TIER2_SCENE_DURATION,
|
||||
OUTRO_DURATION,
|
||||
TRANSITION_DURATION,
|
||||
TIER1_FEATURES,
|
||||
TIER2_FEATURES,
|
||||
TOTAL_DURATION,
|
||||
} from "./constants";
|
||||
import { TitleCard } from "./components/TitleCard";
|
||||
import { FeatureScene } from "./components/FeatureScene";
|
||||
import { OutroCard } from "./components/OutroCard";
|
||||
|
||||
export function MyComposition() {
|
||||
const fadeOutDuration = 2 * FPS; // 2 seconds fade out
|
||||
|
||||
return (
|
||||
<AbsoluteFill>
|
||||
<Audio
|
||||
src={staticFile("music.mp3")}
|
||||
volume={(f) =>
|
||||
interpolate(f, [TOTAL_DURATION - fadeOutDuration, TOTAL_DURATION], [1, 0], {
|
||||
extrapolateLeft: "clamp",
|
||||
extrapolateRight: "clamp",
|
||||
})
|
||||
}
|
||||
/>
|
||||
<TransitionSeries>
|
||||
{/* Title scene */}
|
||||
<TransitionSeries.Sequence durationInFrames={TITLE_DURATION}>
|
||||
<TitleCard />
|
||||
</TransitionSeries.Sequence>
|
||||
|
||||
{/* Tier 1 feature scenes */}
|
||||
{TIER1_FEATURES.map((feature) => (
|
||||
<React.Fragment key={feature.screenshot}>
|
||||
<TransitionSeries.Transition
|
||||
presentation={slide({ direction: "from-right" })}
|
||||
timing={linearTiming({ durationInFrames: TRANSITION_DURATION })}
|
||||
/>
|
||||
<TransitionSeries.Sequence
|
||||
durationInFrames={TIER1_SCENE_DURATION}
|
||||
premountFor={TRANSITION_DURATION}
|
||||
>
|
||||
<FeatureScene feature={feature} />
|
||||
</TransitionSeries.Sequence>
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
{/* Tier 2 feature scenes */}
|
||||
{TIER2_FEATURES.map((feature) => (
|
||||
<React.Fragment key={feature.screenshot}>
|
||||
<TransitionSeries.Transition
|
||||
presentation={slide({ direction: "from-right" })}
|
||||
timing={linearTiming({ durationInFrames: TRANSITION_DURATION })}
|
||||
/>
|
||||
<TransitionSeries.Sequence
|
||||
durationInFrames={TIER2_SCENE_DURATION}
|
||||
premountFor={TRANSITION_DURATION}
|
||||
>
|
||||
<FeatureScene feature={feature} />
|
||||
</TransitionSeries.Sequence>
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
{/* Outro */}
|
||||
<TransitionSeries.Transition
|
||||
presentation={fade()}
|
||||
timing={linearTiming({ durationInFrames: TRANSITION_DURATION })}
|
||||
/>
|
||||
<TransitionSeries.Sequence
|
||||
durationInFrames={OUTRO_DURATION}
|
||||
premountFor={TRANSITION_DURATION}
|
||||
>
|
||||
<OutroCard />
|
||||
</TransitionSeries.Sequence>
|
||||
</TransitionSeries>
|
||||
</AbsoluteFill>
|
||||
);
|
||||
}
|
||||
19
my-video/src/Root.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import "./index.css";
|
||||
import { Composition } from "remotion";
|
||||
import { MyComposition } from "./Composition";
|
||||
import { FPS, WIDTH, HEIGHT, TOTAL_DURATION } from "./constants";
|
||||
|
||||
export const RemotionRoot: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<Composition
|
||||
id="ReleaseVideo"
|
||||
component={MyComposition}
|
||||
durationInFrames={TOTAL_DURATION}
|
||||
fps={FPS}
|
||||
width={WIDTH}
|
||||
height={HEIGHT}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
50
my-video/src/components/AnimatedText.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import { type CSSProperties } from "react";
|
||||
import { interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion";
|
||||
|
||||
type AnimatedTextProps = {
|
||||
text: string;
|
||||
delay?: number;
|
||||
fontSize?: number;
|
||||
fontWeight?: CSSProperties["fontWeight"];
|
||||
color?: string;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
|
||||
export function AnimatedText({
|
||||
text,
|
||||
delay = 0,
|
||||
fontSize = 48,
|
||||
fontWeight = "bold",
|
||||
color = "#ffffff",
|
||||
style,
|
||||
}: AnimatedTextProps) {
|
||||
const frame = useCurrentFrame();
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
const progress = spring({
|
||||
frame: frame - delay,
|
||||
fps,
|
||||
config: {
|
||||
damping: 20,
|
||||
stiffness: 200,
|
||||
},
|
||||
});
|
||||
|
||||
const translateY = interpolate(progress, [0, 1], [30, 0]);
|
||||
const opacity = interpolate(progress, [0, 1], [0, 1]);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
fontSize,
|
||||
fontWeight,
|
||||
color,
|
||||
transform: `translateY(${translateY}px)`,
|
||||
opacity,
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
131
my-video/src/components/BrowserFrame.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
import { type ReactNode } from "react";
|
||||
import { useCurrentFrame, useVideoConfig } from "remotion";
|
||||
import { COLORS } from "../constants";
|
||||
|
||||
type BrowserFrameProps = {
|
||||
children: ReactNode;
|
||||
accentColor?: string;
|
||||
};
|
||||
|
||||
export function BrowserFrame({
|
||||
children,
|
||||
accentColor = COLORS.accentCyan,
|
||||
}: BrowserFrameProps) {
|
||||
const frame = useCurrentFrame();
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
// Rotate once every 3 seconds
|
||||
const angle = (frame / fps) * 120; // 120 degrees per second
|
||||
|
||||
return (
|
||||
<div style={{ position: "relative", width: "100%", height: "100%" }}>
|
||||
{/* Rotating gradient border layer */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
inset: -2,
|
||||
borderRadius: 14,
|
||||
background: `conic-gradient(from ${angle}deg, transparent 0%, transparent 60%, ${accentColor} 75%, ${accentColor}cc 80%, transparent 95%, transparent 100%)`,
|
||||
filter: "blur(4px)",
|
||||
}}
|
||||
/>
|
||||
{/* Subtle static glow underneath */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
inset: -1,
|
||||
borderRadius: 13,
|
||||
border: `1px solid ${accentColor}22`,
|
||||
boxShadow: `0 0 30px ${accentColor}15`,
|
||||
}}
|
||||
/>
|
||||
{/* Main frame content */}
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
borderRadius: 12,
|
||||
overflow: "hidden",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
{/* Title bar */}
|
||||
<div
|
||||
style={{
|
||||
background: "#2d2d3a",
|
||||
height: 40,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
flexShrink: 0,
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
{/* Traffic lights */}
|
||||
<div style={{ display: "flex", gap: 8, zIndex: 1 }}>
|
||||
<div
|
||||
style={{
|
||||
width: 12,
|
||||
height: 12,
|
||||
borderRadius: "50%",
|
||||
background: "#ff5f57",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: 12,
|
||||
height: 12,
|
||||
borderRadius: "50%",
|
||||
background: "#ffbd2e",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: 12,
|
||||
height: 12,
|
||||
borderRadius: "50%",
|
||||
background: "#28c840",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Centered title */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
right: 0,
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
color: COLORS.textSecondary,
|
||||
fontSize: 13,
|
||||
fontFamily: "sans-serif",
|
||||
}}
|
||||
>
|
||||
Actual Budget
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content area */}
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
background: "#0f0f1a",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
116
my-video/src/components/FeatureScene.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
import { AbsoluteFill, Img, interpolate, spring, staticFile, useCurrentFrame, useVideoConfig } from "remotion";
|
||||
import { loadFont } from "@remotion/google-fonts/Inter";
|
||||
import { type Feature, COLORS, FRAMES_PER_BEAT } from "../constants";
|
||||
import { AnimatedText } from "./AnimatedText";
|
||||
import { BrowserFrame } from "./BrowserFrame";
|
||||
|
||||
const { fontFamily } = loadFont();
|
||||
|
||||
type FeatureSceneProps = {
|
||||
feature: Feature;
|
||||
};
|
||||
|
||||
export function FeatureScene({ feature }: FeatureSceneProps) {
|
||||
const frame = useCurrentFrame();
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
// Browser frame slides in from right
|
||||
const slideProgress = spring({
|
||||
frame,
|
||||
fps,
|
||||
config: {
|
||||
damping: 20,
|
||||
stiffness: 200,
|
||||
},
|
||||
});
|
||||
|
||||
const translateX = interpolate(slideProgress, [0, 1], [400, 0]);
|
||||
|
||||
return (
|
||||
<AbsoluteFill
|
||||
style={{
|
||||
background: `radial-gradient(ellipse at 30% 50%, ${feature.accentColor}18 0%, ${COLORS.bgDark} 60%)`,
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
padding: "60px 80px",
|
||||
gap: 60,
|
||||
fontFamily,
|
||||
}}
|
||||
>
|
||||
{/* Background gradient overlay */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
inset: 0,
|
||||
background: `linear-gradient(135deg, ${COLORS.bgDark} 0%, ${COLORS.bgGradient} 100%)`,
|
||||
zIndex: 0,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Accent glow */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: feature.screenshot ? -100 : "50%",
|
||||
top: "50%",
|
||||
transform: feature.screenshot ? "translateY(-50%)" : "translate(-50%, -50%)",
|
||||
width: 500,
|
||||
height: 500,
|
||||
borderRadius: "50%",
|
||||
background: `radial-gradient(ellipse at center, ${feature.accentColor}20 0%, transparent 70%)`,
|
||||
zIndex: 0,
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Text area */}
|
||||
<div
|
||||
style={{
|
||||
flex: feature.screenshot ? "0 0 360px" : 1,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: feature.screenshot ? "flex-start" : "center",
|
||||
justifyContent: feature.screenshot ? "flex-start" : "center",
|
||||
gap: 16,
|
||||
zIndex: 1,
|
||||
}}
|
||||
>
|
||||
<AnimatedText
|
||||
text={feature.title}
|
||||
delay={0}
|
||||
fontSize={feature.screenshot ? 42 : 56}
|
||||
fontWeight="bold"
|
||||
color={feature.accentColor}
|
||||
style={{ lineHeight: 1.2, textAlign: feature.screenshot ? "left" : "center" }}
|
||||
/>
|
||||
<AnimatedText
|
||||
text={feature.tagline}
|
||||
delay={FRAMES_PER_BEAT}
|
||||
fontSize={feature.screenshot ? 22 : 28}
|
||||
fontWeight={400}
|
||||
color={COLORS.textSecondary}
|
||||
style={{ lineHeight: 1.5, textAlign: feature.screenshot ? "left" : "center" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Browser frame with screenshot */}
|
||||
{feature.screenshot && (
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
transform: `translateX(${translateX}px)`,
|
||||
zIndex: 1,
|
||||
}}
|
||||
>
|
||||
<BrowserFrame accentColor={feature.accentColor}>
|
||||
<Img
|
||||
src={staticFile(`screenshots/${feature.screenshot}`)}
|
||||
style={{ width: "100%", display: "block" }}
|
||||
/>
|
||||
</BrowserFrame>
|
||||
</div>
|
||||
)}
|
||||
</AbsoluteFill>
|
||||
);
|
||||
}
|
||||
201
my-video/src/components/OutroCard.tsx
Normal file
@@ -0,0 +1,201 @@
|
||||
import { AbsoluteFill, Img, interpolate, spring, staticFile, useCurrentFrame, useVideoConfig } from "remotion";
|
||||
import { loadFont } from "@remotion/google-fonts/Inter";
|
||||
import { COLORS, FRAMES_PER_BEAT, OUTRO_DURATION } from "../constants";
|
||||
|
||||
const { fontFamily } = loadFont();
|
||||
|
||||
const STATS = [
|
||||
{ number: "4", label: "Features" },
|
||||
{ number: "45", label: "Enhancements" },
|
||||
{ number: "32", label: "Bugfixes" },
|
||||
];
|
||||
|
||||
type StatCardProps = {
|
||||
number: string;
|
||||
label: string;
|
||||
delay: number;
|
||||
};
|
||||
|
||||
function StatCard({ number, label, delay }: StatCardProps) {
|
||||
const frame = useCurrentFrame();
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
const progress = spring({
|
||||
frame: frame - delay,
|
||||
fps,
|
||||
config: {
|
||||
damping: 15,
|
||||
stiffness: 120,
|
||||
},
|
||||
});
|
||||
|
||||
const translateY = interpolate(progress, [0, 1], [40, 0]);
|
||||
const opacity = interpolate(progress, [0, 1], [0, 1]);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: 8,
|
||||
transform: `translateY(${translateY}px)`,
|
||||
opacity,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 80,
|
||||
fontWeight: "bold",
|
||||
color: COLORS.accentGold,
|
||||
lineHeight: 1,
|
||||
}}
|
||||
>
|
||||
{number}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 22,
|
||||
color: COLORS.textSecondary,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function OutroCard() {
|
||||
const frame = useCurrentFrame();
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
const statsEndDelay = STATS.length * FRAMES_PER_BEAT * 2;
|
||||
|
||||
// CTA appears after stats
|
||||
const ctaProgress = spring({
|
||||
frame: frame - statsEndDelay,
|
||||
fps,
|
||||
config: {
|
||||
damping: 20,
|
||||
stiffness: 150,
|
||||
},
|
||||
});
|
||||
|
||||
const ctaOpacity = interpolate(ctaProgress, [0, 1], [0, 1]);
|
||||
const ctaTranslateY = interpolate(ctaProgress, [0, 1], [20, 0]);
|
||||
|
||||
// Fade out in last 1 second (30 frames)
|
||||
const fadeOutOpacity = interpolate(
|
||||
frame,
|
||||
[OUTRO_DURATION - 30, OUTRO_DURATION],
|
||||
[1, 0],
|
||||
{
|
||||
extrapolateLeft: "clamp",
|
||||
extrapolateRight: "clamp",
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<AbsoluteFill
|
||||
style={{
|
||||
background: `radial-gradient(ellipse at center, ${COLORS.bgGradient} 0%, ${COLORS.bgDark} 100%)`,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
gap: 48,
|
||||
fontFamily,
|
||||
opacity: fadeOutOpacity,
|
||||
}}
|
||||
>
|
||||
{/* Background glow */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
width: 700,
|
||||
height: 700,
|
||||
borderRadius: "50%",
|
||||
background: `radial-gradient(ellipse at center, ${COLORS.accentGold}10 0%, transparent 70%)`,
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Stats row */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: 80,
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
{STATS.map((stat, i) => (
|
||||
<StatCard
|
||||
key={stat.label}
|
||||
number={stat.number}
|
||||
label={stat.label}
|
||||
delay={i * FRAMES_PER_BEAT * 2}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* CTA */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
opacity: ctaOpacity,
|
||||
transform: `translateY(${ctaTranslateY}px)`,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 36,
|
||||
fontWeight: "bold",
|
||||
color: COLORS.white,
|
||||
}}
|
||||
>
|
||||
Update now
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 22,
|
||||
color: COLORS.accentCyan,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
actualbudget.org
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Logo at bottom */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: 40,
|
||||
opacity: 0.3,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={staticFile("logo.svg")}
|
||||
style={{ width: 36, height: 36 }}
|
||||
/>
|
||||
<span
|
||||
style={{
|
||||
color: COLORS.textSecondary,
|
||||
fontSize: 16,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
Actual Budget
|
||||
</span>
|
||||
</div>
|
||||
</AbsoluteFill>
|
||||
);
|
||||
}
|
||||
124
my-video/src/components/TitleCard.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
import { AbsoluteFill, Img, interpolate, spring, staticFile, useCurrentFrame, useVideoConfig } from "remotion";
|
||||
import { loadFont } from "@remotion/google-fonts/Inter";
|
||||
import { COLORS } from "../constants";
|
||||
|
||||
const { fontFamily } = loadFont();
|
||||
|
||||
export function TitleCard() {
|
||||
const frame = useCurrentFrame();
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
// Logo springs in with heavy config
|
||||
const logoProgress = spring({
|
||||
frame,
|
||||
fps,
|
||||
config: {
|
||||
damping: 200,
|
||||
},
|
||||
});
|
||||
|
||||
const logoScale = interpolate(logoProgress, [0, 1], [0.5, 1]);
|
||||
const logoOpacity = interpolate(logoProgress, [0, 1], [0, 1]);
|
||||
|
||||
// Version badge fades in at 1-2s (30-60 frames)
|
||||
const badgeOpacity = interpolate(frame, [30, 60], [0, 1], {
|
||||
extrapolateLeft: "clamp",
|
||||
extrapolateRight: "clamp",
|
||||
});
|
||||
|
||||
// "Here's what's new" subtitle springs in at 2s (frame 60)
|
||||
const subtitleProgress = spring({
|
||||
frame: frame - 60,
|
||||
fps,
|
||||
config: {
|
||||
damping: 200,
|
||||
stiffness: 200,
|
||||
},
|
||||
});
|
||||
|
||||
const subtitleTranslateY = interpolate(subtitleProgress, [0, 1], [20, 0]);
|
||||
const subtitleOpacity = interpolate(subtitleProgress, [0, 1], [0, 1]);
|
||||
|
||||
return (
|
||||
<AbsoluteFill
|
||||
style={{
|
||||
background: `radial-gradient(ellipse at center, ${COLORS.bgGradient} 0%, ${COLORS.bgDark} 100%)`,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
fontFamily,
|
||||
}}
|
||||
>
|
||||
{/* Radial glow */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
width: 600,
|
||||
height: 600,
|
||||
borderRadius: "50%",
|
||||
background: `radial-gradient(ellipse at center, ${COLORS.accentPurple}22 0%, transparent 70%)`,
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Logo + title */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: 24,
|
||||
transform: `scale(${logoScale})`,
|
||||
opacity: logoOpacity,
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={staticFile("logo.svg")}
|
||||
style={{ width: 120, height: 120 }}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 64,
|
||||
fontWeight: "bold",
|
||||
color: COLORS.white,
|
||||
letterSpacing: -1,
|
||||
}}
|
||||
>
|
||||
Actual Budget
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Version badge */}
|
||||
<div
|
||||
style={{
|
||||
marginTop: 20,
|
||||
opacity: badgeOpacity,
|
||||
background: COLORS.accentPurple,
|
||||
color: COLORS.white,
|
||||
fontSize: 22,
|
||||
fontWeight: 600,
|
||||
padding: "6px 20px",
|
||||
borderRadius: 999,
|
||||
letterSpacing: 1,
|
||||
}}
|
||||
>
|
||||
v26.4.0
|
||||
</div>
|
||||
|
||||
{/* Subtitle */}
|
||||
<div
|
||||
style={{
|
||||
marginTop: 32,
|
||||
fontSize: 32,
|
||||
color: COLORS.textSecondary,
|
||||
fontWeight: 400,
|
||||
opacity: subtitleOpacity,
|
||||
transform: `translateY(${subtitleTranslateY}px)`,
|
||||
}}
|
||||
>
|
||||
{"Here's what's new"}
|
||||
</div>
|
||||
</AbsoluteFill>
|
||||
);
|
||||
}
|
||||
73
my-video/src/constants.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
export const FPS = 30;
|
||||
export const WIDTH = 1280;
|
||||
export const HEIGHT = 720;
|
||||
|
||||
export const BPM = 139;
|
||||
export const FRAMES_PER_BEAT = Math.round((60 / BPM) * FPS); // ~13
|
||||
|
||||
export const TITLE_DURATION = 120;
|
||||
export const TIER1_SCENE_DURATION = 160;
|
||||
export const TIER2_SCENE_DURATION = 180;
|
||||
export const OUTRO_DURATION = 240;
|
||||
export const TRANSITION_DURATION = FRAMES_PER_BEAT;
|
||||
|
||||
export const COLORS = {
|
||||
bgDark: "#1a1a2e",
|
||||
bgGradient: "#16213e",
|
||||
accentCyan: "#00d2ff",
|
||||
accentCoral: "#e94560",
|
||||
accentGold: "#ffd700",
|
||||
accentPurple: "#7c3aed",
|
||||
white: "#ffffff",
|
||||
textSecondary: "#94a3b8",
|
||||
};
|
||||
|
||||
export type Feature = {
|
||||
title: string;
|
||||
tagline: string;
|
||||
screenshot?: string;
|
||||
accentColor: string;
|
||||
};
|
||||
|
||||
export const TIER1_FEATURES: Feature[] = [
|
||||
{
|
||||
title: "Donut Chart Reports",
|
||||
tagline: "Beautiful category breakdowns",
|
||||
screenshot: "donut-chart.png",
|
||||
accentColor: COLORS.accentCyan,
|
||||
},
|
||||
{
|
||||
title: "Budget Notes",
|
||||
tagline: "Monthly per-category notes",
|
||||
screenshot: "budget-notes.png",
|
||||
accentColor: COLORS.accentCyan,
|
||||
},
|
||||
];
|
||||
|
||||
export const TIER2_FEATURES: Feature[] = [
|
||||
{
|
||||
title: "Drag & Drop Reordering",
|
||||
tagline: "Reorder transactions — your way",
|
||||
screenshot: "drag-drop.png",
|
||||
accentColor: COLORS.accentCyan,
|
||||
},
|
||||
{
|
||||
title: "Actual CLI",
|
||||
tagline: "Your budget, from the command line",
|
||||
screenshot: "cli-tool.png",
|
||||
accentColor: COLORS.accentCyan,
|
||||
},
|
||||
{
|
||||
title: "And much more...",
|
||||
tagline: "Thanks to all the contributors",
|
||||
accentColor: COLORS.accentCoral,
|
||||
},
|
||||
];
|
||||
|
||||
// Total = TITLE + 3*TIER1 + 4*TIER2 + OUTRO - 8*TRANSITION
|
||||
export const TOTAL_DURATION =
|
||||
TITLE_DURATION +
|
||||
TIER1_FEATURES.length * TIER1_SCENE_DURATION +
|
||||
TIER2_FEATURES.length * TIER2_SCENE_DURATION +
|
||||
OUTRO_DURATION -
|
||||
(TIER1_FEATURES.length + TIER2_FEATURES.length + 1) * TRANSITION_DURATION;
|
||||
1
my-video/src/index.css
Normal file
@@ -0,0 +1 @@
|
||||
@import "tailwindcss";
|
||||
4
my-video/src/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { registerRoot } from "remotion";
|
||||
import { RemotionRoot } from "./Root";
|
||||
|
||||
registerRoot(RemotionRoot);
|
||||
15
my-video/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2018",
|
||||
"module": "commonjs",
|
||||
"jsx": "react-jsx",
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"lib": ["es2015"],
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noUnusedLocals": true
|
||||
},
|
||||
"exclude": ["remotion.config.ts"]
|
||||
}
|
||||
@@ -61,6 +61,7 @@
|
||||
"install:server": "yarn workspaces focus @actual-app/sync-server --production",
|
||||
"constraints": "yarn constraints",
|
||||
"typecheck": "tsgo -p tsconfig.root.json --noEmit && lage typecheck",
|
||||
"jq": "./node_modules/node-jq/bin/jq",
|
||||
"prepare": "husky"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -69,6 +70,7 @@
|
||||
"@types/prompts": "^2.4.9",
|
||||
"@typescript/native-preview": "^7.0.0-dev.20260309.1",
|
||||
"@yarnpkg/types": "^4.0.1",
|
||||
"baseline-browser-mapping": "^2.10.0",
|
||||
"cross-env": "^10.1.0",
|
||||
"eslint": "^9.39.3",
|
||||
"eslint-plugin-perfectionist": "^5.6.0",
|
||||
@@ -78,12 +80,14 @@
|
||||
"lage": "^2.14.19",
|
||||
"lint-staged": "^16.3.2",
|
||||
"minimatch": "^10.2.4",
|
||||
"node-jq": "^6.3.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"oxfmt": "^0.32.0",
|
||||
"oxlint": "^1.51.0",
|
||||
"oxlint-tsgolint": "^0.13.0",
|
||||
"p-limit": "^7.3.0",
|
||||
"prompts": "^2.4.2",
|
||||
"source-map-support": "^0.5.21",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
import type {
|
||||
RequestInfo as FetchInfo,
|
||||
RequestInit as FetchInit,
|
||||
} from 'node-fetch';
|
||||
|
||||
import { init as initLootCore } from '@actual-app/core/server/main';
|
||||
import type { InitConfig, lib } from '@actual-app/core/server/main';
|
||||
|
||||
@@ -12,6 +17,14 @@ export let internal: typeof lib | null = null;
|
||||
export async function init(config: InitConfig = {}) {
|
||||
validateNodeVersion();
|
||||
|
||||
if (!globalThis.fetch) {
|
||||
globalThis.fetch = (url: URL | RequestInfo, init?: RequestInit) => {
|
||||
return import('node-fetch').then(({ default: fetch }) =>
|
||||
fetch(url as unknown as FetchInfo, init as unknown as FetchInit),
|
||||
) as unknown as Promise<Response>;
|
||||
};
|
||||
}
|
||||
|
||||
internal = await initLootCore(config);
|
||||
return internal;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
"@actual-app/crdt": "workspace:*",
|
||||
"better-sqlite3": "^12.6.2",
|
||||
"compare-versions": "^6.1.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"uuid": "^13.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
"@storybook/addon-a11y": "^10.2.16",
|
||||
"@storybook/addon-docs": "^10.2.16",
|
||||
"@storybook/react-vite": "^10.2.16",
|
||||
"@svgr/babel-plugin-add-jsx-attribute": "^8.0.0",
|
||||
"@svgr/cli": "^8.1.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@typescript/native-preview": "^7.0.0-dev.20260309.1",
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
module.exports = {
|
||||
prettier: true,
|
||||
prettierConfig: {
|
||||
singleQuote: true,
|
||||
},
|
||||
svgoConfig: {
|
||||
plugins: [
|
||||
{
|
||||
|
||||
@@ -9,4 +9,4 @@ function indexTemplate(filePaths: { path: string }[]) {
|
||||
return exportEntries.join('\n');
|
||||
}
|
||||
|
||||
export default indexTemplate;
|
||||
module.exports = indexTemplate;
|
||||
|
||||
@@ -13,11 +13,11 @@ export const SvgLogo = (props: SVGProps<SVGSVGElement>) => (
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="m1.138 30.423 13.8-29.309a.32.32 0 0 1 .289-.184h.605a.32.32 0 0 1 .287.18l8.903 18.29 2.791-1.074a.32.32 0 0 1 .414.184l.742 1.932a.32.32 0 0 1-.183.413l-2.574.99 3.175 6.524a.32.32 0 0 1-.147.428l-1.861.905a.32.32 0 0 1-.428-.147l-3.277-6.733-21.98 8.453a.32.32 0 0 1-.415-.189l-.152-.418a.32.32 0 0 1 .01-.245M15.56 6.152 5.85 26.774l16.634-6.398z"
|
||||
d="m1.138 30.423 13.8-29.309a.32.32 0 0 1 .289-.184h.605a.32.32 0 0 1 .287.18l8.903 18.29 2.791-1.074a.32.32 0 0 1 .414.184l.742 1.932a.32.32 0 0 1-.183.413l-2.574.99 3.175 6.524a.32.32 0 0 1-.147.428l-1.861.905a.32.32 0 0 1-.428-.147l-3.277-6.733-21.98 8.453a.32.32 0 0 1-.415-.189l-.152-.418a.32.32 0 0 1 .01-.245ZM15.56 6.152 5.85 26.774l16.634-6.398L15.56 6.152Z"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="m21.777 14.568.932 2.544-21.203 7.775a.32.32 0 0 1-.41-.19l-.713-1.944a.32.32 0 0 1 .19-.41z"
|
||||
d="m21.777 14.568.932 2.544-21.203 7.775a.32.32 0 0 1-.41-.19l-.713-1.944a.32.32 0 0 1 .19-.41l21.204-7.775Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -15,4 +15,4 @@ export const ${componentName} = (${props}) => (
|
||||
`;
|
||||
};
|
||||
|
||||
export default tmpl;
|
||||
module.exports = tmpl;
|
||||
|
||||
@@ -11,11 +11,11 @@ export const SvgAdd = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M23 11.5a1.5 1.5 0 0 1-1.5 1.5h-20a1.5 1.5 0 0 1 0-3h20a1.5 1.5 0 0 1 1.5 1.5"
|
||||
d="M23 11.5a1.5 1.5 0 0 1-1.5 1.5h-20a1.5 1.5 0 0 1 0-3h20a1.5 1.5 0 0 1 1.5 1.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M11.5 23a1.5 1.5 0 0 1-1.5-1.5v-20a1.5 1.5 0 0 1 3 0v20a1.5 1.5 0 0 1-1.5 1.5"
|
||||
d="M11.5 23a1.5 1.5 0 0 1-1.5-1.5v-20a1.5 1.5 0 0 1 3 0v20a1.5 1.5 0 0 1-1.5 1.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -12,7 +12,7 @@ export const SvgExpandArrow = (props: SVGProps<SVGSVGElement>) => (
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M24.483.576q-.463-.49-1.097-.49H1.56q-.633 0-1.096.49A1.64 1.64 0 0 0 0 1.737q0 .671.463 1.161l10.913 11.558q.465.49 1.097.49.633 0 1.096-.49L24.483 2.898q.462-.49.463-1.16 0-.672-.463-1.162"
|
||||
d="M24.483.576c-.309-.327-.674-.49-1.097-.49H1.56C1.137.086.771.25.463.576A1.635 1.635 0 0 0 0 1.737c0 .448.154.834.463 1.161l10.913 11.558c.31.327.675.49 1.097.49.422 0 .788-.163 1.096-.49L24.483 2.898c.308-.327.463-.713.463-1.16 0-.448-.155-.835-.463-1.162Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ export const SvgLeftArrow2 = (props: SVGProps<SVGSVGElement>) => (
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M30.256 48.614a3.14 3.14 0 0 0-.989-2.153L10.803 29.063h76.915a3 3 0 0 0 .315 0c1.584-.084 2.95-1.64 2.867-3.266-.082-1.625-1.598-3.028-3.182-2.943H10.803L29.267 5.49c1.284-1.099 1.456-3.057.385-4.373a2.972 2.972 0 0 0-4.48-.187L.971 23.695a3.163 3.163 0 0 0 0 4.56l24.2 22.766a2.98 2.98 0 0 0 2.205.84c1.669-.08 2.958-1.534 2.88-3.247"
|
||||
d="M30.256 48.614a3.14 3.14 0 0 0-.989-2.153L10.803 29.063h76.915a3.2 3.2 0 0 0 .315 0c1.584-.084 2.95-1.64 2.867-3.266-.082-1.625-1.598-3.028-3.182-2.943H10.803L29.267 5.49c1.284-1.099 1.456-3.057.385-4.373a2.972 2.972 0 0 0-4.48-.187L.971 23.695a3.163 3.163 0 0 0 0 4.56l24.2 22.766a2.98 2.98 0 0 0 2.205.84c1.669-.08 2.958-1.534 2.88-3.247Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ export const SvgMath = (props: SVGProps<SVGSVGElement>) => (
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M2.813 0A2.81 2.81 0 0 0 0 2.812v8.022a2.8 2.8 0 0 0 2.813 2.802h8.01a2.8 2.8 0 0 0 2.813-2.802V2.812A2.81 2.81 0 0 0 10.824 0zm16.363 0a2.81 2.81 0 0 0-2.812 2.812v8.022a2.8 2.8 0 0 0 2.812 2.802h8.012A2.8 2.8 0 0 0 30 10.834V2.812A2.81 2.81 0 0 0 27.187 0h-8.01zM6.796 2.365c.73-.011 1.397.657 1.386 1.385v1.705h1.704c.72-.01 1.383.643 1.383 1.363s-.662 1.374-1.383 1.364H8.182v1.704c.01.72-.643 1.383-1.364 1.383-.72 0-1.374-.662-1.363-1.383V8.182H3.75c-.72.01-1.383-.643-1.383-1.364 0-.72.663-1.374 1.383-1.363h1.705V3.75c-.012-.714.628-1.374 1.342-1.385zm15.182 1.321 1.204 1.204 1.204-1.204c.573-.468 1.285-.54 1.841-.101.605.531.563 1.545.087 2.03L25.11 6.817l1.204 1.204c.522.5.531 1.437.02 1.948-.512.512-1.447.502-1.948-.02l-1.204-1.204-1.204 1.204c-.501.522-1.437.532-1.948.02-.512-.511-.502-1.447.02-1.948l1.204-1.204-1.204-1.204c-.53-.769-.48-1.4.062-2.008.617-.41 1.322-.464 1.866.08zM2.812 16.364A2.81 2.81 0 0 0 0 19.176v8.022A2.8 2.8 0 0 0 2.813 30h8.01a2.8 2.8 0 0 0 2.813-2.802v-8.022a2.81 2.81 0 0 0-2.812-2.812H2.813zm16.364 0a2.81 2.81 0 0 0-2.812 2.812v8.022A2.8 2.8 0 0 0 19.176 30h8.012A2.8 2.8 0 0 0 30 27.198v-8.022a2.81 2.81 0 0 0-2.813-2.812h-8.01zm.8 3.409h6.274c.72-.01 1.383.643 1.383 1.363S26.97 22.51 26.25 22.5h-6.136c-.714.036-1.397-.58-1.433-1.294s.58-1.397 1.294-1.433zM3.611 21.818h6.274c.72-.01 1.383.643 1.383 1.364 0 .72-.662 1.374-1.383 1.363H3.75c-.714.037-1.397-.58-1.433-1.294s.58-1.397 1.295-1.433zm16.363 2.046h6.275c.72-.01 1.383.643 1.383 1.363s-.663 1.374-1.383 1.364h-6.136c-.714.036-1.397-.58-1.433-1.295-.037-.714.58-1.396 1.294-1.432"
|
||||
d="M2.813 0A2.81 2.81 0 0 0 0 2.812v8.022a2.8 2.8 0 0 0 2.813 2.802h8.01a2.8 2.8 0 0 0 2.813-2.802V2.812A2.81 2.81 0 0 0 10.824 0H2.813zm16.363 0a2.81 2.81 0 0 0-2.812 2.812v8.022a2.8 2.8 0 0 0 2.812 2.802h8.012A2.8 2.8 0 0 0 30 10.834V2.812A2.81 2.81 0 0 0 27.187 0h-8.01zM6.796 2.365c.73-.011 1.397.657 1.386 1.385v1.705h1.704c.72-.01 1.383.643 1.383 1.363s-.662 1.374-1.383 1.364H8.182v1.704c.01.72-.643 1.383-1.364 1.383-.72 0-1.374-.662-1.363-1.383V8.182H3.75c-.72.01-1.383-.643-1.383-1.364 0-.72.663-1.374 1.383-1.363h1.705V3.75c-.012-.714.628-1.374 1.342-1.385zm15.182 1.321 1.204 1.204 1.204-1.204c.573-.468 1.285-.54 1.841-.101.605.531.563 1.545.087 2.03L25.11 6.817l1.204 1.204c.522.5.531 1.437.02 1.948-.512.512-1.447.502-1.948-.02l-1.204-1.204-1.204 1.204c-.501.522-1.437.532-1.948.02-.512-.511-.502-1.447.02-1.948l1.204-1.204-1.204-1.204c-.53-.769-.48-1.4.062-2.008.617-.41 1.322-.464 1.866.08zM2.812 16.364A2.81 2.81 0 0 0 0 19.176v8.022A2.8 2.8 0 0 0 2.813 30h8.01a2.8 2.8 0 0 0 2.813-2.802v-8.022a2.81 2.81 0 0 0-2.812-2.812H2.813zm16.364 0a2.81 2.81 0 0 0-2.812 2.812v8.022A2.8 2.8 0 0 0 19.176 30h8.012A2.8 2.8 0 0 0 30 27.198v-8.022a2.81 2.81 0 0 0-2.813-2.812h-8.01zm.8 3.409h6.274c.72-.01 1.383.643 1.383 1.363S26.97 22.51 26.25 22.5h-6.136c-.714.036-1.397-.58-1.433-1.294-.037-.714.58-1.397 1.294-1.433zM3.611 21.818h6.274c.72-.01 1.383.643 1.383 1.364 0 .72-.662 1.374-1.383 1.363H3.75c-.714.037-1.397-.58-1.433-1.294-.036-.714.58-1.397 1.295-1.433zm16.363 2.046h6.275c.72-.01 1.383.643 1.383 1.363s-.663 1.374-1.383 1.364h-6.136c-.714.036-1.397-.58-1.433-1.295-.037-.714.58-1.396 1.294-1.432z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ export const SvgRightArrow2 = (props: SVGProps<SVGSVGElement>) => (
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M63.004.003a3 3 0 0 0-1.875 5.219L79.44 22.034H3.16a3 3 0 0 0-.313 0c-1.57.082-2.925 1.585-2.843 3.156s1.585 2.926 3.156 2.844H79.44L61.129 44.815a3 3 0 1 0 4.062 4.407l24-22a3 3 0 0 0 0-4.407l-24-22a3 3 0 0 0-2.187-.812"
|
||||
d="M63.004.003a3 3 0 0 0-1.875 5.219L79.44 22.034H3.16a3.257 3.257 0 0 0-.313 0c-1.57.082-2.925 1.585-2.843 3.156.081 1.571 1.585 2.926 3.156 2.844H79.44L61.129 44.815a3 3 0 1 0 4.062 4.407l24-22a3 3 0 0 0 0-4.407l-24-22a3 3 0 0 0-2.187-.812Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgSubtract = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M23 11.5a1.5 1.5 0 0 1-1.5 1.5h-20a1.5 1.5 0 0 1 0-3h20a1.5 1.5 0 0 1 1.5 1.5"
|
||||
d="M23 11.5a1.5 1.5 0 0 1-1.5 1.5h-20a1.5 1.5 0 0 1 0-3h20a1.5 1.5 0 0 1 1.5 1.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -12,12 +12,12 @@ export const SvgAdd = (props: SVGProps<SVGSVGElement>) => (
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M23 11.5a1.5 1.5 0 0 1-1.5 1.5h-20a1.5 1.5 0 0 1 0-3h20a1.5 1.5 0 0 1 1.5 1.5"
|
||||
d="M23 11.5a1.5 1.5 0 0 1-1.5 1.5h-20a1.5 1.5 0 0 1 0-3h20a1.5 1.5 0 0 1 1.5 1.5Z"
|
||||
className="path"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M11.5 23a1.5 1.5 0 0 1-1.5-1.5v-20a1.5 1.5 0 0 1 3 0v20a1.5 1.5 0 0 1-1.5 1.5"
|
||||
d="M11.5 23a1.5 1.5 0 0 1-1.5-1.5v-20a1.5 1.5 0 0 1 3 0v20a1.5 1.5 0 0 1-1.5 1.5Z"
|
||||
className="path"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAddOutline = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M11 9h4v2h-4v4H9v-4H5V9h4V5h2zm-1 11a10 10 0 1 1 0-20 10 10 0 0 1 0 20m0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16"
|
||||
d="M11 9h4v2h-4v4H9v-4H5V9h4V5h2v4zm-1 11a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAddSolid = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M11 9V5H9v4H5v2h4v4h2v-4h4V9zm-1 11a10 10 0 1 1 0-20 10 10 0 0 1 0 20"
|
||||
d="M11 9V5H9v4H5v2h4v4h2v-4h4V9h-4zm-1 11a10 10 0 1 1 0-20 10 10 0 0 1 0 20z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAdjust = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M10 2v16a8 8 0 1 0 0-16m0 18a10 10 0 1 1 0-20 10 10 0 0 1 0 20"
|
||||
d="M10 2v16a8 8 0 1 0 0-16zm0 18a10 10 0 1 1 0-20 10 10 0 0 1 0 20z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAirplane = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M8.4 12H2.8L1 15H0V5h1l1.8 3h5.6L6 0h2l4.8 8H18a2 2 0 1 1 0 4h-5.2L8 20H6z"
|
||||
d="M8.4 12H2.8L1 15H0V5h1l1.8 3h5.6L6 0h2l4.8 8H18a2 2 0 1 1 0 4h-5.2L8 20H6l2.4-8z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAlbum = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M0 0h20v20H0zm10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16m0-5a3 3 0 1 1 0-6 3 3 0 0 1 0 6"
|
||||
d="M0 0h20v20H0V0zm10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm0-5a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAlignCenter = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M1 1h18v2H1zm0 8h18v2H1zm0 8h18v2H1zM4 5h12v2H4zm0 8h12v2H4z"
|
||||
d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM4 5h12v2H4V5zm0 8h12v2H4v-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAlignJustified = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M1 1h18v2H1zm0 8h18v2H1zm0 8h18v2H1zM1 5h18v2H1zm0 8h18v2H1z"
|
||||
d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM1 5h18v2H1V5zm0 8h18v2H1v-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAlignLeft = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M1 1h18v2H1zm0 8h18v2H1zm0 8h18v2H1zM1 5h12v2H1zm0 8h12v2H1z"
|
||||
d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM1 5h12v2H1V5zm0 8h12v2H1v-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAlignRight = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M1 1h18v2H1zm0 8h18v2H1zm0 8h18v2H1zM7 5h12v2H7zm0 8h12v2H7z"
|
||||
d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM7 5h12v2H7V5zm0 8h12v2H7v-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAnchor = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M4.34 15.66A7.97 7.97 0 0 0 9 17.94V10H5V8h4V5.83a3 3 0 1 1 2 0V8h4v2h-4v7.94a7.97 7.97 0 0 0 4.66-2.28l-1.42-1.42h5.66l-2.83 2.83a10 10 0 0 1-14.14 0L.1 14.24h5.66zM10 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2"
|
||||
d="M4.34 15.66A7.97 7.97 0 0 0 9 17.94V10H5V8h4V5.83a3 3 0 1 1 2 0V8h4v2h-4v7.94a7.97 7.97 0 0 0 4.66-2.28l-1.42-1.42h5.66l-2.83 2.83a10 10 0 0 1-14.14 0L.1 14.24h5.66l-1.42 1.42zM10 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAnnouncement = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M3 6c0-1.1.9-2 2-2h8l4-4h2v16h-2l-4-4H5a2 2 0 0 1-2-2H1V6zm8 9v5H8l-1.67-5H5v-2h8v2z"
|
||||
d="M3 6c0-1.1.9-2 2-2h8l4-4h2v16h-2l-4-4H5a2 2 0 0 1-2-2H1V6h2zm8 9v5H8l-1.67-5H5v-2h8v2h-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgApparel = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M7 0H6L0 3v6l4-1v12h12V8l4 1V3l-6-3h-1a3 3 0 0 1-6 0"
|
||||
d="M7 0H6L0 3v6l4-1v12h12V8l4 1V3l-6-3h-1a3 3 0 0 1-6 0z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgArrowLeft = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="m3.828 9 6.071-6.071-1.414-1.414L0 10l.707.707 7.778 7.778 1.414-1.414L3.828 11H20V9z"
|
||||
d="m3.828 9 6.071-6.071-1.414-1.414L0 10l.707.707 7.778 7.778 1.414-1.414L3.828 11H20V9H3.828z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgArrowOutlineDown = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20m0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16m-2-8V5h4v5h3l-5 5-5-5z"
|
||||
d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm-2-8V5h4v5h3l-5 5-5-5h3z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgArrowOutlineLeft = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0m2 0a8 8 0 1 0 16 0 8 8 0 0 0-16 0m8-2h5v4h-5v3l-5-5 5-5z"
|
||||
d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0zm2 0a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm8-2h5v4h-5v3l-5-5 5-5v3z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgArrowOutlineRight = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M20 10a10 10 0 1 1-20 0 10 10 0 0 1 20 0m-2 0a8 8 0 1 0-16 0 8 8 0 0 0 16 0m-8 2H5V8h5V5l5 5-5 5z"
|
||||
d="M20 10a10 10 0 1 1-20 0 10 10 0 0 1 20 0zm-2 0a8 8 0 1 0-16 0 8 8 0 0 0 16 0zm-8 2H5V8h5V5l5 5-5 5v-3z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgArrowOutlineUp = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20m0 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16m2 8v5H8v-5H5l5-5 5 5z"
|
||||
d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm0 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm2 8v5H8v-5H5l5-5 5 5h-3z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -10,6 +10,6 @@ export const SvgArrowThickDown = (props: SVGProps<SVGSVGElement>) => (
|
||||
...props.style,
|
||||
}}
|
||||
>
|
||||
<path d="M7 10V2h6v8h5l-8 8-8-8z" fill="currentColor" />
|
||||
<path d="M7 10V2h6v8h5l-8 8-8-8h5z" fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,6 @@ export const SvgArrowThickLeft = (props: SVGProps<SVGSVGElement>) => (
|
||||
...props.style,
|
||||
}}
|
||||
>
|
||||
<path d="M10 13h8V7h-8V2l-8 8 8 8z" fill="currentColor" />
|
||||
<path d="M10 13h8V7h-8V2l-8 8 8 8v-5z" fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,6 @@ export const SvgArrowThickRight = (props: SVGProps<SVGSVGElement>) => (
|
||||
...props.style,
|
||||
}}
|
||||
>
|
||||
<path d="M10 7H2v6h8v5l8-8-8-8z" fill="currentColor" />
|
||||
<path d="M10 7H2v6h8v5l8-8-8-8v5z" fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,6 @@ export const SvgArrowThickUp = (props: SVGProps<SVGSVGElement>) => (
|
||||
...props.style,
|
||||
}}
|
||||
>
|
||||
<path d="M7 10v8h6v-8h5l-8-8-8 8z" fill="currentColor" />
|
||||
<path d="M7 10v8h6v-8h5l-8-8-8 8h5z" fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgArrowThinLeft = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="m3.828 9 6.071-6.071-1.414-1.414L0 10l.707.707 7.778 7.778 1.414-1.414L3.828 11H20V9z"
|
||||
d="m3.828 9 6.071-6.071-1.414-1.414L0 10l.707.707 7.778 7.778 1.414-1.414L3.828 11H20V9H3.828z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgArrowThinUp = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M9 3.828 2.929 9.899 1.515 8.485 10 0l.707.707 7.778 7.778-1.414 1.414L11 3.828V20H9z"
|
||||
d="M9 3.828 2.929 9.899 1.515 8.485 10 0l.707.707 7.778 7.778-1.414 1.414L11 3.828V20H9V3.828z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgArrowUp = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M9 3.828 2.929 9.899 1.515 8.485 10 0l.707.707 7.778 7.778-1.414 1.414L11 3.828V20H9z"
|
||||
d="M9 3.828 2.929 9.899 1.515 8.485 10 0l.707.707 7.778 7.778-1.414 1.414L11 3.828V20H9V3.828z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgArtist = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="m15.75 8-3.74-3.75a3.99 3.99 0 0 1 6.82-3.08A4 4 0 0 1 15.75 8m-13.9 7.3 9.2-9.19 2.83 2.83-9.2 9.2-2.82-2.84zm-1.4 2.83 2.11-2.12 1.42 1.42-2.12 2.12-1.42-1.42zM10 15l2-2v7h-2z"
|
||||
d="m15.75 8-3.74-3.75a3.99 3.99 0 0 1 6.82-3.08A4 4 0 0 1 15.75 8zm-13.9 7.3 9.2-9.19 2.83 2.83-9.2 9.2-2.82-2.84zm-1.4 2.83 2.11-2.12 1.42 1.42-2.12 2.12-1.42-1.42zM10 15l2-2v7h-2v-5z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAtSymbol = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M13.6 13.47A4.99 4.99 0 0 1 5 10a5 5 0 0 1 8-4V5h2v6.5a1.5 1.5 0 0 0 3 0V10a8 8 0 1 0-4.42 7.16l.9 1.79A10 10 0 1 1 20 10h-.18.17v1.5a3.5 3.5 0 0 1-6.4 1.97zM10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6"
|
||||
d="M13.6 13.47A4.99 4.99 0 0 1 5 10a5 5 0 0 1 8-4V5h2v6.5a1.5 1.5 0 0 0 3 0V10a8 8 0 1 0-4.42 7.16l.9 1.79A10 10 0 1 1 20 10h-.18.17v1.5a3.5 3.5 0 0 1-6.4 1.97zM10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgAttachment = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M15 3H7a7 7 0 1 0 0 14h8v-2H7A5 5 0 0 1 7 5h8a3 3 0 0 1 0 6H7a1 1 0 0 1 0-2h8V7H7a3 3 0 1 0 0 6h8a5 5 0 0 0 0-10"
|
||||
d="M15 3H7a7 7 0 1 0 0 14h8v-2H7A5 5 0 0 1 7 5h8a3 3 0 0 1 0 6H7a1 1 0 0 1 0-2h8V7H7a3 3 0 1 0 0 6h8a5 5 0 0 0 0-10z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBackspace = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="m0 10 7-7h13v14H7zm14.41 0 2.13-2.12-1.42-1.42L13 8.6l-2.12-2.13-1.42 1.42L11.6 10l-2.13 2.12 1.42 1.42L13 11.4l2.12 2.13 1.42-1.42L14.4 10z"
|
||||
d="m0 10 7-7h13v14H7l-7-7zm14.41 0 2.13-2.12-1.42-1.42L13 8.6l-2.12-2.13-1.42 1.42L11.6 10l-2.13 2.12 1.42 1.42L13 11.4l2.12 2.13 1.42-1.42L14.4 10z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -10,6 +10,6 @@ export const SvgBackward = (props: SVGProps<SVGSVGElement>) => (
|
||||
...props.style,
|
||||
}}
|
||||
>
|
||||
<path d="M19 5v10l-9-5zm-9 0v10l-9-5z" fill="currentColor" />
|
||||
<path d="M19 5v10l-9-5 9-5zm-9 0v10l-9-5 9-5z" fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,6 @@ export const SvgBackwardStep = (props: SVGProps<SVGSVGElement>) => (
|
||||
...props.style,
|
||||
}}
|
||||
>
|
||||
<path d="M4 5h3v10H4zm12 0v10l-9-5z" fill="currentColor" />
|
||||
<path d="M4 5h3v10H4V5zm12 0v10l-9-5 9-5z" fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBadge = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M10 12a6 6 0 1 1 0-12 6 6 0 0 1 0 12m0-3a3 3 0 1 0 0-6 3 3 0 0 0 0 6m4 2.75V20l-4-4-4 4v-8.25a6.97 6.97 0 0 0 8 0"
|
||||
d="M10 12a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-3a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm4 2.75V20l-4-4-4 4v-8.25a6.97 6.97 0 0 0 8 0z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBatteryFull = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2 0v8h16V6zm1 1h4v6H3zm5 0h4v6H8zm5 0h4v6h-4z"
|
||||
d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v8h16V6H2zm1 1h4v6H3V7zm5 0h4v6H8V7zm5 0h4v6h-4V7z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBatteryHalf = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2 0v8h16V6zm1 1h4v6H3zm5 0h4v6H8z"
|
||||
d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v8h16V6H2zm1 1h4v6H3V7zm5 0h4v6H8V7z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBatteryLow = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2 0v8h16V6zm1 1h4v6H3z"
|
||||
d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v8h16V6H2zm1 1h4v6H3V7z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBeverage = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M9 18v-7L0 2V0h20v2l-9 9v7l5 1v1H4v-1zm2-10a2 2 0 1 0 0-4 2 2 0 0 0 0 4"
|
||||
d="M9 18v-7L0 2V0h20v2l-9 9v7l5 1v1H4v-1l5-1zm2-10a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBlock = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0m16.32-4.9L5.09 16.31A8 8 0 0 0 16.32 5.09zm-1.41-1.42A8 8 0 0 0 3.68 14.91z"
|
||||
d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0zm16.32-4.9L5.09 16.31A8 8 0 0 0 16.32 5.09zm-1.41-1.42A8 8 0 0 0 3.68 14.91L14.91 3.68z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBluetooth = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="m9.41 0 6 6-4 4 4 4-6 6H9v-7.59l-3.3 3.3-1.4-1.42L8.58 10l-4.3-4.3L5.7 4.3 9 7.58V0zM11 4.41V7.6L12.59 6zM12.59 14 11 12.41v3.18z"
|
||||
d="m9.41 0 6 6-4 4 4 4-6 6H9v-7.59l-3.3 3.3-1.4-1.42L8.58 10l-4.3-4.3L5.7 4.3 9 7.58V0h.41zM11 4.41V7.6L12.59 6 11 4.41zM12.59 14 11 12.41v3.18L12.59 14z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -10,6 +10,6 @@ export const SvgBolt = (props: SVGProps<SVGSVGElement>) => (
|
||||
...props.style,
|
||||
}}
|
||||
>
|
||||
<path d="M13 8V0L8.11 5.87 3 12h4v8L17 8z" fill="currentColor" />
|
||||
<path d="M13 8V0L8.11 5.87 3 12h4v8L17 8h-4z" fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBookReference = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M6 4H5a1 1 0 1 1 0-2h11V1a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V5a1 1 0 0 0-1-1h-7v8l-2-2-2 2z"
|
||||
d="M6 4H5a1 1 0 1 1 0-2h11V1a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V5a1 1 0 0 0-1-1h-7v8l-2-2-2 2V4z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBookmark = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4z"
|
||||
d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4V2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBookmarkOutline = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4zm2 0v15l6-3 6 3V2z"
|
||||
d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4V2zm2 0v15l6-3 6 3V2H4z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBookmarkOutlineAdd = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4zm2 0v15l6-3 6 3V2zm5 5V5h2v2h2v2h-2v2H9V9H7V7z"
|
||||
d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4V2zm2 0v15l6-3 6 3V2H4zm5 5V5h2v2h2v2h-2v2H9V9H7V7h2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBorderAll = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M11 11v6h6v-6zm0-2h6V3h-6zm-2 2H3v6h6zm0-2V3H3v6zm-8 9V1h18v18H1z"
|
||||
d="M11 11v6h6v-6h-6zm0-2h6V3h-6v6zm-2 2H3v6h6v-6zm0-2V3H3v6h6zm-8 9V1h18v18H1v-1z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBorderBottom = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M1 1h2v2H1zm0 4h2v2H1zm0 4h2v2H1zm0 4h2v2H1zm0 4h18v2H1zM5 1h2v2H5zm0 8h2v2H5zm4-8h2v2H9zm0 4h2v2H9zm0 4h2v2H9zm0 4h2v2H9zm4-12h2v2h-2zm0 8h2v2h-2zm4-8h2v2h-2zm0 4h2v2h-2zm0 4h2v2h-2zm0 4h2v2h-2z"
|
||||
d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h18v2H1v-2zM5 1h2v2H5V1zm0 8h2v2H5V9zm4-8h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm4-12h2v2h-2V1zm0 8h2v2h-2V9zm4-8h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBorderHorizontal = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M1 1h2v2H1zm0 4h2v2H1zm0 4h18v2H1zm0 4h2v2H1zm0 4h2v2H1zM5 1h2v2H5zm0 16h2v2H5zM9 1h2v2H9zm0 4h2v2H9zm0 8h2v2H9zm0 4h2v2H9zm4-16h2v2h-2zm0 16h2v2h-2zm4-16h2v2h-2zm0 4h2v2h-2zm0 8h2v2h-2zm0 4h2v2h-2z"
|
||||
d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h18v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 16h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 8h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 16h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 8h2v2h-2v-2zm0 4h2v2h-2v-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBorderInner = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M9 9V1h2v8h8v2h-8v8H9v-8H1V9zM1 1h2v2H1zm0 4h2v2H1zm0 8h2v2H1zm0 4h2v2H1zM5 1h2v2H5zm0 16h2v2H5zm8-16h2v2h-2zm0 16h2v2h-2zm4-16h2v2h-2zm0 4h2v2h-2zm0 8h2v2h-2zm0 4h2v2h-2z"
|
||||
d="M9 9V1h2v8h8v2h-8v8H9v-8H1V9h8zM1 1h2v2H1V1zm0 4h2v2H1V5zm0 8h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 16h2v2H5v-2zm8-16h2v2h-2V1zm0 16h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 8h2v2h-2v-2zm0 4h2v2h-2v-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBorderLeft = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M1 1h2v18H1zm4 0h2v2H5zm0 8h2v2H5zm0 8h2v2H5zM9 1h2v2H9zm0 4h2v2H9zm0 4h2v2H9zm0 4h2v2H9zm0 4h2v2H9zm4-16h2v2h-2zm0 8h2v2h-2zm0 8h2v2h-2zm4-16h2v2h-2zm0 4h2v2h-2zm0 4h2v2h-2zm0 4h2v2h-2zm0 4h2v2h-2z"
|
||||
d="M1 1h2v18H1V1zm4 0h2v2H5V1zm0 8h2v2H5V9zm0 8h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 8h2v2h-2V9zm0 8h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2zm0 4h2v2h-2v-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBorderNone = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M1 1h2v2H1zm0 4h2v2H1zm0 4h2v2H1zm0 4h2v2H1zm0 4h2v2H1zM5 1h2v2H5zm0 8h2v2H5zm0 8h2v2H5zM9 1h2v2H9zm0 4h2v2H9zm0 4h2v2H9zm0 4h2v2H9zm0 4h2v2H9zm4-16h2v2h-2zm0 8h2v2h-2zm0 8h2v2h-2zm4-16h2v2h-2zm0 4h2v2h-2zm0 4h2v2h-2zm0 4h2v2h-2zm0 4h2v2h-2z"
|
||||
d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 8h2v2H5V9zm0 8h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 8h2v2h-2V9zm0 8h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2zm0 4h2v2h-2v-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const SvgBorderOuter = (props: SVGProps<SVGSVGElement>) => (
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M2 19H1V1h18v18zm1-2h14V3H3zm10-8h2v2h-2zM9 9h2v2H9zM5 9h2v2H5zm4-4h2v2H9zm0 8h2v2H9z"
|
||||
d="M2 19H1V1h18v18H2zm1-2h14V3H3v14zm10-8h2v2h-2V9zM9 9h2v2H9V9zM5 9h2v2H5V9zm4-4h2v2H9V5zm0 8h2v2H9v-2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||