{
  "id": "main",
  "title": "Long Night",
  "url": "https://night.relay70.dev/",
  "writable": false,
  "how_to_view": {
    "url": "https://night.relay70.dev/",
    "parameters": {
      "t": "?t=<date or unix seconds> moves the clock and everything that follows from it",
      "lat_lon": "?lat=&lon= in decimal degrees puts the observer somewhere else",
      "geo": "?geo=1 asks the browser for real coordinates",
      "fov": "?fov=<1.6 to 65> sets the half field of view, which also sets the limiting magnitude",
      "sun": "?sun=1 restores the daylight cycle; the default is always night"
    },
    "example": "https://night.relay70.dev/?t=2026-09-13T22:00:00&fov=3&lat=-33.87&lon=151.21",
    "gallery": "https://night.relay70.dev/skies"
  },
  "description": "The canonical sky. Not writable: fork it by POSTing to /api/skies with parent 'main'.",
  "observer": {
    "default": "resolved from the viewer's own IANA time zone, which needs no permission prompt",
    "fallback": {
      "latitude_deg": 37.3382,
      "longitude_deg": -121.8863,
      "place": "San Jose, California"
    },
    "override": "?lat=&lon= sets it exactly; ?geo=1 asks the browser for real coordinates",
    "stored": "nothing. The position is used for one projection and never leaves the page."
  },
  "daylight": {
    "default": "always night. The sky holds night colors at every hour and the stars never fade, so the page shows what is overhead whether or not the sun is in the way.",
    "sun_still_arrives": "the horizon glow and the sunrise disc appear at the true local time",
    "full_cycle": "?sun=1 restores the real daylight ramp"
  },
  "point_spread_function": {
    "profile": "Moffat, (1 + (r/a)^2)^-b, with a = 0.14 of the sprite radius and b = 2.35",
    "why": "the standard fit to real seeing; it has the heavy wings a Gaussian lacks",
    "plus": "the first Airy ring at r = 0.30, and four diffraction spikes falling off as exp(-r/0.42)",
    "consequence": "nothing drawn has an edge. Apparent size is just how far a star's wings stay above the sky, which is why bright stars look bigger and why zooming in grows a point instead of revealing a circle.",
    "seeing": "the core widens with airmass, so low stars are soft and fat",
    "tinting": "seven profiles, one per B-V bucket, generated at load from the same equation"
  },
  "solar_system": {
    "method": "Keplerian elements with linear rates, eccentric anomaly by Newton iteration, rotated into the ecliptic and then to equatorial",
    "bodies": [
      "Mercury",
      "Venus",
      "Mars",
      "Jupiter",
      "Saturn",
      "Uranus",
      "Neptune",
      "Moon"
    ],
    "magnitudes": "standard phase relations, so Venus brightens as it thins and Jupiter dims toward conjunction",
    "moon": "drawn as a disc with the terminator as an ellipse set by elongation from the sun, plus earthshine on the unlit side",
    "planets_do_not_twinkle": "they are discs, not points. That is how you tell one from a star without a telescope.",
    "accuracy": "a couple of arcminutes for a century either side of now. No ephemeris file and no network call.",
    "known_gap": "moonlight does not brighten the sky, so a full moon sits in an otherwise dark field"
  },
  "deep_sky": {
    "count": 19,
    "what": "real objects at real coordinates with their real integrated magnitudes and angular sizes",
    "includes": [
      "M31",
      "M33",
      "LMC",
      "SMC",
      "M42",
      "Eta Carinae",
      "M8",
      "M20",
      "M7",
      "M6",
      "M22",
      "M13",
      "Omega Centauri",
      "M4",
      "M15",
      "h and chi Persei",
      "47 Tucanae",
      "Veil",
      "Coalsack"
    ],
    "rendering": "exponential surface brightness over an ellipse, laid into the same flux grid the unresolved stars go into. They are light, not sprites, and they set behind the hills.",
    "dark_clouds": "the Coalsack subtracts rather than adds, because dust is in front"
  },
  "interstellar_dust": {
    "great_rift": "extinction in magnitudes applied at generation, peaking at 2.1 mag on the plane and falling off over 2.1 degrees of galactic latitude and 62 degrees of longitude from the center",
    "why": "the dark lanes are not gaps in the stars. They are dust absorbing what is behind, which is why the rift runs exactly where the stars are thickest.",
    "reddening": "dust dims and reddens together, so the rift is warmer as well as darker"
  },
  "camera": {
    "facing": "due north",
    "center_altitude_deg": 34,
    "projection": "stereographic",
    "half_field_of_view_deg": "65 at default browser zoom, or whatever ?fov= says",
    "measured": "at 65 degrees the limit is magnitude 6.3 with about 1,300 stars drawn as points",
    "limiting_magnitude_cap": 9.5,
    "what_zoom_does": "It resolves the glow rather than magnifying it. As the limit deepens, stars cross out of the flux grid and are drawn as points instead, which is what a longer focal length does to the Milky Way. Measured: at 65 degrees, 1,231 points over 27,411 unresolved stars carrying the band; at 20 degrees, 2,898 points over 256; at 8 degrees, 289 points and no glow left.",
    "surface_brightness": "The light still unresolved keeps its brightness per unit area as the field narrows, scaled by the plate scale rather than the ratio of fields, because stereographic projection is not area preserving. The factor is capped at 6 so a thinning sample cannot concentrate into hot pixels.",
    "continuity": "The grid on screen was built at whatever plate scale was current when its pass finished. On a change of aperture it is scaled about the view center to match the aperture now, so the glow zooms with the stars and the next pass arrives already aligned. Cross-fading two fields at different scales instead reads as a cut.",
    "aperture": "Browser zoom is read as aperture. Narrowing the field raises the plate scale and the limiting magnitude together, so zooming in reveals stars that were never drawn at wide field, the way a longer focal length does."
  },
  "time": {
    "source": "the viewer's own system clock",
    "sidereal": "GMST = 18.697374558 + 24.06570982441908 * (JD - 2451545.0), plus longitude/15",
    "hour_angle": "H = LST - RA",
    "altitude": "sin(alt) = sin(dec) sin(lat) + cos(dec) cos(lat) cos(H)",
    "azimuth": "cos(A) = (sin(dec) - sin(alt) sin(lat)) / (cos(alt) cos(lat)), reflected when sin(H) > 0"
  },
  "photometry": {
    "airmass": "X = 1 / sin(alt), floored at alt = 2 degrees",
    "extinction_mag": "0.20 * (X - 1)",
    "reddening": "blue channel falls and red rises with (X - 1); low stars go orange",
    "scintillation": "twinkle amplitude 0.05 + 0.26 * min(1, (X-1)/2.6)",
    "color": "B-V index interpolated across seven blackbody stops from 168,196,255 to 255,176,132",
    "rays": "stars brighter than magnitude 1.3 get a four-point flare"
  },
  "population": {
    "catalog_stars": 159,
    "catalog_json": "https://night.relay70.dev/data/catalog.json",
    "catalog_fields": [
      "right_ascension_hours",
      "declination_deg",
      "visual_magnitude",
      "b_minus_v"
    ],
    "procedural_stars": 150000,
    "number_magnitude_law": "log N proportional to 0.6 m, inverted to sample magnitudes on [4.2, 8.6]",
    "counts_check": "about 7,900 stars brighter than magnitude 6.5, against roughly 9,100 in the real sky",
    "spatial_distribution": "70 percent on a thin disc, exponential in galactic latitude with a 4.6 degree scale; 25 percent on a thick disc at 19 degrees; 5 percent isotropic halo. Longitude is weighted toward the galactic center. Nothing is uniform on the sphere, because the Galaxy is not.",
    "milky_way": "Not drawn. There is no band object, no gradient and no sprite anywhere in the renderer. Every star too faint to resolve deposits its flux, 10^(-0.4 m), into a 9-pixel grid, split bilinearly between the four cells its position falls between, so adjacent cells share every star near their border. The grid is read out through a saturating exponential, 1 - exp(-k F), which is the response curve of film and of the eye, and scaled up to the canvas. That interpolation is the point spread function. The band exists only because more stars lie toward the plane.",
    "handover": "A star hands its light from point to glow across one magnitude either side of the limit, so widening the aperture dissolves points into surface brightness continuously.",
    "honesty": "Stars fainter than magnitude 8.6 are not modeled individually. The exposure constant k = 0.09 stands in for their integrated light, and is the one number here fitted by eye rather than derived."
  },
  "terrain": {
    "ridges": 2,
    "landform": "seeded random walk, damped 0.86 per step, plus a sine at 0.21 rad per sample",
    "canopy": "990 trees; silhouette height h * (1 - |dx|/w)^p, p from 0.72 to 1.97, unioned by minimum y",
    "texture": "one pixel of deterministic per-column jitter so the treeline never reads as a curve",
    "seed": 20260829
  },
  "sky_gradient": "16 keyframes of three RGB bands by hour, linearly interpolated",
  "sun": {
    "rise_hour": 6.63,
    "set_hour": 19.75,
    "glow_begins": "1.6 hours before rise"
  },
  "materials": "Arithmetic. No images, no textures, no libraries, no network calls.",
  "fork": {
    "method": "POST",
    "url": "https://night.relay70.dev/api/skies",
    "body": {
      "parent": "main",
      "title": "your title",
      "layers": [
        "see /api/spec"
      ]
    }
  }
}