diff --git a/lang/en.json b/lang/en.json
index beeaf2a..fe23530 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -55,6 +55,8 @@
"AWEMMY.Sheet.Tab.Main": "Main",
"AWEMMY.Sheet.Tab.Biography": "Biography",
"AWEMMY.Sheet.Tab.Equipment": "Equipment",
+ "AWEMMY.Sheet.Tab.Description": "Description",
+ "AWEMMY.Sheet.Tab.Eureka": "Eureka",
"AWEMMY.Sheet.EditMode": "Edit",
"AWEMMY.Sheet.PlayMode": "Play",
"AWEMMY.Character.Level": "Level",
diff --git a/module/applications/sheets/character-sheet.mjs b/module/applications/sheets/character-sheet.mjs
index f3ec0e0..cb98965 100644
--- a/module/applications/sheets/character-sheet.mjs
+++ b/module/applications/sheets/character-sheet.mjs
@@ -27,12 +27,12 @@ export default class AwECharacterSheet extends AwEActorSheet {
header: {
template: "systems/fvtt-adventures-with-emmy/templates/character-header.hbs"
},
- main: {
- template: "systems/fvtt-adventures-with-emmy/templates/character-main.hbs"
- },
tabs: {
template: "templates/generic/tab-navigation.hbs"
},
+ main: {
+ template: "systems/fvtt-adventures-with-emmy/templates/character-main.hbs"
+ },
biography: {
template: "systems/fvtt-adventures-with-emmy/templates/character-biography.hbs"
},
diff --git a/module/applications/sheets/creature-sheet.mjs b/module/applications/sheets/creature-sheet.mjs
index ed29619..b2897d9 100644
--- a/module/applications/sheets/creature-sheet.mjs
+++ b/module/applications/sheets/creature-sheet.mjs
@@ -6,7 +6,7 @@ export default class AwECreatureSheet extends AwEActorSheet {
classes: ["creature"],
position: {
width: 700,
- height: "auto"
+ height: 700
},
window: {
contentClasses: ["creature-content"]
@@ -15,17 +15,64 @@ export default class AwECreatureSheet extends AwEActorSheet {
/** @override */
static PARTS = {
+ header: {
+ template: "systems/fvtt-adventures-with-emmy/templates/creature-header.hbs"
+ },
+ tabs: {
+ template: "templates/generic/tab-navigation.hbs"
+ },
main: {
template: "systems/fvtt-adventures-with-emmy/templates/creature-main.hbs"
+ },
+ description: {
+ template: "systems/fvtt-adventures-with-emmy/templates/creature-description.hbs"
+ },
+ eureka: {
+ template: "systems/fvtt-adventures-with-emmy/templates/creature-eureka.hbs"
}
}
+ /** @override */
+ tabGroups = {
+ sheet: "main"
+ }
+
+ #getTabs() {
+ const tabs = {
+ main: { id: "main", group: "sheet", icon: "fa-solid fa-dragon", label: "AWEMMY.Sheet.Tab.Main" },
+ description: { id: "description", group: "sheet", icon: "fa-solid fa-scroll", label: "AWEMMY.Sheet.Tab.Description" },
+ eureka: { id: "eureka", group: "sheet", icon: "fa-solid fa-lightbulb", label: "AWEMMY.Sheet.Tab.Eureka" }
+ }
+ for (const v of Object.values(tabs)) {
+ v.active = this.tabGroups[v.group] === v.id
+ v.cssClass = v.active ? "active" : ""
+ }
+ return tabs
+ }
+
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
+ context.tabs = this.#getTabs()
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
this.document.system.description, { async: true }
)
return context
}
+
+ /** @override */
+ async _preparePartContext(partId, context) {
+ switch (partId) {
+ case "main":
+ context.tab = context.tabs.main
+ break
+ case "description":
+ context.tab = context.tabs.description
+ break
+ case "eureka":
+ context.tab = context.tabs.eureka
+ break
+ }
+ return context
+ }
}
diff --git a/module/models/character.mjs b/module/models/character.mjs
index 0182b6e..4884a38 100644
--- a/module/models/character.mjs
+++ b/module/models/character.mjs
@@ -17,7 +17,8 @@ export default class AwECharacter extends foundry.abstract.TypeDataModel {
schema.backgroundName = new fields.StringField({ initial: "", required: false, nullable: true })
// Core stats
- schema.level = new fields.NumberField({ ...requiredInteger, initial: 1, min: 1, max: 10 })
+ schema.level = new fields.NumberField({ ...requiredInteger, initial: 1, min: 1, max: 10,
+ choices: Object.fromEntries([1,2,3,4,5,6,7,8,9,10].map(v => [v, String(v)])) })
schema.stride = new fields.NumberField({ ...requiredInteger, initial: 5, min: 0 })
// Hit Points
@@ -39,7 +40,8 @@ export default class AwECharacter extends foundry.abstract.TypeDataModel {
// dc = 10 + mod (computed)
// bonus: manual +/- bonus
const attributeField = () => new fields.SchemaField({
- boostLevel: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 4 }),
+ boostLevel: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 4,
+ choices: {0:"0", 1:"1", 2:"2", 3:"3", 4:"4"} }),
bonus: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 })
})
diff --git a/styles/adventures-with-emmy.less b/styles/adventures-with-emmy.less
index 56f3145..59a1ff3 100644
--- a/styles/adventures-with-emmy.less
+++ b/styles/adventures-with-emmy.less
@@ -28,6 +28,34 @@
color: @color-text;
background: @color-bg;
+ // --------------------------------------------------------
+ // Global form field overrides (light theme)
+ // --------------------------------------------------------
+ input[type="text"],
+ input[type="number"],
+ input[type="search"],
+ input:not([type]),
+ select,
+ textarea {
+ background: white;
+ color: @color-text;
+ border: 1px solid @color-border;
+ border-radius: 3px;
+
+ &:focus {
+ border-color: @color-primary;
+ outline: none;
+ box-shadow: 0 0 0 2px fade(@color-primary, 20%);
+ }
+
+ &:disabled,
+ &[disabled] {
+ background: lighten(@color-border, 15%);
+ color: @color-text-light;
+ cursor: default;
+ }
+ }
+
.window-header {
background: @color-primary;
color: white;
@@ -98,16 +126,24 @@
.attributes-table {
width: 100%;
border-collapse: collapse;
- margin: 0.5rem 0;
+ margin: 0.3rem 0;
+ font-size: 0.85rem;
+
+ // Col widths: name | boost | mod | dc | bonus
+ th:nth-child(1), td:nth-child(1) { width: 30%; }
+ th:nth-child(2), td:nth-child(2) { width: 20%; }
+ th:nth-child(3), td:nth-child(3) { width: 15%; }
+ th:nth-child(4), td:nth-child(4) { width: 15%; }
+ th:nth-child(5), td:nth-child(5) { width: 20%; }
thead tr {
background: @color-primary;
color: white;
th {
- padding: 0.4rem 0.5rem;
+ padding: 0.25rem 0.4rem;
text-align: center;
- font-size: 0.8rem;
+ font-size: 0.75rem;
text-transform: uppercase;
}
}
@@ -118,19 +154,37 @@
}
td {
- padding: 0.35rem 0.5rem;
+ padding: 0.2rem 0.4rem;
text-align: center;
border-bottom: 1px solid @color-border;
+ select {
+ width: auto;
+ min-width: 55px;
+ padding: 0.1rem 0.25rem;
+ font-size: 0.82rem;
+ background: white;
+ color: @color-text;
+ border: 1px solid @color-border;
+ border-radius: 3px;
+ }
+
input {
- width: 50px;
+ width: 48px;
text-align: center;
+ padding: 0.1rem 0.2rem;
+ font-size: 0.82rem;
+ background: white;
+ color: @color-text;
+ border: 1px solid @color-border;
+ border-radius: 3px;
}
}
.attr-label {
text-align: left;
font-weight: bold;
+ white-space: nowrap;
}
.rollable {
@@ -313,8 +367,240 @@
}
}
+
// --------------------------------------------------------
- // Creature Sheet - Eureka Rubric
+ // Character Sheet Header
+ // --------------------------------------------------------
+ .character-content {
+ .actor-header {
+ display: grid;
+ grid-template-columns: 80px 1fr auto auto;
+ gap: 0.5rem 0.75rem;
+ align-items: center;
+ padding: 0.5rem 0.75rem;
+
+ .actor-img {
+ grid-row: 1 / 3;
+ align-self: start;
+ width: 80px;
+ height: 80px;
+ }
+
+ .actor-identity {
+ grid-column: 2;
+ grid-row: 1 / 3;
+ display: flex;
+ flex-direction: column;
+ gap: 0.3rem;
+ justify-content: center;
+
+ .actor-name {
+ font-size: 1.3rem;
+ width: 100%;
+ }
+
+ .actor-details {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.3rem 1rem;
+ align-items: center;
+
+ .detail-item {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+
+ label {
+ font-size: 0.72rem;
+ text-transform: uppercase;
+ color: @color-text-light;
+ white-space: nowrap;
+ font-weight: 600;
+ }
+
+ select, input[type="number"] {
+ width: 64px;
+ padding: 0.15rem 0.25rem;
+ font-size: 0.9rem;
+ text-align: center;
+ }
+ }
+ }
+ }
+
+ .actor-stats {
+ grid-column: 3;
+ grid-row: 1 / 3;
+ display: flex;
+ flex-direction: column;
+ gap: 0.3rem;
+ justify-content: center;
+
+ .resource-block {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ flex-wrap: nowrap;
+
+ > label {
+ font-size: 0.7rem;
+ text-transform: uppercase;
+ color: @color-text-light;
+ font-weight: 600;
+ min-width: 70px;
+ white-space: nowrap;
+ }
+
+ .resource-values {
+ display: flex;
+ align-items: center;
+ gap: 0.2rem;
+
+ input {
+ width: 42px;
+ text-align: center;
+ font-size: 0.9rem;
+ }
+ }
+
+ .resource-temp {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+
+ label {
+ font-size: 0.65rem;
+ text-transform: uppercase;
+ color: @color-text-light;
+ white-space: nowrap;
+ }
+
+ input {
+ width: 38px;
+ text-align: center;
+ font-size: 0.85rem;
+ }
+ }
+
+ .resource-stepper {
+ margin-left: 0.2rem;
+ }
+ }
+ }
+
+ .sheet-controls {
+ grid-column: 4;
+ grid-row: 1 / 3;
+ align-self: center;
+ }
+ }
+ }
+
+
+ // --------------------------------------------------------
+ // Creature Sheet Header (compact)
+ // --------------------------------------------------------
+ .creature-content {
+ .actor-header {
+ align-items: center;
+ flex-wrap: wrap;
+
+ .actor-img {
+ width: 56px;
+ height: 56px;
+ }
+
+ .actor-identity {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+ }
+
+ .actor-details {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem 1rem;
+ align-items: center;
+
+ .detail-item {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+
+ label {
+ font-size: 0.75rem;
+ text-transform: uppercase;
+ color: @color-text-light;
+ white-space: nowrap;
+ }
+
+ input {
+ width: 42px;
+ text-align: center;
+ }
+
+ span {
+ color: @color-text-light;
+ }
+ }
+ }
+ }
+
+ // Eureka tab — large textareas
+ .eureka-rubric {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+ padding: 0.25rem 0;
+
+ .eureka-field {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+
+ label {
+ font-weight: bold;
+ font-size: 0.85rem;
+ color: darken(@color-accent, 20%);
+ text-transform: uppercase;
+ }
+
+ textarea {
+ width: 100%;
+ resize: vertical;
+ border: 1px solid @color-border;
+ border-radius: 4px;
+ padding: 0.4rem 0.5rem;
+ font-family: @font-body;
+ font-size: 0.9rem;
+ background: white;
+ color: @color-text;
+ line-height: 1.4;
+
+ &:focus {
+ border-color: @color-primary;
+ outline: none;
+ box-shadow: 0 0 0 2px fadeout(@color-primary, 75%);
+ }
+
+ &::placeholder {
+ color: @color-text-light;
+ font-style: italic;
+ }
+ }
+ }
+
+ .eureka-columns {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 0.75rem;
+ }
+ }
+ }
+
+ // --------------------------------------------------------
+ // Creature Sheet - Eureka Rubric (legacy / fieldset version)
// --------------------------------------------------------
.eureka-rubric {
background: lighten(@color-accent, 45%);
diff --git a/templates/creature-description.hbs b/templates/creature-description.hbs
new file mode 100644
index 0000000..4d84b5c
--- /dev/null
+++ b/templates/creature-description.hbs
@@ -0,0 +1,14 @@
+