{
  description = "Nix flake for the tui-pages website — static HTML/CSS/SVG, CDN-loaded JS";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    # NOTE: No rust-overlay — this is a pure-static site, no Rust toolchain required.
  };

  outputs = { self, nixpkgs, ... }:
    let
      systems = [
        "x86_64-linux"
        "aarch64-linux"
        "x86_64-darwin"
        "aarch64-darwin"
      ];
      forAllSystems = f: nixpkgs.lib.genAttrs systems f;

      version = "0.1.0";
    in
    {
      # `nix fmt` — format this flake
      formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixpkgs-fmt);

      # -------------------------------------------------------------------------
      # packages.<system>.default
      #
      # The whole website as a single derivation. `nix build` produces ./result/
      # containing the static files, ready to:
      #   - serve with any static file server, or
      #   - upload to Netlify / Cloudflare Pages / GitHub Pages / S3 / etc.
      # -------------------------------------------------------------------------
      packages = forAllSystems (system:
        let
          pkgs = nixpkgs.legacyPackages.${system};
          src = ./.;
        in {
          default = pkgs.stdenvNoCC.mkDerivation {
            pname = "tui-pages-website";
            inherit version;
            inherit src;

            dontBuild = true;

            installPhase = ''
              runHook preInstall
              mkdir -p $out
              # Use cp -R with --no-preserve=mode so the read-only Nix-store
              # permissions don't leak into $out (a few hosts reject the
              # resulting 0444 file modes when serving).
              cp -R --no-preserve=mode ${src}/. $out/
              chmod -R u+w $out
              runHook postInstall
            '';

            meta = with pkgs.lib; {
              description = "Static website for the tui-pages Rust crate";
              homepage = "https://tui-pages.dev";
              license = licenses.mit;
              platforms = platforms.unix;
            };
          };
        });

      # -------------------------------------------------------------------------
      # apps.<system>.serve
      #
      # `nix run .#serve` — build the site and boot `python3 -m http.server`
      # against the built result. Honours $PORT (defaults to 8000).
      # -------------------------------------------------------------------------
      apps = forAllSystems (system:
        let
          pkgs = nixpkgs.legacyPackages.${system};
          site = self.packages.${system}.default;
        in {
          serve = {
            type = "app";
            program = toString (pkgs.writeShellScript "tui-pages-web-serve" ''
              echo "Serving ${site} on http://localhost:''${PORT:-8000}"
              cd ${site}
              exec ${pkgs.python3}/bin/python3 -m http.server "''${PORT:-8000}"
            '');
            meta = with pkgs.lib; {
              description = "Build the tui-pages website and serve it on $PORT (default 8000)";
              platforms = platforms.unix;
            };
          };
        });

      # -------------------------------------------------------------------------
      # devShells.<system>.default
      #
      # `nix develop` — everything the Makefile, the README, and future
      # workflows need. No Rust toolchain by design.
      # -------------------------------------------------------------------------
      devShells = forAllSystems (system:
        let pkgs = nixpkgs.legacyPackages.${system};
        in {
          default = pkgs.mkShell {
            packages = with pkgs; [
              # --- Build / serve / validate (the Makefile uses these) ----
              gnumake
              python3
              gawk
              gnused
              gnugrep
              coreutils

              # --- HTML validation (optional, for the tidy check) --------
              html-tidy

              # --- Smoke-test the local server ---------------------------
              curl

              # --- Record TUI demos (used to replace the SVG mockups) ----
              asciinema

              # --- Generate the animated ASCII background from a video.
              #     `make video NAME=<name>` extracts frames from video/<name>.mp4
              #     with ffmpeg at 12 fps, runs chafa on each to get 80x24 ASCII,
              #     and bundles them into static/js/mountain.js for the cycler.
              ffmpeg
              chafa
              # --- `make video` also needs python3 (already in the default set)
              # to run tools/build_mountain_js.py.

              # --- Optional: standalone Tailwind CLI for production CSS --
              # Uncomment if you switch from the Play CDN to a precompiled stylesheet.
              # nodejs
            ];

            shellHook = ''
              # Some distros ship `python` but not `python3`. Make the
              # `python3` invocation in the Makefile portable.
              if ! command -v python3 >/dev/null 2>&1 && command -v python >/dev/null 2>&1; then
                alias python3=python
              fi

              cat <<'EOF'
              ┌──────────────────────────────────────────────────────────────┐
              │ tui-pages website dev shell                                  │
              │                                                              │
              │   make serve         python3 -m http.server 8000             │
              │   make size          report file sizes                       │
              │   make validate      HTML tag balance check                  │
              │   make tidy          run html-tidy on every .html            │
              │   make video NAME=foo  regenerate the ASCII background from   │
              │                       video/foo.mp4 (12 fps, 80x24 ASCII)      │
              │                                                              │
              │   asciinema rec static/demos/intro.cast   record a demo      │
              │   make video-list     show available videos in video/        │
              │   make video-frames   extract + chafa frames for $NAME       │
              │   make video-bundle   bundle frames into mountain.js         │
              │                                                              │
              │   nix build          build site → ./result/                  │
              │   nix run .#serve    build + serve (honours $PORT)           │
              │   nix fmt            format this flake                       │
              │   nix flake check    run all checks                          │
              └──────────────────────────────────────────────────────────────┘
              EOF
            '';
          };
        });

      # -------------------------------------------------------------------------
      # checks.<system>.tidy
      #
      # HTML sanity check using tidy. Non-blocking — prints warnings to the
      # build log, never fails. `nix flake check` runs this.
      # -------------------------------------------------------------------------
      checks = forAllSystems (system:
        let
          pkgs = nixpkgs.legacyPackages.${system};
          site = self.packages.${system}.default;
        in {
          tidy = pkgs.runCommand "tui-pages-website-html-check"
            {
              nativeBuildInputs = [ pkgs.html-tidy ];
            } ''
              cd ${site}
              for f in *.html; do
                echo "─── $f ───"
                ${pkgs.html-tidy}/bin/tidy -e -q -utf8 "$f" 2>&1 | head -20 || true
              done
              touch $out
            '';
        });
    };
}
