This commit is contained in:
2026-08-03 15:35:36 +02:00
parent 8798c74d4b
commit 50c04d56b2
59 changed files with 1601 additions and 34 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

+442
View File
@@ -0,0 +1,442 @@
# Space Station 33 — Card Illustrations
98 cards total
---
# Action Cards (48)
### New Arrival
A: Introduce a new cast member. They arrive at the station for the first time.
B: Introduce a cast member who has been here all along — their timeline starts at the very beginning.
### Departure
A: A cast member leaves the station permanently. Give them an end date and a reason.
B: A cast member dies. The cause should be connected to an existing event or project.
### Foundation Work
A: Start a new engineering project with no end date. It is still ongoing.
B: Start a new science project with no end date. Its outcome is not yet known.
### Completion
A: Mark an active project as completed. Add a sentence about what it produced.
B: Mark an active project as abandoned. Explain what stopped it.
### Crisis
A: Create a dark event that threatens or damages an existing project.
B: Create a dark event that puts a cast member in danger or changes them permanently.
### Breakthrough
A: Create a light event announcing a discovery. Define the discovery as a keyword.
B: Create a light event marking a milestone in [PROJECT].
### The Record
A: Create an event that references an existing keyword using **bold**.
B: Create an event that mentions [CAST].
### Consequence
A: Create an event that is a direct result of [PROJECT].
B: Create a dark event that permanently changes what a cast member does or believes.
### Terminology
A: Define a new keyword naming something unique to this station — a place, substance, or system.
B: Define a keyword that names a recurring problem the colony cannot fully solve.
### The Archive
A: Add a definition to [KEYWORD].
B: Create an event that uses at least two existing keywords in its description.
### Before and After
A: Create an event placed near the very start of the timeline.
B: Create an event placed near the very end of the timeline.
### The Gap
A: Find the longest empty stretch on the timeline and place an event there.
B: Start a project that spans at least half the total length of the timeline.
### Resource Strain
A: Create a dark event about scarcity. Reference a keyword or project by name.
B: Create a dark event that forces [PROJECT] to end prematurely — mark it abandoned.
### Disagreement
A: Create an event where [CAST] and [CAST] are in direct conflict.
B: Create an event that splits the colony's opinion on whether a project should continue.
### The Cost
A: End [CAST] — their involvement in a project brings their time on the station to a close.
B: Mark a project abandoned during the same period as a dark event already on the timeline.
### Something New
A: Create a light event introducing technology unique to this world. Keyword it.
B: Start a science project that was directly inspired by something in an existing event.
### Against the Odds
A: Create a light event where an abandoned project unexpectedly produces results.
B: Introduce a cast member who has come to solve a problem named in an existing keyword.
### Legacy
A: Create an event that references a cast member who has already died or left.
B: Start a project named after or dedicated to [CAST].
### Witness
A: Create an event where [CAST] is the sole witness to something.
B: Create a light event celebrating [CAST]'s achievement.
### The Successor
A: Introduce a new cast member who takes over a role from [CAST]. Connect them in the description.
B: A cast member's departure directly inspires a new project. Start that project.
### The Quiet Years
A: Create a light event that is calm, routine, and unremarkable — but it happened.
B: Add a cast member who lives quietly in the background and appears in no events.
### What They Left Behind
A: [CAST] departs and leaves something behind. Define what it is as a keyword.
B: Create an event that references a cast member who is no longer on the station.
### The Turning Point
A: Create a dark event that marks the moment things started going wrong for the colony.
B: Create a light event that marks the moment things started getting better.
### Names and Numbers
A: Define a measurement, unit, or index unique to this world as a keyword.
B: Create an event that puts a precise number or quantity to something previously vague.
### The Unexpected
A: Introduce a cast member arriving from outside — not a planned transfer. Who are they?
B: Create an event that surprises the other players. It must contradict an existing assumption.
### Revisit
A: Add new detail to an existing event — something that was not known at the time.
B: Give [CAST] more background. Edit their description.
### The Pattern
A: Create an event that echoes a previous event. Use [KEYWORD] in your description.
B: Start a project that was clearly born from the failure of an earlier one.
### Milestone
A: Create a significant event at approximately the midpoint of the timeline.
B: Start a project that was planned from the very beginning of the colony.
### Human Cost
A: End a cast member who never appeared in any recorded event. They are gone, unwitnessed.
B: Create a dark event that directly involves [CAST], [CAST], and [CAST].
### Echoes
A: Create an event set early in the timeline that explains the origin of an existing keyword.
B: Introduce a cast member whose arrival predates an existing event — backfill their entry.
### Jargon
A: Define a technical term used by engineers or scientists as a keyword.
B: Define a nickname, slang term, or station-specific title as a keyword.
### Parallel Lives
A: Introduce two cast members who arrive at the station on the same date.
B: Introduce a cast member who arrives at exactly the same time as a project begins.
### Free Move
A: Create any entry of your choosing — event, project, or cast. Make it count.
B: End any single ongoing element: a project or a cast member's time on the station.
### Storm Before Calm
A: Create a dark event, then immediately create a light event within the same year.
B: End a long-running project with an event that explains how it finally concluded.
### Pivot
A: An active project changes its stated goal entirely. Update its description to reflect the shift.
B: Mark one active project as abandoned and use its resources to start a replacement.
### The Face of It
A: [CAST] publicly champions [PROJECT]. Introduce them or update their description.
B: Introduce a cast member who works quietly against an active project. No one else knows.
### Old Blood
A: Introduce a cast member who arrived in the earliest days of the station.
B: Create an event commemorating someone who died before the timeline began.
### Rumour
A: Create an event that mentions something unexplained. Define that thing as a new keyword.
B: Create an event that references a keyword but adds conflicting information about it.
### The Day Everything Changed
A: Create a pivotal dark event. Every active project at that date is affected — reference at least one.
B: Create a light event so significant it changes the station's identity. Define a keyword for what it produced.
### Investigator
A: Create an event investigating the cause of something — the answer involves [KEYWORD].
B: Introduce a cast member brought in to solve the problem of [KEYWORD].
### Long Shadow
A: Create an event whose consequences only become clear much later on the timeline.
B: Start a project motivated by grief — connect it to a cast member who is no longer on the station.
### Hard Labour
A: Create a labour event — something built, dug, welded, or moved by human hands. Give it discipline: Labour.
B: Start a labour project with no end date. It involves physical work that will take years.
### The Body Count
A: Create a dark labour event — [CAST] is injured or killed doing dangerous physical work.
B: Create a dark labour event about unsafe conditions. Define the hazard as a keyword.
### The Work Crew
A: Introduce a cast member who does manual labour — maintenance, construction, extraction.
B: Create a light labour event celebrating the completion of something difficult and physical.
### The Deep Cut
A: A labour project hits an unexpected obstacle. Create a dark event that delays or changes it.
B: A labour project succeeds ahead of schedule. Create a light event marking the milestone. Mark the project completed.
### The Lab
A: Create a science event — a discovery, an experiment, a result. Give it discipline: Science.
B: Start a science project with no end date. Its purpose is to answer a question no one can answer yet.
### Infrastructure
A: Create an engineering event — something planned, built, or repaired. Give it discipline: Engineering.
B: Start an engineering project that addresses a structural or systems problem on the station.
### Cross-Discipline
A: Create an event that bridges two disciplines — reference a science project in an engineering event, or vice versa.
B: Introduce a cast member whose work crosses disciplines. They do not fit neatly into one category.
---
# Question Cards (30)
### What's Working?
Q: Which sector is doing best right now — science, engineering, or labour? Why is it ahead of the others?
A: Create an event celebrating that sector's success.
B: Define a keyword for the practice or discovery that gave them the edge.
### The Link to Earth
Q: How does communication with Earth work? How long does a message take? Who controls access to it?
A: Create an event involving a message sent to or received from Earth.
B: Define a keyword for the communication system, protocol, or relay used.
### Off the Clock
Q: What do people do for leisure on the station? What is the one thing most people look forward to?
A: Create a light event centred on a leisure activity or communal gathering.
B: Define a keyword for a pastime, tradition, or gathering place unique to this station.
### Who's Actually in Charge?
Q: How is authority structured? Is the person with the title the person with the power?
A: Introduce a cast member who holds formal authority over some part of the station.
B: Create an event where the real decision-maker acts — and it is not who you would expect.
### The Open Problem
Q: What is the one problem the station has never been able to solve? Has anyone stopped trying?
A: Define the problem as a keyword.
B: Create an event where someone tries and fails to solve it.
### Never Seen the Sky
Q: What do children born on the station think of Earth? Do they want to go there, or does it feel like a myth?
A: Introduce a cast member who was born here and has never left.
B: Create an event where someone born here confronts what Earth means to them.
### The Hard Jobs
Q: What is the most dangerous job on the station? Who does it, and why?
A: Introduce a cast member who does this dangerous work.
B: Create an event caused by the dangers of this work — an accident, a close call, or a death.
### What Time Is It?
Q: How does the station measure time? Do people still use Earth calendars, or has something local replaced them?
A: Define the station's time-keeping system as a keyword.
B: Create an event where the difference between station time and Earth time causes a problem.
### What Keeps Them Up at Night?
Q: What do people on the station fear most? Is it spoken aloud or only whispered?
A: Create a dark event that embodies this fear.
B: Define the feared thing as a keyword.
### The Dead
Q: How does the station handle death? Are the dead buried, recycled, sent back to Earth? What do people believe happens after?
A: Create an event centred on a death and how the community responds.
B: Define a keyword for the ritual, practice, or location associated with the dead.
### Contested Ground
Q: What space on the station do people argue about most — a room, a corridor, a resource? Who claims it and why?
A: Define the contested space as a keyword.
B: Create an event where the contest over this space comes to a head.
### The Founders
Q: Who were the people who first established this station? Are they remembered as heroes, cautionary tales, or forgotten entirely?
A: Create an event set near the very beginning of the timeline that shows what they built or broke.
B: Introduce a cast member who is directly descended from or trained by one of the founders.
### The Unwritten Rule
Q: What is the one rule everyone follows even though it has never been written down? What happens when someone breaks it?
A: Define the rule as a keyword.
B: Create an event where someone breaks the rule and the community responds.
### What Home Means
Q: What does 'home' mean to someone born here, versus someone who chose to come? Do they use the same word?
A: Create an event exploring what home means to a specific cast member — @"mention" them.
B: Define a keyword for the word, place, or feeling that people here call home.
### Those Who Left
Q: What happened to people who chose to return to Earth or go elsewhere? Are they talked about? Missed? Resented?
A: Create an event about a departure and how the remaining community responded.
B: Introduce a cast member who came back after having left once before.
### The World They Left
Q: Pick a cast member. What was their relationship with Earth? Did they leave willingly?
A: Update their description with a detail about their life before the station.
B: Create an event that reveals this aspect of their history.
### Why Are They Here?
Q: Pick a cast member. What brought them to this station specifically? Was it duty, desperation, or ambition?
A: Create an event set at their arrival that shows the circumstances.
B: Update their description with the reason they came and what they expected to find.
### When They're Not Working
Q: Pick a cast member. What do they do when they are off duty? What do they need to feel like themselves?
A: Create a light event featuring them in an off-duty moment.
B: Update their description with a personal habit, ritual, or pastime.
### What They're Afraid Of
Q: Pick a cast member. What is their greatest fear — the one they won't admit to?
A: Create an event that brings this fear close to the surface.
B: Update their description with a line about what they are afraid of and why.
### What Others Think
Q: Pick a cast member. What do most people on the station think of them? Is that reputation accurate?
A: Create an event that shows how others react to or talk about them.
B: Update their description with a detail that complicates their public reputation.
### Their Finest Hour
Q: Pick a cast member. What is the moment they are most proud of — even if no one else knows about it?
A: Create an event that records this achievement.
B: Update their description with this accomplishment and what it cost them.
### The Thing They'd Undo
Q: Pick a cast member. What is the decision they most regret? Do they let it show?
A: Create an event that was caused by or stems from this regret.
B: Update their description with a line about this regret and how they carry it.
### What They'd Die For
Q: Pick a cast member. What would they sacrifice everything for — a person, a belief, a piece of the station?
A: Create an event where they are pushed close to that line.
B: Update their description with what they value above their own survival.
### The Connection
Q: Pick two cast members. What is the relationship between them? Do they know each other? Is it warm or fraught?
A: Create an event showing the relationship between [CAST] and [CAST] — what does it look like in action?
B: Update the descriptions of [CAST] and [CAST] to acknowledge the connection between them.
### How They See It Ending
Q: Pick a cast member. Do they think the station will survive? What do they believe the future holds?
A: Create an event that reflects their hope or despair about the station's future.
B: Update their description with their personal vision of how this ends.
### What They're Hiding
Q: Pick a cast member. What are they keeping from the rest of the station? Is it for their protection or someone else's?
A: Create an event where the secret almost comes out.
B: Update their description with a hidden truth — vague enough that others can build on it.
### The Minority Opinion
Q: Pick a cast member. What do they believe that almost no one else on the station does?
A: Create an event where this belief puts them at odds with others.
B: Update their description with this belief and where it came from.
### How They Grieve
Q: Pick a cast member. How do they handle loss? Do they go silent, go to work, go looking for someone to blame?
A: Create a dark event that forces them to grieve something or someone.
B: Update their description with how they cope — and whether it works.
### The Threshold
Q: Pick a cast member. What would it take for them to leave the station? Is that threshold close?
A: Create an event that brings them to the edge of that decision.
B: Update their description with the one condition under which they would go.
### Their Take on Power
Q: Pick a cast member. What do they think of how the station is run? Do they trust those in charge?
A: Create an event where their opinion on leadership is tested or confirmed.
B: Update their description with their stance on authority — loyal, cynical, or something more complicated.
---
# Mystery Cards (10)
### The Disappearance
A: [CAST] vanishes for a period with no explanation. Create a dark event recording when they were last seen — and nothing more.
B: Something on the station goes missing: equipment, records, a person's entire file. Define what it is as a keyword.
### Not What It Seems
A: [PROJECT]'s stated purpose and its real purpose are different. Update its description to hint at this — obliquely.
B: Create an event where something clearly happened, but the official record does not explain it.
### The Other Name
A: Introduce a cast member who is using a false identity. No one on the station knows who they really are.
B: A keyword that everyone uses turns out to mean something different to one group. Create an event that hints at this.
### Redacted
A: Create an event where the details have been deliberately obscured — something happened, but the record is incomplete.
B: [CAST] knows something they refuse to say. Update their description with what they know but will not share.
### The Signal
A: Create an event about a transmission or signal that no one on the station can explain. Define it as a keyword.
B: Create a dark event suggesting someone has been communicating with someone they should not be communicating with.
### No Body Found
A: [CAST] is gone but there is no body and no confirmed cause. Give them an end date — leave the reason deliberately blank.
B: Create an event where someone was seen somewhere they should not have been. It was never mentioned again.
### The Watcher
A: Introduce a cast member who has been quietly observing something for a long time. Their description should raise more questions than it answers.
B: Create an event where it becomes clear someone knew something was going to happen — and said nothing.
### Classified
A: A project exists that almost nobody knows about. Start one with a deliberately vague description.
B: Create an event that references something which officially does not exist. Do not explain it.
### The Two Stories
A: Create an event where [CAST] and [CAST] tell conflicting versions of what happened.
B: Define a keyword that carries two competing meanings. Note both in its definition without resolving which is true.
### Something in the Walls
A: Create a dark event where an ordinary part of the station behaves unexpectedly. No cause is found.
B: Define a keyword for a recurring anomaly that the station cannot explain and has learned to ignore.
---
# Exploration Cards (10)
### Uncharted
A: Create an event about discovering an unmapped section of the station. Define it as a keyword.
B: Start a project to map, survey, or document an area no one has fully explored.
### Beyond the Seal
A: Create an event where someone goes where they are not supposed to go. What did they find?
B: Create a dark event about what happens when a physical or social boundary is crossed for the first time.
### First Survey
A: Create a science event recording the first systematic study of something on the station. What was found?
B: Introduce a cast member who spends their time cataloguing things others overlook.
### Something Old
A: Create an event where an old section of the station is reopened. What was left behind? Define it as a keyword.
B: Create an event discovering records or materials from the station's earliest days — before the current colony.
### Outer Edge
A: Create an event where someone reaches the outermost part of the station. What is the view from there?
B: Start a project to extend the station's reach — physically or in terms of knowledge.
### What Lives There
A: Create an event about discovering something — biological, mechanical, or social — in a place no one expected.
B: Define a keyword for something that exists on the station that most people do not know about.
### The Map Was Wrong
A: Create an event where an established understanding ([KEYWORD]) turns out to be incomplete or incorrect.
B: Create a dark event where acting on wrong information leads to a serious consequence.
### Into the Dark
A: Create a dark event where an exploration goes badly. Something is found that should not have been found.
B: Introduce a cast member who returned from a solo exploration changed in a way they will not explain.
### The Expedition
A: Start a science or labour project explicitly about going somewhere on the station no one has been before.
B: Create an event where a small group ventures somewhere together — and not everyone comes back the same.
### Deeper Still
A: An earlier exploration revealed something. Create an event where someone goes back to look more carefully.
B: Create a light event where the unknown turns out to be less threatening than feared — and more interesting.
+780
View File
@@ -0,0 +1,780 @@
[
{
"id": "new-arrival",
"title": "New Arrival",
"a": "Introduce a new cast member. They arrive at the station for the first time.",
"b": "Introduce a cast member who has been here all along — their timeline starts at the very beginning."
},
{
"id": "departure",
"title": "Departure",
"requires": [
"cast"
],
"a": "A cast member leaves the station permanently. Give them an end date and a reason.",
"b": "A cast member dies. The cause should be connected to an existing event or project."
},
{
"id": "foundation-work",
"title": "Foundation Work",
"a": "Start a new engineering project with no end date. It is still ongoing.",
"b": "Start a new science project with no end date. Its outcome is not yet known."
},
{
"id": "completion",
"title": "Completion",
"requires": [
"project"
],
"a": "Mark an active project as completed. Add a sentence about what it produced.",
"b": "Mark an active project as abandoned. Explain what stopped it."
},
{
"id": "crisis",
"title": "Crisis",
"a": "Create a dark event that threatens or damages an existing project.",
"b": "Create a dark event that puts a cast member in danger or changes them permanently."
},
{
"id": "breakthrough",
"title": "Breakthrough",
"a": "Create a light event announcing a discovery. Define the discovery as a keyword.",
"b": "Create a light event marking a milestone in {project}.",
"requires": [
"project"
]
},
{
"id": "the-record",
"title": "The Record",
"requires": [
"keyword"
],
"a": "Create an event that references an existing keyword using **bold**.",
"b": "Create an event that mentions {cast}."
},
{
"id": "consequence",
"title": "Consequence",
"a": "Create an event that is a direct result of {project}.",
"b": "Create a dark event that permanently changes what a cast member does or believes."
},
{
"id": "terminology",
"title": "Terminology",
"a": "Define a new keyword naming something unique to this station — a place, substance, or system.",
"b": "Define a keyword that names a recurring problem the colony cannot fully solve."
},
{
"id": "the-archive",
"title": "The Archive",
"requires": [
"keyword"
],
"a": "Add a definition to {keyword}.",
"b": "Create an event that uses at least two existing keywords in its description."
},
{
"id": "before-and-after",
"title": "Before and After",
"a": "Create an event placed near the very start of the timeline.",
"b": "Create an event placed near the very end of the timeline."
},
{
"id": "the-gap",
"title": "The Gap",
"a": "Find the longest empty stretch on the timeline and place an event there.",
"b": "Start a project that spans at least half the total length of the timeline."
},
{
"id": "resource-strain",
"title": "Resource Strain",
"a": "Create a dark event about scarcity. Reference a keyword or project by name.",
"b": "Create a dark event that forces {project} to end prematurely — mark it abandoned.",
"requires": [
"project"
]
},
{
"id": "disagreement",
"title": "Disagreement",
"requires": [
"cast"
],
"a": "Create an event where {cast} and {cast} are in direct conflict.",
"b": "Create an event that splits the colony's opinion on whether a project should continue."
},
{
"id": "the-cost",
"title": "The Cost",
"requires": [
"cast",
"project"
],
"a": "End {cast} — their involvement in a project brings their time on the station to a close.",
"b": "Mark a project abandoned during the same period as a dark event already on the timeline."
},
{
"id": "something-new",
"title": "Something New",
"a": "Create a light event introducing technology unique to this world. Keyword it.",
"b": "Start a science project that was directly inspired by something in an existing event."
},
{
"id": "against-the-odds",
"title": "Against the Odds",
"a": "Create a light event where an abandoned project unexpectedly produces results.",
"b": "Introduce a cast member who has come to solve a problem named in an existing keyword.",
"requires": [
"project"
]
},
{
"id": "legacy",
"title": "Legacy",
"requires": [
"cast"
],
"a": "Create an event that references a cast member who has already died or left.",
"b": "Start a project named after or dedicated to {cast}."
},
{
"id": "witness",
"title": "Witness",
"requires": [
"cast"
],
"a": "Create an event where {cast} is the sole witness to something.",
"b": "Create a light event celebrating {cast}'s achievement."
},
{
"id": "the-successor",
"title": "The Successor",
"requires": [
"cast"
],
"a": "Introduce a new cast member who takes over a role from {cast}. Connect them in the description.",
"b": "A cast member's departure directly inspires a new project. Start that project."
},
{
"id": "the-quiet-years",
"title": "The Quiet Years",
"a": "Create a light event that is calm, routine, and unremarkable — but it happened.",
"b": "Add a cast member who lives quietly in the background and appears in no events."
},
{
"id": "what-they-left-behind",
"title": "What They Left Behind",
"requires": [
"cast"
],
"a": "{cast} departs and leaves something behind. Define what it is as a keyword.",
"b": "Create an event that references a cast member who is no longer on the station."
},
{
"id": "the-turning-point",
"title": "The Turning Point",
"a": "Create a dark event that marks the moment things started going wrong for the colony.",
"b": "Create a light event that marks the moment things started getting better."
},
{
"id": "names-and-numbers",
"title": "Names and Numbers",
"a": "Define a measurement, unit, or index unique to this world as a keyword.",
"b": "Create an event that puts a precise number or quantity to something previously vague."
},
{
"id": "the-unexpected",
"title": "The Unexpected",
"a": "Introduce a cast member arriving from outside — not a planned transfer. Who are they?",
"b": "Create an event that surprises the other players. It must contradict an existing assumption."
},
{
"id": "revisit",
"title": "Revisit",
"requires": [
"cast"
],
"a": "Add new detail to an existing event — something that was not known at the time.",
"b": "Give {cast} more background. Edit their description."
},
{
"id": "the-pattern",
"title": "The Pattern",
"requires": [
"keyword"
],
"a": "Create an event that echoes a previous event. Use {keyword} in your description.",
"b": "Start a project that was clearly born from the failure of an earlier one."
},
{
"id": "milestone",
"title": "Milestone",
"a": "Create a significant event at approximately the midpoint of the timeline.",
"b": "Start a project that was planned from the very beginning of the colony."
},
{
"id": "human-cost",
"title": "Human Cost",
"requires": [
"cast"
],
"a": "End a cast member who never appeared in any recorded event. They are gone, unwitnessed.",
"b": "Create a dark event that directly involves {cast}, {cast}, and {cast}."
},
{
"id": "echoes",
"title": "Echoes",
"requires": [
"keyword"
],
"a": "Create an event set early in the timeline that explains the origin of an existing keyword.",
"b": "Introduce a cast member whose arrival predates an existing event — backfill their entry."
},
{
"id": "jargon",
"title": "Jargon",
"a": "Define a technical term used by engineers or scientists as a keyword.",
"b": "Define a nickname, slang term, or station-specific title as a keyword."
},
{
"id": "parallel-lives",
"title": "Parallel Lives",
"a": "Introduce two cast members who arrive at the station on the same date.",
"b": "Introduce a cast member who arrives at exactly the same time as a project begins."
},
{
"id": "your-choice",
"title": "Free Move",
"a": "Create any entry of your choosing — event, project, or cast. Make it count.",
"b": "End any single ongoing element: a project or a cast member's time on the station."
},
{
"id": "storm-before-calm",
"title": "Storm Before Calm",
"a": "Create a dark event, then immediately create a light event within the same year.",
"b": "End a long-running project with an event that explains how it finally concluded."
},
{
"id": "pivot",
"title": "Pivot",
"requires": [
"project"
],
"a": "An active project changes its stated goal entirely. Update its description to reflect the shift.",
"b": "Mark one active project as abandoned and use its resources to start a replacement."
},
{
"id": "the-face-of-it",
"title": "The Face of It",
"requires": [
"project"
],
"a": "{cast} publicly champions {project}. Introduce them or update their description.",
"b": "Introduce a cast member who works quietly against an active project. No one else knows."
},
{
"id": "old-blood",
"title": "Old Blood",
"a": "Introduce a cast member who arrived in the earliest days of the station.",
"b": "Create an event commemorating someone who died before the timeline began."
},
{
"id": "rumour",
"title": "Rumour",
"a": "Create an event that mentions something unexplained. Define that thing as a new keyword.",
"b": "Create an event that references a keyword but adds conflicting information about it."
},
{
"id": "the-day-everything-changed",
"title": "The Day Everything Changed",
"a": "Create a pivotal dark event. Every active project at that date is affected — reference at least one.",
"b": "Create a light event so significant it changes the station's identity. Define a keyword for what it produced."
},
{
"id": "investigator",
"title": "Investigator",
"requires": [
"keyword"
],
"a": "Create an event investigating the cause of something — the answer involves {keyword}.",
"b": "Introduce a cast member brought in to solve the problem of {keyword}."
},
{
"id": "long-shadow",
"title": "Long Shadow",
"a": "Create an event whose consequences only become clear much later on the timeline.",
"b": "Start a project motivated by grief — connect it to a cast member who is no longer on the station."
},
{
"id": "q-industry",
"type": "question",
"title": "What's Working?",
"question": "Which sector is doing best right now — science, engineering, or labour? Why is it ahead of the others?",
"a": "Create an event celebrating that sector's success.",
"b": "Define a keyword for the practice or discovery that gave them the edge."
},
{
"id": "q-earth-link",
"type": "question",
"title": "The Link to Earth",
"question": "How does communication with Earth work? How long does a message take? Who controls access to it?",
"a": "Create an event involving a message sent to or received from Earth.",
"b": "Define a keyword for the communication system, protocol, or relay used."
},
{
"id": "q-leisure",
"type": "question",
"title": "Off the Clock",
"question": "What do people do for leisure on the station? What is the one thing most people look forward to?",
"a": "Create a light event centred on a leisure activity or communal gathering.",
"b": "Define a keyword for a pastime, tradition, or gathering place unique to this station."
},
{
"id": "q-authority",
"type": "question",
"title": "Who's Actually in Charge?",
"question": "How is authority structured? Is the person with the title the person with the power?",
"a": "Introduce a cast member who holds formal authority over some part of the station.",
"b": "Create an event where the real decision-maker acts — and it is not who you would expect."
},
{
"id": "q-unsolved",
"type": "question",
"title": "The Open Problem",
"question": "What is the one problem the station has never been able to solve? Has anyone stopped trying?",
"a": "Define the problem as a keyword.",
"b": "Create an event where someone tries and fails to solve it."
},
{
"id": "q-born-here",
"type": "question",
"title": "Never Seen the Sky",
"question": "What do children born on the station think of Earth? Do they want to go there, or does it feel like a myth?",
"a": "Introduce a cast member who was born here and has never left.",
"b": "Create an event where someone born here confronts what Earth means to them."
},
{
"id": "q-dangerous",
"type": "question",
"title": "The Hard Jobs",
"question": "What is the most dangerous job on the station? Who does it, and why?",
"a": "Introduce a cast member who does this dangerous work.",
"b": "Create an event caused by the dangers of this work — an accident, a close call, or a death."
},
{
"id": "q-time",
"type": "question",
"title": "What Time Is It?",
"question": "How does the station measure time? Do people still use Earth calendars, or has something local replaced them?",
"a": "Define the station's time-keeping system as a keyword.",
"b": "Create an event where the difference between station time and Earth time causes a problem."
},
{
"id": "q-fear",
"type": "question",
"title": "What Keeps Them Up at Night?",
"question": "What do people on the station fear most? Is it spoken aloud or only whispered?",
"a": "Create a dark event that embodies this fear.",
"b": "Define the feared thing as a keyword."
},
{
"id": "q-the-dead",
"type": "question",
"title": "The Dead",
"question": "How does the station handle death? Are the dead buried, recycled, sent back to Earth? What do people believe happens after?",
"a": "Create an event centred on a death and how the community responds.",
"b": "Define a keyword for the ritual, practice, or location associated with the dead."
},
{
"id": "q-contested",
"type": "question",
"title": "Contested Ground",
"question": "What space on the station do people argue about most — a room, a corridor, a resource? Who claims it and why?",
"a": "Define the contested space as a keyword.",
"b": "Create an event where the contest over this space comes to a head."
},
{
"id": "q-founders",
"type": "question",
"title": "The Founders",
"question": "Who were the people who first established this station? Are they remembered as heroes, cautionary tales, or forgotten entirely?",
"a": "Create an event set near the very beginning of the timeline that shows what they built or broke.",
"b": "Introduce a cast member who is directly descended from or trained by one of the founders."
},
{
"id": "q-unwritten-rule",
"type": "question",
"title": "The Unwritten Rule",
"question": "What is the one rule everyone follows even though it has never been written down? What happens when someone breaks it?",
"a": "Define the rule as a keyword.",
"b": "Create an event where someone breaks the rule and the community responds."
},
{
"id": "q-home",
"type": "question",
"title": "What Home Means",
"question": "What does 'home' mean to someone born here, versus someone who chose to come? Do they use the same word?",
"a": "Create an event exploring what home means to a specific cast member — @\"mention\" them.",
"b": "Define a keyword for the word, place, or feeling that people here call home."
},
{
"id": "q-leaving",
"type": "question",
"title": "Those Who Left",
"question": "What happened to people who chose to return to Earth or go elsewhere? Are they talked about? Missed? Resented?",
"a": "Create an event about a departure and how the remaining community responded.",
"b": "Introduce a cast member who came back after having left once before."
},
{
"id": "q-cast-earth",
"type": "question",
"requires": [
"cast"
],
"title": "The World They Left",
"question": "Pick a cast member. What was their relationship with Earth? Did they leave willingly?",
"a": "Update their description with a detail about their life before the station.",
"b": "Create an event that reveals this aspect of their history."
},
{
"id": "q-cast-here-why",
"type": "question",
"requires": [
"cast"
],
"title": "Why Are They Here?",
"question": "Pick a cast member. What brought them to this station specifically? Was it duty, desperation, or ambition?",
"a": "Create an event set at their arrival that shows the circumstances.",
"b": "Update their description with the reason they came and what they expected to find."
},
{
"id": "q-cast-leisure",
"type": "question",
"requires": [
"cast"
],
"title": "When They're Not Working",
"question": "Pick a cast member. What do they do when they are off duty? What do they need to feel like themselves?",
"a": "Create a light event featuring them in an off-duty moment.",
"b": "Update their description with a personal habit, ritual, or pastime."
},
{
"id": "q-cast-fear",
"type": "question",
"requires": [
"cast"
],
"title": "What They're Afraid Of",
"question": "Pick a cast member. What is their greatest fear — the one they won't admit to?",
"a": "Create an event that brings this fear close to the surface.",
"b": "Update their description with a line about what they are afraid of and why."
},
{
"id": "q-cast-reputation",
"type": "question",
"requires": [
"cast"
],
"title": "What Others Think",
"question": "Pick a cast member. What do most people on the station think of them? Is that reputation accurate?",
"a": "Create an event that shows how others react to or talk about them.",
"b": "Update their description with a detail that complicates their public reputation."
},
{
"id": "q-cast-achievement",
"type": "question",
"requires": [
"cast"
],
"title": "Their Finest Hour",
"question": "Pick a cast member. What is the moment they are most proud of — even if no one else knows about it?",
"a": "Create an event that records this achievement.",
"b": "Update their description with this accomplishment and what it cost them."
},
{
"id": "q-cast-regret",
"type": "question",
"requires": [
"cast"
],
"title": "The Thing They'd Undo",
"question": "Pick a cast member. What is the decision they most regret? Do they let it show?",
"a": "Create an event that was caused by or stems from this regret.",
"b": "Update their description with a line about this regret and how they carry it."
},
{
"id": "q-cast-worth-dying",
"type": "question",
"requires": [
"cast"
],
"title": "What They'd Die For",
"question": "Pick a cast member. What would they sacrifice everything for — a person, a belief, a piece of the station?",
"a": "Create an event where they are pushed close to that line.",
"b": "Update their description with what they value above their own survival."
},
{
"id": "q-cast-relationship",
"type": "question",
"requires": [
"cast"
],
"title": "The Connection",
"question": "Pick two cast members. What is the relationship between them? Do they know each other? Is it warm or fraught?",
"a": "Create an event showing the relationship between {cast} and {cast} — what does it look like in action?",
"b": "Update the descriptions of {cast} and {cast} to acknowledge the connection between them."
},
{
"id": "q-cast-future",
"type": "question",
"requires": [
"cast"
],
"title": "How They See It Ending",
"question": "Pick a cast member. Do they think the station will survive? What do they believe the future holds?",
"a": "Create an event that reflects their hope or despair about the station's future.",
"b": "Update their description with their personal vision of how this ends."
},
{
"id": "q-cast-secret",
"type": "question",
"requires": [
"cast"
],
"title": "What They're Hiding",
"question": "Pick a cast member. What are they keeping from the rest of the station? Is it for their protection or someone else's?",
"a": "Create an event where the secret almost comes out.",
"b": "Update their description with a hidden truth — vague enough that others can build on it."
},
{
"id": "q-cast-belief",
"type": "question",
"requires": [
"cast"
],
"title": "The Minority Opinion",
"question": "Pick a cast member. What do they believe that almost no one else on the station does?",
"a": "Create an event where this belief puts them at odds with others.",
"b": "Update their description with this belief and where it came from."
},
{
"id": "q-cast-loss",
"type": "question",
"requires": [
"cast"
],
"title": "How They Grieve",
"question": "Pick a cast member. How do they handle loss? Do they go silent, go to work, go looking for someone to blame?",
"a": "Create a dark event that forces them to grieve something or someone.",
"b": "Update their description with how they cope — and whether it works."
},
{
"id": "q-cast-leaving",
"type": "question",
"requires": [
"cast"
],
"title": "The Threshold",
"question": "Pick a cast member. What would it take for them to leave the station? Is that threshold close?",
"a": "Create an event that brings them to the edge of that decision.",
"b": "Update their description with the one condition under which they would go."
},
{
"id": "q-cast-leadership",
"type": "question",
"requires": [
"cast"
],
"title": "Their Take on Power",
"question": "Pick a cast member. What do they think of how the station is run? Do they trust those in charge?",
"a": "Create an event where their opinion on leadership is tested or confirmed.",
"b": "Update their description with their stance on authority — loyal, cynical, or something more complicated."
},
{
"id": "hard-labour",
"title": "Hard Labour",
"a": "Create a labour event — something built, dug, welded, or moved by human hands. Give it discipline: Labour.",
"b": "Start a labour project with no end date. It involves physical work that will take years."
},
{
"id": "the-body-count",
"title": "The Body Count",
"requires": [
"cast"
],
"a": "Create a dark labour event — {cast} is injured or killed doing dangerous physical work.",
"b": "Create a dark labour event about unsafe conditions. Define the hazard as a keyword."
},
{
"id": "the-work-crew",
"title": "The Work Crew",
"a": "Introduce a cast member who does manual labour — maintenance, construction, extraction.",
"b": "Create a light labour event celebrating the completion of something difficult and physical."
},
{
"id": "deep-cut",
"title": "The Deep Cut",
"requires": [
"project"
],
"a": "A labour project hits an unexpected obstacle. Create a dark event that delays or changes it.",
"b": "A labour project succeeds ahead of schedule. Create a light event marking the milestone. Mark the project completed."
},
{
"id": "the-lab",
"title": "The Lab",
"a": "Create a science event — a discovery, an experiment, a result. Give it discipline: Science.",
"b": "Start a science project with no end date. Its purpose is to answer a question no one can answer yet."
},
{
"id": "infrastructure",
"title": "Infrastructure",
"a": "Create an engineering event — something planned, built, or repaired. Give it discipline: Engineering.",
"b": "Start an engineering project that addresses a structural or systems problem on the station."
},
{
"id": "cross-discipline",
"title": "Cross-Discipline",
"requires": [
"project"
],
"a": "Create an event that bridges two disciplines — reference a science project in an engineering event, or vice versa.",
"b": "Introduce a cast member whose work crosses disciplines. They do not fit neatly into one category."
},
{
"id": "the-disappearance",
"title": "The Disappearance",
"requires": [
"cast"
],
"a": "{cast} vanishes for a period with no explanation. Create a dark event recording when they were last seen — and nothing more.",
"b": "Something on the station goes missing: equipment, records, a person's entire file. Define what it is as a keyword."
},
{
"id": "not-what-it-seems",
"title": "Not What It Seems",
"requires": [
"project"
],
"a": "{project}'s stated purpose and its real purpose are different. Update its description to hint at this — obliquely.",
"b": "Create an event where something clearly happened, but the official record does not explain it."
},
{
"id": "the-other-name",
"title": "The Other Name",
"a": "Introduce a cast member who is using a false identity. No one on the station knows who they really are.",
"b": "A keyword that everyone uses turns out to mean something different to one group. Create an event that hints at this."
},
{
"id": "redacted",
"title": "Redacted",
"a": "Create an event where the details have been deliberately obscured — something happened, but the record is incomplete.",
"b": "{cast} knows something they refuse to say. Update their description with what they know but will not share."
},
{
"id": "the-signal",
"title": "The Signal",
"a": "Create an event about a transmission or signal that no one on the station can explain. Define it as a keyword.",
"b": "Create a dark event suggesting someone has been communicating with someone they should not be communicating with."
},
{
"id": "no-body-found",
"title": "No Body Found",
"requires": [
"cast"
],
"a": "{cast} is gone but there is no body and no confirmed cause. Give them an end date — leave the reason deliberately blank.",
"b": "Create an event where someone was seen somewhere they should not have been. It was never mentioned again."
},
{
"id": "the-watcher",
"title": "The Watcher",
"a": "Introduce a cast member who has been quietly observing something for a long time. Their description should raise more questions than it answers.",
"b": "Create an event where it becomes clear someone knew something was going to happen — and said nothing."
},
{
"id": "classified",
"title": "Classified",
"a": "A project exists that almost nobody knows about. Start one with a deliberately vague description.",
"b": "Create an event that references something which officially does not exist. Do not explain it."
},
{
"id": "the-two-stories",
"title": "The Two Stories",
"requires": [
"cast"
],
"a": "Create an event where {cast} and {cast} tell conflicting versions of what happened.",
"b": "Define a keyword that carries two competing meanings. Note both in its definition without resolving which is true."
},
{
"id": "something-in-the-walls",
"title": "Something in the Walls",
"a": "Create a dark event where an ordinary part of the station behaves unexpectedly. No cause is found.",
"b": "Define a keyword for a recurring anomaly that the station cannot explain and has learned to ignore."
},
{
"id": "uncharted",
"title": "Uncharted",
"a": "Create an event about discovering an unmapped section of the station. Define it as a keyword.",
"b": "Start a project to map, survey, or document an area no one has fully explored."
},
{
"id": "beyond-the-seal",
"title": "Beyond the Seal",
"a": "Create an event where someone goes where they are not supposed to go. What did they find?",
"b": "Create a dark event about what happens when a physical or social boundary is crossed for the first time."
},
{
"id": "first-survey",
"title": "First Survey",
"a": "Create a science event recording the first systematic study of something on the station. What was found?",
"b": "Introduce a cast member who spends their time cataloguing things others overlook."
},
{
"id": "something-old",
"title": "Something Old",
"a": "Create an event where an old section of the station is reopened. What was left behind? Define it as a keyword.",
"b": "Create an event discovering records or materials from the station's earliest days — before the current colony."
},
{
"id": "outer-edge",
"title": "Outer Edge",
"a": "Create an event where someone reaches the outermost part of the station. What is the view from there?",
"b": "Start a project to extend the station's reach — physically or in terms of knowledge."
},
{
"id": "what-lives-there",
"title": "What Lives There",
"a": "Create an event about discovering something — biological, mechanical, or social — in a place no one expected.",
"b": "Define a keyword for something that exists on the station that most people do not know about."
},
{
"id": "the-map-was-wrong",
"title": "The Map Was Wrong",
"requires": [
"keyword"
],
"a": "Create an event where an established understanding ({keyword}) turns out to be incomplete or incorrect.",
"b": "Create a dark event where acting on wrong information leads to a serious consequence."
},
{
"id": "into-the-dark",
"title": "Into the Dark",
"a": "Create a dark event where an exploration goes badly. Something is found that should not have been found.",
"b": "Introduce a cast member who returned from a solo exploration changed in a way they will not explain."
},
{
"id": "the-expedition",
"title": "The Expedition",
"a": "Start a science or labour project explicitly about going somewhere on the station no one has been before.",
"b": "Create an event where a small group ventures somewhere together — and not everyone comes back the same."
},
{
"id": "deeper-still",
"title": "Deeper Still",
"a": "An earlier exploration revealed something. Create an event where someone goes back to look more carefully.",
"b": "Create a light event where the unknown turns out to be less threatening than feared — and more interesting."
}
]
Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

+373 -30
View File
@@ -370,6 +370,43 @@
flex-shrink: 0;
}
.entry-env {
border: 1px solid rgba(232,220,196,.22);
box-shadow: var(--shadow);
background: var(--panel);
padding: 6px;
}
.entry-env img { width: 100%; display: block; }
/* Image below text (default) */
.entry-body.env-after .entry-env { margin-top: 1.2rem; max-width: 540px; }
/* Image to the right — text left, image right */
.entry-body.env-right {
display: grid;
grid-template-columns: 1fr 280px;
column-gap: 2rem;
align-items: start;
}
.entry-body.env-right > *:not(.entry-env) { grid-column: 1; }
.entry-body.env-right .entry-env { grid-column: 2; grid-row: 1 / 10; position: sticky; top: 5.3rem; }
/* Image to the left — image left, text right */
.entry-body.env-left {
display: grid;
grid-template-columns: 280px 1fr;
column-gap: 2rem;
align-items: start;
}
.entry-body.env-left > *:not(.entry-env) { grid-column: 2; }
.entry-body.env-left .entry-env { grid-column: 1; grid-row: 1 / 10; position: sticky; top: 5.3rem; }
@media (max-width: 700px) {
.entry-body.env-left, .entry-body.env-right { display: block; }
.entry-body.env-left .entry-env,
.entry-body.env-right .entry-env { position: relative; top: auto; margin-top: 1rem; }
}
.empty-section {
padding: 2rem 0;
color: var(--muted);
@@ -460,6 +497,102 @@
footer .shell { display: flex; justify-content: space-between; gap: 2rem; flex-wrap: wrap; }
footer p { margin: 0; font: .72rem/1.7 var(--mono); letter-spacing: .08em; text-transform: uppercase; }
/* Card draw */
.card-overlay {
position: fixed;
inset: 0;
background: rgba(23,21,19,.92);
backdrop-filter: blur(8px);
z-index: 300;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
}
/* Card scales to fit viewport in both dimensions */
.card-frame {
position: relative;
width: min(360px, 88vw, calc(88vh * 9 / 13));
aspect-ratio: 9 / 13;
background: url('assets/card-frame.png') center / cover no-repeat;
flex-shrink: 0;
}
/* Inner content area sits on the lined paper, inside the ornate border */
.card-inner {
position: absolute;
top: 16%;
left: 17%;
right: 17%;
bottom: 13%;
display: flex;
flex-direction: column;
}
.card-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
.card-type-label {
font: 700 .55rem/1 var(--mono);
letter-spacing: .22em;
text-transform: uppercase;
color: #8a5c2c;
text-align: center;
margin-bottom: .3rem;
}
.card-title {
font-family: var(--serif);
font-size: 1.3rem;
font-weight: 700;
color: #160d04;
letter-spacing: -.01em;
line-height: 1.1;
text-align: center;
margin-bottom: .4rem;
}
.card-question {
font: italic .75rem/1.45 var(--serif);
color: #2c1a0e;
text-align: center;
margin-bottom: .3rem;
}
.card-divider {
width: 35%;
height: 1px;
background: rgba(90,50,20,.3);
margin: .2rem auto .45rem;
}
.card-options { display: flex; flex-direction: column; gap: .45rem; }
.card-option {
font: .75rem/1.45 var(--serif);
color: #1e0e04;
padding-left: 1.8rem;
position: relative;
}
.card-option-label {
position: absolute;
left: 0;
font: 700 .6rem/1.6 var(--mono);
letter-spacing: .06em;
color: #7a4c1e;
}
.card-dismiss {
display: block;
width: 100%;
background: rgba(90,50,20,.07);
border: 1px solid rgba(90,50,20,.55);
color: #3d2008;
font: 700 .58rem/1 var(--mono);
letter-spacing: .18em;
text-transform: uppercase;
padding: .5rem;
cursor: pointer;
transition: background .15s, border-color .15s;
margin-top: .5rem;
}
.card-dismiss:hover { background: rgba(90,50,20,.18); border-color: rgba(90,50,20,.8); }
/* Timeline click chooser */
.tl-chooser {
position: fixed;
@@ -542,14 +675,22 @@
<a href="games.html">Sessions</a>
<a x-show="game" x-text="game && game.title" style="color:var(--paper);pointer-events:none;"></a>
</div>
<button
x-show="game"
class="edit-toggle"
:class="editMode ? 'unlocked' : 'locked'"
@click="editMode ? lock() : openUnlock()"
>
<span x-text="editMode ? '⊙ Editing' : '⊘ Read-only'"></span>
</button>
<div style="display:flex;align-items:center;gap:.8rem">
<button
x-show="game && cards.length"
class="edit-toggle locked"
style="border-color:rgba(184,138,67,.35)"
@click="drawCard()"
>Draw Card</button>
<button
x-show="game"
class="edit-toggle"
:class="editMode ? 'unlocked' : 'locked'"
@click="editMode ? lock() : openUnlock()"
>
<span x-text="editMode ? '⊙ Editing' : '⊘ Read-only'"></span>
</button>
</div>
</div>
</nav>
@@ -569,7 +710,7 @@
<div class="game-header-title">
<h2 x-text="game && game.title"></h2>
<div class="game-meta-row">
<span class="mood-badge" :class="game && game.mood" x-text="game && game.mood"></span>
<span class="mood-badge" :class="game && game.mood" x-text="game && (game.mood === 'dark' ? '◉' : '○')"></span>
<span class="game-dates" x-text="game && (game.timeline_start + ' → ' + game.timeline_end)"></span>
</div>
<p class="game-desc" x-show="game && game.description" x-text="game && game.description"></p>
@@ -675,15 +816,18 @@
<div class="entry-list">
<template x-for="item in allEventsForDisplay()" :key="item.id">
<div class="entry" :id="'entry-' + item.id">
<div class="entry-body">
<div class="entry-body" :class="item.env ? 'env-' + (item.env_layout || 'after') : ''">
<div class="entry-eyebrow">
<span x-text="item.date"></span>
<span x-show="item.isAnchor"><span class="sep"> // </span><span class="e-anchor" x-text="item.anchorType === 'start' ? 'Opening' : 'Closing'"></span></span>
<span x-show="item.discipline"><span class="sep"> // </span><span class="disc-emoji" x-text="disciplineIcon(item.discipline)"></span> <span x-text="item.discipline"></span></span>
<span x-show="item.mood"><span class="sep"> // </span><span :class="item.mood === 'dark' ? 'e-dark' : ''" x-text="item.mood"></span></span>
<span x-show="item.mood"><span class="sep"> // </span><span :class="item.mood === 'dark' ? 'e-dark' : ''" x-text="item.mood === 'dark' ? '◉' : '○'"></span></span>
</div>
<div class="entry-title" x-text="item.title"></div>
<div class="entry-desc" x-show="item.description" x-html="renderDesc(item.description)"></div>
<div class="entry-env" x-show="item.env">
<img :src="'assets/' + item.env + '.jpg'" :alt="item.title" loading="lazy" />
</div>
</div>
<div class="entry-actions" x-show="editMode && !item.isAnchor">
<button class="btn sm ghost" @click="openEditItem(item)">Edit</button>
@@ -711,7 +855,7 @@
<div class="entry-list">
<template x-for="item in projects()" :key="item.id">
<div class="entry" :id="'entry-' + item.id">
<div class="entry-body">
<div class="entry-body" :class="item.env ? 'env-' + (item.env_layout || 'after') : ''">
<div class="entry-eyebrow">
<span x-text="item.date"></span>
<span x-show="item.end_date"> → <span x-text="item.end_date"></span></span>
@@ -722,6 +866,9 @@
</div>
<div class="entry-title" x-text="item.title"></div>
<div class="entry-desc" x-show="item.description" x-html="renderDesc(item.description)"></div>
<div class="entry-env" x-show="item.env">
<img :src="'assets/' + item.env + '.jpg'" :alt="item.title" loading="lazy" />
</div>
</div>
<div class="entry-actions" x-show="editMode">
<button class="btn sm ghost" @click="openEditItem(item)">Edit</button>
@@ -749,7 +896,7 @@
<div class="entry-list">
<template x-for="(item, idx) in cast()" :key="item.id">
<div class="entry" :id="'entry-' + item.id">
<div class="entry-body">
<div class="entry-body" :class="item.env ? 'env-' + (item.env_layout || 'after') : ''">
<div class="entry-eyebrow">
<span class="cast-dot" :style="`background:${castColor(idx)}`"></span>
Arrived <span x-text="item.date"></span>
@@ -758,6 +905,14 @@
</div>
<div class="entry-title" x-text="item.title"></div>
<div class="entry-desc" x-show="item.description" x-html="renderDesc(item.description)"></div>
<div class="kw-usage-row" x-show="castUsages(item.title).length > 0">
<template x-for="ref in castUsages(item.title)" :key="ref.id">
<a class="kw-usage" :href="'#entry-' + ref.id" x-text="ref.title"></a>
</template>
</div>
<div class="entry-env" x-show="item.env">
<img :src="'assets/' + item.env + '.jpg'" :alt="item.title" loading="lazy" />
</div>
</div>
<div class="entry-actions" x-show="editMode">
<button class="btn sm ghost" @click="openEditItem(item)">Edit</button>
@@ -785,9 +940,9 @@
<div class="entry-list">
<template x-for="kw in allKeywords()" :key="kw.term">
<div class="entry">
<div class="entry-body">
<div class="entry-body" :class="item.env ? 'env-' + (item.env_layout || 'after') : ''">
<div class="entry-title" x-text="kw.term"></div>
<div class="entry-desc" x-show="kw.definition" x-text="kw.definition"></div>
<div class="entry-desc" x-show="kw.definition" x-html="renderDesc(kw.definition)"></div>
<div class="entry-desc" x-show="!kw.definition" style="font-style:italic;color:var(--muted)">No definition yet.</div>
<div class="kw-usage-row" x-show="keywordUsages(kw.term).length > 0">
<template x-for="item in keywordUsages(kw.term)" :key="item.id">
@@ -809,6 +964,31 @@
</main>
<!-- Card modal -->
<div class="card-overlay" x-show="showCard" @click.self="showCard = false" @keydown.escape.window="showCard = false">
<div class="card-frame" x-show="drawnCard">
<div class="card-inner">
<div class="card-content">
<div class="card-type-label" x-text="drawnCard && drawnCard.type === 'question' ? 'Question' : 'Action'"></div>
<div class="card-title" x-text="drawnCard && drawnCard.title"></div>
<div class="card-question" x-show="drawnCard && drawnCard.question" x-text="drawnCard && drawnCard.question"></div>
<div class="card-divider"></div>
<div class="card-options">
<div class="card-option">
<span class="card-option-label">A —</span>
<span x-html="drawnCard && drawnCard.a"></span>
</div>
<div class="card-option">
<span class="card-option-label">B —</span>
<span x-html="drawnCard && drawnCard.b"></span>
</div>
</div>
</div>
<button class="card-dismiss" @click="showCard = false">Dismiss</button>
</div>
</div>
</div>
<!-- Timeline click chooser — dismiss on outside click via transparent backdrop -->
<div x-show="tlChooser.show"
style="position:fixed;inset:0;z-index:199"
@@ -973,25 +1153,104 @@
</div>
</div>
<!-- Mood + discipline (not for persons) -->
<!-- Mood + discipline + environment (not for persons) -->
<div x-show="activeForm.type !== 'person'">
<div class="form-group">
<label class="form-label">Mood</label>
<select x-model="activeForm.mood">
<option value="">Inherit from session</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
<div class="date-row">
<div class="form-group">
<label class="form-label">Mood</label>
<select x-model="activeForm.mood">
<option value="">Inherit</option>
<option value="light">○ Light</option>
<option value="dark">◉ Dark</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Discipline</label>
<select x-model="activeForm.discipline"
@change="if(!activeForm.env) { activeForm.env = randomEnv($event.target.value); if(activeForm.env) activeForm.env_layout = randomEnvLayout() }">
<option value="">None</option>
<option value="science">🔬 Science</option>
<option value="engineering">⚙️ Engineering</option>
<option value="labour">👷 Labour</option>
</select>
</div>
</div>
<div class="form-group">
<label class="form-label">Discipline</label>
<select x-model="activeForm.discipline">
<label class="form-label">Environment Image</label>
<select x-model="activeForm.env">
<option value="">None</option>
<option value="science">Science</option>
<option value="engineering">Engineering</option>
<option value="labour">Labour</option>
<optgroup label="Central Environments">
<option value="env-grand-hall">Grand Hall</option>
<option value="env-workshop">Workshop</option>
<option value="env-greenhouse">Greenhouse</option>
<option value="env-library">Library</option>
<option value="env-reactor">Reactor</option>
<option value="env-observatory">Observatory</option>
</optgroup>
<optgroup label="Engineering">
<option value="eng-blueprint">Blueprint Room</option>
<option value="eng-scaffold">Scaffolding</option>
<option value="eng-survey">Survey Exterior</option>
<option value="eng-planning-room">Planning Room</option>
<option value="eng-facility">Industrial Facility</option>
<option value="eng-construction">Construction Site</option>
</optgroup>
<optgroup label="Science">
<option value="sci-botanist">Botanist at Work</option>
<option value="sci-specimen-hall">Specimen Hall</option>
<option value="sci-laboratory">Laboratory</option>
<option value="sci-telescope">Telescope Room</option>
<option value="sci-excavation">Excavation Site</option>
<option value="sci-weather-station">Weather Station</option>
<option value="sci-specimen-tanks">Specimen Tanks</option>
<option value="sci-aquatic-lab">Aquatic Lab</option>
<option value="sci-growth-chamber">Growth Chamber</option>
<option value="sci-herbarium">Herbarium</option>
<option value="sci-globe-room">Globe Room</option>
<option value="sci-paleontology">Paleontology</option>
</optgroup>
<optgroup label="Labour">
<option value="lab-pipeline">Pipeline</option>
<option value="lab-tunnel">Tunnel</option>
<option value="lab-crane-lift">Crane Lift</option>
<option value="lab-shift-change">Shift Change</option>
<option value="lab-pour">Concrete Pour</option>
<option value="lab-solar-panels">Solar Panels</option>
<option value="lab-machinery">Machinery</option>
<option value="lab-transport">Transport</option>
<option value="lab-excavator">Excavator</option>
<option value="lab-scaffold">Scaffolding</option>
<option value="lab-canteen">Canteen</option>
<option value="lab-archway">Archway</option>
</optgroup>
<optgroup label="Atmospheric">
<option value="atm-corridor">Corridor</option>
<option value="atm-study">Study at Night</option>
<option value="atm-dome-rain">Dome in Rain</option>
<option value="atm-dawn">Dawn Exterior</option>
<option value="atm-sunset-city">Sunset City</option>
<option value="atm-moonrise">Moonrise</option>
<option value="atm-dust-storm">Dust Storm</option>
<option value="atm-reading-room">Reading Room</option>
<option value="atm-breakroom">Breakroom</option>
<option value="atm-cemetery">Cemetery</option>
<option value="atm-festival">Festival</option>
<option value="atm-children-play">Children Playing</option>
<option value="atm-night-observatory">Night Observatory</option>
<option value="atm-garden-light">Garden Light</option>
<option value="atm-lantern-hall">Lantern Hall</option>
<option value="atm-blizzard">Blizzard</option>
</optgroup>
</select>
</div>
<div class="form-group" x-show="activeForm.env">
<label class="form-label">Image Layout</label>
<div style="display:flex;gap:1.4rem">
<label class="mood-radio"><input type="radio" x-model="activeForm.env_layout" value="after" /><span>Below</span></label>
<label class="mood-radio"><input type="radio" x-model="activeForm.env_layout" value="left" /><span>Left</span></label>
<label class="mood-radio"><input type="radio" x-model="activeForm.env_layout" value="right" /><span>Right</span></label>
</div>
</div>
</div>
<div class="form-group">
@@ -1092,6 +1351,11 @@
saving: false,
tlItems: [],
_tlRows: { top: 1, bot: 1 },
// Card draw
cards: [],
drawnCard: null,
recentCardIds: [],
showCard: false,
// Timeline click chooser
tlChooser: { show: false, x: 0, y: 0, date: '' },
// Autocomplete
@@ -1121,6 +1385,7 @@
this.loading = false
return
}
this.loadCards()
const ok = await this.loadGame()
if (!ok) { this.loading = false; return }
await Promise.all([this.loadItems(), this.loadKeywords()])
@@ -1153,6 +1418,60 @@
this.tlItems = this.computeLayout()
},
async loadCards() {
try {
const r = await fetch('/assets/cards.json')
this.cards = r.ok ? await r.json() : []
} catch { this.cards = [] }
},
drawCard() {
if (!this.cards.length) return
const hasCast = this.cast().length > 0
const hasKeyword = this.allKeywords().length > 0
const hasProject = this.projects().length > 0
const meets = c => {
if (!c.requires) return true
return c.requires.every(r =>
r === 'cast' ? hasCast : r === 'keyword' ? hasKeyword : r === 'project' ? hasProject : true
)
}
const eligible = this.cards.filter(meets)
const available = eligible.filter(c => !this.recentCardIds.includes(c.id))
const pool = available.length > 0 ? available : eligible
if (!pool.length) return
const idx = Math.floor(Math.random() * pool.length)
this.drawnCard = this.resolveDynamic(pool[idx])
this.recentCardIds = [...this.recentCardIds.slice(-9), pool[idx].id]
this.showCard = true
},
resolveDynamic(card) {
const pick = arr => arr.length ? arr[Math.floor(Math.random() * arr.length)] : null
const castList = [...this.cast()]
const kwList = this.allKeywords()
const projectList = this.projects()
let usedCastIds = []
const resolve = text => text
.replace(/\{cast\}/g, () => {
const avail = castList.filter(c => !usedCastIds.includes(c.id))
const p = pick(avail.length ? avail : castList)
if (p) { usedCastIds.push(p.id); return `<em>${p.title.replace(/&/g,'&amp;').replace(/</g,'&lt;')}</em>` }
return 'a cast member'
})
.replace(/\{keyword\}/g, () => {
const p = pick(kwList)
return p ? `**${p.term}**` : 'an existing keyword'
})
.replace(/\{project\}/g, () => {
const p = pick(projectList)
return p ? `"${p.title}"` : 'an active project'
})
return { ...card, a: resolve(card.a), b: resolve(card.b) }
},
async loadKeywords() {
try {
const r = await fetch('/api/games/' + this.slug + '/keywords')
@@ -1274,6 +1593,23 @@
return `left:${e.pct}%;top:${railY}px;width:${sz}px;height:${sz}px;`
},
randomEnv(discipline) {
if (Math.random() > 0.33) return ''
const pools = {
science: ['sci-botanist','sci-specimen-hall','sci-laboratory','sci-telescope','sci-excavation','sci-weather-station','sci-specimen-tanks','sci-aquatic-lab','sci-growth-chamber','sci-herbarium','sci-globe-room','sci-paleontology'],
engineering: ['eng-blueprint','eng-scaffold','eng-survey','eng-planning-room','eng-facility','eng-construction'],
labour: ['lab-pipeline','lab-tunnel','lab-crane-lift','lab-shift-change','lab-pour','lab-solar-panels','lab-machinery','lab-transport','lab-excavator','lab-scaffold','lab-canteen','lab-archway'],
default: ['env-grand-hall','env-workshop','env-greenhouse','env-library','env-reactor','env-observatory','atm-corridor','atm-study','atm-dome-rain','atm-dawn','atm-sunset-city','atm-moonrise','atm-dust-storm','atm-reading-room','atm-breakroom','atm-cemetery','atm-festival','atm-children-play','atm-night-observatory','atm-garden-light','atm-lantern-hall','atm-blizzard'],
}
const pool = pools[discipline] || pools.default
return pool[Math.floor(Math.random() * pool.length)]
},
randomEnvLayout() {
const r = Math.random()
return r < 0.34 ? 'left' : r < 0.67 ? 'right' : 'after'
},
disciplineIcon(disc) {
return { science: '🔬', engineering: '⚙️', labour: '👷' }[disc] || ''
},
@@ -1487,6 +1823,12 @@
return result.sort((a, b) => a.term.localeCompare(b.term))
},
castUsages(name) {
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
const re = new RegExp(`@"${escaped}"`, 'i')
return this.items.filter(i => re.test(i.description || ''))
},
keywordUsages(term) {
const re = new RegExp('\\*\\*' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\*\\*', 'i')
return this.items.filter(i => re.test(i.description || ''))
@@ -1604,7 +1946,8 @@
},
openAddItem(type) {
this.activeForm = { type, title: '', description: '', mood: '', date: '', end_date: '', status: 'active', discipline: '' }
const env = this.randomEnv(null)
this.activeForm = { type, title: '', description: '', mood: '', date: '', end_date: '', status: 'active', discipline: '', env, env_layout: env ? this.randomEnvLayout() : 'after' }
this.editingId = null
this.formError = null
this.modalType = 'item'
@@ -1612,7 +1955,7 @@
},
openEditItem(item) {
this.activeForm = Object.assign({}, item)
this.activeForm = Object.assign({ env: '', env_layout: 'after' }, item)
this.editingId = item.id
this.formError = null
this.modalType = 'item'
+1 -1
View File
@@ -247,7 +247,7 @@
<div class="game-row-eyebrow">
<span x-text="game.timeline_start"></span> → <span x-text="game.timeline_end"></span>
<span class="sep"> // </span>
<span :class="game.mood === 'dark' ? 'e-dark' : ''" x-text="game.mood"></span>
<span :class="game.mood === 'dark' ? 'e-dark' : ''" x-text="game.mood === 'dark' ? '◉' : '○'"></span>
</div>
<div class="game-row-title" x-text="game.title"></div>
<div class="game-row-desc" x-show="game.description" x-text="game.description"
+5 -3
View File
@@ -146,7 +146,7 @@ app.get('/api/games/:slug/items', (req, res) => {
})
app.post('/api/games/:slug/items', requirePassword, (req, res) => {
const { type, title, description, mood, date, end_date, status, discipline } = req.body
const { type, title, description, mood, date, end_date, status, discipline, env } = req.body
if (!type || !title || !date) return res.status(400).json({ error: 'type, title, date required' })
if (!['event', 'project', 'person'].includes(type)) {
return res.status(400).json({ error: 'type must be event, project, or person' })
@@ -154,7 +154,8 @@ app.post('/api/games/:slug/items', requirePassword, (req, res) => {
const item = {
id: newId(), type, title, description: description || '',
mood: mood || null, date, end_date: end_date || null,
status: status || null, discipline: discipline || null, created_at: now()
status: status || null, discipline: discipline || null,
env: env || null, env_layout: req.body.env_layout || null, created_at: now()
}
req.game.items = req.game.items || []
req.game.items.push(item)
@@ -168,7 +169,8 @@ app.put('/api/games/:slug/items/:id', requirePassword, (req, res) => {
if (idx === -1) return res.status(404).json({ error: 'Item not found' })
const { title, description, mood, date, end_date, status, discipline } = req.body
if (!title || !date) return res.status(400).json({ error: 'title, date required' })
items[idx] = { ...items[idx], title, description: description || '', mood: mood || null, date, end_date: end_date || null, status: status || null, discipline: discipline || null }
const { env, env_layout } = req.body
items[idx] = { ...items[idx], title, description: description || '', mood: mood || null, date, end_date: end_date || null, status: status || null, discipline: discipline || null, env: env || null, env_layout: env_layout || null }
saveDB(req.db)
res.json(items[idx])
})