mirror of
https://github.com/priyanshujain/margin.git
synced 2026-10-02 19:17:03 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
530e260903 | ||
|
|
74a684498a | ||
|
|
3fccb17060 | ||
|
|
9acb3aae3c |
No files matched your search
@@ -137,6 +137,19 @@ jobs:
|
||||
- name: Install frontend dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Provision Google credentials
|
||||
shell: bash
|
||||
env:
|
||||
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
|
||||
run: |
|
||||
if [ -n "$GOOGLE_CREDENTIALS" ]; then
|
||||
printf '%s' "$GOOGLE_CREDENTIALS" > google-credentials.json
|
||||
echo "Wrote google-credentials.json from GOOGLE_CREDENTIALS secret."
|
||||
else
|
||||
cp google-credentials.example.json google-credentials.json
|
||||
echo "::warning::GOOGLE_CREDENTIALS secret not set — embedding placeholder credentials; Google Drive backup will be disabled in this release."
|
||||
fi
|
||||
|
||||
- name: Build and upload
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "margin-app",
|
||||
"private": true,
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.6",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
Generated
+1
-1
@@ -4713,7 +4713,7 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
|
||||
[[package]]
|
||||
name = "margin-app"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"fontdb",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "margin-app"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "margin",
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.6",
|
||||
"identifier": "studio.margin.app",
|
||||
"build": {
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
|
||||
@@ -17,16 +17,16 @@ const cols = [
|
||||
{
|
||||
title: "Product",
|
||||
links: [
|
||||
{ label: "Features", href: "#features" },
|
||||
{ label: "Publishing", href: "#publish" },
|
||||
{ label: "Compare", href: "#compare" },
|
||||
{ label: "Pricing", href: "#pricing" },
|
||||
{ label: "Features", href: "/#features" },
|
||||
{ label: "Publishing", href: "/#publish" },
|
||||
{ label: "Compare", href: "/#compare" },
|
||||
{ label: "Pricing", href: "/#pricing" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Help",
|
||||
links: [
|
||||
{ label: "Questions", href: "#faq" },
|
||||
{ label: "Questions", href: "/#faq" },
|
||||
{ label: "Email us", href: `mailto:${site.supportEmail}` },
|
||||
],
|
||||
},
|
||||
@@ -50,14 +50,14 @@ const cols = [
|
||||
<p class="footer__title">{col.title}</p>
|
||||
<ul>
|
||||
{col.links.map((l) => {
|
||||
const isAnchor = l.href.startsWith("#") || l.href.startsWith("mailto:");
|
||||
const isExternal = l.href.startsWith("http");
|
||||
return (
|
||||
<li>
|
||||
<a
|
||||
href={l.href}
|
||||
data-download-os={(l as { os?: string }).os}
|
||||
target={isAnchor ? undefined : "_blank"}
|
||||
rel={isAnchor ? undefined : "noopener"}
|
||||
target={isExternal ? "_blank" : undefined}
|
||||
rel={isExternal ? "noopener" : undefined}
|
||||
>
|
||||
{l.label}
|
||||
</a>
|
||||
@@ -73,6 +73,10 @@ const cols = [
|
||||
|
||||
<div class="container footer__base">
|
||||
<span>© {site.name}. Built with <span class="heart">♥</span> in NYC</span>
|
||||
<nav class="footer__legal" aria-label="Legal">
|
||||
<a href="/privacy">Privacy</a>
|
||||
<a href="/terms">Terms</a>
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -136,10 +140,23 @@ const cols = [
|
||||
.footer__base {
|
||||
padding-top: 22px;
|
||||
border-top: 1px solid var(--line);
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
font-size: 0.82rem;
|
||||
color: var(--ink-faint);
|
||||
}
|
||||
.footer__legal {
|
||||
display: flex;
|
||||
gap: 18px;
|
||||
}
|
||||
.footer__legal a {
|
||||
color: var(--ink-faint);
|
||||
}
|
||||
.footer__legal a:hover {
|
||||
color: var(--ink);
|
||||
}
|
||||
.heart {
|
||||
color: var(--danger);
|
||||
}
|
||||
@@ -153,5 +170,10 @@ const cols = [
|
||||
.footer__cols {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
.footer__base {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -11,15 +11,15 @@ import Logo from "./Logo.astro";
|
||||
</a>
|
||||
|
||||
<nav class="nav__links" aria-label="Primary">
|
||||
<a href="#features">Features</a>
|
||||
<a href="#publish">Publishing</a>
|
||||
<a href="#compare">Compare</a>
|
||||
<a href="#pricing">Pricing</a>
|
||||
<a href="#faq">Questions</a>
|
||||
<a href="/#features">Features</a>
|
||||
<a href="/#publish">Publishing</a>
|
||||
<a href="/#compare">Compare</a>
|
||||
<a href="/#pricing">Pricing</a>
|
||||
<a href="/#faq">Questions</a>
|
||||
</nav>
|
||||
|
||||
<div class="nav__actions">
|
||||
<a class="btn nav__cta" href="#download">
|
||||
<a class="btn nav__cta" href="/#download">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
|
||||
<path d="M12 3v12m0 0 4-4m-4 4-4-4M5 21h14" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
</svg>
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
import Base from "./Base.astro";
|
||||
import Nav from "../components/Nav.astro";
|
||||
import Footer from "../components/Footer.astro";
|
||||
import { site } from "../data/site";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
updated: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
const { title, updated, description } = Astro.props;
|
||||
---
|
||||
|
||||
<Base title={`${title} · ${site.name}`} description={description}>
|
||||
<Nav />
|
||||
<main class="legal">
|
||||
<div class="container legal__inner">
|
||||
<header class="legal__head">
|
||||
<p class="eyebrow">Legal</p>
|
||||
<h1>{title}</h1>
|
||||
<p class="legal__updated">Last updated {updated}</p>
|
||||
</header>
|
||||
<div class="legal__prose">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<Footer />
|
||||
</Base>
|
||||
|
||||
<style>
|
||||
.legal {
|
||||
padding-block: clamp(48px, 7vw, 96px);
|
||||
}
|
||||
.legal__inner {
|
||||
max-width: 760px;
|
||||
}
|
||||
.legal__head {
|
||||
padding-bottom: clamp(28px, 4vw, 44px);
|
||||
margin-bottom: clamp(28px, 4vw, 44px);
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.legal__head h1 {
|
||||
font-family: var(--font-book);
|
||||
font-weight: 560;
|
||||
letter-spacing: -0.012em;
|
||||
line-height: 1.08;
|
||||
font-size: clamp(2.1rem, 1.4rem + 2.8vw, 3.2rem);
|
||||
}
|
||||
.legal__updated {
|
||||
margin-top: 16px;
|
||||
color: var(--ink-faint);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.legal__prose {
|
||||
color: var(--ink-soft);
|
||||
font-size: 1.04rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.legal__prose :global(h2) {
|
||||
font-size: clamp(1.3rem, 1.05rem + 0.9vw, 1.6rem);
|
||||
color: var(--ink);
|
||||
margin: 44px 0 14px;
|
||||
}
|
||||
.legal__prose :global(h2:first-child) {
|
||||
margin-top: 0;
|
||||
}
|
||||
.legal__prose :global(p) {
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
.legal__prose :global(ul) {
|
||||
margin: 0 0 16px;
|
||||
padding-left: 22px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.legal__prose :global(li) {
|
||||
padding-left: 4px;
|
||||
}
|
||||
.legal__prose :global(li::marker) {
|
||||
color: var(--ink-faint);
|
||||
}
|
||||
.legal__prose :global(strong) {
|
||||
color: var(--ink);
|
||||
font-weight: 600;
|
||||
}
|
||||
.legal__prose :global(a) {
|
||||
color: var(--ink);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
text-decoration-color: var(--line-strong);
|
||||
}
|
||||
.legal__prose :global(a:hover) {
|
||||
text-decoration-color: var(--ink);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
import Legal from "../layouts/Legal.astro";
|
||||
import { site } from "../data/site";
|
||||
---
|
||||
|
||||
<Legal
|
||||
title="Privacy Policy"
|
||||
updated="June 22, 2026"
|
||||
description={`How ${site.name} handles your data. The short version: your book never leaves your machine, and we keep no copy.`}
|
||||
>
|
||||
<h2>The short version</h2>
|
||||
<p>
|
||||
Margin is an offline writing studio that runs on your own computer. Your book and everything
|
||||
you write stay on your device. We never receive a copy, and nothing you write is sent away to
|
||||
be read or stored by us. This page explains the few places where data is involved, so you know
|
||||
exactly what happens and what does not.
|
||||
</p>
|
||||
|
||||
<h2>What stays on your device</h2>
|
||||
<p>
|
||||
Your manuscript, your spelling and grammar checks, your fonts and book setup, and every print
|
||||
and ebook export all happen locally on your machine. None of this requires an account, a login,
|
||||
or an internet connection, and none of it passes through our servers.
|
||||
</p>
|
||||
|
||||
<h2>No account, no tracking</h2>
|
||||
<p>
|
||||
You do not need to sign up, log in, or give us an email address to write with Margin. This
|
||||
website does not use tracking cookies, advertising pixels, or third-party analytics. The only
|
||||
thing the site stores in your browser is your light or dark theme preference, kept locally so
|
||||
the page looks the way you left it.
|
||||
</p>
|
||||
|
||||
<h2>Downloads and updates</h2>
|
||||
<p>
|
||||
Margin is distributed through GitHub Releases. When you download the app, or when the app checks
|
||||
for a new version to keep itself up to date, a request is made to GitHub to fetch the latest
|
||||
release. As with any web request, GitHub can see your IP address for that request, handled under
|
||||
GitHub's own privacy policy. We do not add any tracking of our own to these requests.
|
||||
</p>
|
||||
|
||||
<h2>Optional backup to your Google Drive</h2>
|
||||
<p>
|
||||
Margin can save a backup of your book to your own Google Drive, but only if you turn it on. When
|
||||
you do, you connect your own Google account, and the backup is written to your Drive, in your
|
||||
account, under your control. We never receive a copy of that backup and cannot read it. You can
|
||||
disconnect Margin from your Google account at any time from your Google account settings, and the
|
||||
app works exactly the same with the feature switched off.
|
||||
</p>
|
||||
|
||||
<h2>Payments</h2>
|
||||
<p>
|
||||
If you buy Margin, the payment is handled by a third-party payment processor. We do not see or
|
||||
store your full card details. The processor handles the transaction and shares with us only what
|
||||
we need to confirm your purchase and provide support.
|
||||
</p>
|
||||
|
||||
<h2>Children</h2>
|
||||
<p>
|
||||
Margin is a tool for writers and is not directed at children under 13. We do not knowingly
|
||||
collect personal information from children.
|
||||
</p>
|
||||
|
||||
<h2>Changes to this policy</h2>
|
||||
<p>
|
||||
If we update this policy, we will change the date at the top of this page. Because the app keeps
|
||||
your book on your own device, the spirit of this policy is unlikely to change: your words belong
|
||||
to you.
|
||||
</p>
|
||||
|
||||
<h2>Contact</h2>
|
||||
<p>
|
||||
Questions about your privacy? Write to <a href={`mailto:${site.supportEmail}`}>{site.supportEmail}</a>
|
||||
and a real person will answer.
|
||||
</p>
|
||||
</Legal>
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
import Legal from "../layouts/Legal.astro";
|
||||
import { site } from "../data/site";
|
||||
---
|
||||
|
||||
<Legal
|
||||
title="Terms of Use"
|
||||
updated="June 22, 2026"
|
||||
description={`The terms for using ${site.name}: a one-time purchase, your content stays yours, used as is.`}
|
||||
>
|
||||
<h2>Acceptance</h2>
|
||||
<p>
|
||||
These terms cover your use of Margin, the offline writing app, and this website. By downloading,
|
||||
buying, or using Margin, you agree to them. If you do not agree, please do not use the app.
|
||||
</p>
|
||||
|
||||
<h2>Your license to use Margin</h2>
|
||||
<p>
|
||||
Margin is a one-time purchase. When you buy it, you get a personal, non-exclusive license to
|
||||
install and use the app on the devices you own. You keep using the version you bought, and
|
||||
updates are included at no extra cost. You may not resell, rent, or redistribute the app, or
|
||||
attempt to defeat its purchase, and you may not reverse engineer it except where the law
|
||||
expressly allows.
|
||||
</p>
|
||||
|
||||
<h2>Your content is yours</h2>
|
||||
<p>
|
||||
Everything you write in Margin belongs to you. Your book is a file on your own computer. We claim
|
||||
no ownership of it, take no license to it, and never receive a copy. You are responsible for your
|
||||
own work, including keeping your own backups and making sure you have the right to publish what
|
||||
you write.
|
||||
</p>
|
||||
|
||||
<h2>Acceptable use</h2>
|
||||
<p>
|
||||
Use Margin lawfully. Do not use it to create or distribute material that is illegal, or that
|
||||
infringes someone else's rights. What you choose to write and publish is your responsibility, not
|
||||
ours.
|
||||
</p>
|
||||
|
||||
<h2>Third-party services</h2>
|
||||
<p>
|
||||
Margin can connect to services you choose, such as your own Google Drive for backups, and you
|
||||
download and publish through platforms like GitHub and the ebook and print stores. Your use of
|
||||
those services is governed by their own terms and policies, which we do not control.
|
||||
</p>
|
||||
|
||||
<h2>Updates and availability</h2>
|
||||
<p>
|
||||
We work to keep Margin reliable and to improve it over time, but we may change, pause, or
|
||||
discontinue parts of the app or this website. Because Margin runs on your own machine, the copy
|
||||
you have installed keeps working even if a feature that depends on an outside service changes.
|
||||
</p>
|
||||
|
||||
<h2>The app is provided as is</h2>
|
||||
<p>
|
||||
Margin is provided "as is" and "as available," without warranties of any kind, whether express or
|
||||
implied, including fitness for a particular purpose and non-infringement. We do not warrant that
|
||||
the app will be error-free or uninterrupted, or that it will meet every need. You are responsible
|
||||
for backing up your own work.
|
||||
</p>
|
||||
|
||||
<h2>Limitation of liability</h2>
|
||||
<p>
|
||||
To the fullest extent permitted by law, Margin and its maker will not be liable for any indirect,
|
||||
incidental, or consequential damages, or for any loss of data or content, arising from your use
|
||||
of the app. Our total liability for any claim is limited to the amount you paid for Margin.
|
||||
</p>
|
||||
|
||||
<h2>Refunds</h2>
|
||||
<p>
|
||||
If Margin is not working for you, write to us. We would rather make it right or refund your
|
||||
purchase than have you stuck with a tool you cannot use.
|
||||
</p>
|
||||
|
||||
<h2>Changes to these terms</h2>
|
||||
<p>
|
||||
We may update these terms from time to time. When we do, we will change the date at the top of
|
||||
this page. Continuing to use Margin after a change means you accept the updated terms.
|
||||
</p>
|
||||
|
||||
<h2>Governing law</h2>
|
||||
<p>
|
||||
These terms are governed by the laws of the State of New York, United States, without regard to
|
||||
its conflict of laws rules.
|
||||
</p>
|
||||
|
||||
<h2>Contact</h2>
|
||||
<p>
|
||||
Questions about these terms? Write to <a href={`mailto:${site.supportEmail}`}>{site.supportEmail}</a>.
|
||||
</p>
|
||||
</Legal>
|
||||
Reference in new issue
Block a user