@sebastienrousseau/dotfiles 0.2.508 → 0.2.510

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +5 -5
  3. package/docs/COPYRIGHT +1 -1
  4. package/docs/GOVERNANCE.md +2 -2
  5. package/docs/adr/ADR-011-nushell-tier3-keep.md +2 -2
  6. package/docs/guides/INSTALL.md +3 -3
  7. package/docs/index.md +116 -27
  8. package/docs/interop/A2A.md +2 -2
  9. package/docs/interop/POWERSHELL.md +4 -4
  10. package/docs/manual/00-introduction.md +3 -3
  11. package/docs/manual/01-concepts/02-trust-model.md +3 -3
  12. package/docs/manual/01-concepts/04-fleet.md +1 -1
  13. package/docs/manual/02-tutorials/01-first-install.md +1 -1
  14. package/docs/manual/02-tutorials/05-deploy-fleet.md +2 -2
  15. package/docs/manual/03-reference/02-config-files.md +1 -1
  16. package/docs/manual/03-reference/04-templates.md +1 -1
  17. package/docs/manual/04-cookbook/01-recipes.md +1 -1
  18. package/docs/manual/04-cookbook/02-troubleshooting.md +1 -1
  19. package/docs/manual/05-appendices/B-security-checklist.md +1 -1
  20. package/docs/manual/command-index.md +76 -1
  21. package/docs/manual/index.md +1 -1
  22. package/docs/operations/ARCHITECTURE_ROADMAP.md +145 -0
  23. package/docs/operations/CI_CADENCE.md +2 -2
  24. package/docs/operations/COMPLETIONS.md +2 -2
  25. package/docs/operations/COVERAGE.md +4 -4
  26. package/docs/operations/DRIFT.md +1 -1
  27. package/docs/operations/MAINTENANCE.md +6 -6
  28. package/docs/operations/PERFORMANCE.md +6 -6
  29. package/docs/operations/RELIABILITY.md +1 -1
  30. package/docs/operations/ROADMAP_V0_2_503.md +1 -1
  31. package/docs/operations/TRACEABILITY.md +2 -0
  32. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +6 -6
  33. package/docs/operations/VERSION_SYNC.md +3 -3
  34. package/docs/reference/UTILS.md +82 -0
  35. package/docs/security/AUDIT_BYPASS.md +3 -3
  36. package/docs/security/AUTOMATION_SECRETS.md +1 -1
  37. package/docs/security/CI_PINNING.md +10 -10
  38. package/docs/security/COMMIT_SIGNING.md +10 -10
  39. package/docs/security/DEPS_DEV_EXCEPTIONS.md +4 -4
  40. package/docs/security/DISCLOSURE.md +3 -3
  41. package/docs/security/INCIDENT_RESPONSE.md +1 -1
  42. package/docs/security/INSTALL_VERIFICATION.md +2 -2
  43. package/docs/security/MCP_POLICY.md +4 -4
  44. package/docs/security/SCORECARD.md +7 -7
  45. package/docs/security/SECURITY_CHECKLIST.md +1 -1
  46. package/docs/security/SHELL_EXEMPTIONS.md +2 -2
  47. package/docs/security/SOUP_REGISTER.md +4 -4
  48. package/docs/stylesheets/extra.css +444 -0
  49. package/docs/themes/hero-shot.svg +1 -1
  50. package/install.sh +17 -6
  51. package/package.json +1 -1
  52. package/scripts/ci/check-copyright-headers.sh +1 -1
  53. package/scripts/ci/check-shell-preamble.sh +1 -1
  54. package/scripts/ci/guard-gitleaks-checkout.sh +1 -1
  55. package/scripts/dot/commands/agent.sh +7 -6
  56. package/scripts/dot/commands/ai.sh +8 -5
  57. package/scripts/dot/commands/appearance.sh +14 -1
  58. package/scripts/dot/commands/completion.sh +134 -0
  59. package/scripts/dot/commands/core.sh +8 -0
  60. package/scripts/dot/commands/diagnostics.sh +16 -0
  61. package/scripts/dot/commands/fleet.sh +7 -3
  62. package/scripts/dot/commands/lint.sh +55 -30
  63. package/scripts/dot/commands/secrets.sh +61 -7
  64. package/scripts/dot/commands/security.sh +8 -0
  65. package/scripts/dot/powershell/Dot.psm1 +1 -1
  66. package/scripts/git-hooks/pre-commit-audit.sh +1 -1
  67. package/scripts/ops/heal-tools.sh +28 -0
  68. package/scripts/ops/teleport.sh +2 -2
  69. package/scripts/qa/examples-coverage.sh +94 -0
  70. package/scripts/version-sync.sh +29 -2
  71. package/docs/_config.yml +0 -59
@@ -7,7 +7,7 @@ render_with_liquid: false
7
7
  The CI workflow `.github/workflows/deps-dev-validation.yml` scans
8
8
  direct dependencies (npm + PyPI + GitHub Actions) against the
9
9
  [deps.dev Insights API](https://docs.deps.dev/) on every PR, every
10
- push to `master`, and every Tuesday at 04:00 UTC. When an advisory
10
+ push to `main`, and every Tuesday at 04:00 UTC. When an advisory
11
11
  is reported at or above the threshold (default `HIGH`), the workflow
12
12
  fails.
13
13
 
@@ -79,8 +79,8 @@ auto-fail the gate even when they're still listed here.
79
79
 
80
80
  ## References
81
81
 
82
- - [`tools/ci/check-deps-dev.sh`](../../tools/ci/check-deps-dev.sh) — the scanner.
83
- - [`.github/workflows/deps-dev-validation.yml`](../../.github/workflows/deps-dev-validation.yml) — CI wiring.
84
- - [`tests/unit/security/test_check_deps_dev.sh`](../../tests/unit/security/test_check_deps_dev.sh) — contract test against canned fixtures.
82
+ - [`tools/ci/check-deps-dev.sh`](https://github.com/sebastienrousseau/dotfiles/blob/main/tools/ci/check-deps-dev.sh) — the scanner.
83
+ - [`.github/workflows/deps-dev-validation.yml`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/workflows/deps-dev-validation.yml) — CI wiring.
84
+ - [`tests/unit/security/test_check_deps_dev.sh`](https://github.com/sebastienrousseau/dotfiles/blob/main/tests/unit/security/test_check_deps_dev.sh) — contract test against canned fixtures.
85
85
  - [deps.dev API reference](https://docs.deps.dev/api/v3/).
86
86
  - Issue [#877](https://github.com/sebastienrousseau/dotfiles/issues/877).
@@ -34,7 +34,7 @@ gpg --fingerprint security@sebastienrousseau.com
34
34
  ```
35
35
 
36
36
  The fingerprint must match the one published in
37
- [`.github/SECURITY.md`](../../.github/SECURITY.md). Cross-verify
37
+ [`.github/SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/SECURITY.md). Cross-verify
38
38
  against the SSH signing key in `dot_config/git/allowed_signers.tmpl`
39
39
  — the maintainer signs commits with the same identity, so both
40
40
  fingerprints derive from the same identity claim.
@@ -75,7 +75,7 @@ subjects in plain text).
75
75
  ## 5. Acknowledgement
76
76
 
77
77
  You should receive an acknowledgement within the SLA in
78
- [`.github/SECURITY.md`](../../.github/SECURITY.md):
78
+ [`.github/SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/SECURITY.md):
79
79
 
80
80
  | Severity | Initial response |
81
81
  |---|---|
@@ -122,7 +122,7 @@ The maintainer commits to:
122
122
 
123
123
  ## See also
124
124
 
125
- - [`.github/SECURITY.md`](../../.github/SECURITY.md) — policy
125
+ - [`.github/SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/SECURITY.md) — policy
126
126
  overview + fingerprint.
127
127
  - [`docs/security/KEY_ROTATION.md`](KEY_ROTATION.md) — schedule for
128
128
  when the disclosure key is rotated.
@@ -113,7 +113,7 @@ lock-configs
113
113
  gh workflow disable <workflow-name>
114
114
 
115
115
  # Force-protect the main branch
116
- gh api repos/{owner}/{repo}/branches/master/protection \
116
+ gh api repos/{owner}/{repo}/branches/main/protection \
117
117
  --method PUT \
118
118
  --field required_status_checks='{"strict":true,"contexts":["ci"]}' \
119
119
  --field enforce_admins=true
@@ -56,7 +56,7 @@ These are weaker than a SHA256 check, but they catch the obvious
56
56
  After chezmoi is installed, `install.sh` clones the dotfiles repo
57
57
  itself. This isn't currently cryptographically verified beyond Git's
58
58
  own object integrity, but commits in the repo are SSH-signed and
59
- branch protection on `master` requires signed commits (see #853).
59
+ branch protection on `main` requires signed commits (see #853).
60
60
 
61
61
  ## How to obtain per-release hashes
62
62
 
@@ -64,7 +64,7 @@ The verified-install snippet uses the SHA256 of the `install.sh`
64
64
  file *as it exists at the release tag*. To regenerate after a release:
65
65
 
66
66
  ```bash
67
- git switch master
67
+ git switch main
68
68
  git pull
69
69
  NEW_TAG="v0.2.502" # adjust
70
70
  git tag -s "$NEW_TAG" -m "..."
@@ -21,9 +21,9 @@ Properties:
21
21
 
22
22
  ## Policy artifact
23
23
 
24
- The source of truth lives in [mcp-policy.json](../../defaults/dot_config/dotfiles/mcp-policy.json).
25
- Approved package pins live in [mcp-lock.json](../../defaults/dot_config/dotfiles/mcp-lock.json).
26
- Tracked server registry entries live in [mcp-registry.json](../../defaults/dot_config/dotfiles/mcp-registry.json).
24
+ The source of truth lives in [mcp-policy.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/mcp-policy.json).
25
+ Approved package pins live in [mcp-lock.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/mcp-lock.json).
26
+ Tracked server registry entries live in [mcp-registry.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/mcp-registry.json).
27
27
 
28
28
  Current defaults:
29
29
 
@@ -75,4 +75,4 @@ Current approved refs:
75
75
  - active servers match the tracked registry entries
76
76
  - remote HTTP transports are HTTPS and OAuth-backed
77
77
 
78
- Policy bundle baselines live in [policy-bundles.json](../../defaults/dot_config/dotfiles/policy-bundles.json).
78
+ Policy bundle baselines live in [policy-bundles.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/policy-bundles.json).
@@ -41,7 +41,7 @@ Aggregate score **7.6 / 10** at 2026-05-17T08:11:51Z.
41
41
  [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/sebastienrousseau/dotfiles/badge)](https://scorecard.dev/viewer/?uri=github.com/sebastienrousseau/dotfiles)
42
42
 
43
43
  The badge above is regenerated every Monday at 06:00 UTC and on every
44
- push to `master` by `.github/workflows/scorecard.yml`. The SARIF
44
+ push to `main` by `.github/workflows/scorecard.yml`. The SARIF
45
45
  result is uploaded to GitHub Code Scanning (Security tab) and
46
46
  retained as a 30-day workflow artifact.
47
47
 
@@ -57,7 +57,7 @@ Regressions are triaged within one Monday cycle: identify the check
57
57
  that dropped, either remediate or file an exception entry below with
58
58
  a rationale and an expiry date.
59
59
 
60
- ## Per-check posture (snapshot, master HEAD)
60
+ ## Per-check posture (snapshot, main HEAD)
61
61
 
62
62
  The checks below come from OpenSSF Scorecard's published rubric. Tick
63
63
  marks reflect this repo's posture at the time of writing — the
@@ -65,19 +65,19 @@ marks reflect this repo's posture at the time of writing — the
65
65
 
66
66
  | Check | Status | Notes |
67
67
  |---|---|---|
68
- | Branch-Protection | ⚠ | `master` requires signed commits, linear history, required checks (`.github/rulesets/master.json`). Scorecard can't read classic protection rules without a fine-grained PAT, so this check reports as `-1` ("internal error"). |
68
+ | Branch-Protection | ⚠ | `main` requires signed commits, linear history, required checks (`.github/rulesets/main.json`). Scorecard can't read classic protection rules without a fine-grained PAT, so this check reports as `-1` ("internal error"). |
69
69
  | Code-Review | ⚠ | Single-maintainer repo; PRs are self-merged after CI. Scorecard scores 0/30 here by design — see `Open findings` below. |
70
70
  | Signed-Commits | ✓ | Enforced by pre-push hook (`scripts/git-hooks/pre-push`) and at-push by branch protection (#853 + #857). |
71
71
  | Dependency-Update-Tool | ✓ | Dependabot configured for github-actions / npm / docker / devcontainers / uv. |
72
72
  | Fuzzing | ⚠ | `install.sh` fuzz harness lives under `tests/fuzz/` (closes #881), but it's shell-based and Scorecard's heuristic only recognizes OSS-Fuzz / ClusterFuzzLite / native Go fuzz / libFuzzer / Atheris. None support shell. Property tests under `tests/unit/functions/test_property_*.sh` cover the closest equivalent surface. |
73
73
  | License | ✓ | MIT at repo root (`LICENSE`). |
74
- | Maintained | ✓ | Active commit cadence; the [README](../../README.md) lists the current `dotfiles_version`. |
74
+ | Maintained | ✓ | Active commit cadence; the [README](https://github.com/sebastienrousseau/dotfiles/blob/main/README.md) lists the current `dotfiles_version`. |
75
75
  | Pinned-Dependencies | ⚠ | Closed 8 of 14 findings this cycle (every Dockerfile base + every workflow action + 2 `curl \| sh` installers + the `npm install -g npm` upgrade step). 5 residual findings stay open by design — see `Open findings`. |
76
76
  | SAST | ✓ | CodeQL (`.github/workflows/codeql.yml`) + Checkov + Grype. |
77
77
  | SBOM | ✓ | Generated per PR by `sbom-diff.yml` and per release by `security-release.yml`. |
78
78
  | Security-Policy | ✓ | `.github/SECURITY.md` + this page + `docs/security/THREAT_MODEL.md`. |
79
79
  | Token-Permissions | ✓ | Top-level `permissions:` blocks restricted to `contents: read`. `write` scopes scoped to the jobs that need them (#886). |
80
- | Vulnerabilities | ✓ | Grype gate hard-fails on `high` / `critical` on `master` (#852). |
80
+ | Vulnerabilities | ✓ | Grype gate hard-fails on `high` / `critical` on `main` (#852). |
81
81
  | Webhooks | n/a | No external webhooks configured. |
82
82
  | CI-Tests | ✓ | Linux + macOS Intel + Apple Silicon matrix; optional Windows. |
83
83
  | CII-Best-Practices | ☐ | Not applied yet — see `Open work` below. |
@@ -138,7 +138,7 @@ false positives in Scorecard's regex.
138
138
  - **Re-trigger Scorecard after SLSA backfill propagates** — expected `Signed-Releases` 3 → 10.
139
139
  - **`harden-runner` block-mode adoption (#878)** — should tighten the `Token-Permissions` check further.
140
140
  - **Investigate `License` 9/10 false-positive** — repo is MIT (SPDX-compliant), Scorecard's penalty should not apply.
141
- - **Investigate `Branch-Protection` `-1`** — scanner internal error; manually verify with `gh api repos/:owner/:repo/branches/master/protection` and document.
141
+ - **Investigate `Branch-Protection` `-1`** — scanner internal error; manually verify with `gh api repos/:owner/:repo/branches/main/protection` and document.
142
142
 
143
143
  ### Enabling Branch-Protection + Webhooks checks (one-time PAT setup)
144
144
 
@@ -180,7 +180,7 @@ gh api 'repos/sebastienrousseau/dotfiles/code-scanning/alerts?state=open&per_pag
180
180
  --jq '[.[].rule.id] | group_by(.) | map({rule: .[0], count: length})'
181
181
 
182
182
  # Trigger Scorecard manually:
183
- gh workflow run scorecard.yml --ref master
183
+ gh workflow run scorecard.yml --ref main
184
184
  ```
185
185
 
186
186
  If a new category appears, add a row to the matching bucket. If a
@@ -45,7 +45,7 @@ Run `dot mcp --strict --json` to validate all MCP server configurations and capt
45
45
  - [ ] **SBOM Generation**: Verify `dotfiles-sbom.spdx.json` is generated in release workflow.
46
46
  - [ ] **Attestation Signing**: Confirm `actions/attest-build-provenance` signs the release artifacts.
47
47
  - [ ] **Attestation Verification**: Verify with `gh attestation verify <artifact> --repo sebastienrousseau/dotfiles`.
48
- - [ ] **Branch Protection**: Ensure `security-attestation` is a required status check on master.
48
+ - [ ] **Branch Protection**: Ensure `security-attestation` is a required status check on main.
49
49
  - [ ] **Automation Keying**: Confirm `ACTIONS_BOT_SIGNING_KEY` exists and matches the signer in `dot_config/git/allowed_signers`.
50
50
 
51
51
  ## 7. Final Verification
@@ -7,10 +7,10 @@ render_with_liquid: false
7
7
  Every bash script in this repo must include `set -euo pipefail` (or
8
8
  `set -eu` for POSIX `sh`) within its first 50 lines. The rule is
9
9
  enforced by
10
- [`tools/ci/check-shell-preamble.sh`](../../tools/ci/check-shell-preamble.sh),
10
+ [`tools/ci/check-shell-preamble.sh`](https://github.com/sebastienrousseau/dotfiles/blob/main/tools/ci/check-shell-preamble.sh),
11
11
  wired into `pre-commit` and the `reusable-shell-lint.yml` CI job.
12
12
  Tests pin the contract under
13
- [`tests/unit/security/test_shell_preamble_lint.sh`](../../tests/unit/security/test_shell_preamble_lint.sh).
13
+ [`tests/unit/security/test_shell_preamble_lint.sh`](https://github.com/sebastienrousseau/dotfiles/blob/main/tests/unit/security/test_shell_preamble_lint.sh).
14
14
 
15
15
  ## Why the preamble is mandatory
16
16
 
@@ -12,13 +12,13 @@ Controlled inventory for software of unknown pedigree used by the dotfiles platf
12
12
 
13
13
  | Component | Source | Version control | Verification path | Owner | Status |
14
14
  | :--- | :--- | :--- | :--- | :--- | :--- |
15
- | Homebrew installer | `raw.githubusercontent.com/Homebrew/install` | Moving upstream script, gated by `HOMEBREW_INSTALLER_SHA256` | SHA-256 in [package_managers.sh](../../install/lib/package_managers.sh) | Repo maintainer | Conditional |
15
+ | Homebrew installer | `raw.githubusercontent.com/Homebrew/install` | Moving upstream script, gated by `HOMEBREW_INSTALLER_SHA256` | SHA-256 in [package_managers.sh](https://github.com/sebastienrousseau/dotfiles/blob/main/install/lib/package_managers.sh) | Repo maintainer | Conditional |
16
16
  | Chezmoi installer | `get.chezmoi.io` | Pinned by `CHEZMOI_INSTALLER_SHA256` when used | SHA-256 in `install/lib/chezmoi.sh` | Repo maintainer | Controlled |
17
17
  | GitHub Actions marketplace actions | GitHub Marketplace | Full commit SHA pinning | Workflow `uses:` pins | Repo maintainer | Controlled |
18
- | Grype container | `anchore/grype` | Pinned tag in workflow | Container tag in [security-enhanced.yml](../../.github/workflows/security-enhanced.yml) | Repo maintainer | Controlled |
19
- | Trivy container | `aquasec/trivy` | Pinned tag in workflow | Container tag in [security-enhanced.yml](../../.github/workflows/security-enhanced.yml) | Repo maintainer | Controlled |
18
+ | Grype container | `anchore/grype` | Pinned tag in workflow | Container tag in [security-enhanced.yml](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/workflows/security-enhanced.yml) | Repo maintainer | Controlled |
19
+ | Trivy container | `aquasec/trivy` | Pinned tag in workflow | Container tag in [security-enhanced.yml](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/workflows/security-enhanced.yml) | Repo maintainer | Controlled |
20
20
  | Checkov action | GitHub Marketplace | Full commit SHA pinning | Workflow `uses:` pin | Repo maintainer | Controlled |
21
- | Nix inputs | GitHub flakes | Locked in [flake.lock](../../flake.lock) | `narHash` and revision lock | Repo maintainer | Controlled |
21
+ | Nix inputs | GitHub flakes | Locked in [flake.lock](https://github.com/sebastienrousseau/dotfiles/blob/main/flake.lock) | `narHash` and revision lock | Repo maintainer | Controlled |
22
22
  | GitHub release metadata queries | GitHub API | Discovery only, not release validation | `update-deps.yml` query path | Repo maintainer | Monitored |
23
23
 
24
24
  ## Validation record
@@ -0,0 +1,444 @@
1
+ /* ──────────────────────────────────────────────────────────────────────────
2
+ * doc.dotfiles.io — custom theme
3
+ * Dark + terminal-green palette on MkDocs Material.
4
+ * Inspired by the polish of docs.n8n.io / GitHub docs dark, adapted to
5
+ * Material's structure.
6
+ * ────────────────────────────────────────────────────────────────────── */
7
+
8
+ /* -- font stack ------------------------------------------------------------ */
9
+ @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap");
10
+
11
+ :root {
12
+ --dot-font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
13
+ "Helvetica Neue", Arial, sans-serif;
14
+ --dot-font-code: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono",
15
+ Menlo, Consolas, monospace;
16
+
17
+ --dot-green: #7ee787; /* terminal green */
18
+ --dot-green-bright: #b0f5b7; /* hover / focused */
19
+ --dot-green-dim: #4a9153; /* muted / secondary */
20
+ --dot-green-rgb: 126, 231, 135;
21
+
22
+ --dot-bg: #0b0e14; /* base */
23
+ --dot-bg-elev: #111621; /* elevated card */
24
+ --dot-bg-elev-2: #161b26; /* higher elevation */
25
+ --dot-border: #1f2937;
26
+ --dot-border-strong: #2b3646;
27
+
28
+ --dot-fg: #e4e7ec;
29
+ --dot-fg-muted: #94a3b8;
30
+ --dot-fg-subtle: #64748b;
31
+ }
32
+
33
+ /* -- global typography ----------------------------------------------------- */
34
+ body,
35
+ .md-typeset {
36
+ font-family: var(--dot-font-body);
37
+ font-feature-settings: "ss01", "cv11";
38
+ -webkit-font-smoothing: antialiased;
39
+ -moz-osx-font-smoothing: grayscale;
40
+ }
41
+
42
+ .md-typeset code,
43
+ .md-typeset kbd,
44
+ .md-typeset pre,
45
+ code {
46
+ font-family: var(--dot-font-code);
47
+ font-feature-settings: "calt", "ss20";
48
+ }
49
+
50
+ /* -- dark palette override (slate) ---------------------------------------- */
51
+ [data-md-color-scheme="slate"] {
52
+ --md-hue: 210;
53
+ --md-default-bg-color: var(--dot-bg);
54
+ --md-default-fg-color: var(--dot-fg);
55
+ --md-default-fg-color--light: var(--dot-fg-muted);
56
+ --md-default-fg-color--lighter: var(--dot-fg-subtle);
57
+ --md-default-fg-color--lightest: hsla(210, 20%, 40%, 0.3);
58
+
59
+ --md-primary-fg-color: var(--dot-green);
60
+ --md-primary-fg-color--light: var(--dot-green-bright);
61
+ --md-primary-fg-color--dark: var(--dot-green-dim);
62
+ --md-primary-bg-color: var(--dot-bg);
63
+ --md-primary-bg-color--light: var(--dot-bg-elev);
64
+
65
+ --md-accent-fg-color: var(--dot-green-bright);
66
+ --md-accent-fg-color--transparent: rgba(126, 231, 135, 0.1);
67
+ --md-accent-bg-color: var(--dot-bg);
68
+ --md-accent-bg-color--light: var(--dot-bg-elev);
69
+
70
+ --md-typeset-a-color: var(--dot-green);
71
+
72
+ --md-code-bg-color: var(--dot-bg-elev-2);
73
+ --md-code-fg-color: var(--dot-fg);
74
+ --md-code-hl-color: rgba(126, 231, 135, 0.12);
75
+ --md-code-hl-color--light: rgba(126, 231, 135, 0.08);
76
+
77
+ /* Admonitions */
78
+ --md-admonition-bg-color: var(--dot-bg-elev);
79
+ --md-admonition-fg-color: var(--dot-fg);
80
+
81
+ /* Footer */
82
+ --md-footer-bg-color: #050710;
83
+ --md-footer-bg-color--dark: #030509;
84
+ }
85
+
86
+ /* -- header --------------------------------------------------------------- */
87
+ .md-header {
88
+ background-color: rgba(11, 14, 20, 0.92);
89
+ backdrop-filter: saturate(180%) blur(12px);
90
+ -webkit-backdrop-filter: saturate(180%) blur(12px);
91
+ border-bottom: 1px solid var(--dot-border);
92
+ box-shadow: none;
93
+ }
94
+
95
+ .md-header[data-md-state="shadow"] {
96
+ box-shadow: 0 1px 0 var(--dot-border);
97
+ }
98
+
99
+ .md-header__title {
100
+ font-weight: 600;
101
+ letter-spacing: -0.01em;
102
+ }
103
+
104
+ .md-header__button.md-logo :is(img, svg) {
105
+ color: var(--dot-green);
106
+ fill: var(--dot-green);
107
+ height: 1.6rem;
108
+ width: 1.6rem;
109
+ }
110
+
111
+ /* -- tabs --------------------------------------------------------------- */
112
+ .md-tabs {
113
+ background-color: rgba(11, 14, 20, 0.85);
114
+ border-bottom: 1px solid var(--dot-border);
115
+ }
116
+
117
+ .md-tabs__link {
118
+ color: var(--dot-fg-muted);
119
+ opacity: 1;
120
+ font-size: 0.75rem;
121
+ font-weight: 500;
122
+ transition: color 120ms ease;
123
+ }
124
+
125
+ .md-tabs__link:hover,
126
+ .md-tabs__link--active {
127
+ color: var(--dot-green-bright);
128
+ }
129
+
130
+ .md-tabs__link--active {
131
+ position: relative;
132
+ }
133
+ .md-tabs__link--active::after {
134
+ content: "";
135
+ position: absolute;
136
+ left: 0;
137
+ right: 0;
138
+ bottom: -2px;
139
+ height: 2px;
140
+ background: linear-gradient(90deg, transparent, var(--dot-green), transparent);
141
+ }
142
+
143
+ /* -- sidebar (left nav) --------------------------------------------------- */
144
+ .md-nav__title {
145
+ font-size: 0.68rem;
146
+ font-weight: 700;
147
+ text-transform: uppercase;
148
+ letter-spacing: 0.05em;
149
+ color: var(--dot-fg-subtle);
150
+ padding-top: 1.2rem;
151
+ }
152
+
153
+ .md-nav__link {
154
+ color: var(--dot-fg-muted);
155
+ transition: color 120ms ease, background-color 120ms ease;
156
+ border-radius: 6px;
157
+ padding: 4px 8px;
158
+ margin: 1px 0;
159
+ }
160
+ .md-nav__link:hover {
161
+ color: var(--dot-fg);
162
+ background: rgba(126, 231, 135, 0.06);
163
+ }
164
+ .md-nav__link--active,
165
+ .md-nav__link.md-nav__link--active {
166
+ color: var(--dot-green-bright);
167
+ background: rgba(126, 231, 135, 0.1);
168
+ font-weight: 500;
169
+ }
170
+
171
+ /* -- right TOC ------------------------------------------------------------ */
172
+ .md-nav--secondary .md-nav__title {
173
+ border-left: 2px solid var(--dot-border);
174
+ background: transparent;
175
+ }
176
+ .md-nav--secondary .md-nav__link--active {
177
+ border-left: 2px solid var(--dot-green);
178
+ color: var(--dot-green-bright);
179
+ background: transparent;
180
+ }
181
+
182
+ /* -- content -------------------------------------------------------------- */
183
+ .md-typeset h1,
184
+ .md-typeset h2,
185
+ .md-typeset h3,
186
+ .md-typeset h4 {
187
+ font-family: var(--dot-font-body);
188
+ letter-spacing: -0.02em;
189
+ color: var(--dot-fg);
190
+ }
191
+
192
+ .md-typeset h1 {
193
+ font-weight: 700;
194
+ font-size: 2.2rem;
195
+ line-height: 1.15;
196
+ margin-bottom: 0.6em;
197
+ background: linear-gradient(180deg, #ffffff 0%, #cbd5e1 100%);
198
+ -webkit-background-clip: text;
199
+ background-clip: text;
200
+ color: transparent;
201
+ }
202
+
203
+ .md-typeset h2 {
204
+ font-weight: 600;
205
+ font-size: 1.6rem;
206
+ margin-top: 2.4em;
207
+ padding-top: 0.4em;
208
+ border-top: 1px solid var(--dot-border);
209
+ }
210
+
211
+ .md-typeset h3 {
212
+ font-weight: 600;
213
+ font-size: 1.2rem;
214
+ color: var(--dot-green-bright);
215
+ }
216
+
217
+ .md-typeset a {
218
+ text-decoration: none;
219
+ border-bottom: 1px solid transparent;
220
+ transition: border-color 120ms ease, color 120ms ease;
221
+ }
222
+ .md-typeset a:hover {
223
+ border-bottom-color: var(--dot-green-bright);
224
+ color: var(--dot-green-bright);
225
+ }
226
+
227
+ /* -- code blocks ---------------------------------------------------------- */
228
+ .md-typeset pre > code,
229
+ .md-typeset .highlight pre {
230
+ background-color: var(--dot-bg-elev-2);
231
+ border: 1px solid var(--dot-border);
232
+ border-radius: 8px;
233
+ }
234
+ .md-typeset code {
235
+ background-color: rgba(126, 231, 135, 0.08);
236
+ border: 1px solid rgba(126, 231, 135, 0.15);
237
+ color: var(--dot-green-bright);
238
+ border-radius: 4px;
239
+ padding: 0.1em 0.35em;
240
+ font-size: 0.88em;
241
+ }
242
+ .md-typeset pre > code {
243
+ background: transparent;
244
+ border: none;
245
+ color: var(--dot-fg);
246
+ padding: 0;
247
+ }
248
+
249
+ /* -- tables --------------------------------------------------------------- */
250
+ .md-typeset table:not([class]) {
251
+ border: 1px solid var(--dot-border);
252
+ border-radius: 8px;
253
+ overflow: hidden;
254
+ font-size: 0.8rem;
255
+ }
256
+ .md-typeset table:not([class]) th {
257
+ background: var(--dot-bg-elev);
258
+ color: var(--dot-fg);
259
+ font-weight: 600;
260
+ border-bottom: 1px solid var(--dot-border-strong);
261
+ }
262
+ .md-typeset table:not([class]) tr:hover {
263
+ background: rgba(126, 231, 135, 0.03);
264
+ }
265
+
266
+ /* -- admonitions ---------------------------------------------------------- */
267
+ .md-typeset .admonition,
268
+ .md-typeset details {
269
+ background: var(--dot-bg-elev);
270
+ border: 1px solid var(--dot-border);
271
+ border-left: 3px solid var(--dot-green);
272
+ border-radius: 8px;
273
+ box-shadow: none;
274
+ }
275
+ .md-typeset .admonition-title,
276
+ .md-typeset summary {
277
+ background: transparent;
278
+ border-bottom: 1px solid var(--dot-border);
279
+ font-weight: 600;
280
+ }
281
+
282
+ /* -- grid cards ----------------------------------------------------------- */
283
+ .md-typeset .grid.cards > :is(ul, ol) > li,
284
+ .md-typeset .grid.cards > .card {
285
+ background: var(--dot-bg-elev);
286
+ border: 1px solid var(--dot-border);
287
+ border-radius: 12px;
288
+ padding: 1.2rem;
289
+ transition: transform 180ms ease, border-color 180ms ease,
290
+ box-shadow 180ms ease, background 180ms ease;
291
+ position: relative;
292
+ overflow: hidden;
293
+ }
294
+ .md-typeset .grid.cards > :is(ul, ol) > li::before {
295
+ content: "";
296
+ position: absolute;
297
+ inset: 0;
298
+ background: radial-gradient(
299
+ circle at top left,
300
+ rgba(126, 231, 135, 0.06),
301
+ transparent 60%
302
+ );
303
+ opacity: 0;
304
+ transition: opacity 220ms ease;
305
+ pointer-events: none;
306
+ }
307
+ .md-typeset .grid.cards > :is(ul, ol) > li:hover {
308
+ transform: translateY(-2px);
309
+ border-color: rgba(126, 231, 135, 0.35);
310
+ background: var(--dot-bg-elev-2);
311
+ box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.5),
312
+ 0 0 0 1px rgba(126, 231, 135, 0.08) inset;
313
+ }
314
+ .md-typeset .grid.cards > :is(ul, ol) > li:hover::before {
315
+ opacity: 1;
316
+ }
317
+ .md-typeset .grid.cards > :is(ul, ol) > li > :first-child {
318
+ margin-top: 0;
319
+ }
320
+ .md-typeset .grid.cards > :is(ul, ol) > li strong {
321
+ color: var(--dot-green-bright);
322
+ font-weight: 600;
323
+ font-size: 1rem;
324
+ display: block;
325
+ margin-bottom: 0.4rem;
326
+ }
327
+ .md-typeset .grid.cards > :is(ul, ol) > li .twemoji,
328
+ .md-typeset .grid.cards > :is(ul, ol) > li svg {
329
+ color: var(--dot-green);
330
+ fill: var(--dot-green);
331
+ height: 1.4rem;
332
+ width: 1.4rem;
333
+ margin-bottom: 0.6rem;
334
+ }
335
+
336
+ /* -- hero banner (used by landing page) ----------------------------------- */
337
+ .dot-hero {
338
+ padding: 3rem 0 2.4rem;
339
+ margin: -1.6rem -0.8rem 2.4rem;
340
+ text-align: center;
341
+ border-bottom: 1px solid var(--dot-border);
342
+ position: relative;
343
+ background: radial-gradient(
344
+ ellipse 60% 100% at 50% 0%,
345
+ rgba(126, 231, 135, 0.08),
346
+ transparent 70%
347
+ );
348
+ }
349
+ .dot-hero h1 {
350
+ font-size: 3rem;
351
+ line-height: 1.05;
352
+ margin-bottom: 0.4em;
353
+ padding: 0;
354
+ border: none;
355
+ }
356
+ .dot-hero .tagline {
357
+ font-size: 1.1rem;
358
+ color: var(--dot-fg-muted);
359
+ max-width: 40rem;
360
+ margin: 0 auto 1.4rem;
361
+ }
362
+ .dot-hero .buttons {
363
+ display: flex;
364
+ gap: 0.6rem;
365
+ justify-content: center;
366
+ flex-wrap: wrap;
367
+ }
368
+ .dot-hero .buttons a {
369
+ display: inline-flex;
370
+ align-items: center;
371
+ gap: 0.4rem;
372
+ padding: 0.6rem 1.1rem;
373
+ border-radius: 8px;
374
+ font-weight: 500;
375
+ font-size: 0.9rem;
376
+ text-decoration: none;
377
+ border: 1px solid var(--dot-border-strong);
378
+ color: var(--dot-fg);
379
+ transition: all 160ms ease;
380
+ }
381
+ .dot-hero .buttons a.primary {
382
+ background: var(--dot-green);
383
+ color: var(--dot-bg);
384
+ border-color: var(--dot-green);
385
+ font-weight: 600;
386
+ }
387
+ .dot-hero .buttons a.primary:hover {
388
+ background: var(--dot-green-bright);
389
+ border-color: var(--dot-green-bright);
390
+ transform: translateY(-1px);
391
+ }
392
+ .dot-hero .buttons a:not(.primary):hover {
393
+ border-color: var(--dot-green);
394
+ color: var(--dot-green-bright);
395
+ }
396
+
397
+ /* -- search --------------------------------------------------------------- */
398
+ .md-search__form {
399
+ background: var(--dot-bg-elev);
400
+ border: 1px solid var(--dot-border);
401
+ border-radius: 8px;
402
+ }
403
+ .md-search__form:hover,
404
+ .md-search__input:focus + .md-search__icon,
405
+ .md-search__form:focus-within {
406
+ border-color: var(--dot-green);
407
+ background: var(--dot-bg-elev-2);
408
+ }
409
+ .md-search__input {
410
+ color: var(--dot-fg);
411
+ }
412
+ .md-search__input::placeholder {
413
+ color: var(--dot-fg-subtle);
414
+ }
415
+
416
+ /* -- footer --------------------------------------------------------------- */
417
+ .md-footer {
418
+ border-top: 1px solid var(--dot-border);
419
+ }
420
+ .md-footer-meta {
421
+ background: var(--dot-bg);
422
+ border-top: 1px solid var(--dot-border);
423
+ }
424
+ .md-copyright {
425
+ color: var(--dot-fg-subtle);
426
+ font-size: 0.72rem;
427
+ }
428
+
429
+ /* -- scrollbar (webkit) --------------------------------------------------- */
430
+ ::-webkit-scrollbar {
431
+ width: 10px;
432
+ height: 10px;
433
+ }
434
+ ::-webkit-scrollbar-track {
435
+ background: transparent;
436
+ }
437
+ ::-webkit-scrollbar-thumb {
438
+ background: var(--dot-border-strong);
439
+ border-radius: 8px;
440
+ border: 2px solid var(--dot-bg);
441
+ }
442
+ ::-webkit-scrollbar-thumb:hover {
443
+ background: var(--dot-green-dim);
444
+ }
@@ -70,7 +70,7 @@
70
70
  <!-- New prompt -->
71
71
  <text x="40" y="405" fill="#a6e3a1">&#10148;</text>
72
72
  <text x="60" y="405" fill="#cdd6f4">~/.dotfiles</text>
73
- <text x="170" y="405" fill="#f5c2e7">on master</text>
73
+ <text x="170" y="405" fill="#f5c2e7">on main</text>
74
74
  <rect x="275" y="393" width="8" height="16" fill="#cdd6f4">
75
75
  <animate attributeName="opacity" values="1;0;1" dur="1s" repeatCount="indefinite" />
76
76
  </rect>