diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index e37996c..617340d 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -1,6 +1,6 @@
name: Pages
-# Checks the palette, the mark and the screenshots against their sources on every push and pull request, and
+# Checks the palette, the mark and the screens against their sources on every push and pull request, and
# publishes main to GitHub Pages: index.html with dist/, logos/, fonts/ and assets/ beside it.
on:
diff --git a/README.md b/README.md
index 6da5588..bd70710 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ variables) and anything else (`dist/tokens.json`).
**[See it](https://spin-stack.github.io/brand/)**: `index.html` is the laboratory.
It draws the site's landing and a docs page, the dashboard's workspaces with their states, a
-dialog and a toast; the app as it is, in screenshots spin's own suite takes; the mark's guide -
+dialog and a toast; where the app as it is is shown; the mark's guide -
sizes, clear space, the lockup, the grounds it goes on and what it is not; the palette by what
each color is for; and the same page at a phone's and a tablet's width - in dark or light and
through protanopia, deuteranopia or tritanopia, with every pair the palette is held to.
@@ -14,7 +14,6 @@ through protanopia, deuteranopia or tritanopia, with every pair the palette is h
| Source | What it makes |
|---|---|
| `palette.toml` | `dist/`: `tokens.css` (every role as `--spin-*`), `starlight.css` (the website's `--sl-color-*`), `dashboard.css` (shadcn's HSL variables, light on `:root`, dark on `.dark`, and the dashboard's radius, scrim, dense type scale, heading tracking and motion), `tokens.json`, and `perception.js` and `simulate.svg` for the preview |
-| spin's `dashboard/e2e/site.spec.ts` | `shots/`: the app as it is, screenshots spin's dashboard suite takes of its e2e stack, with the release and commit of the spin tree that took them (`task screenshots SHOTS=
`); the website copies them from here |
| spin's `dashboard/e2e/catalog.spec.ts` | `screens/`: every route, tab, dialog and menu of the app in both themes at 1440 and 390 px, and what each draws that this palette does not have - a colour, a face, a size, a radius, contrast, overflow, a target too small (`task screens SCREENS=`). The catalog and the audit are committed; the images, hundreds a release, are an archive on a release of this repository that `screens.json` names and Pages unpacks. [See them](https://spin-stack.github.io/brand/screens.html) |
| `assets/mark.png` | `logos/`: the stack of disks, cut from the mark as it was drawn (1024 px on a clear ground): the tile on the brand's navy (512, 256; the touch icon at 180, the favicon at 64 and 32) for a dark ground, and clear (512, 256) for a light one. Each is the drawing reduced; a size it would have to enlarge fails |
diff --git a/Taskfile.yml b/Taskfile.yml
index 31e0fc0..60b9210 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -25,13 +25,6 @@ tasks:
cmds:
- go run ./cmd/mark
- screenshots:
- desc: Take the app's screenshots from SHOTS=, where `SITE_SHOTS= task e2e:dashboard -- site.spec.ts` in a spin checkout (SPIN=, by default ../spin) wrote them, with that checkout's release.
- vars:
- SPIN: '{{.SPIN | default "../spin"}}'
- cmds:
- - go run ./cmd/shots -spin {{.SPIN}} -from {{.SHOTS}}
-
screens:
desc: Keep every screen of the app from SCREENS=, where `CATALOG_SHOTS= task e2e:dashboard -- catalog.spec.ts` in a spin checkout (SPIN=, by default ../spin) wrote them - the catalog and the audit in screens/, the images on a release of this repository.
vars:
@@ -45,7 +38,7 @@ tasks:
- python3 -m http.server 4330 --bind 127.0.0.1
check:
- desc: What CI runs - fail if a pair is below its floor, dist/ or logos/ is not what the sources make, shots/ lacks a screenshot it lists, a workflow step is not one task, or an install skips Socket Firewall.
+ desc: What CI runs - fail if a pair is below its floor, dist/ or logos/ is not what the sources make, a workflow step is not one task, or an install skips Socket Firewall.
cmds:
- go tool taskgate
- go tool sfw check
@@ -53,7 +46,6 @@ tasks:
- go test ./...
- go run ./cmd/palette -check
- go run ./cmd/mark -check
- - go run ./cmd/shots -check
- go run ./cmd/screens -check
screens:download:
diff --git a/cmd/shots/main.go b/cmd/shots/main.go
deleted file mode 100644
index f64ab39..0000000
--- a/cmd/shots/main.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Command shots keeps the app's screenshots beside the palette that draws it, so the brand, the
-// website and anything else show the dashboard as it is, from one place. spin's own dashboard
-// suite takes them (dashboard/e2e/site.spec.ts, of its end-to-end stack - real workspaces on a
-// real runner - each test first checking the screen shows what its title says); `task
-// screenshots` copies them into shots/ with the release and the commit of the spin tree that
-// took them, and the title of the test that took each. With -check it fails on a shot
-// shots/shots.json lists and shots/ does not hold.
-package main
-
-import (
- "encoding/json"
- "flag"
- "fmt"
- "os"
- "os/exec"
- "path/filepath"
- "regexp"
- "strings"
-)
-
-const spec = "dashboard/e2e/site.spec.ts"
-
-type record struct {
- Release string `json:"release"`
- Commit string `json:"commit"`
- Shots []shot `json:"shots"`
-}
-
-type shot struct {
- Name string `json:"name"`
- Test string `json:"test"`
-}
-
-// specTest is a test of the spec and the name its shoot() call writes.
-var specTest = regexp.MustCompile(`(?s)test\("([^"]+)",.*?shoot\(\w+, "([\w-]+)"\)`)
-
-func main() {
- if err := run(); err != nil {
- fmt.Fprintln(os.Stderr, "shots:", err)
- os.Exit(1)
- }
-}
-
-func run() error {
- spin := flag.String("spin", "../spin", "the spin checkout whose dashboard suite took the shots")
- from := flag.String("from", "", "where the suite wrote them: SITE_SHOTS= task e2e:dashboard -- site.spec.ts")
- out := flag.String("out", "shots", "where they are kept")
- check := flag.Bool("check", false, "write nothing; fail on a shot shots.json lists and shots/ does not hold")
- flag.Parse()
-
- index := filepath.Join(*out, "shots.json")
- if *check {
- raw, err := os.ReadFile(index)
- if err != nil {
- return err
- }
- var r record
- if err := json.Unmarshal(raw, &r); err != nil {
- return fmt.Errorf("%s: %w", index, err)
- }
- for _, s := range r.Shots {
- if _, err := os.Stat(filepath.Join(*out, s.Name+".png")); err != nil {
- return fmt.Errorf("%s lists %s, and %s has no %s.png: run `task screenshots`", index, s.Name, *out, s.Name)
- }
- }
- fmt.Printf("shots: %d screenshots of spin %s\n", len(r.Shots), r.Release)
- return nil
- }
- if *from == "" {
- return fmt.Errorf("-from names where spin's suite wrote the screenshots")
- }
- raw, err := os.ReadFile(filepath.Join(*spin, spec))
- if err != nil {
- return err
- }
- r := record{}
- for _, m := range specTest.FindAllSubmatch(raw, -1) {
- r.Shots = append(r.Shots, shot{Name: string(m[2]), Test: string(m[1])})
- }
- if len(r.Shots) == 0 {
- return fmt.Errorf("%s: no test that shoots", spec)
- }
- if r.Release, err = git(*spin, "describe", "--tags", "--abbrev=0", "--match", "v[0-9]*"); err != nil {
- return err
- }
- if r.Commit, err = git(*spin, "rev-parse", "HEAD"); err != nil {
- return err
- }
- old, _ := filepath.Glob(filepath.Join(*out, "*.png"))
- for _, o := range old {
- if err := os.Remove(o); err != nil {
- return err
- }
- }
- if err := os.MkdirAll(*out, 0o755); err != nil {
- return err
- }
- for _, s := range r.Shots {
- png, err := os.ReadFile(filepath.Join(*from, s.Name+".png"))
- if err != nil {
- return fmt.Errorf("%w: run `SITE_SHOTS=%s task e2e:dashboard -- site.spec.ts` in spin first", err, *from)
- }
- if err := os.WriteFile(filepath.Join(*out, s.Name+".png"), png, 0o644); err != nil {
- return err
- }
- }
- b, err := json.MarshalIndent(r, "", "\t")
- if err != nil {
- return err
- }
- return os.WriteFile(index, append(b, '\n'), 0o644)
-}
-
-func git(dir string, args ...string) (string, error) {
- out, err := exec.Command("git", append([]string{"-C", dir}, args...)...).Output()
- if err != nil {
- return "", fmt.Errorf("git %s in %s: %w", strings.Join(args, " "), dir, err)
- }
- return strings.TrimSpace(string(out)), nil
-}
diff --git a/index.html b/index.html
index 809e5ed..5f572df 100644
--- a/index.html
+++ b/index.html
@@ -77,9 +77,6 @@
.group h3 { font-size: 14px; margin: 0 0 .25rem; } .group p { margin: 0; font-size: 13px; }
.group .example { margin-top: .75rem; display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; font-size: 14px; }
-/* The app's screenshots */
-.shots { display: grid; grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr)); gap: 1rem; }
-.shots figure { margin: 0; } .shots img { width: 100%; border-radius: var(--spin-radius); border: 1px solid var(--spin-border); display: block; }
/* The docs' contents on a narrow screen: a disclosure where the side column was. */
.otp { display: none; margin-bottom: 1rem; border: 1px solid var(--spin-border); border-radius: var(--spin-radius-sm); background: var(--spin-raised); }
@@ -256,8 +253,7 @@
Workspaces
The app, as it is
-
Screenshots spin's own dashboard suite takes of a real installation (shots/, by task screenshots).
-
+
Every screen of it in both themes, and what each draws that this palette does not have, is the catalog. The screenshots the site shows are of the spin release it documents, put on that release by spin's site-shots.yml: the dashboard.
2
Decisions
What the brand is: the mark and how it is used, and the palette, each color by what it is for. These are what palette.toml and the mark's cut hold.
`; }).join('') +
'').join('');
}
-fetch('shots/shots.json').then((r) => r.ok ? r.json() : null).then((s) => {
- if (!s) { document.getElementById('shots-note').textContent = 'No screenshots yet: task screenshots takes them from spin.'; return; }
- document.getElementById('shots-note').innerHTML = `Screenshots of spin ${s.release}, taken by its dashboard suite on a real installation - each by a test that first checks the screen shows what its title says.`;
- document.getElementById('shots').innerHTML = s.shots.map((x) => `${x.test}`).join('');
-});
const views = ['drawn','ips','dim','protan','deutan','tritan','protan+ips','deutan+ips'];
document.getElementById('perc').innerHTML = '