Themes, pt2 (#953)

* Themes pt1

* Themes pt2

* Standard -> Classic, new default is Gruvbox Dark

* Make settings shell fatter

* more theme fixes :nodnod:

* Remove orphaned file
This commit is contained in:
Mahad Kalam 2026-02-15 22:36:34 +00:00 committed by GitHub
parent dd978bbeb9
commit 7273fad8dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 80 additions and 61 deletions

View file

@ -54,3 +54,9 @@ We do development using docker-compose. Run `docker-compose ps` to see if the de
- **Jobs**: GoodJob with 4 priority queues, inherit from `ApplicationJob`, concurrency control for cache jobs
- **Auth**: `ensure_authenticated!` for APIs, token via `Authorization` header or `?api_key=`
- **CSS**: Using Tailwind CSS, no inline styles, use utility classes. We define some custom classes in `config/tailwind.config.js` and `app/assets/tailwind/application.css`.
## Inertia Components
On Inertia pages, use the `<Button />` component for buttons, not `<button>` tags.
When linking to an Inertia page, use the `<Link />` component instead of `<a>` tags.

View file

@ -1,66 +1,72 @@
aside[data-nav-target="nav"] {
@apply fixed inset-y-0 left-0 w-[15.625rem] bg-dark border-r border-r-darkless z-1000 overflow-y-auto py-6 px-2 transition-transform duration-300 ease-in-out;
color: var(--color-surface-content);
@apply fixed inset-y-0 left-0 w-[15.625rem] bg-dark border-r border-r-darkless z-1000 overflow-y-auto py-6 px-2 transition-transform duration-300 ease-in-out;
color: var(--color-surface-content);
}
aside[data-nav-target="nav"] a.block {
@apply block py-2.5 px-4 rounded-md transition-colors duration-150 no-underline;
aside[data-nav-target="nav"] a.block,
aside[data-nav-target="nav"] button.block {
@apply block py-2.5 px-4 rounded-md transition-colors duration-150 no-underline;
}
aside[data-nav-target="nav"] a.block.bg-primary\/20 {
@apply text-primary;
background-color: color-mix(in oklab, var(--color-primary) 18%, transparent);
aside[data-nav-target="nav"] a.block.bg-primary\/20,
aside[data-nav-target="nav"] button.block.bg-primary\/20 {
@apply text-primary;
background-color: color-mix(in oklab, var(--color-primary) 18%, transparent);
}
aside[data-nav-target="nav"] a.block.bg-primary {
color: var(--color-on-primary);
aside[data-nav-target="nav"] a.block.bg-primary,
aside[data-nav-target="nav"] button.block.bg-primary {
color: var(--color-on-primary);
}
aside[data-nav-target="nav"] a.block:not(.bg-primary):not(.bg-primary\/20):hover {
@apply bg-darkless;
@apply text-primary;
aside[data-nav-target="nav"]
a.block:not(.bg-primary):not(.bg-primary\/20):hover,
aside[data-nav-target="nav"]
button.block:not(.bg-primary):not(.bg-primary\/20):hover {
@apply bg-darkless;
@apply text-primary;
}
@media (max-width: 1023px) {
aside[data-nav-target="nav"] {
@apply -translate-x-full z-9999;
}
aside[data-nav-target="nav"] {
@apply -translate-x-full z-9999;
}
aside[data-nav-target="nav"].open {
@apply translate-x-0 shadow-[2px_0_20px_rgba(0,0,0,0.3)];
}
aside[data-nav-target="nav"].open {
@apply translate-x-0 shadow-[2px_0_20px_rgba(0,0,0,0.3)];
}
}
.mobile-nav-button {
background: var(--color-darkless);
color: var(--color-primary);
@apply hidden fixed top-5 left-5 z-100 border-none rounded-md p-3 cursor-pointer shadow-[0_2px_8px_rgba(0,0,0,0.2)] transition-[background-color] duration-200;
background: var(--color-darkless);
color: var(--color-primary);
@apply hidden fixed top-5 left-5 z-100 border-none rounded-md p-3 cursor-pointer shadow-[0_2px_8px_rgba(0,0,0,0.2)] transition-[background-color] duration-200;
}
.mobile-nav-button:hover {
@apply bg-darkless;
@apply bg-darkless;
}
.mobile-nav-button svg {
@apply size-6;
@apply size-6;
}
@media (max-width: 1023px) {
.mobile-nav-button {
@apply block;
}
.mobile-nav-button {
@apply block;
}
}
.nav-overlay {
@apply hidden fixed inset-0 bg-[rgba(0,0,0,0.5)] backdrop-blur-xs z-9998 opacity-0 transition-opacity duration-300 ease-in-out;
@apply hidden fixed inset-0 bg-[rgba(0,0,0,0.5)] backdrop-blur-xs z-9998 opacity-0 transition-opacity duration-300 ease-in-out;
}
.nav-overlay.open {
@apply opacity-100;
@apply opacity-100;
}
@media (max-width: 1023px) {
.nav-overlay.open {
@apply block;
}
.nav-overlay.open {
@apply block;
}
}

View file

@ -47,7 +47,8 @@
<a
href={extension.install}
target="_blank"
class="flex items-center justify-center gap-2 px-4 py-2 rounded bg-primary text-white font-medium text-sm hover:opacity-90 transition-opacity"
rel="noopener noreferrer"
class="flex items-center justify-center gap-2 px-4 py-2 rounded bg-primary text-on-primary font-medium text-sm hover:opacity-90 transition-opacity"
>
<span>Install</span>
<svg
@ -69,6 +70,7 @@
<a
href={extension.source}
target="_blank"
rel="noopener noreferrer"
class="flex items-center justify-center gap-2 px-4 py-2 rounded bg-surface-200 text-surface-content font-medium text-sm hover:bg-surface-300 transition-colors"
>
Source

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { Link } from "@inertiajs/svelte";
import Button from "../../components/Button.svelte";
type HomeStats = { seconds_tracked?: number; users_tracked?: number };
@ -182,12 +183,13 @@
required
class="flex-1 bg-dark text-white placeholder-secondary/40 rounded-xl py-3.5 px-4 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all border border-darkless focus:border-primary text-sm"
/>
<button
<Button
type="submit"
unstyled
class="px-5 py-3.5 bg-dark border border-primary text-white rounded-xl hover:bg-primary transition-all text-sm font-medium"
>
Send link
</button>
</Button>
</div>
</form>
{/if}

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { onMount } from "svelte";
import Button from "../../../components/Button.svelte";
import SettingsShell from "./Shell.svelte";
import type { DataPageProps } from "./types";
@ -45,12 +46,12 @@
</p>
<form method="post" action={paths.migrate_heartbeats_path} class="mt-4">
<input type="hidden" name="authenticity_token" value={csrfToken} />
<button
<Button
type="submit"
class="rounded-md bg-primary px-4 py-2 text-sm font-semibold text-white transition-opacity hover:opacity-90"
class="rounded-md"
>
Start migration
</button>
</Button>
</form>
{#if migration.jobs.length > 0}
@ -122,12 +123,13 @@
required
class="rounded-md border border-surface-200 bg-surface px-3 py-2 text-sm text-surface-content focus:border-primary focus:outline-none"
/>
<button
<Button
type="submit"
class="rounded-md border border-surface-200 bg-surface-100 px-4 py-2 text-sm font-semibold text-surface-content transition-colors hover:bg-surface-200"
variant="surface"
class="rounded-md"
>
Export date range
</button>
</Button>
</form>
</div>
@ -150,12 +152,13 @@
required
class="w-full rounded-md border border-surface-200 bg-surface px-3 py-2 text-sm text-surface-content"
/>
<button
<Button
type="submit"
class="mt-3 rounded-md border border-surface-200 bg-surface-100 px-4 py-2 text-sm font-semibold text-surface-content transition-colors hover:bg-surface-200"
variant="surface"
class="mt-3 rounded-md"
>
Import file
</button>
</Button>
</form>
{/if}
{/if}
@ -183,12 +186,13 @@
}}
>
<input type="hidden" name="authenticity_token" value={csrfToken} />
<button
<Button
type="submit"
class="rounded-md border border-surface-200 bg-surface-100 px-4 py-2 text-sm font-semibold text-surface-content transition-colors hover:bg-surface-200"
variant="surface"
class="rounded-md"
>
Request deletion
</button>
</Button>
</form>
{:else}
<p class="mt-3 rounded-md border border-surface-200 bg-darker px-3 py-2 text-sm text-muted">

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { onMount } from "svelte";
import Button from "../../../components/Button.svelte";
import SettingsShell from "./Shell.svelte";
import type { IntegrationsPageProps } from "./types";
@ -70,12 +71,7 @@
Update my Slack status automatically
</label>
<button
type="submit"
class="rounded-md bg-primary px-4 py-2 text-sm font-semibold text-white transition-opacity hover:opacity-90"
>
Save Slack settings
</button>
<Button type="submit">Save Slack settings</Button>
</form>
</section>
@ -139,12 +135,13 @@
>
<input type="hidden" name="_method" value="delete" />
<input type="hidden" name="authenticity_token" value={csrfToken} />
<button
<Button
type="submit"
class="rounded-md border border-surface-200 bg-surface-100 px-4 py-2 text-sm font-semibold text-surface-content transition-colors hover:bg-surface-200"
variant="surface"
class="rounded-md"
>
Unlink GitHub
</button>
</Button>
</form>
</div>
{:else}
@ -176,12 +173,14 @@
<input type="hidden" name="_method" value="delete" />
<input type="hidden" name="authenticity_token" value={csrfToken} />
<input type="hidden" name="email" value={email.email} />
<button
<Button
type="submit"
class="rounded-md border border-surface-200 bg-surface-100 px-3 py-1.5 text-xs font-semibold text-surface-content transition-colors hover:bg-surface-200"
variant="surface"
size="xs"
class="rounded-md"
>
Unlink
</button>
</Button>
</form>
{/if}
</div>
@ -202,12 +201,12 @@
placeholder="name@example.com"
class="grow rounded-md border border-surface-200 bg-darker px-3 py-2 text-sm text-surface-content focus:border-primary focus:outline-none"
/>
<button
<Button
type="submit"
class="rounded-md bg-primary px-4 py-2 text-sm font-semibold text-white transition-opacity hover:opacity-90"
class="rounded-md"
>
Add email
</button>
</Button>
</form>
</section>
</div>