// content.jsx — All user-facing copy in one place.
//
// Rules (see INVARIANTS.md INV-001):
//   - Write what something IS. Not what it "empowers" or "delivers."
//   - One clear sentence beats three vague ones.
//   - No marketing-speak. If it sounds like an app store description, rewrite it.

const COPY = {

  // ── Navigation ──────────────────────────────────────────────────────────────
  nav: {
    appName: 'Chesswarp',
    version: 'v0.4',
    progressLabel: "Today's reading",
    progressLesson: 'Lesson 7 · The Promise of the f5 Square',
    routes: {
      home:       { label: 'Today',      subtitle: 'home'      },
      onboarding: { label: 'Welcome',    subtitle: 'onboarding'},
      lesson:     { label: 'Lesson',     subtitle: 'sequence'  },
      puzzle:     { label: 'Study',      subtitle: 'position'  },
      hero:       { label: 'Piece room', subtitle: 'deep dive' },
      tension:    { label: 'Tension',    subtitle: 'explorer'  },
      targets:    { label: 'Targets',    subtitle: 'weakest piece' },
      vectors:    { label: 'Vectors',    subtitle: 'how pieces coordinate' },
      overload:   { label: 'Overload',   subtitle: 'too many jobs' },
      ghost:      { label: 'Ghost route', subtitle: 'route the piece' },
      play:       { label: 'Play',       subtitle: 'continue vs engine' },
    },
  },

  // ── Onboarding ───────────────────────────────────────────────────────────────
  onboarding: {
    steps: [
      {
        kicker: 'A new way to read the board',
        title: 'Welcome to Chesswarp.',
        body: 'Most chess apps grade you. Chesswarp shows you. Every position has invisible forces: pressure, tension, illumination. We draw them for you.',
      },
      {
        kicker: 'Piece-centric study',
        title: 'The piece, not the puzzle.',
        body: 'You will not be asked to find moves. You will be asked to read pieces. Which one is doing the work? Which one is overloaded? Which one is just resting?',
      },
      {
        kicker: 'Slow looking',
        title: 'Sit with each board.',
        body: 'Lessons unfold one observation at a time. Heatmap, then hero piece, then trajectory, then tension. Each layer is added only when you have looked enough.',
      },
    ],
    buttons: {
      continue: 'Continue',
      back: '← Back',
      enter: 'Enter the studio →',
    },
    knightLabel: 'N · Knight · F3',
  },

  // ── Home ─────────────────────────────────────────────────────────────────────
  home: {
    heroCopy: {
      kicker: 'Studio open',
      subhead: 'Take your time. Each room teaches one small thing well.',
    },
    todaySection: {
      kicker: 'On view today',
    },
    exhibits: [
      {
        num: '01',
        room: 'Lesson',
        title: 'The Promise of the f5 Square',
        body: 'Six observations. A knight finds its calling. About eight minutes.',
        tag: '3 of 6 read',
        tone: 'brass',
        route: 'lesson',
      },
      {
        num: '02',
        room: 'Tension',
        title: 'The thread under strain',
        body: 'One overload, in a position you can rotate around. Trust the line, then look closer.',
        tag: 'New',
        tone: 'sienna',
        route: 'tension',
      },
      {
        num: '03',
        room: 'Piece room',
        title: 'A close look at Nf3',
        body: 'Five factors that make this knight worth +0.87. Pull each card and read the back.',
        tag: 'Featured',
        tone: 'celadon',
        route: 'hero',
      },
    ],
    enterRoom: 'Enter the room →',
    resumeSection: {
      kicker: 'Position study',
      noProgressTitle: 'Start your first lesson',
      noProgressNote: 'Pick any position from the catalog.',
      resumeTitle: 'Pick up where you left off',
      resumeButton: 'Return to the lesson',
    },
    collectionSection: {
      kicker: 'Your collection',
      title: "Pieces you've sat with",
      noProgressNote: 'Complete a lesson to track your progress.',
    },
  },

  // ── Layer toggles (shared across Lesson and Study screens) ────────────────
  layers: {
    heatmap:    'Heatmap',
    hero:       'Hero',
    trajectory: 'Trajectory',
    tension:    'Tension',
  },

  // ── Lesson ───────────────────────────────────────────────────────────────────
  lesson: {
    header: 'Lesson 7 · The Promise of the f5 Square',
    observationLabel: (n) => `Observation ${n}`,
    layersLabel: 'Layers in this step',
    buttons: {
      back: '← Back',
      continue: 'Continue →',
      done: 'Lesson complete',
    },
  },

  // ── Study / Puzzle ────────────────────────────────────────────────────────
  puzzle: {
    topbarKicker: 'Position · Karpov, Spassky 1973',
    topbarTitle: 'A knight in search of an outpost',
    sideToMove: 'White to move',
    coachKicker: 'Coaching · Aria',
    coachTitle: 'Walk through with me',
    selectionHint: 'Click any piece to read its influence.',
    evalLabel: 'Position evaluation',
    evalValue: '+1.42',
    evalSub: 'white · clearly better',
    commentary: [
      {
        anchor: 'f3',
        mood: 'curious',
        text: "Start with the knight. It doesn't look like much yet, but every other plan on the board flows through it.",
      },
      {
        anchor: 'e5',
        mood: 'warning',
        text: 'Now look at e5. One defender: the c6 knight. Two attackers: d4 pawn and your f3 knight. This is a thread under strain.',
      },
      {
        anchor: 'h4',
        mood: 'curious',
        text: 'Imagine Nh4 next move. Awkward-looking, but read what it threatens.',
      },
      {
        anchor: 'f5',
        mood: 'discovery',
        text: "Nf5. A strong outpost — Black would need to push e6 or g6 to challenge it, and both weaken the king. The knight has found its calling.",
      },
    ],
  },

  // ── Hero Piece / Piece Room ───────────────────────────────────────────────
  hero: {
    topbarKicker: 'Piece room · Hero piece',
    topbarTitle: 'Nf3 · +0.87',
    badge: 'Featured today',
    pieceLabel: 'Knight · White · f3',
    shapLabel: 'SHAP contribution',
    quote: '"A piece worth more than it currently costs."',
    stats: {
      mobility: { label: 'Mobility',          value: '7 / 8'    },
      defenders: { label: 'Defenders',         value: '2'        },
      attackers: { label: 'Attackers',         value: '0'        },
      tempoToOutpost: { label: 'Tempo to outpost', value: '2 moves' },
    },
    factorsSectionKicker: 'Pull each card to read the back',
    factorsSectionTitle: 'Five reasons this knight is worth so much.',
    sumLabel: 'Sum of factors',
  },

  // ── Tension Explorer ─────────────────────────────────────────────────────
  tension: {
    topbarKicker: 'Tension · find the overload',
    topbarTitle: 'Where is the position quietly breaking?',
    listSectionKicker: 'On this board',
    listSectionTitle: 'Threads under strain',
    overloadedLabel: 'Overloaded',
    balancedLabel: 'Just balanced',
    howToReadTitle: 'How to read this',
    howToReadBody: "A thread is taut when load equals support. It frays when load exceeds support. Don't look for tactics. Look for strain.",
    defenderLabel: (sq) => `Defender · ${sq.toUpperCase()}`,
    strainLabel: 'Strain reading',
    attackersLabel: (n) => `Attackers · ${n}`,
    supportersLabel: (n) => `Supporters · ${n}`,
    strainOverloaded: 'Frayed. White can pile and Black cannot match.',
    strainBalanced: 'Holding. But one mis-step and the thread snaps.',
    breakdownTitleOverloaded: (sq) => `The strain at ${sq}`,
    breakdownTitleBalanced: 'Just holding',
  },

  // ── Targets (vulnerable piece scanner) ───────────────────────────────
  targets: {
    topbarKicker: 'Targets · who falls first',
    topbarTitle: 'The weakest piece on the board',
    listKicker: 'Ranked by vulnerability',
    listTitle: 'Targets',
    howToReadTitle: 'How to read this',
    howToReadBody: 'A piece is vulnerable when its defenders are not really defending — pinned, overworked, or about to be removed by force. Pressure is not the same as a target. This room asks: if I lose a tempo, which of my pieces falls first?',
    sideToggleLabel: 'View',
    sideLabels: { attack: 'Their pieces', defend: 'My pieces' },
    classLabels: {
      stable: 'Stable',
      under_tension: 'Under tension',
      vulnerable: 'Vulnerable',
      hanging: 'Hanging',
    },
    classBlurbs: {
      stable: 'No attackers, or defenders comfortably cover the count.',
      under_tension: 'Contested, but the defenders hold up. No clear tactic wins it.',
      vulnerable: 'A real weakness. The count is unfavorable or a defender is unreliable.',
      hanging: 'Falls to a forcing move, or sits with no defender at all.',
    },
    breakdownTitle: (sq) => `Targeting ${sq}`,
    factorsLabel: 'Why',
    attackersLabel: (n) => `Attackers · ${n}`,
    defendersLabel: (n) => `Defenders · ${n}`,
    unreliableLabel: 'Defenders that do not defend',
    emptyState: 'No vulnerability analysis is available for this position.',
    exerciseKicker: 'Exercise',
    exerciseTitle: 'Find the weakest piece',
    exerciseSubtitle: 'Click any piece. Compare your guess against the analysis.',
    exerciseCorrect: (sq) => `Yes. The piece on ${sq} is the weakest target.`,
    exerciseClose: (theirs, correct) => `${theirs} is under tension but not the weakest. The piece on ${correct} is the real target.`,
    exerciseWrong: (theirs, correct) => `${theirs} is well defended. The weakest piece is on ${correct}.`,
    exerciseEmpty: 'No clear weakest piece in this position. Try the next one.',
    nextButton: 'Next position →',
    modeBrowse: 'Browse',
    modeExercise: 'Exercise',
  },

  // ── Attack Vectors ──────────────────────────────────────────────────
  attackVectors: {
    topbarKicker: 'Vectors · how pieces coordinate',
    topbarTitle: 'Where attacks come together',
    listKicker: 'Detected on this board',
    listTitle: 'Vectors',
    filterAll: 'All',
    filterConvergent: 'Convergent',
    filterBattery: 'Batteries',
    filterMating: 'Mating nets',
    noVectors: 'No coordination of this type on this board.',
    howToReadTitle: 'How to read this',
    howToReadBody: 'Convergent: two or more pieces bear on the same target. Battery: a sliding piece backs another along a ray. Mating net: the enemy king has run out of squares. Hover or click an entry to see its arrows.',
    selectPrompt: 'Pick a vector to see how the pieces line up.',
    attackersLabel: (n) => `Attackers · ${n}`,
    typeBlurbs: {
      convergent_attack: 'Multiple pieces aim at one target. If the defender count cannot match, the target falls.',
      battery: 'A sliding piece sits behind a friend on the same ray. The rear piece extends the threat without moving.',
      mating_net_candidate: 'The enemy king has zero or one safe square left. Verify with the engine before calling it mate.',
    },
    matingNetCaveat: 'This is a candidate signal, not a proof. Some "trapped" kings still have a defensive resource a static scan misses.',
    emptyState: 'No vector data is available for this position.',
  },

  // ── Overloaded Defender ──────────────────────────────────────────
  overload: {
    topbarKicker: 'Overload · too many jobs',
    topbarTitle: 'Defenders that cannot cover everything',
    listKicker: 'Detected on this board',
    listTitle: 'Overloaded defenders',
    pinnedTag: 'Pinned + overloaded',
    overloadedTag: 'Overloaded',
    pinnedTitle: 'Pinned and overloaded',
    overloadedTitle: 'Overloaded',
    pinnedBlurb: 'This piece is the sole defender of two attacked friendlies and is also pinned. It cannot move to recapture without losing more.',
    overloadedBlurb: 'This piece is the sole defender of two attacked friendlies. If it moves to cover one, the other falls.',
    jobsLabel: (n) => `Jobs · ${n}`,
    jobsShort: 'jobs',
    ideaLabel: 'Idea',
    ideaPinned: 'Hit the pinned defender directly. It cannot move without exposing its king, so it cannot trade itself out.',
    ideaDeflect: 'Force this piece to choose. Attack one of its defended targets with tempo, or capture/deflect the defender itself.',
    selectPrompt: 'Click a defender to see what it is trying to hold together.',
    howToReadTitle: 'How to read this',
    howToReadBody: 'A defender is overloaded when it is the only thing holding up two or more pieces under attack. Pinned + overloaded is the strongest pattern: the piece cannot even trade itself off to save material.',
    none: 'No overloaded defenders in this position.',
    emptyState: 'No overload analysis is available for this position.',
  },

  // ── Ghost Routes ──────────────────────────────────────────────────
  ghostRoutes: {
    topbarKicker: 'Ghost route · route the piece',
    topbarTitle: 'Move the knight to its target square',
    listKicker: 'Exercise',
    listTitle: 'Ghost route',
    prompt: (from, to) => `Route the knight from ${from} to ${to}. Click reachable squares one hop at a time.`,
    optimalLabel: 'Shortest route',
    yoursLabel: 'Your hops',
    correctOptimal: (n) => `Reached the target in ${n} ${n === 1 ? 'hop' : 'hops'} — that is the shortest path.`,
    correctNotOptimal: (n, opt, path) => `Reached the target in ${n} hops. Shortest is ${opt}: ${path.join(' → ')}.`,
    invalidHop: (sq) => `${sq} is not a knight move away from the current square.`,
    blockedByOwn: (sq) => `${sq} has one of your own pieces. Pick another square.`,
    safeStep: (sq) => `${sq} is safe. Keep going.`,
    steppedOnUnsafe: (sq) => `${sq} is attacked by an enemy piece. The knight survives this turn, but the route runs through danger.`,
    reset: 'Reset',
    legendKicker: 'Legend',
    legendTitle: 'What the dots mean',
    legendSafe: 'Safe next-hop',
    legendUnsafe: 'Attacked by enemy',
    legendTarget: 'Target square',
    howToReadTitle: 'How to read this',
    howToReadBody: 'Green dots mark squares the knight can reach in one hop and where no enemy piece attacks. Red dots mark reachable squares that are under enemy fire. The dashed outline marks the target.',
    emptyState: 'Ghost routes only run for knight heroes with a multi-hop trajectory. Try another lesson.',
  },

};

window.COPY = COPY;
