Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
*.png binary
*.pdf binary
*.woff2 binary
*.webp binary
*.woff binary
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ masters, colours, type, voice, every design token and the UI specs, published fr
| `fonts/` | Gilroy Regular, Medium, Semibold and Bold (WOFF), plus Unbounded (WOFF2). Legacy faces retained for existing consumers. See `fonts/README.md`. |
| `tokens/` | `tokens.css` (`@font-face` + light/dark colour variables as RGB triplets) and `tokens.json` (the same colours as hex, plus the seven brand colours) |
| `docs/` | `ui-brand-spec.md` (token derivations, contrast ratios, states, status pills, type scale, logo use), `ux-spec.md` (**Space Works UX**: our interaction patterns, reusable layouts, navigation and screen specs), `ux-screens-longtail.md` (remaining screens) |
| `screenshots/ux/` | Screenshots of Space Works UX in Space Works Events (light, dark and phone), used by the site's UX pages |
| `site/` | The Starlight website published to GitHub Pages; `scripts/sync-kit.mjs` copies the kit in at build time |
| `references/yuyu/` | The reference boards from [Yuyu](https://github.com/twilighty-abhi/yuyu) that inspired Space Works UX |

Expand Down
7 changes: 7 additions & 0 deletions screenshots/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Screenshots

`ux/` holds screenshots of Space Works UX in a real Space Works product, used by the design site's UX pages.

- **Source:** SpaceWorks-Events at `origin/dev` `03186e0`, run locally with demo data (no real people or data).
- **Naming:** `<screen>-<desktop|phone>-<light|dark>.webp`. Desktop is 1280×800, phone is 390×844, both at 1×.
- **Refresh:** re-capture whenever the patterns change, keeping the same names so the site picks them up.
Binary file added screenshots/ux/account-profile-desktop-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/account-profile-desktop-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/auth-sign-in-desktop-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/auth-sign-in-desktop-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/auth-sign-in-phone-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/detail-overview-desktop-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/detail-overview-desktop-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/detail-overview-phone-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/flow-check-in-desktop-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/flow-check-in-desktop-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/flow-check-in-phone-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/list-guests-desktop-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/list-guests-desktop-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/list-guests-phone-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/list-member-ids-desktop-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/list-member-ids-desktop-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/list-member-ids-phone-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/public-event-desktop-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/public-event-desktop-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/public-event-phone-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/ux/public-ticket-desktop-dark.webp
Binary file added screenshots/ux/public-ticket-desktop-light.webp
Binary file added screenshots/ux/public-ticket-phone-light.webp
Binary file added screenshots/ux/table-team-desktop-dark.webp
Binary file added screenshots/ux/table-team-desktop-light.webp
2 changes: 1 addition & 1 deletion site/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default defineConfig({
],
},
{ label: 'Tokens', items: ['tokens/using-the-kit', 'tokens/reference'] },
{ label: 'UX', items: ['ux/introduction'] },
{ label: 'UX', items: ['ux/introduction', 'ux/patterns', 'ux/gallery', 'ux/inspiration'] },
{ label: 'Specs', items: [{ autogenerate: { directory: 'specs' } }] },
{ label: 'About', items: ['about/credits'] },
],
Expand Down
11 changes: 9 additions & 2 deletions site/scripts/sync-kit.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// so the site always shows the real masters and never a hand-maintained copy of them.
//
// logo/ icons/ fonts/ tokens/ brand/ -> public/kit/... (served for preview and download)
// screenshots/ references/yuyu/ -> public/kit/... (UX screenshots and reference boards)
// logo/*.svg -> src/assets/kit/ (header logo and hero art)
// docs/*.md -> src/content/docs/specs/ (rendered spec pages)
//
Expand All @@ -21,11 +22,17 @@ for (const dir of [kit, assets, specs]) {
mkdirSync(dir, { recursive: true });
}

for (const folder of ['logo', 'icons', 'fonts', 'tokens']) {
for (const folder of ['logo', 'icons', 'fonts', 'tokens', 'screenshots']) {
cpSync(join(root, folder), join(kit, folder), { recursive: true });
}
cpSync(join(root, 'brand', 'space-works-brand-guidelines-v1.pdf'), join(kit, 'brand', 'space-works-brand-guidelines-v1.pdf'));
cpSync(join(root, 'brand', 'guidelines', 'png'), join(kit, 'brand', 'guidelines'), { recursive: true });
// Reference boards get URL-safe names ("Sign in, invites & account.png" -> "sign-in-invites-account.png").
mkdirSync(join(kit, 'references', 'yuyu'), { recursive: true });
for (const file of readdirSync(join(root, 'references', 'yuyu')).filter((f) => f.endsWith('.png'))) {
const slug = file.replace(/\.png$/, '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
cpSync(join(root, 'references', 'yuyu', file), join(kit, 'references', 'yuyu', `${slug}.png`));
}

for (const file of readdirSync(join(root, 'logo')).filter((f) => f.endsWith('.svg'))) {
cpSync(join(root, 'logo', file), join(assets, file));
Expand Down Expand Up @@ -56,4 +63,4 @@ for (const { file, slug, order, label } of specPages) {
writeFileSync(join(specs, `${slug}.md`), frontmatter + source.slice(match[0].length));
}

console.log('sync-kit: copied logo, icons, fonts, tokens, brand pages and 3 specs');
console.log('sync-kit: copied logo, icons, fonts, tokens, screenshots, brand pages, reference boards and 3 specs');
19 changes: 19 additions & 0 deletions site/src/components/ReferenceBoards.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
// The four reference boards from Yuyu that inspired Space Works UX. Files live in references/yuyu/.
import { kitUrl } from './kit-url';

const boards = ['Organiser workspace', 'Managing an event', 'Sign in, invites & account', 'Attending an event'];
const slug = (name: string) => name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
const src = (name: string) => kitUrl(`references/yuyu/${slug(name)}.png`);
---

<div class="sw-boards not-content">
{
boards.map((name) => (
<a href={src(name)}>
<img src={src(name)} alt={`Yuyu reference board: ${name}`} loading="lazy" decoding="async" />
<span>{name} · Yuyu</span>
</a>
))
}
</div>
36 changes: 36 additions & 0 deletions site/src/components/UxShot.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
// One Space Works UX screen: desktop light and dark side by side, plus the phone view when captured.
// Each image opens at full size. Files live in screenshots/ux/ at the repository root.
import { kitUrl } from './kit-url';

interface Props {
name: string;
alt: string;
phone?: boolean;
caption?: string;
}
const { name, alt, phone = false, caption } = Astro.props;
const src = (size: string, mode: string) => kitUrl(`screenshots/ux/${name}-${size}-${mode}.webp`);
---

<figure class="sw-shot not-content">
<div class:list={['sw-shot-row', { 'has-phone': phone }]}>
<a href={src('desktop', 'light')}>
<img src={src('desktop', 'light')} alt={`${alt}, light theme`} width="1280" height="800" loading="lazy" decoding="async" />
<span>Light · desktop</span>
</a>
<a class="sw-shot-dark" href={src('desktop', 'dark')}>
<img src={src('desktop', 'dark')} alt={`${alt}, dark theme`} width="1280" height="800" loading="lazy" decoding="async" />
<span>Dark · desktop</span>
</a>
{
phone && (
<a class="sw-shot-phone" href={src('phone', 'light')}>
<img src={src('phone', 'light')} alt={`${alt}, phone`} width="390" height="844" loading="lazy" decoding="async" />
<span>Phone</span>
</a>
)
}
</div>
{caption && <figcaption>{caption}</figcaption>}
</figure>
7 changes: 5 additions & 2 deletions site/src/content/docs/about/credits.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ paint styles and the ten text styles.
[Space Works UX](/ux/introduction/) is our own interaction system: the patterns, layouts and
interaction details in the specs. It was inspired by [Yuyu](https://github.com/twilighty-abhi/yuyu), whose
screens we studied as reference boards. The reference boards are kept in
[`references/yuyu/`](https://github.com/SpaceWorks-HQ/SpaceWorks-Design/tree/main/references/yuyu) and are not
republished on this site.
[`references/yuyu/`](https://github.com/SpaceWorks-HQ/SpaceWorks-Design/tree/main/references/yuyu) and are shown,
with attribution, on [Inspired by Yuyu](/ux/inspiration/). They remain Yuyu's work and are not relicensed.

The screenshots on the UX pages are of Space Works Events, run with demo data. They are in
[`screenshots/ux/`](https://github.com/SpaceWorks-HQ/SpaceWorks-Design/tree/main/screenshots/ux).

## Fonts

Expand Down
52 changes: 52 additions & 0 deletions site/src/content/docs/ux/gallery.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Screen gallery
description: Every captured Space Works UX screen, grouped by the layout it uses, in light, dark and phone views.
---

import UxShot from '../../../components/UxShot.astro';

Every screen is the app shell plus exactly one layout from the [closed set](/specs/ux-patterns/). The screens
below come from **Space Works Events** with demo data. The files are in
[`screenshots/ux/`](https://github.com/SpaceWorks-HQ/SpaceWorks-Design/tree/main/screenshots/ux).

## L1 + L2 · App shell and dashboard

<UxShot name="workspace-organisations" alt="Your organisations" />
<UxShot name="workspace-dashboard" alt="Organisation dashboard" phone />
<UxShot name="workspace-empty-state" alt="New organisation dashboard" />

## L3 · List

<UxShot name="list-member-ids" alt="Member ID list" phone />
<UxShot name="list-guests" alt="Guest list" phone />
<UxShot name="table-team" alt="Team table" />

## L4 · Detail

<UxShot name="detail-overview" alt="Event detail overview" phone />

## L5 · Settings

<UxShot name="settings-organisation" alt="Organisation settings" phone />
<UxShot name="account-profile" alt="Account profile" />

## L6 · Form page

<UxShot name="form-new-organisation" alt="Create an organisation" />

## L7 · Flow

<UxShot name="flow-check-in" alt="Check-in desk" phone />

## L8 · Auth and centred card

<UxShot name="auth-sign-in" alt="Sign in" phone />
<UxShot name="auth-reset-password" alt="Reset password" />

## L9 · Public and public detail

<UxShot name="public-organisation" alt="Public organisation page" phone />
<UxShot name="public-event" alt="Public event page" phone />
<UxShot name="public-ticket" alt="Mobile ticket" phone />
<UxShot name="public-verify-card" alt="Valid member card check" phone />
<UxShot name="public-verify-not-found" alt="Card not found" phone />
32 changes: 32 additions & 0 deletions site/src/content/docs/ux/inspiration.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: Inspired by Yuyu
description: The reference boards from Yuyu that Space Works UX grew from, and what we changed.
---

import ReferenceBoards from '../../../components/ReferenceBoards.astro';

Space Works UX is our own, and it started from [Yuyu](https://github.com/twilighty-abhi/yuyu), an event
platform by Abhiram N J. We studied 28 of its screens on four boards (R1–R28 in the
[spec](/specs/ux-patterns/)) for layout, navigation and interaction, then adapted them for Space Works.

## What we kept

- A calm workspace: one shell, text-only navigation and one filled primary action per region.
- Stat cards, contextual callouts and lists that put the next step inline.
- Undo in place for reversible actions, and a danger zone for the rest.
- A split-screen sign-in, centred task cards and public pages with a sticky action card.

## What we changed

- **Visual identity.** Every colour, typeface, logo and icon comes from the
[Space Works brand guidelines](/brand/guidelines/), not from the boards. Yuyu's near-black pill buttons became
Maker Teal, and its warm-grey sidebar became a Citron field.
- **Scale.** Dense tables, guided multi-step flows, payments with receipts, kiosks and many roles. See
"Where the reference boards don't scale" in the [spec](/specs/ux-patterns/).

## The reference boards

These boards are Yuyu's work, shown here for attribution and study. They are not part of the Space Works design
kit and are not relicensed.

<ReferenceBoards />
8 changes: 7 additions & 1 deletion site/src/content/docs/ux/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ description: Our interaction system. The patterns, layouts and quality bar every
---

import { Card, CardGrid, LinkCard } from '@astrojs/starlight/components';
import UxShot from '../../../components/UxShot.astro';

**Space Works UX** sets how every Space Works screen works: where things go, how you move between them, and
what happens when you act. The brand decides how a screen looks. Space Works UX decides how it behaves.

<UxShot name="workspace-dashboard" alt="A Space Works dashboard built on Space Works UX" phone caption="Space Works Events, built on Space Works UX: the app shell, a callout that names the next step, and real numbers." />

## The rules to remember

<CardGrid>
Expand Down Expand Up @@ -47,6 +50,8 @@ what happens when you act. The brand decides how a screen looks. Space Works UX
- **A quality bar** that every screen has to pass before it ships.

<CardGrid>
<LinkCard title="Patterns in practice" description="Each core pattern in a real screen, in light, dark and phone views." href="/ux/patterns/" />
<LinkCard title="Screen gallery" description="Every captured screen, grouped by the layout it uses." href="/ux/gallery/" />
<LinkCard title="Space Works UX spec" description="Patterns, layouts, navigation, core screens and the quality bar." href="/specs/ux-patterns/" />
<LinkCard title="Long-tail screens" description="The remaining screens, each composed from the same patterns and layouts." href="/specs/ux-long-tail-screens/" />
<LinkCard title="UI brand spec" description="How the brand becomes interface: tokens, states, pills and the type scale." href="/specs/ui-brand-spec/" />
Expand All @@ -57,4 +62,5 @@ what happens when you act. The brand decides how a screen looks. Space Works UX
Space Works UX is our own. It was inspired by [Yuyu](https://github.com/twilighty-abhi/yuyu), whose screens we
studied as reference boards (R1–R28 in the spec) and then adapted for Space Works: bigger tables, guided
flows, payments, kiosks and many roles. The visual identity comes only from the
[Space Works brand guidelines](/brand/guidelines/). See [Credits and licences](/about/credits/).
[Space Works brand guidelines](/brand/guidelines/). See [Inspired by Yuyu](/ux/inspiration/) and
[Credits and licences](/about/credits/).
99 changes: 99 additions & 0 deletions site/src/content/docs/ux/patterns.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
title: Patterns in practice
description: The core Space Works UX patterns, each shown in a real Space Works screen in light, dark and phone views.
---

import UxShot from '../../../components/UxShot.astro';

These are real screens from **Space Works Events**, built on Space Works UX and run with demo data. Each pattern
links back to its number in the [Space Works UX spec](/specs/ux-patterns/). Select any image to open it at full
size.

## App shell and sidebar (P1)

A Citron sidebar with the workspace switcher on top, a text-only nav with one filled active item, then "View
public page ↗" and the account chip at the bottom. On a phone it folds into a top bar and sheet.

<UxShot name="workspace-dashboard" alt="Organisation dashboard in the app shell" phone caption="The dashboard answers “what needs me?” first: the callout links straight to the approvals and the draft." />

## Page header, callout and stats (P2, P4, P5)

One identity block per page: name, meta and at most one filled primary action. A contextual callout carries the
next step, and stat cards show real numbers.

<UxShot name="detail-overview" alt="Event detail with header, stat cards and readiness callout" phone caption="Detail header with a date tile, status chips, underline tabs and a readiness checklist where every gap links to its fix." />

## Lists with filter chips and bulk actions (P6, P8, P10)

Filter chips carry their counts. Selecting rows turns on the bulk bar. Every status is a word in a pill, never
colour alone.

<UxShot name="list-member-ids" alt="Member list with filter chips, search and status pills" phone caption="Member IDs: All 10 · Waiting 2 · Approved 6 · Rejected 1 · Revoked 1, with a reason shown under a rejection." />

<UxShot name="list-guests" alt="Guest list with status chips and inline actions" phone caption="Guests: the next step is inline in the row; rare actions sit in the row menu." />

## Tables inside a card (P14)

Dense data keeps the card chrome: a bordered card, sentence-case column labels and a hairline between rows.

<UxShot name="table-team" alt="Team table with roles and an invite card" caption="Team members with roles, and the invite card on top." />

## Settings rows, live preview and sticky save (P15, P16)

Settings are labelled rows with helper text beside each field. Changes collect in a sticky Discard / Save bar,
and the danger zone sits at the very end.

<UxShot name="settings-organisation" alt="Organisation settings with live public-page preview" phone caption="The public-page preview updates as you type. Nothing is saved until you choose Save changes." />

## Create with a live preview (P18)

Create forms stay short, mark optional fields inline, and check the web address as you type.

<UxShot name="form-new-organisation" alt="Create an organisation form" />

## Empty states and first-run (P17)

An empty workspace never just says "nothing here". It names the next step, and the first-run checklist shows only
one call to action at a time.

<UxShot name="workspace-empty-state" alt="New organisation with the first-run checklist" />

## Work in a focused flow (P21, P30)

High-frequency work gets its own focused surface: the scanner, search, live progress and an offline callout.
Reversible actions offer Undo in place instead of asking "Are you sure?".

<UxShot name="flow-check-in" alt="Check-in desk with scanner and progress" phone />

## Auth split screen and centred task card (P22, P23)

Sign-in is a split screen: the form on one side, one bold brand moment on the other. Single tasks, like resetting
a password, get one centred card.

<UxShot name="auth-sign-in" alt="Sign-in split screen" phone />

<UxShot name="auth-reset-password" alt="Reset password centred card" />

## Account (P24)

One header card with the person and their verification chips, then tabs, each a column of cards.

<UxShot name="account-profile" alt="Account profile settings" />

## Public pages (P25)

Public pages use the organisation's identity and a sticky card with the one action that matters.

<UxShot name="public-organisation" alt="Public organisation page" phone />

<UxShot name="public-event" alt="Public event page with the Join this event card" phone />

## Mobile ticket and card checks (P27)

Things people show at a door are built for a phone first: large type, high contrast and a clear state.

<UxShot name="public-ticket" alt="Mobile ticket with QR code" phone />

<UxShot name="public-verify-card" alt="Member card check showing a valid card" phone caption="A valid card shows only what is needed to confirm it." />

<UxShot name="public-verify-not-found" alt="Member card check with no match" phone caption="Errors are calm and specific, and say what to try next." />
28 changes: 28 additions & 0 deletions site/src/styles/kit.css
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,31 @@

/* Voice */
.sw-say { font-weight: 600; color: var(--sl-color-white); }

/* UX screenshots */
.sw-shot { margin-block: 1.25rem 2rem; }
.sw-shot-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.75rem;
align-items: start;
}
.sw-shot-row.has-phone { grid-template-columns: 1fr 1fr minmax(0, 0.32fr); }
.sw-shot a { display: grid; gap: 0.35rem; text-decoration: none; color: var(--sl-color-gray-3); font-size: 0.8125rem; }
.sw-shot img {
width: 100%;
height: auto;
border-radius: 10px;
border: 1px solid var(--sl-color-hairline);
}
.sw-shot a:hover img { border-color: var(--sl-color-text-accent); }
.sw-shot a:hover { color: var(--sl-color-text-accent); }
.sw-shot figcaption { margin-top: 0.5rem; color: var(--sl-color-gray-2); font-size: 0.9375rem; }
@media (max-width: 50rem) {
.sw-shot-row, .sw-shot-row.has-phone { grid-template-columns: 1fr; }
.sw-shot-row .sw-shot-dark { display: none; }
.sw-shot-row .sw-shot-phone { max-width: 14rem; }
}
.sw-boards { display: grid; gap: 1.5rem; margin-block: 1.5rem; }
.sw-boards a { display: grid; gap: 0.5rem; text-decoration: none; color: var(--sl-color-gray-3); font-size: 0.875rem; }
.sw-boards img { width: 100%; height: auto; border-radius: 10px; border: 1px solid var(--sl-color-hairline); }
Loading