chore: initial deploy — SLA Industries Foundry VTT
Co-authored-by: slaguru666 <timevans666@gmail.com>
@@ -0,0 +1,15 @@
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
.npm/
|
||||
dist/
|
||||
*.min.js
|
||||
*.min.css
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
Thumbs.db
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
worlds/
|
||||
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<rect width="128" height="128" rx="24" fill="#101722"/>
|
||||
<rect x="8" y="8" width="112" height="112" rx="20" fill="none" stroke="#9a7cff" stroke-width="4"/>
|
||||
<path d="M64 18 95 34v28c0 24-14 39-31 48C47 101 33 86 33 62V34z" fill="#9a7cff" opacity=".16"/>
|
||||
<path d="M64 26 87 38v22c0 18-10 30-23 38-13-8-23-20-23-38V38z" fill="none" stroke="#9a7cff" stroke-width="4"/>
|
||||
<path d="M49 50h20c10 0 16 5 16 13 0 6-3 10-9 12 8 2 12 6 12 14 0 10-8 17-22 17H49z" fill="#f3efff"/>
|
||||
<path d="M59 58v14h8c5 0 8-3 8-7s-3-7-8-7zm0 22v15h9c6 0 10-3 10-7 0-6-4-8-10-8z" fill="#101722"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<rect width="128" height="128" rx="24" fill="#101722"/>
|
||||
<rect x="8" y="8" width="112" height="112" rx="20" fill="none" stroke="#57b3ff" stroke-width="4"/>
|
||||
<path d="M64 18 95 34v28c0 24-14 39-31 48C47 101 33 86 33 62V34z" fill="#57b3ff" opacity=".16"/>
|
||||
<path d="M64 26 87 38v22c0 18-10 30-23 38-13-8-23-20-23-38V38z" fill="none" stroke="#57b3ff" stroke-width="4"/>
|
||||
<path d="M49 50h20c10 0 16 5 16 13 0 6-3 10-9 12 8 2 12 6 12 14 0 10-8 17-22 17H49z" fill="#eef6ff"/>
|
||||
<path d="M59 58v14h8c5 0 8-3 8-7s-3-7-8-7zm0 22v15h9c6 0 10-3 10-7 0-6-4-8-10-8z" fill="#101722"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<rect width="128" height="128" rx="24" fill="#101722"/>
|
||||
<rect x="8" y="8" width="112" height="112" rx="20" fill="none" stroke="#78d48f" stroke-width="4"/>
|
||||
<path d="M64 18 95 34v28c0 24-14 39-31 48C47 101 33 86 33 62V34z" fill="#78d48f" opacity=".16"/>
|
||||
<path d="M64 26 87 38v22c0 18-10 30-23 38-13-8-23-20-23-38V38z" fill="none" stroke="#78d48f" stroke-width="4"/>
|
||||
<path d="M49 50h20c10 0 16 5 16 13 0 6-3 10-9 12 8 2 12 6 12 14 0 10-8 17-22 17H49z" fill="#effef2"/>
|
||||
<path d="M59 58v14h8c5 0 8-3 8-7s-3-7-8-7zm0 22v15h9c6 0 10-3 10-7 0-6-4-8-10-8z" fill="#101722"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<rect width="128" height="128" rx="24" fill="#101722"/>
|
||||
<rect x="8" y="8" width="112" height="112" rx="20" fill="none" stroke="#9da6b3" stroke-width="4"/>
|
||||
<path d="M64 18 95 34v28c0 24-14 39-31 48C47 101 33 86 33 62V34z" fill="#9da6b3" opacity=".16"/>
|
||||
<path d="M64 26 87 38v22c0 18-10 30-23 38-13-8-23-20-23-38V38z" fill="none" stroke="#9da6b3" stroke-width="4"/>
|
||||
<path d="M49 50h20c10 0 16 5 16 13 0 6-3 10-9 12 8 2 12 6 12 14 0 10-8 17-22 17H49z" fill="#f2f4f7"/>
|
||||
<path d="M59 58v14h8c5 0 8-3 8-7s-3-7-8-7zm0 22v15h9c6 0 10-3 10-7 0-6-4-8-10-8z" fill="#101722"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<rect width="128" height="128" rx="24" fill="#101722"/>
|
||||
<rect x="8" y="8" width="112" height="112" rx="20" fill="none" stroke="#41d0a3" stroke-width="4"/>
|
||||
<path d="M64 18 95 34v28c0 24-14 39-31 48C47 101 33 86 33 62V34z" fill="#41d0a3" opacity=".16"/>
|
||||
<path d="M64 26 87 38v22c0 18-10 30-23 38-13-8-23-20-23-38V38z" fill="none" stroke="#41d0a3" stroke-width="4"/>
|
||||
<path d="M49 50h20c10 0 16 5 16 13 0 6-3 10-9 12 8 2 12 6 12 14 0 10-8 17-22 17H49z" fill="#eefef9"/>
|
||||
<path d="M59 58v14h8c5 0 8-3 8-7s-3-7-8-7zm0 22v15h9c6 0 10-3 10-7 0-6-4-8-10-8z" fill="#101722"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<rect width="128" height="128" rx="24" fill="#101722"/>
|
||||
<rect x="8" y="8" width="112" height="112" rx="20" fill="none" stroke="#f5f0d7" stroke-width="4"/>
|
||||
<path d="M64 18 95 34v28c0 24-14 39-31 48C47 101 33 86 33 62V34z" fill="#f5f0d7" opacity=".16"/>
|
||||
<path d="M64 26 87 38v22c0 18-10 30-23 38-13-8-23-20-23-38V38z" fill="none" stroke="#f5f0d7" stroke-width="4"/>
|
||||
<path d="M49 50h20c10 0 16 5 16 13 0 6-3 10-9 12 8 2 12 6 12 14 0 10-8 17-22 17H49z" fill="#fffdf6"/>
|
||||
<path d="M59 58v14h8c5 0 8-3 8-7s-3-7-8-7zm0 22v15h9c6 0 10-3 10-7 0-6-4-8-10-8z" fill="#101722"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<rect width="128" height="128" rx="24" fill="#101722"/>
|
||||
<rect x="8" y="8" width="112" height="112" rx="20" fill="none" stroke="#ff6f6f" stroke-width="4"/>
|
||||
<path d="M64 18 95 34v28c0 24-14 39-31 48C47 101 33 86 33 62V34z" fill="#ff6f6f" opacity=".16"/>
|
||||
<path d="M64 26 87 38v22c0 18-10 30-23 38-13-8-23-20-23-38V38z" fill="none" stroke="#ff6f6f" stroke-width="4"/>
|
||||
<path d="M49 50h20c10 0 16 5 16 13 0 6-3 10-9 12 8 2 12 6 12 14 0 10-8 17-22 17H49z" fill="#fff0f0"/>
|
||||
<path d="M59 58v14h8c5 0 8-3 8-7s-3-7-8-7zm0 22v15h9c6 0 10-3 10-7 0-6-4-8-10-8z" fill="#101722"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<rect width="128" height="128" rx="24" fill="#101722"/>
|
||||
<rect x="8" y="8" width="112" height="112" rx="20" fill="none" stroke="#d7dee8" stroke-width="4"/>
|
||||
<path d="M64 18 95 34v28c0 24-14 39-31 48C47 101 33 86 33 62V34z" fill="#d7dee8" opacity=".16"/>
|
||||
<path d="M64 26 87 38v22c0 18-10 30-23 38-13-8-23-20-23-38V38z" fill="none" stroke="#d7dee8" stroke-width="4"/>
|
||||
<path d="M49 50h20c10 0 16 5 16 13 0 6-3 10-9 12 8 2 12 6 12 14 0 10-8 17-22 17H49z" fill="#fbfdff"/>
|
||||
<path d="M59 58v14h8c5 0 8-3 8-7s-3-7-8-7zm0 22v15h9c6 0 10-3 10-7 0-6-4-8-10-8z" fill="#101722"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<rect width="128" height="128" rx="24" fill="#101722"/>
|
||||
<rect x="8" y="8" width="112" height="112" rx="20" fill="none" stroke="#dce8f9" stroke-width="4"/>
|
||||
<path d="M64 18 95 34v28c0 24-14 39-31 48C47 101 33 86 33 62V34z" fill="#dce8f9" opacity=".16"/>
|
||||
<path d="M64 26 87 38v22c0 18-10 30-23 38-13-8-23-20-23-38V38z" fill="none" stroke="#dce8f9" stroke-width="4"/>
|
||||
<path d="M49 50h20c10 0 16 5 16 13 0 6-3 10-9 12 8 2 12 6 12 14 0 10-8 17-22 17H49z" fill="#ffffff"/>
|
||||
<path d="M59 58v14h8c5 0 8-3 8-7s-3-7-8-7zm0 22v15h9c6 0 10-3 10-7 0-6-4-8-10-8z" fill="#101722"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<rect width="128" height="128" rx="24" fill="#101722"/>
|
||||
<rect x="8" y="8" width="112" height="112" rx="20" fill="none" stroke="#ffdb6e" stroke-width="4"/>
|
||||
<path d="M64 18 95 34v28c0 24-14 39-31 48C47 101 33 86 33 62V34z" fill="#ffdb6e" opacity=".16"/>
|
||||
<path d="M64 26 87 38v22c0 18-10 30-23 38-13-8-23-20-23-38V38z" fill="none" stroke="#ffdb6e" stroke-width="4"/>
|
||||
<path d="M49 50h20c10 0 16 5 16 13 0 6-3 10-9 12 8 2 12 6 12 14 0 10-8 17-22 17H49z" fill="#fff8de"/>
|
||||
<path d="M59 58v14h8c5 0 8-3 8-7s-3-7-8-7zm0 22v15h9c6 0 10-3 10-7 0-6-4-8-10-8z" fill="#101722"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1,352 @@
|
||||
{
|
||||
"colours": [
|
||||
{
|
||||
"key": "blue",
|
||||
"label": "Blue",
|
||||
"type": "Street Maintenance",
|
||||
"summary": "Street maintenance and dirty clean-up contracts.",
|
||||
"details": "Sewer clearances, vermin extermination, infrastructure support, and low-end evictions.",
|
||||
"sclReq": "10 - 9",
|
||||
"sclRange": { "min": 0.05, "typical": 0.1, "max": 0.2 },
|
||||
"cbsPerOpRange": { "min": 50, "max": 150 },
|
||||
"cbsPerSquadRange": { "min": 100, "max": 300 },
|
||||
"mediaCoverage": "Rare / None"
|
||||
},
|
||||
{
|
||||
"key": "yellow",
|
||||
"label": "Yellow",
|
||||
"type": "Retrieval",
|
||||
"summary": "Recover a person, item, data package, or specimen.",
|
||||
"details": "Primary objective is bring it back, often issued by Housing, Cloak, or Karma.",
|
||||
"sclReq": "10 - 9",
|
||||
"sclRange": { "min": 0.05, "typical": 0.1, "max": 0.2 },
|
||||
"cbsPerOpRange": { "min": 100, "max": 200 },
|
||||
"cbsPerSquadRange": { "min": 200, "max": 400 },
|
||||
"mediaCoverage": "Station Analysis / None"
|
||||
},
|
||||
{
|
||||
"key": "green",
|
||||
"label": "Green",
|
||||
"type": "Cloak / Extermination",
|
||||
"summary": "Combat-focused extermination and suppression assignments.",
|
||||
"details": "Kill or capture designated threats before they escalate into full emergency response.",
|
||||
"sclReq": "10 - 8",
|
||||
"sclRange": { "min": 0.1, "typical": 0.1, "max": 0.3 },
|
||||
"cbsPerOpRange": { "min": 100, "max": 250 },
|
||||
"cbsPerSquadRange": { "min": 200, "max": 500 },
|
||||
"mediaCoverage": "Station Analysis / Third Eye"
|
||||
},
|
||||
{
|
||||
"key": "white",
|
||||
"label": "White",
|
||||
"type": "Investigation",
|
||||
"summary": "Detective and analytical assignments.",
|
||||
"details": "Evidence-led cases with witness work, profiling, and pattern analysis.",
|
||||
"sclReq": "10 - 7",
|
||||
"sclRange": { "min": 0.1, "typical": 0.1, "max": 0.3 },
|
||||
"cbsPerOpRange": { "min": 150, "max": 300 },
|
||||
"cbsPerSquadRange": { "min": 250, "max": 500 },
|
||||
"mediaCoverage": "Third Eye / Station Analysis"
|
||||
},
|
||||
{
|
||||
"key": "grey",
|
||||
"label": "Grey",
|
||||
"type": "Departmental Enforcement / Corporate",
|
||||
"summary": "Internal enforcement and politically sensitive corporate work.",
|
||||
"details": "Escort, asset protection, audit support, and departmentally awkward clean-ups.",
|
||||
"sclReq": "9 - 7",
|
||||
"sclRange": { "min": 0.1, "typical": 0.2, "max": 0.3 },
|
||||
"cbsPerOpRange": { "min": 200, "max": 400 },
|
||||
"cbsPerSquadRange": { "min": 300, "max": 600 },
|
||||
"mediaCoverage": "Station Analysis"
|
||||
},
|
||||
{
|
||||
"key": "silver",
|
||||
"label": "Silver",
|
||||
"type": "Diplomatic / Escort / PR",
|
||||
"summary": "High-profile, social, and reputation-sensitive contracts.",
|
||||
"details": "VIP escort, public appearances, negotiations, and camera-facing operations.",
|
||||
"sclReq": "9 - 6",
|
||||
"sclRange": { "min": 0.1, "typical": 0.2, "max": 0.4 },
|
||||
"cbsPerOpRange": { "min": 200, "max": 500 },
|
||||
"cbsPerSquadRange": { "min": 300, "max": 800 },
|
||||
"mediaCoverage": "Third Eye / GoreZone"
|
||||
},
|
||||
{
|
||||
"key": "jade",
|
||||
"label": "Jade",
|
||||
"type": "Environmental / Biohazard",
|
||||
"summary": "Containment and neutralisation of biological and chemical threats.",
|
||||
"details": "Biohazard incidents, toxic leaks, mutations, and containment failures.",
|
||||
"sclReq": "9 - 6",
|
||||
"sclRange": { "min": 0.1, "typical": 0.2, "max": 0.4 },
|
||||
"cbsPerOpRange": { "min": 250, "max": 500 },
|
||||
"cbsPerSquadRange": { "min": 400, "max": 800 },
|
||||
"mediaCoverage": "Third Eye / Contract Circuit"
|
||||
},
|
||||
{
|
||||
"key": "red",
|
||||
"label": "Red",
|
||||
"type": "Emergency Response",
|
||||
"summary": "Crisis-response and red-alert operations.",
|
||||
"details": "Riots, terror incidents, major failures, and high-risk live-response deployments.",
|
||||
"sclReq": "10 - 5",
|
||||
"sclRange": { "min": 0.1, "typical": 0.2, "max": 0.5 },
|
||||
"cbsPerOpRange": { "min": 200, "max": 500 },
|
||||
"cbsPerSquadRange": { "min": 300, "max": 1000 },
|
||||
"mediaCoverage": "Third Eye / GoreZone"
|
||||
},
|
||||
{
|
||||
"key": "black",
|
||||
"label": "Black",
|
||||
"type": "Covert / Black Ops",
|
||||
"summary": "Classified, deniable, and often off-record operations.",
|
||||
"details": "Assassination, sabotage, deep infiltration, and disavowed clean-up actions.",
|
||||
"sclReq": "7 - 4",
|
||||
"sclRange": { "min": 0.2, "typical": 0.4, "max": 0.7 },
|
||||
"cbsPerOpRange": { "min": 500, "max": 1000 },
|
||||
"cbsPerSquadRange": { "min": 800, "max": 2000 },
|
||||
"mediaCoverage": "None (classified)"
|
||||
},
|
||||
{
|
||||
"key": "platinum",
|
||||
"label": "Platinum",
|
||||
"type": "Head Office / Top Secret",
|
||||
"summary": "Highest-level Head Office operations.",
|
||||
"details": "World-shaping, deeply classified, and politically lethal assignments.",
|
||||
"sclReq": "5 - 1",
|
||||
"sclRange": { "min": 0.3, "typical": 0.5, "max": 1.0 },
|
||||
"cbsPerOpRange": { "min": 1000, "max": null },
|
||||
"cbsPerSquadRange": { "min": 1500, "max": null },
|
||||
"mediaCoverage": "Classified / Special"
|
||||
}
|
||||
],
|
||||
"colourRollTable": [
|
||||
{ "min": 1, "max": 4, "key": "blue" },
|
||||
{ "min": 5, "max": 7, "key": "yellow" },
|
||||
{ "min": 8, "max": 9, "key": "green" },
|
||||
{ "min": 10, "max": 12, "key": "white" },
|
||||
{ "min": 13, "max": 13, "key": "grey" },
|
||||
{ "min": 14, "max": 14, "key": "silver" },
|
||||
{ "min": 15, "max": 15, "key": "jade" },
|
||||
{ "min": 16, "max": 17, "key": "red" },
|
||||
{ "min": 18, "max": 18, "key": "black" },
|
||||
{ "min": 19, "max": 19, "key": "black" },
|
||||
{ "min": 20, "max": 20, "key": "platinum" }
|
||||
],
|
||||
"missionFocus": [
|
||||
"Eliminate a threat before it reaches public view.",
|
||||
"Capture a target alive for interrogation.",
|
||||
"Protect or escort a person through a hostile district.",
|
||||
"Protect or escort a cargo asset.",
|
||||
"Retrieve an item or specimen intact.",
|
||||
"Retrieve data or recordings without contamination.",
|
||||
"Investigate a crime scene with political fallout.",
|
||||
"Profile and locate a serial killer before media lock-on.",
|
||||
"Contain or quarantine an outbreak or Ebb event.",
|
||||
"Crowd control and riot suppression under cameras.",
|
||||
"Hunt a named hostile and confirm status.",
|
||||
"Clean up an old SLA operational mess."
|
||||
],
|
||||
"locations": [
|
||||
"Downtown backstreets.",
|
||||
"Sewer network and maintenance tunnels.",
|
||||
"Industrial sector and power spine.",
|
||||
"Residential block or tenement arc.",
|
||||
"Transit system and monorail stations.",
|
||||
"Cannibal Sector perimeter.",
|
||||
"Corporate laboratory or asset vault.",
|
||||
"Nightclub and entertainment block.",
|
||||
"Broadcast tower and media hub.",
|
||||
"Hospital, triage zone, or Karma lab."
|
||||
],
|
||||
"opposition": [
|
||||
"Street gang with light arms and local lookouts.",
|
||||
"Organised crime syndicate with political backing.",
|
||||
"Serial killer cell already moving to a second target.",
|
||||
"DarkNight agents with a deniable brief.",
|
||||
"Carrien pack using service tunnels.",
|
||||
"Rogue biogenetic asset or escaped Stormer variant.",
|
||||
"Rival SLA squad chasing the same payout.",
|
||||
"Corrupt Shivers protecting the wrong people.",
|
||||
"Cultists, Sh'ien influence, or Ebb residue.",
|
||||
"Corporate security with strict no-survivor orders."
|
||||
],
|
||||
"complications": [
|
||||
"The issuing department withheld one critical fact.",
|
||||
"Third Eye goes live before the squad enters the zone.",
|
||||
"A witness can identify one operative by name.",
|
||||
"The target is embedded in civilians.",
|
||||
"The package is alive and unstable.",
|
||||
"Transit lockdown traps everyone inside the district.",
|
||||
"The real employer is not the signatory on the BPN.",
|
||||
"L.A.D. response in the zone is unreliable.",
|
||||
"Communications are jammed or intercepted.",
|
||||
"The BPN is partly a ratings play dressed up as emergency work."
|
||||
],
|
||||
"colourMissionIdeas": {
|
||||
"blue": [
|
||||
"Clear out Carrien and secure the pump station before repairs begin.",
|
||||
"Survey a derelict subway spur and mark safe lanes for clean-up crews.",
|
||||
"Evict a low-level gang from a recycling depot without wrecking the machinery."
|
||||
],
|
||||
"yellow": [
|
||||
"Recover a stolen prototype before it disappears through the black market.",
|
||||
"Locate a missing departmental courier and return the carried drives intact.",
|
||||
"Retrieve a captured informant before rivals extract anything useful."
|
||||
],
|
||||
"green": [
|
||||
"Neutralise a threat before it can trigger full emergency escalation.",
|
||||
"Sweep a district after repeated monster sightings and stop the panic source.",
|
||||
"Guard a prisoner transfer while hostile assets try to reclaim the cargo."
|
||||
],
|
||||
"white": [
|
||||
"Uncover who is issuing forged BPNs to lure squads into ambushes.",
|
||||
"Trace sabotaged SLA-manufactured ammo back to the source.",
|
||||
"Link a string of identical killings across multiple sectors."
|
||||
],
|
||||
"grey": [
|
||||
"Protect engineers installing surveillance hardware in a tense district.",
|
||||
"Assist a corporate audit team investigating missing shipments.",
|
||||
"Guard a prototype vehicle during a live test run."
|
||||
],
|
||||
"silver": [
|
||||
"Escort a diplomatic envoy without provoking a public incident.",
|
||||
"Keep a sponsor-backed appearance alive while controlling optics.",
|
||||
"Secure a high-profile interview venue before the cameras roll."
|
||||
],
|
||||
"jade": [
|
||||
"Contain a biohazard leak in a mixed-use block and secure samples.",
|
||||
"Neutralise a mutated outbreak before it reaches transport lines.",
|
||||
"Lock down a failed research ward and extract surviving technicians."
|
||||
],
|
||||
"red": [
|
||||
"Board a hijacked monorail in motion and rescue the hostages.",
|
||||
"Retake a broadcast tower seized by extremists.",
|
||||
"Stabilise a district where fires, looters, and panic are all spreading."
|
||||
],
|
||||
"black": [
|
||||
"Infiltrate a sealed compound, remove a target, and leave no public trace.",
|
||||
"Sabotage a rival operation and redirect blame elsewhere.",
|
||||
"Extract records from an internal vault while command denies the mission exists."
|
||||
],
|
||||
"platinum": [
|
||||
"Recover a lost prototype before anyone realises it escaped.",
|
||||
"Investigate an off-limits sector where sensors keep going dark.",
|
||||
"Quietly remove an inconvenient public hero from the board."
|
||||
]
|
||||
},
|
||||
"contactRoles": [
|
||||
"Shiver precinct liaison",
|
||||
"Mort Department dispatcher",
|
||||
"Department-M observer",
|
||||
"Corporate asset handler",
|
||||
"Embedded media fixer",
|
||||
"Sector security captain",
|
||||
"Karma field scientist",
|
||||
"Independent financier",
|
||||
"Freelance financier",
|
||||
"Darkfinder case officer"
|
||||
],
|
||||
"contactFirstNames": [
|
||||
"Anika",
|
||||
"Blaine",
|
||||
"Caro",
|
||||
"Drex",
|
||||
"Ephra",
|
||||
"Fenn",
|
||||
"Galia",
|
||||
"Havel",
|
||||
"Iona",
|
||||
"Jarek",
|
||||
"Kiva",
|
||||
"Luther",
|
||||
"Mara",
|
||||
"Nikol",
|
||||
"Orin",
|
||||
"Petra"
|
||||
],
|
||||
"contactLastNames": [
|
||||
"Voss",
|
||||
"Kane",
|
||||
"Talon",
|
||||
"Mercer",
|
||||
"Sloane",
|
||||
"Varik",
|
||||
"Drahl",
|
||||
"Kessler",
|
||||
"Morn",
|
||||
"Black",
|
||||
"Harrow",
|
||||
"Vale",
|
||||
"Kestral",
|
||||
"Renn",
|
||||
"Soren",
|
||||
"Yarrow"
|
||||
],
|
||||
"civilianFactions": [
|
||||
"Local residents trying to keep their block standing.",
|
||||
"Black-market traders who know the unofficial routes.",
|
||||
"A fan club for a specific operative or squad.",
|
||||
"A semi-legal street clinic with decent gear and bad ties.",
|
||||
"Displaced refugees from a devastated sector.",
|
||||
"A corporate outreach team doing smiling PR work."
|
||||
],
|
||||
"oppositionAttitudes": [
|
||||
"Underestimate the squad and get cocky.",
|
||||
"Are terrified of SLA but cornered and desperate.",
|
||||
"See the squad as expendable obstacles, not people.",
|
||||
"Are only in it for the money.",
|
||||
"Hope to cut a deal or run rather than die.",
|
||||
"Use the squad as a distraction for a bigger move."
|
||||
],
|
||||
"atmospheres": [
|
||||
"Oppressive rain, thunder, and ankle-deep water in the streets.",
|
||||
"Chemical smog and neon halos around every light source.",
|
||||
"Rolling blackouts, flicker failures, and generator hum.",
|
||||
"Industrial noise and heavy machine vibration.",
|
||||
"Crowded streets with sale events or festivals in progress.",
|
||||
"Curfew with Shivers on every corner and everyone watching."
|
||||
],
|
||||
"localTwists": [
|
||||
"The district is regarded as cursed by locals.",
|
||||
"A recent promo shoot left half-finished set pieces everywhere.",
|
||||
"A minor celebrity is present and drawing attention.",
|
||||
"Surveillance coverage is patchy or disabled.",
|
||||
"Someone is independently live-streaming the operation.",
|
||||
"A rival squad failed a BPN here recently and left damage behind."
|
||||
],
|
||||
"extraObjectives": [
|
||||
"Capture at least one enemy alive for interrogation.",
|
||||
"Recover specific data intact with no EMP or overkill.",
|
||||
"Ensure a particular building remains undamaged.",
|
||||
"Plant a tracking device unnoticed.",
|
||||
"Secure a specific piece of gear for a sponsor.",
|
||||
"Ensure that no civilians witness one critical event."
|
||||
],
|
||||
"escalationEvents": [
|
||||
"Opposition reinforcements arrive mid-operation.",
|
||||
"The environment becomes more dangerous: fire, flood, or collapse.",
|
||||
"Media crews show up and start reframing the mission.",
|
||||
"A key NPC flees, forcing an ugly pursuit.",
|
||||
"Communications fail at the worst possible moment.",
|
||||
"A supposedly neutral faction chooses a side."
|
||||
],
|
||||
"issuingDepartments": [
|
||||
"Mort Department / Ops Control",
|
||||
"Department-M / Internal Containment",
|
||||
"Shiver Command Liaison Desk",
|
||||
"Karma Hazard Response",
|
||||
"Cloak Tactical Oversight",
|
||||
"Media Relations / Sponsor Operations",
|
||||
"Head Office Special Assignments"
|
||||
],
|
||||
"mediaOptions": [
|
||||
"None",
|
||||
"Rare / None",
|
||||
"Station Analysis",
|
||||
"Third Eye News",
|
||||
"GoreZone / Contract Circuit Special",
|
||||
"Classified / Special"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"SLABPNDispatch.Title": "SLA BPN Dispatch"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"id": "sla-bpn-dispatch",
|
||||
"title": "SLA BPN Dispatch",
|
||||
"description": "Creates random SLA BPN briefings and matching GM debrief journals using SLA mission colour logic.",
|
||||
"version": "0.3.0",
|
||||
"compatibility": {
|
||||
"minimum": "13",
|
||||
"verified": "13.350",
|
||||
"maximum": "13"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Tim Evans"
|
||||
}
|
||||
],
|
||||
"esmodules": [
|
||||
"module/sla-bpn-dispatch.mjs"
|
||||
],
|
||||
"styles": [
|
||||
"styles/sla-bpn-dispatch.css"
|
||||
],
|
||||
"languages": [
|
||||
{
|
||||
"lang": "en",
|
||||
"name": "English",
|
||||
"path": "lang/en.json"
|
||||
}
|
||||
],
|
||||
"manifest": "https://raw.githubusercontent.com/slaguru666/sla-bpn-dispatch/main/module.json",
|
||||
"download": "https://github.com/slaguru666/sla-bpn-dispatch/releases/latest/download/sla-bpn-dispatch.zip",
|
||||
"url": "https://github.com/slaguru666/sla-bpn-dispatch"
|
||||
}
|
||||
@@ -0,0 +1,471 @@
|
||||
.sla-bpn-dispatch {
|
||||
font-family: "Trebuchet MS", "Arial", sans-serif;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch .window-content {
|
||||
background:
|
||||
radial-gradient(circle at top right, rgba(255, 255, 255, 0.06), transparent 28%),
|
||||
linear-gradient(180deg, #0d1117 0%, #151d27 56%, #11151d 100%);
|
||||
color: #edf3fb !important;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-form {
|
||||
--panel: rgba(18, 24, 34, 0.92);
|
||||
--panel-alt: rgba(11, 16, 24, 0.9);
|
||||
--line: rgba(255, 255, 255, 0.11);
|
||||
--soft: rgba(255, 255, 255, 0.68);
|
||||
--text: #edf3fb;
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
padding: 4px;
|
||||
background-image:
|
||||
linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch .window-title,
|
||||
.sla-bpn-dispatch p,
|
||||
.sla-bpn-dispatch span,
|
||||
.sla-bpn-dispatch strong,
|
||||
.sla-bpn-dispatch label,
|
||||
.sla-bpn-dispatch h1,
|
||||
.sla-bpn-dispatch h2,
|
||||
.sla-bpn-dispatch h3,
|
||||
.sla-bpn-dispatch input,
|
||||
.sla-bpn-dispatch select,
|
||||
.sla-bpn-dispatch textarea,
|
||||
.sla-bpn-dispatch option {
|
||||
color: var(--text) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-hero {
|
||||
display: grid;
|
||||
grid-template-columns: 150px 1fr 310px;
|
||||
gap: 14px;
|
||||
align-items: stretch;
|
||||
padding: 16px;
|
||||
border: 1px solid color-mix(in srgb, var(--bpn-accent) 55%, transparent);
|
||||
border-radius: 18px;
|
||||
background:
|
||||
linear-gradient(135deg, color-mix(in srgb, var(--bpn-accent) 16%, transparent), transparent 45%),
|
||||
linear-gradient(180deg, rgba(21, 28, 39, 0.95), rgba(8, 13, 20, 0.97));
|
||||
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.03) inset, 0 18px 32px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
.sla-bpn-hero-band {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
align-content: center;
|
||||
min-height: 112px;
|
||||
border-radius: 14px;
|
||||
background:
|
||||
linear-gradient(180deg, color-mix(in srgb, var(--bpn-accent) 25%, #0c1119), #0d1117);
|
||||
border: 1px solid color-mix(in srgb, var(--bpn-accent) 58%, transparent);
|
||||
font-size: 1.25rem;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sla-bpn-hero-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.sla-bpn-hero-band-label {
|
||||
line-height: 1.05;
|
||||
}
|
||||
|
||||
.sla-bpn-overline {
|
||||
font-size: 0.74rem;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: color-mix(in srgb, var(--bpn-accent) 66%, #dce6f3) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-hero-copy h1 {
|
||||
margin: 8px 0 4px;
|
||||
font-size: 2rem;
|
||||
line-height: 1.05;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.sla-bpn-hero-copy p {
|
||||
margin: 0;
|
||||
color: var(--soft) !important;
|
||||
font-size: 0.98rem;
|
||||
}
|
||||
|
||||
.sla-bpn-hero-meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.sla-bpn-chip {
|
||||
padding: 10px 12px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, 0.035);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.sla-bpn-chip span {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: color-mix(in srgb, var(--bpn-accent) 55%, #dde7f5) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-chip strong {
|
||||
font-size: 1rem;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-grid--top,
|
||||
.sla-bpn-dispatch-grid--meta {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-grid--top {
|
||||
grid-template-columns: 1.15fr 1fr 0.9fr 1fr;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-field,
|
||||
.sla-bpn-dispatch-card {
|
||||
position: relative;
|
||||
padding: 12px 14px;
|
||||
border-radius: 16px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(27, 35, 48, 0.92), rgba(13, 18, 26, 0.95));
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-field::before,
|
||||
.sla-bpn-dispatch-card::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0 auto 0 0;
|
||||
width: 4px;
|
||||
border-radius: 16px 0 0 16px;
|
||||
background: linear-gradient(180deg, var(--bpn-accent), transparent);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-field label,
|
||||
.sla-bpn-dispatch-card h3 {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 0.74rem;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: color-mix(in srgb, var(--bpn-accent) 55%, #ebf4ff) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-card p {
|
||||
margin: 0 0 8px;
|
||||
color: #f2f6fd !important;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-card p strong {
|
||||
color: var(--bpn-accent) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-field input,
|
||||
.sla-bpn-dispatch-field select,
|
||||
.sla-bpn-dispatch-field textarea {
|
||||
width: 100%;
|
||||
padding: 10px 12px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
background: rgba(5, 9, 14, 0.48);
|
||||
color: #f5f8fd !important;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-field textarea {
|
||||
min-height: 90px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.sla-bpn-field-help {
|
||||
margin-top: 8px;
|
||||
font-size: 0.72rem;
|
||||
line-height: 1.25;
|
||||
color: color-mix(in srgb, var(--bpn-accent) 38%, #c2cfdf) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-field--wide textarea,
|
||||
.sla-bpn-dispatch-field textarea[name="missionBrief"] {
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-field--danger {
|
||||
background:
|
||||
linear-gradient(180deg, rgba(45, 21, 28, 0.9), rgba(18, 11, 16, 0.96));
|
||||
border-color: rgba(255, 123, 123, 0.18);
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-actions button,
|
||||
.sla-bpn-dispatch-open,
|
||||
.sla-bpn-dispatch-settings-open {
|
||||
border-radius: 999px;
|
||||
border: 1px solid color-mix(in srgb, var(--bpn-accent) 45%, rgba(255,255,255,0.2)) !important;
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--bpn-accent) 48%, #f7d17d), color-mix(in srgb, var(--bpn-accent) 36%, #8f631d)) !important;
|
||||
color: #111317 !important;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
padding: 10px 16px;
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-launch-row {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 6px 0 0;
|
||||
}
|
||||
|
||||
.journal-sidebar .sla-bpn-dispatch-launch-row .sla-bpn-dispatch-open,
|
||||
.tab.journal .sla-bpn-dispatch-launch-row .sla-bpn-dispatch-open,
|
||||
.sla-bpn-dispatch-launch-row .sla-bpn-dispatch-open {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #f8f2e3 !important;
|
||||
background: linear-gradient(180deg, #1d2430, #10161f) !important;
|
||||
border: 1px solid color-mix(in srgb, var(--bpn-accent) 38%, #ffb174) !important;
|
||||
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-actions button:hover,
|
||||
.sla-bpn-dispatch-open:hover,
|
||||
.sla-bpn-dispatch-settings-open:hover {
|
||||
filter: brightness(1.06);
|
||||
}
|
||||
|
||||
.sla-bpn-dispatch-form[data-colour-key="red"] .sla-bpn-hero,
|
||||
.sla-bpn-dispatch-form[data-colour-key="black"] .sla-bpn-hero,
|
||||
.sla-bpn-dispatch-form[data-colour-key="jade"] .sla-bpn-hero {
|
||||
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.03) inset, 0 18px 32px rgba(0, 0, 0, 0.36), 0 0 28px color-mix(in srgb, var(--bpn-accent) 18%, transparent);
|
||||
}
|
||||
|
||||
.chat-message .sla-bpn-chat {
|
||||
--bpn-accent: #dce8f9;
|
||||
color: #181512 !important;
|
||||
background:
|
||||
radial-gradient(circle at top right, rgba(0,0,0,0.04), transparent 30%),
|
||||
linear-gradient(180deg, #f0ead8 0%, #e6ddc6 100%);
|
||||
border: 1px solid rgba(56, 43, 20, 0.18);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__hero {
|
||||
display: grid;
|
||||
grid-template-columns: 64px 1fr;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
padding: 14px;
|
||||
background:
|
||||
linear-gradient(90deg, color-mix(in srgb, var(--bpn-accent) 28%, transparent), transparent 50%),
|
||||
rgba(16, 20, 27, 0.94);
|
||||
}
|
||||
|
||||
.sla-bpn-chat__icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__eyebrow {
|
||||
font-size: 0.66rem;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: color-mix(in srgb, var(--bpn-accent) 70%, #ffffff) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__heading h3,
|
||||
.sla-bpn-chat__heading p {
|
||||
margin: 0;
|
||||
color: #f4f7fb !important;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__heading h3 {
|
||||
font-size: 1.55rem;
|
||||
line-height: 1;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__heading p {
|
||||
margin-top: 6px;
|
||||
font-weight: 700;
|
||||
color: color-mix(in srgb, var(--bpn-accent) 32%, #f4f7fb) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__body {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__brief {
|
||||
margin: 0 0 12px;
|
||||
font-size: 1rem;
|
||||
line-height: 1.42;
|
||||
color: #211b15 !important;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__grid div {
|
||||
padding: 10px 12px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255,255,255,0.46);
|
||||
border: 1px solid rgba(56, 43, 20, 0.12);
|
||||
}
|
||||
|
||||
.sla-bpn-chat__grid strong,
|
||||
.sla-bpn-chat__grid span,
|
||||
.sla-bpn-chat__grid em {
|
||||
display: block;
|
||||
color: #191613 !important;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__grid strong {
|
||||
margin-bottom: 4px;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.sla-bpn-chat__grid em {
|
||||
margin-top: 4px;
|
||||
opacity: 0.72;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.sla-bpn-journal {
|
||||
--bpn-accent: #dce8f9;
|
||||
color: #181512;
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.sla-bpn-journal__hero {
|
||||
display: grid;
|
||||
grid-template-columns: 88px 1fr;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
padding: 18px;
|
||||
border-radius: 18px;
|
||||
background:
|
||||
linear-gradient(90deg, color-mix(in srgb, var(--bpn-accent) 22%, transparent), transparent 45%),
|
||||
linear-gradient(180deg, #161c24, #10161e);
|
||||
}
|
||||
|
||||
.sla-bpn-journal__icon {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
}
|
||||
|
||||
.sla-bpn-journal__eyebrow {
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: color-mix(in srgb, var(--bpn-accent) 68%, #ffffff) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-journal__hero h2,
|
||||
.sla-bpn-journal__hero p {
|
||||
margin: 0;
|
||||
color: #f6f8fc !important;
|
||||
}
|
||||
|
||||
.sla-bpn-journal__hero h2 {
|
||||
margin-top: 6px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.sla-bpn-journal__hero p {
|
||||
margin-top: 8px;
|
||||
color: color-mix(in srgb, var(--bpn-accent) 35%, #f6f8fc) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-journal__meta,
|
||||
.sla-bpn-journal__grid {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.sla-bpn-journal__meta {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.sla-bpn-journal__grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.sla-bpn-journal__meta div,
|
||||
.sla-bpn-journal__grid div,
|
||||
.sla-bpn-journal__briefing {
|
||||
padding: 14px 16px;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(180deg, #f4eddb, #e6dcc5);
|
||||
border: 1px solid rgba(72, 54, 24, 0.16);
|
||||
}
|
||||
|
||||
.sla-bpn-journal__meta strong,
|
||||
.sla-bpn-journal__grid strong,
|
||||
.sla-bpn-journal__briefing h3 {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
font-size: 0.76rem;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: color-mix(in srgb, var(--bpn-accent) 40%, #312615) !important;
|
||||
}
|
||||
|
||||
.sla-bpn-journal__meta span,
|
||||
.sla-bpn-journal__grid span,
|
||||
.sla-bpn-journal__briefing p {
|
||||
color: #1b1712 !important;
|
||||
}
|
||||
|
||||
@media (max-width: 960px) {
|
||||
.sla-bpn-hero {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sla-bpn-hero-meta,
|
||||
.sla-bpn-dispatch-grid--top,
|
||||
.sla-bpn-dispatch-grid--meta,
|
||||
.sla-bpn-dispatch-grid,
|
||||
.sla-bpn-chat__grid,
|
||||
.sla-bpn-journal__meta,
|
||||
.sla-bpn-journal__grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<form class="sla-bpn-dispatch-form" data-colour-key="{{draft.colourKey}}" style="--bpn-accent: {{draft.colourAccent}};">
|
||||
<header class="sla-bpn-hero">
|
||||
<div class="sla-bpn-hero-band">
|
||||
<img class="sla-bpn-hero-icon" src="{{draft.iconPath}}" alt="{{draft.colourLabel}} BPN">
|
||||
<div class="sla-bpn-hero-band-label">{{draft.colourLabel}} BPN</div>
|
||||
</div>
|
||||
<div class="sla-bpn-hero-copy">
|
||||
<div class="sla-bpn-overline">SLA INDUSTRIES // CORPORATE DISPATCH GRID</div>
|
||||
<h1>{{draft.shortTitle}}</h1>
|
||||
<p>{{draft.colourType}} // {{draft.colourSummary}}</p>
|
||||
</div>
|
||||
<div class="sla-bpn-hero-meta">
|
||||
<div class="sla-bpn-chip">
|
||||
<span>BPN ID</span>
|
||||
<strong>{{draft.bpnId}}</strong>
|
||||
</div>
|
||||
<div class="sla-bpn-chip">
|
||||
<span>SCL</span>
|
||||
<strong>{{draft.sclRequirement}}</strong>
|
||||
</div>
|
||||
<div class="sla-bpn-chip">
|
||||
<span>Gross</span>
|
||||
<strong>{{draft.grossContract}}</strong>
|
||||
</div>
|
||||
<div class="sla-bpn-chip">
|
||||
<span>Take-home</span>
|
||||
<strong>{{draft.estimatedTakeHomeEach}}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="sla-bpn-dispatch-grid sla-bpn-dispatch-grid--top">
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Job Name</label>
|
||||
<input type="text" name="shortTitle" value="{{draft.shortTitle}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>BPN ID</label>
|
||||
<input type="text" name="bpnId" value="{{draft.bpnId}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Colour Band</label>
|
||||
<select name="colourKey">
|
||||
{{selectOptions colourOptions selected=draft.colourKey valueAttr="key" labelAttr="label"}}
|
||||
</select>
|
||||
<div class="sla-bpn-field-help">{{draft.colourType}}</div>
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Scenario Frame</label>
|
||||
<select name="frameKey">
|
||||
{{selectOptions frameOptions selected=draft.frameKey valueAttr="key" labelAttr="label"}}
|
||||
</select>
|
||||
<div class="sla-bpn-field-help">{{draft.shortTitle}}</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sla-bpn-dispatch-grid sla-bpn-dispatch-grid--meta">
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Issuing Department</label>
|
||||
<input type="text" name="issuingDepartment" value="{{draft.issuingDepartment}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Squad Size</label>
|
||||
<input type="number" min="1" max="8" name="squadSize" value="{{draft.squadSize}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Primary Contact</label>
|
||||
<input type="text" name="primaryContact" value="{{draft.primaryContact}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Contact Position</label>
|
||||
<input type="text" name="primaryContactLocation" value="{{draft.primaryContactLocation}}">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sla-bpn-dispatch-grid sla-bpn-dispatch-grid--summary">
|
||||
<div class="sla-bpn-dispatch-card">
|
||||
<h3>Colour Dossier</h3>
|
||||
<p><strong>Type:</strong> {{draft.colourType}}</p>
|
||||
<p><strong>Summary:</strong> {{draft.colourSummary}}</p>
|
||||
<p><strong>Details:</strong> {{draft.colourDetails}}</p>
|
||||
<p><strong>Primary Contact:</strong> {{draft.primaryContact}}</p>
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-card">
|
||||
<h3>Pressure Stack</h3>
|
||||
<p><strong>Media:</strong> {{draft.mediaCoverage}}</p>
|
||||
<p><strong>CBS Band:</strong> {{draft.cbsBand}}</p>
|
||||
<p><strong>Financier Cut:</strong> {{draft.financierCut}}</p>
|
||||
<p><strong>SCL Increase:</strong> {{draft.sclIncrease}}</p>
|
||||
<p><strong>Threat Lead:</strong> {{draft.threatLead}}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sla-bpn-dispatch-grid">
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Mission Focus</label>
|
||||
<input type="text" name="missionFocus" value="{{draft.missionFocus}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Operational Hook</label>
|
||||
<input type="text" name="colourMissionIdea" value="{{draft.colourMissionIdea}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Location</label>
|
||||
<input type="text" name="location" value="{{draft.location}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Atmosphere</label>
|
||||
<input type="text" name="atmosphere" value="{{draft.atmosphere}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Opposition</label>
|
||||
<input type="text" name="opposition" value="{{draft.opposition}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Opposition Attitude</label>
|
||||
<input type="text" name="oppositionAttitude" value="{{draft.oppositionAttitude}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Civilian Faction</label>
|
||||
<input type="text" name="civilianFaction" value="{{draft.civilianFaction}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Extra Objective</label>
|
||||
<input type="text" name="extraObjective" value="{{draft.extraObjective}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Escalation Event</label>
|
||||
<input type="text" name="escalationEvent" value="{{draft.escalationEvent}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Threat Lead</label>
|
||||
<input type="text" name="threatLead" value="{{draft.threatLead}}">
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Threat Count</label>
|
||||
<input type="text" name="threatCountLabel" value="{{draft.threatCountLabel}}">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sla-bpn-dispatch-grid">
|
||||
<div class="sla-bpn-dispatch-field">
|
||||
<label>Complication</label>
|
||||
<textarea name="complication">{{draft.complication}}</textarea>
|
||||
</div>
|
||||
<div class="sla-bpn-dispatch-field sla-bpn-dispatch-field--danger">
|
||||
<label>GM Twist</label>
|
||||
<textarea name="localTwist">{{draft.localTwist}}</textarea>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sla-bpn-dispatch-field sla-bpn-dispatch-field--wide">
|
||||
<label>Mission Brief</label>
|
||||
<textarea name="missionBrief">{{draft.missionBrief}}</textarea>
|
||||
</section>
|
||||
|
||||
<section class="sla-bpn-dispatch-field">
|
||||
<label>Operational Notes</label>
|
||||
<textarea name="operationalNotes">{{draft.operationalNotes}}</textarea>
|
||||
</section>
|
||||
|
||||
<div class="sla-bpn-dispatch-actions">
|
||||
<button type="button" data-action="randomize">Randomize BPN</button>
|
||||
<button type="button" data-action="chat">Post To Chat</button>
|
||||
<button type="button" data-action="journal">Create Journal + NPCs</button>
|
||||
<button type="button" data-action="save">Save Draft</button>
|
||||
</div>
|
||||
</form>
|
||||