# ╔═════════════════════════════════════════════════════════════════╗
# ║        UI SHOWCASE · JDR-Bot display modes                       ║
# ║                                                                 ║
# ║  showcase.yaml demonstrates the engine SYNTAX.                  ║
# ║  This one demonstrates the DISPLAY MODES (ui:) added in 4.13:   ║
# ║  the same game mechanics, adapted to each interface.            ║
# ║                                                                 ║
# ║  Every room is commented like a tutorial. Open this file next   ║
# ║  to the game to see "what produces what".                       ║
# ║                                                                 ║
# ║  On the menu:                                                    ║
# ║    🃏 cards        → a hand of cards (choice, event, action)     ║
# ║    🎴 cards (game) → War card mini-game (tileset + random draw)  ║
# ║    🗺️  deck         → a maze played by swiping the card           ║
# ║    📱 phone        → a smartphone with its mini-apps             ║
# ║    🖼️  fullscreen   → full-screen point & click                  ║
# ║                                                                 ║
# ║  Reminder: these modes only apply to web and desktop.           ║
# ║  On Discord and in the terminal, the game keeps its classic     ║
# ║  buttons (the modes are ignored without breaking anything).     ║
# ╚═════════════════════════════════════════════════════════════════╝


# ─────────────────────────────────────────────────────────────────
# TITLE + DESCRIPTION
# The title is shown at launch, the description on hovering the
# scenario card (and in the standalone export header).
# ─────────────────────────────────────────────────────────────────
title: "🎴 UI Showcase · display modes"
description: |
  A guided tour of JDR-Bot's display modes: cards, deck, phone and fullscreen. The engine stays the same, only the rendering changes. The comments give you the syntax to reuse each example in your own game.

# markdown: story → enables the narrative rendering (semantic blocks, airy text).
# This mode suits scenarios meant to be played, rather than raw tests.
markdown: story

# A home button always available at the top, handy to move between
# the demos without getting lost.
options:
  home: "🏠"


# ═════════════════════════════════════════════════════════════════
# CARD CONFIG (ui: cards mode)
# Declared once, at scenario level. It provides the "back" and the
# default style for ALL the cards in the game.
#   image        → default front of a card
#   back         → the reverse (visible on a hidden or flipped card)
#   color        → accent tint (border, shadow)
# A card can always override all of this locally (we do it below).
# ═════════════════════════════════════════════════════════════════
cards:
  back: /scenarios/images/showcase-ui/dos-cartes.png
  color: "#c0392b"


# ═════════════════════════════════════════════════════════════════
# PHONE SHAPE (ui: phone mode)
# portrait-start = we start in portrait, AND the shape picked by a
# room PERSISTS (-start suffix). This is what lets the phone's
# Settings menu change the shape durably: each button leads to a
# small room that sets shape: portrait/landscape/tablet. That pick
# is kept.
# (With -global, a room's shape would only last for its visit.)
# ═════════════════════════════════════════════════════════════════
phone_shape: portrait-start


# ═════════════════════════════════════════════════════════════════
# VARIABLES
# The War mini-game needs to count points and remember the drawn
# cards. They are initialized at launch.
# ═════════════════════════════════════════════════════════════════
vars:
  player_score: 0
  ai_score: 0
  round: 1
  player_card: 0    # value (0..12) of the picked card, set on click
  ai_card: 0        # value drawn by the computer
  player_suit: 0    # suit of the picked card (stored on click)
  ai_suit: 0        # suit of the computer's card
  char_dir: 1       # deck character facing (0=up 1=down 2=left 3=right)
  # Suit (0=♥ 1=♠ 2=♦ 3=♣) drawn at random for each card value when
  # entering the War room. The suit does not count toward the score.
  sg_a: 0
  sg_2: 0
  sg_3: 0
  sg_4: 0
  sg_5: 0
  sg_6: 0
  sg_7: 0
  sg_8: 0
  sg_9: 0
  sg_10: 0
  sg_j: 0
  sg_q: 0
  sg_k: 0
  # "Guess the number" mini-game (phone app, conversation screen).
  secret: 0         # the number to find, drawn on entry
  tries: 0          # number of attempts
  guess:
    value: 0
    repondre: true  # ← lets the player type the number directly (no command needed)
  # "Heads or tails" mini-game (phone app, photo screen).
  face: 0           # flip result (0 = heads, 1 = tails)
  # Quiz (phone app, notes screen).
  quiz_score: 0
  # Seek and click (fullscreen mode). One variable per object: it goes to 1
  # when you find it. It is what greys the object IN THE SCENE **and** its
  # twin IN THE LIST: both zones read the same variable.
  obj_socks: 0
  obj_plane: 0
  obj_spring: 0
  obj_windmill: 0
  obj_robot: 0
  found: 0          # counter of found objects (0..5), shown in the banner


rooms:

  # ═══════════════════════════════════════════════════════════════
  # home: the starting hall
  # Nothing special here: a classic room with choices. It only
  # serves as a hub toward each demo. Each demo will set ITS
  # display mode on ITS room (see "ui:" below).
  #
  # clear-hud: all → we clean the HUDs when coming back here.
  # Without it, the banner set by a demo (the Seek and click one,
  # for example) would stay displayed on top of the hall: a HUD
  # lives until it is removed, it does not vanish on room change.
  # ═══════════════════════════════════════════════════════════════
  - id: home
    clear-hud: all
    text: |
      ```narration
      Welcome. Here we are not testing a story but a **way of displaying** the game. Pick a demo: the scenery changes, the mechanics stay the same.
      ```
    choices:
      - button: "🃏 A hand of cards"
        to: cards_hand
      - button: "🎴 War (card mini-game)"
        to: war_reset
      - button: "🗺️ Maze (deck mode)"
        to: maze_sw
      - button: "📱 Smartphone (phone mode)"
        to: phone_hub
      - button: "🖼️ Seek and click (fullscreen mode)"
        to: seek


  # ═══════════════════════════════════════════════════════════════
  # cards_hand: ui: cards MODE, the basics
  #
  # The principle: in cards mode, ALL the room's buttons become
  # cards laid on a rail: moves, events and actions.
  # This room shows the three cases:
  #   • a card that NAVIGATES     (a classic choice)
  #   • a card that TRIGGERS      (an event, without leaving the room)
  #   • a card that ACTS          (an action, without leaving the room)
  #
  # Each card carries its own image via "card: image:". We pick from
  # a sheet of 52 cards cut as a tileset: the syntax
  # "file:13x4:column:row" takes ONE card from the sheet
  # (13 columns = A..K, 4 rows = ♥ ♠ ♦ ♣, indices start at 0).
  # ═══════════════════════════════════════════════════════════════
  - id: cards_hand
    ui: cards
    text: |
      ```narration
      Three cards lie in front of you. They do not all play the same role.
      ```

      ```system
      A♥: goes back to the hall (a plain move).
      2♠: fires an event (some text here, but it could be a trap).
      3♦: runs an action (it acts inside the room without moving you).
      ```

    # ── The card that TRIGGERS (event with button:) ───────────────
    # An event with "button:" does not run on its own: it waits to
    # be clicked. In cards mode, that button IS a card. After the
    # click, the event runs and you STAY in the room.
    events:
      - button: "2 of spades"
        card:
          image: "/scenarios/images/showcase-ui/cartes.png:13x4:1:1"
          title: "2 of spades"
          subtitle: "Event"
        text: |
          ```dialogue
          You fired an event. The card stays on the table: everything happens here, without changing room.
          ```

    # ── The card that ACTS (custom action with button:) ───────────
    # An action has a "verb" and a "target". Here the target is
    # fixed (diamond), so clicking the card is enough: nothing to
    # type. Like the event, the action acts and you stay in place.
    actions:
      - verb: flip
        target: diamond
        button: "3 of diamonds"
        card:
          image: "/scenarios/images/showcase-ui/cartes.png:13x4:2:2"
          title: "3 of diamonds"
          subtitle: "Action"
        success_text: |
          ```dialogue
          You ran an action. An event happens to you; an action, you make happen. The difference is mostly in the author's intent.
          ```

    # ── The card that NAVIGATES (classic choice) ──────────────────
    # The only one of the three that moves you to another room.
    # Here: back to the hall. The ♥ emoji in the label is just
    # for the example.
    choices:
      - button: "♥ Ace of hearts"
        to: home
        card:
          image: "/scenarios/images/showcase-ui/cartes.png:13x4:0:0"
          title: "Ace of hearts"
          subtitle: "Back to the hall"


  # ═══════════════════════════════════════════════════════════════
  # war: ui: cards MODE as a MINI-GAME
  #
  # Same display mode as cards_hand, but the cards serve a real
  # mechanic: a game of War against the computer.
  #
  # "random: 3" draws 3 cards AT RANDOM among the 13 declared
  # (one per value, Ace to King). The draw is frozen while you
  # stay in the room, redone on each round.
  #
  # Factorization trick: we do not declare all 52 cards, just the
  # 13 values. The SUIT (hearts/spades/diamonds/clubs) is drawn at
  # random on entry, one per card, and injected into the image
  # through a variable:
  #   image: "...cartes.png:13x4:COLUMN:{sg_x}"
  # The {sg_x} is resolved at display time: a card image accepts
  # variables, like images in text do. The suit does not break
  # ties (as in real War), so it is purely decorative: perfect
  # for a draw on entry.
  #
  # Rule: 3 cards face down, you pick one. The computer draws its
  # own. The highest card scores a point. First to 3 wins. (Ace
  # low, King high.)
  # ═══════════════════════════════════════════════════════════════
  - id: war
    ui: cards
    text: |
      ```system
      Round v_round_v · You v_player_score_v / v_ai_score_v Computer (first to 3)
      ```

      ```narration
      Three cards, face down. Pick one: the highest card wins.
      ```
    # A suit (0=♥ 1=♠ 2=♦ 3=♣) drawn at random for each value when
    # entering the room. Changes every round. The list under do:
    # is easier to read than gluing everything on one line with @@.
    events:
      - if: ~
        do:
          - "sg_a.=.%0:3"
          - "sg_2.=.%0:3"
          - "sg_3.=.%0:3"
          - "sg_4.=.%0:3"
          - "sg_5.=.%0:3"
          - "sg_6.=.%0:3"
          - "sg_7.=.%0:3"
          - "sg_8.=.%0:3"
          - "sg_9.=.%0:3"
          - "sg_10.=.%0:3"
          - "sg_j.=.%0:3"
          - "sg_q.=.%0:3"
          - "sg_k.=.%0:3"
    choices:
      # random: 3 → 3 cards among the 13 values, laid face down.
      # On click, the effect stores TWO things: the played value
      # (player_card) AND the suit of THAT card (player_suit ← its
      # drawn suit), to recover the picked card at resolution time.
      - random: 3
        choices:
          - button: "A"
            command: c_a
            to: round_result
            hidden: true
            effect:
              - "player_card.=.0"
              - "player_suit.=.v_sg_a_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:0:{sg_a}"
              title: "A"
          - button: "2"
            command: c_2
            to: round_result
            hidden: true
            effect:
              - "player_card.=.1"
              - "player_suit.=.v_sg_2_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:1:{sg_2}"
              title: "2"
          - button: "3"
            command: c_3
            to: round_result
            hidden: true
            effect:
              - "player_card.=.2"
              - "player_suit.=.v_sg_3_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:2:{sg_3}"
              title: "3"
          - button: "4"
            command: c_4
            to: round_result
            hidden: true
            effect:
              - "player_card.=.3"
              - "player_suit.=.v_sg_4_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:3:{sg_4}"
              title: "4"
          - button: "5"
            command: c_5
            to: round_result
            hidden: true
            effect:
              - "player_card.=.4"
              - "player_suit.=.v_sg_5_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:4:{sg_5}"
              title: "5"
          - button: "6"
            command: c_6
            to: round_result
            hidden: true
            effect:
              - "player_card.=.5"
              - "player_suit.=.v_sg_6_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:5:{sg_6}"
              title: "6"
          - button: "7"
            command: c_7
            to: round_result
            hidden: true
            effect:
              - "player_card.=.6"
              - "player_suit.=.v_sg_7_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:6:{sg_7}"
              title: "7"
          - button: "8"
            command: c_8
            to: round_result
            hidden: true
            effect:
              - "player_card.=.7"
              - "player_suit.=.v_sg_8_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:7:{sg_8}"
              title: "8"
          - button: "9"
            command: c_9
            to: round_result
            hidden: true
            effect:
              - "player_card.=.8"
              - "player_suit.=.v_sg_9_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:8:{sg_9}"
              title: "9"
          - button: "10"
            command: c_10
            to: round_result
            hidden: true
            effect:
              - "player_card.=.9"
              - "player_suit.=.v_sg_10_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:9:{sg_10}"
              title: "10"
          - button: "J"
            command: c_j
            to: round_result
            hidden: true
            effect:
              - "player_card.=.10"
              - "player_suit.=.v_sg_j_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:10:{sg_j}"
              title: "J"
          - button: "Q"
            command: c_q
            to: round_result
            hidden: true
            effect:
              - "player_card.=.11"
              - "player_suit.=.v_sg_q_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:11:{sg_q}"
              title: "Q"
          - button: "K"
            command: c_k
            to: round_result
            hidden: true
            effect:
              - "player_card.=.12"
              - "player_suit.=.v_sg_k_v"
            card:
              image: "/scenarios/images/showcase-ui/cartes.png:13x4:12:{sg_k}"
              title: "K"

  # ───────────────────────────────────────────────────────────────
  # round_result: resolving a round
  #
  # We arrive here with player_card already set (by the clicked
  # card). The 997 events are read top to bottom, and each one sees
  # the values left by the previous one. So we chain:
  #   1. the computer draws its card
  #   2. we display both cards (their values are up to date)
  #   3. we count the point
  #   4. if someone reaches 3 → end; otherwise next round
  #
  # ⚠️ Classic trap: an event's text displays the values BEFORE its
  # action. The computer's draw and the point counting are kept
  # separate from the display.
  # ───────────────────────────────────────────────────────────────
  - id: round_result
    ui: cards
    hide_input: false
    events:
      # 1. The computer draws its card: a value (0=Ace ... 12=King) and a suit.
      - if: ~
        do:
          - "ai_card.=.%0:12"
          - "ai_suit.=.%0:3"

      # 2. Display of both drawn cards. We pick the right tile from the
      #    tileset: column = the value, row = the SUIT stored on click
      #    for you (player_suit), drawn on the spot for the computer
      #    (ai_suit). The displayed card thus matches the one that
      #    was picked.
      # The images are NOT inside a ``` block: a semantic block expects
      # text, inserting images cuts it into pieces (orphan ``` marks
      # would show). So we put the label and the image side by side,
      # as plain text.
      - if: ~
        text: |
          **Your card** [[/scenarios/images/showcase-ui/cartes.png:13x4:{player_card}:{player_suit}]]
          **The computer's card** [[/scenarios/images/showcase-ui/cartes.png:13x4:{ai_card}:{ai_suit}]]

      # 3. Counting the point (only one branch is true).
      - if: "v_player_card_v > v_ai_card_v"
        do: "player_score.+.1"
        text: |
          ```dialogue
          You win the round.
          ```
      - if: "v_player_card_v < v_ai_card_v"
        do: "ai_score.+.1"
        text: |
          ```dialogue
          The computer wins the round.
          ```
      - if: "v_player_card_v = v_ai_card_v"
        text: |
          ```dialogue
          A tie: nobody scores, play it again.
          ```

      # 4. End of game or next round.
      #    The first true redirect event stops the following ones.
      - if: "v_player_score_v = 3"
        to: war_won
      - if: "v_ai_score_v = 3"
        to: war_lost
      # Otherwise: next round. We bump the counter and go again.
      - if: ~
        do: "round.+.1"
        to: war


  # ── War endings (local: we do not close the whole scenario) ──
  # These are plain result rooms with a way back. We could have
  # used end: victory / end: defeat to finish the GAME, but in a
  # showcase we prefer sending you back to the hall to try the rest.
  - id: war_won
    text: |
      ```system
      Final score: You v_player_score_v / v_ai_score_v Computer
      ```

      ```narration
      Decisive round won. Luck, probably. Or not.
      ```
    choices:
      - button: "Play again"
        command: play_again
        to: war_reset
      - button: "Back to the hall"
        command: home
        to: home

  - id: war_lost
    text: |
      ```system
      Final score: You v_player_score_v / v_ai_score_v Computer
      ```

      ```narration
      The computer had the good cards tonight. One more?
      ```
    choices:
      - button: "Play again"
        command: play_again
        to: war_reset
      - button: "Back to the hall"
        command: home
        to: home

  # Small "airlock" room to reset the scores before playing again.
  # (An init: on the war room would rerun on EVERY round, which we
  # do not want.)
  - id: war_reset
    text: "null"
    events:
      - if: ~
        do: "player_score.=.0@@ai_score.=.0@@round.=.1"
        to: war


  # ═══════════════════════════════════════════════════════════════
  # MAZE: ui: deck MODE
  #
  # The deck mode stacks rooms like cards you swipe (Reigns style).
  # Each room has up to 4 exits, one per direction: left, right,
  # up, down.
  #
  # By default, deck assigns choices in writing order (1st = left,
  # 2nd = right, and so on). That does not fit a maze: "go north"
  # must ALWAYS be up. Hence the "direction:" key on each choice:
  # it pins the arrow to the right side, whatever the writing
  # order. Both north/south/east/west and up/down/left/right are
  # accepted.
  #
  # Nice touch: the character on the card turns to face the last
  # move. It is a simple sprite (perso.png, 4 tiles = back, front,
  # left profile, right profile) indexed by a char_dir variable
  # updated in the effect: of each move.
  # ═══════════════════════════════════════════════════════════════

  - id: maze_sw
    ui: deck
    text: |
      [[/scenarios/images/showcase-ui/perso.png:4x1:{char_dir}:0]]

      ```narration
      You step into the maze. Corridors lead north and east.
      ```
    choices:
      - button: "North"
        command: north_maze_sw
        to: maze_w
        direction: north
        effect: "char_dir.=.0"
      - button: "East"
        command: east_maze_sw
        to: maze_s
        direction: east
        effect: "char_dir.=.3"
      - button: "🏠 Home"
        command: home_maze_sw
        to: home
        direction: south

  - id: maze_w
    ui: deck
    text: |
      [[/scenarios/images/showcase-ui/perso.png:4x1:{char_dir}:0]]

      ```narration
      A damp corridor. You can push on north or head back down south.
      ```
    choices:
      - button: "North"
        command: north_maze_w
        to: maze_nw
        direction: north
        effect: "char_dir.=.0"
      - button: "South"
        command: south_maze_w
        to: maze_sw
        direction: south
        effect: "char_dir.=.1"

  - id: maze_nw
    ui: deck
    text: |
      [[/scenarios/images/showcase-ui/perso.png:4x1:{char_dir}:0]]

      ```narration
      North-west corner. The only clear passage runs east.
      ```
    choices:
      - button: "East"
        command: east_maze_nw
        to: maze_n
        direction: east
        effect: "char_dir.=.3"
      - button: "South"
        command: south_maze_nw
        to: maze_w
        direction: south
        effect: "char_dir.=.1"

  - id: maze_n
    ui: deck
    text: |
      [[/scenarios/images/showcase-ui/perso.png:4x1:{char_dir}:0]]

      ```narration
      An empty room, two ways out: east toward the light, west where you came from.
      ```
    choices:
      - button: "East"
        command: east_maze_n
        to: maze_ne
        direction: east
        effect: "char_dir.=.3"
      - button: "West"
        command: west_maze_n
        to: maze_nw
        direction: west
        effect: "char_dir.=.2"

  - id: maze_s
    ui: deck
    text: |
      [[/scenarios/images/showcase-ui/perso.png:4x1:{char_dir}:0]]

      ```narration
      South crossroads. North climbs up, west leads back to the entrance.
      ```
    choices:
      - button: "North"
        command: north_maze_s
        to: maze_e
        direction: north
        effect: "char_dir.=.0"
      - button: "West"
        command: west_maze_s
        to: maze_sw
        direction: west
        effect: "char_dir.=.2"

  - id: maze_e
    ui: deck
    text: |
      [[/scenarios/images/showcase-ui/perso.png:4x1:{char_dir}:0]]

      ```narration
      Almost there. The exit glows to the north.
      ```
    choices:
      - button: "North"
        command: north_maze_e
        to: maze_ne
        direction: north
        effect: "char_dir.=.0"
      - button: "South"
        command: south_maze_e
        to: maze_s
        direction: south
        effect: "char_dir.=.1"

  - id: maze_ne
    ui: deck
    text: |
      ```narration
      The exit! You leave the maze, slightly out of breath.
      ```
    choices:
      - button: "Back to the hall"
        command: maze_exit
        to: home


  # ═══════════════════════════════════════════════════════════════
  # SMARTPHONE: ui: phone MODE
  #
  # The phone mode turns the game into a phone interface. Each room
  # picks its screen with "screen:", and the same mechanics (choices,
  # events) take the shape of an app. Here we show:
  #   • an app launcher            (screen: home)
  #   • a mini-game in messaging   (screen: conversation)
  #   • a mini-game in photo       (screen: photo)
  #   • a quiz in notes            (screen: notes)
  #   • a Settings menu that changes the phone SHAPE durably
  #
  # The shape (portrait / landscape / tablet) is driven by
  # phone_shape at the top of the file (portrait-start = the chosen
  # shape persists).
  # ═══════════════════════════════════════════════════════════════
  - id: phone_hub
    ui: phone
    screen: home
    text: "Phone unlocked."
    # shape: icon_square → the buttons become app icons in a grid.
    choices:
      - button: "🔢 Guess the number"
        shape: icon_square
        to: guess_intro
      - button: "🎲 Heads or tails"
        shape: icon_square
        to: coin_flip
      - button: "❓ Quick quiz"
        shape: icon_square
        to: quiz_1
      - button: "⚙️ Settings"
        shape: icon_square
        to: settings
      - button: "↩️ Leave the phone"
        shape: wide
        to: home


  # ── "Guess the number" app: conversation screen ──────────────────
  # We enter through a small intro room that draws the secret number
  # and resets the attempt counter, then moves on to the conversation.
  # (An event on entry of the game room would rerun on every answer:
  #  hence this dedicated airlock room for initialization.)
  - id: guess_intro
    ui: phone
    screen: conversation
    text:
      - type: message
        text: "Hi! I have a number between 1 and 100 in mind."
      - type: message
        text: "Type your guess and I will tell you higher or lower."
    events:
      # New game: we draw the secret number and reset the counters,
      # including guess, otherwise the answer from the previous game
      # stays stored (repondre: keeps it) and fires a ghost hint on
      # replay.
      - if: ~
        do:
          - "secret.=.%1:100"
          - "tries.=.0"
          - "guess.=.0"
        to: guess_game
    choices:
      - button: "Start"
        to: guess_game


  - id: guess_game
    ui: phone
    screen: conversation
    # hide_input: false → the keyboard stays visible: you type the number.
    # Thanks to guess (repondre: true), typing "42" is enough, no
    # command needed. The events compare the answer to the secret number.
    hide_input: false
    text:
      - type: message
        text: "Your turn. What number?"
      - type: system
        text: "Tries: v_tries_v"
    events:
      # guess is filled when the player types a number (repondre fallback).
      # We only count an attempt when a real answer was given.
      # ⚠️ guess keeps its value from one render to the next (repondre:
      # stores it). Each comparison is therefore guarded by
      # "v_guess_v > 0", and the LAST event resets guess to 0: otherwise
      # the hint from the previous turn (or a previous game) shows up
      # again on entry, before any answer.
      - if: "v_guess_v > 0"
        do: "tries.+.1"
      # The player's answer is already displayed by the client (input
      # echo, as a "sent" bubble on the conversation screen): no need
      # to repeat it here.
      - if: "v_guess_v > 0 v_guess_v < v_secret_v"
        text:
          - type: message
            text: "Higher."
      - if: "v_guess_v > v_secret_v"
        text:
          - type: message
            text: "Lower."
      - if: "v_guess_v = v_secret_v v_guess_v > 0"
        to: guess_won
      # Answer consumed: we reset guess to 0 so the hints do not show
      # up again on the next render (runs AFTER the comparisons above).
      - if: "v_guess_v > 0"
        do: "guess.=.0"
    choices:
      - button: "Give up"
        to: phone_hub


  - id: guess_won
    ui: phone
    screen: conversation
    text:
      - type: message
        text: "You got it! It was v_secret_v."
      - type: system
        text: "Found in v_tries_v attempt(s)."
    choices:
      - button: "Play again"
        to: guess_intro
      - button: "Back to the apps"
        to: phone_hub


  # ── "Heads or tails" app: photo screen ───────────────────────────
  # A single toss: we draw 0 (heads) or 1 (tails), and display the
  # right side of the coin. The piece.png sheet has two tiles (2x1),
  # the image picks the right one with the {face} variable, resolved
  # at render time.
  - id: coin_flip
    ui: phone
    screen: photo
    text: |
      **Heads or tails**

      Tap to toss the coin.
    choices:
      - button: "Toss"
        command: toss
        to: coin_result
        effect: "face.=.%0:1"


  - id: coin_result
    ui: phone
    screen: photo
    text: |
      [[/scenarios/images/showcase-ui/piece.png:2x1:{face}:0]]
    choices:
      - button: "Toss again"
        command: toss_again
        to: coin_result
        effect: "face.=.%0:1"
      - button: "Back to the apps"
        to: phone_hub


  # ── "Quick quiz" app: notes screen ───────────────────────────────
  # Three multiple-choice questions. Each right answer scores +1.
  # Along the way we show visible-if on the result button (it only
  # appears at the end). The notes screen lays buttons out as a
  # list, notes-app style.
  - id: quiz_1
    ui: phone
    screen: notes
    text: |
      **Quiz: 1/3**

      What does "RPG" stand for?
    # Each answer has its own command: without it, two buttons toward
    # the same room would merge (the engine sees them as one choice).
    choices:
      - button: "Role-Playing Game"
        command: q1a
        to: quiz_2
        effect: "quiz_score.+.1"
      - button: "Rainy Picnic Games"
        command: q1b
        to: quiz_2
      - button: "Retired Pigeon Gazette"
        command: q1c
        to: quiz_2


  - id: quiz_2
    ui: phone
    screen: notes
    text: |
      **Quiz: 2/3**

      In a tabletop RPG, what do you call the person who tells the story and runs the game?
    choices:
      - button: "The game master"
        command: q2a
        to: quiz_3
        effect: "quiz_score.+.1"
      - button: "The stage manager"
        command: q2b
        to: quiz_3
      - button: "The referee"
        command: q2c
        to: quiz_3


  - id: quiz_3
    ui: phone
    screen: notes
    text: |
      **Quiz: 3/3**

      What do you most often roll to resolve an action in a tabletop RPG?
    choices:
      - button: "Dice"
        command: q3a
        to: quiz_end
        effect: "quiz_score.+.1"
      - button: "A crystal ball"
        command: q3b
        to: quiz_end
      - button: "A stopwatch"
        command: q3c
        to: quiz_end


  - id: quiz_end
    ui: phone
    screen: notes
    text: |
      **Result**

      Score: v_quiz_score_v / 3
    choices:
      - button: "Try again"
        command: quiz_again
        to: quiz_reset
      - button: "Back to the apps"
        to: phone_hub


  - id: quiz_reset
    ui: phone
    screen: notes
    text: "null"
    events:
      - if: ~
        do: "quiz_score.=.0"
        to: quiz_1


  # ── Settings: change the phone SHAPE (persistent) ────────────────
  # Each button leads to a small room that sets shape: and comes
  # back to the settings. Thanks to phone_shape: portrait-start,
  # the chosen shape stays active for all the following rooms. The
  # demo thus shows a persistent setting without adding any logic
  # to the scenario.
  - id: settings
    ui: phone
    screen: folder
    text: |
      **Settings**

      Pick the phone's display. The choice stays active afterwards.
    choices:
      - button: "📱 Portrait"
        shape: wide
        to: set_portrait
      - button: "📺 Landscape"
        shape: wide
        to: set_landscape
      - button: "🖥 Tablet"
        shape: wide
        to: set_tablet
      - button: "Back to the apps"
        shape: wide
        to: phone_hub


  - id: set_portrait
    ui: phone
    screen: folder
    shape: portrait
    text: "Display: portrait."
    choices:
      - button: "OK"
        to: settings


  - id: set_landscape
    ui: phone
    screen: folder
    shape: landscape
    text: "Display: landscape."
    choices:
      - button: "OK"
        to: settings


  - id: set_tablet
    ui: phone
    screen: folder
    shape: tablet
    text: "Display: tablet."
    choices:
      - button: "OK"
        to: settings


  # ═══════════════════════════════════════════════════════════════
  # seek: ui: fullscreen MODE, a "seek and find"
  #
  # In fullscreen, the image fills the screen and you play by
  # clicking INSIDE the image. No buttons: the clickable zones are
  # defined by a MASK, a second image of the same size where each
  # zone is a flat patch of a single color. The mask is never
  # displayed. The engine reads the color of the pixel under the
  # cursor.
  #
  #   [[#map:id:image|mask]]
  #
  # The illustration combines two parts.
  # On the left the scene (the objects to find, hidden in the
  # scenery), on the right the list of wanted objects. Each object
  # therefore has TWO zones of different colors: one in the scene,
  # one in the list.
  #
  # This is where "state:" gets interesting. Each zone has a state:
  #   visible    → clickable, lights up on hover (the default)
  #   disabled   → click cut off; painted permanently if highlight-color
  #   invisible  → no click, no hover, no tooltip: it does not exist
  #
  # That state can be conditioned by "if:" layers. When you click
  # the socks in the scene, the event sets obj_socks to 1: and BOTH
  # zones (scene and list) switch to grey "disabled", because both
  # of them read that same variable.
  #
  # Clicking one zone can therefore grey out another with no extra
  # code: both rely on the same variable.
  #
  # On purpose: no "highlight" and no "hover-tooltip" on the
  # objects. Both give away the position of what you are looking
  # for. A tooltip that pops on hover is an object detector. In
  # this kind of game, the only reward should be the right click.
  # ═══════════════════════════════════════════════════════════════
  - id: seek
    ui: fullscreen

    # The variables are reset on every entry: you can replay the
    # game without relaunching the scenario.
    init:
      - var: obj_socks
        value: 0
      - var: obj_plane
        value: 0
      - var: obj_spring
        value: 0
      - var: obj_windmill
        value: 0
      - var: obj_robot
        value: 0
      - var: found
        value: 0

    # Bottom banner: the goal, then the countdown, then the end. The
    # conditional text (if:) changes on its own as you find objects.
    hud:
      - position: bottom
        height: 12
        text:
          - text: "Five objects are hiding in the room. Click them."
            if: "v_found_v.=.0"
          - text: "**v_found_v / 5**: keep going, there are more."
            if: "v_found_v.in.1-4"
          - text: "**5 / 5**: all found. Nice work."
            if: "v_found_v.=.5"
          - text: "{{🏠 Leave this challenge:@leave_seek_hud}}"

    text: "[[#map:scene:/scenarios/images/showcase-ui/hidden-objects.png|/scenarios/images/showcase-ui/hidden-objects-masque.png]]"

    zones:
      scene:
        colors:

          # ─── THE SCENE (left): the objects to click ─────────────────
          # Each object: clickable at first, greyed once found.
          # No "click:" once disabled → it cannot be counted twice.

          - color: "#F21010"          # socks
            click: ev_socks
            if:
              - if: "v_obj_socks_v.=.1"
                state: disabled
                highlight-color: "#7A7A7A"
                highlight-mode: fill

          - color: "#1E10F2"          # paper plane
            click: ev_plane
            if:
              - if: "v_obj_plane_v.=.1"
                state: disabled
                highlight-color: "#7A7A7A"
                highlight-mode: fill

          - color: "#10F217"          # spring
            click: ev_spring
            if:
              - if: "v_obj_spring_v.=.1"
                state: disabled
                highlight-color: "#7A7A7A"
                highlight-mode: fill

          - color: "#10CCF2"          # windmill
            click: ev_windmill
            if:
              - if: "v_obj_windmill_v.=.1"
                state: disabled
                highlight-color: "#7A7A7A"
                highlight-mode: fill

          - color: "#E1F210"          # robot
            click: ev_robot
            if:
              - if: "v_obj_robot_v.=.1"
                state: disabled
                highlight-color: "#7A7A7A"
                highlight-mode: fill

          # ─── THE LIST (right): purely decorative ────────────────────
          # No "click:" at all: you do not click the list, you watch
          # it get crossed out. These zones ONLY have if: layers, they
          # exist purely to be painted when the object is found.
          #
          # Before "state:", this was impossible: a zone without an
          # event could not have a state, and nothing allowed a click
          # on one color to paint ANOTHER one.

          - color: "#961111"          # socks (list)
            if:
              - if: "v_obj_socks_v.=.1"
                state: disabled
                highlight-color: "#7A7A7A"
                highlight-mode: fill

          - color: "#111D96"          # paper plane (list)
            if:
              - if: "v_obj_plane_v.=.1"
                state: disabled
                highlight-color: "#7A7A7A"
                highlight-mode: fill

          - color: "#119636"          # spring (list)
            if:
              - if: "v_obj_spring_v.=.1"
                state: disabled
                highlight-color: "#7A7A7A"
                highlight-mode: fill

          - color: "#117896"          # windmill (list)
            if:
              - if: "v_obj_windmill_v.=.1"
                state: disabled
                highlight-color: "#7A7A7A"
                highlight-mode: fill

          - color: "#968C11"          # robot (list)
            if:
              - if: "v_obj_robot_v.=.1"
                state: disabled
                highlight-color: "#7A7A7A"
                highlight-mode: fill

    # One event per object. It sets its variable (which greys both
    # zones) and bumps the banner counter. No text: in a seek and
    # find, the visual feedback is enough, a wall of text on every
    # click would break the pace.
    events:
      - id: ev_socks
        do:
          - "obj_socks.=.1"
          - "found.+.1"

      - id: ev_plane
        do:
          - "obj_plane.=.1"
          - "found.+.1"

      - id: ev_spring
        do:
          - "obj_spring.=.1"
          - "found.+.1"

      - id: ev_windmill
        do:
          - "obj_windmill.=.1"
          - "found.+.1"

      - id: ev_robot
        do:
          - "obj_robot.=.1"
          - "found.+.1"

      - id: leave_seek_hud
        to: home

    # This regular choice is a fallback for interfaces without a HUD. In
    # fullscreen mode, the visible exit is the dedicated bottom-banner action.
    choices:
      - button: "Leave seek and click"
        command: leave_seek_fallback
        to: home
