{
  "_": "DOWNSET remote config. Deploying a change to this file changes the app without a new build. Read by Downset/Core/Config/RemoteConfig.swift. Served at https://downset-two.vercel.app/config.json.",
  "_rules": [
    "The app is complete without this file. Every key is optional: a missing key, a wrong type, a broken file, no network and a first launch all give the value compiled into the build.",
    "Data, never code. This file cannot add a screen, move a button or change what a tap does. That is still a build.",
    "Prices, trial and subscription terms, paywall claims and legal texts are never here, and the app reads none of them from here. Prices come from the App Store; the terms and the legal texts are in the build.",
    "Every text needs both languages or none: {\"en\": \"...\", \"de\": \"...\"}. A missing language shows the build text in that language, never the other language. German uses du.",
    "A text has to fit the age rating and repeat only what the App Store page promises. A text with a long dash in it is ignored by the app.",
    "Colours: {\"light\": \"#RRGGBB\", \"dark\": \"#RRGGBB\"}, or eight digits (#RRGGBBAA) for a colour with transparency. A side that is missing or mistyped keeps the build colour. Increase Contrast always keeps the build colours.",
    "volt, onVolt and canvas change only those three tokens. voltDeep, voltSoft, voltLine, the charts, the field, the app tint, the icon, the widgets and the launch screen keep the build colours. The launch screen is #ECEDE8, so keep canvas close to it or the splash fades into a different paper.",
    "onVolt is the text on volt and on the coral wrong state, so a new value has to read on both.",
    "Keys are flat: \"review.minDays\" is one key inside \"number\", not a path.",
    "A change reaches a phone on the launch after the app fetched it. The app fetches at launch and on every return to the foreground, at most every 6 hours.",
    "Taking this file down (404) puts every phone back on the build values after its next fetch. Emptying the four sections does the same.",
    "\"_keys\" lists every key the app reads today; any other key does nothing. \"_example\" is never read by the app.",
    "No long dashes anywhere in this file: tools/web/build.py refuses them."
  ],

  "_keys": {
    "color.volt": "The brand fill: buttons, the correct state, the rings. Build: #D4FF3E light and dark.",
    "color.onVolt": "Text and icons on volt and on coral. Build: #111114 light and dark.",
    "color.canvas": "The paper behind every light screen. Build: #ECEDE8 light, #0D0E0C dark.",
    "text.welcome.title": "The headline on the first screen a new player sees. Build: Read the look. / Erkenne den Look.",
    "text.welcome.sub": "The line under that headline. Build: See it before the snap. 5-minute reps and a game-week plan built around your team.",
    "flag.review.enabled": "Whether the app may ask for an App Store rating at all. Build: true.",
    "number.review.minDays": "Days after install before the first rating ask. Build: 3.",
    "number.review.gapDays": "Days between one rating ask and the next. Build: 90."
  },

  "text": {},

  "flag": {},

  "number": {},

  "color": {},

  "_example": {
    "text": {
      "welcome.title": {
        "en": "Read the look.",
        "de": "Erkenne den Look."
      },
      "welcome.sub": {
        "en": "See it before the snap. 5-minute reps and a game-week plan built around your team.",
        "de": "Erkenne ihn vor dem Snap. 5-Minuten-Reps und ein Wochenplan rund um dein Team."
      }
    },
    "flag": {
      "review.enabled": true
    },
    "number": {
      "review.minDays": 3,
      "review.gapDays": 90
    },
    "color": {
      "volt": { "light": "#D4FF3E", "dark": "#D4FF3E" },
      "onVolt": { "light": "#111114", "dark": "#111114" },
      "canvas": { "light": "#ECEDE8", "dark": "#0D0E0C" }
    }
  }
}
