Style abilities tab with ancestry, features, perks, and effects
- Add ancestry block with header (image, name, type, size) and traits list - Style features and perks lists with grid layout for image/info/description - Add active effects display for temporary and passive effects - Fix perk prerequisites display using getPrerequisiteString() method - Add responsive layout for narrow containers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
7489b60281
commit
10963403e9
@ -203,9 +203,13 @@ export default class VagabondActorSheet extends HandlebarsApplicationMixin(Actor
|
||||
case "feature":
|
||||
items.features.push(item);
|
||||
break;
|
||||
case "perk":
|
||||
case "perk": {
|
||||
// Add formatted prerequisite string for display (hide "None")
|
||||
const prereqStr = item.system.getPrerequisiteString?.() || "";
|
||||
item.prerequisiteString = prereqStr !== "None" ? prereqStr : "";
|
||||
items.perks.push(item);
|
||||
break;
|
||||
}
|
||||
case "class":
|
||||
items.classes.push(item);
|
||||
break;
|
||||
|
||||
@ -1062,6 +1062,323 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
// Abilities Tab Layout
|
||||
// ----------------------------------------
|
||||
.abilities-tab {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $spacing-4;
|
||||
}
|
||||
|
||||
.abilities-section {
|
||||
.section-header-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: $spacing-2;
|
||||
|
||||
.section-header {
|
||||
margin: 0;
|
||||
padding-bottom: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item-create {
|
||||
@include flex-center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 0;
|
||||
background-color: $color-parchment;
|
||||
border: 1px solid $color-border;
|
||||
border-radius: $radius-md;
|
||||
color: $color-text-primary;
|
||||
cursor: pointer;
|
||||
transition: all $transition-fast;
|
||||
|
||||
&:hover {
|
||||
background-color: $color-success;
|
||||
border-color: $color-success;
|
||||
color: white;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ancestry Block
|
||||
.ancestry-block {
|
||||
background-color: $color-parchment-light;
|
||||
border: 1px solid $color-border-light;
|
||||
border-radius: $radius-md;
|
||||
overflow: hidden;
|
||||
|
||||
.ancestry-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $spacing-3;
|
||||
padding: $spacing-3;
|
||||
background-color: $color-parchment-dark;
|
||||
border-bottom: 1px solid $color-border-light;
|
||||
|
||||
.ancestry-img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
object-fit: cover;
|
||||
border: 2px solid $color-border;
|
||||
border-radius: $radius-md;
|
||||
background-color: $color-parchment;
|
||||
}
|
||||
|
||||
.ancestry-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $spacing-1;
|
||||
|
||||
.ancestry-name {
|
||||
font-family: $font-family-header;
|
||||
font-size: $font-size-lg;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $color-text-primary;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $color-accent-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.ancestry-being-type,
|
||||
.ancestry-size {
|
||||
font-size: $font-size-sm;
|
||||
color: $color-text-secondary;
|
||||
}
|
||||
|
||||
.ancestry-being-type::after {
|
||||
content: " · ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ancestry-traits {
|
||||
padding: $spacing-3;
|
||||
|
||||
.trait {
|
||||
padding: $spacing-2 0;
|
||||
border-bottom: 1px solid $color-border-light;
|
||||
font-size: $font-size-sm;
|
||||
line-height: $line-height-relaxed;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: $color-text-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ability Lists (Features & Perks)
|
||||
.ability-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $spacing-2;
|
||||
}
|
||||
|
||||
.ability-item {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
grid-template-rows: auto auto;
|
||||
gap: $spacing-2;
|
||||
padding: $spacing-3;
|
||||
background-color: $color-parchment-light;
|
||||
border: 1px solid $color-border-light;
|
||||
border-radius: $radius-md;
|
||||
transition: background-color $transition-fast;
|
||||
|
||||
&:hover {
|
||||
background-color: $color-parchment;
|
||||
}
|
||||
|
||||
&.empty {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: $spacing-4;
|
||||
font-style: italic;
|
||||
color: $color-text-muted;
|
||||
}
|
||||
|
||||
.ability-img {
|
||||
grid-row: span 2;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
object-fit: cover;
|
||||
border: 1px solid $color-border;
|
||||
border-radius: $radius-md;
|
||||
background-color: $color-parchment;
|
||||
}
|
||||
|
||||
.ability-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
|
||||
.ability-name {
|
||||
font-weight: $font-weight-semibold;
|
||||
color: $color-text-primary;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $color-accent-primary;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.ability-source,
|
||||
.ability-prereqs {
|
||||
font-size: $font-size-xs;
|
||||
color: $color-text-secondary;
|
||||
}
|
||||
|
||||
.ability-prereqs {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
.ability-description {
|
||||
grid-column: 2 / -1;
|
||||
font-size: $font-size-sm;
|
||||
color: $color-text-secondary;
|
||||
line-height: $line-height-normal;
|
||||
|
||||
// Style inline HTML from descriptions
|
||||
p {
|
||||
margin: 0 0 $spacing-2 0;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-delete {
|
||||
grid-row: 1;
|
||||
grid-column: 3;
|
||||
@include flex-center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
border: 1px solid $color-border-light;
|
||||
border-radius: $radius-sm;
|
||||
color: $color-text-muted;
|
||||
cursor: pointer;
|
||||
transition: all $transition-fast;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba($color-danger, 0.1);
|
||||
border-color: $color-danger;
|
||||
color: $color-danger;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Active Effects
|
||||
.effects-group {
|
||||
margin-bottom: $spacing-3;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.effect-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $spacing-1;
|
||||
}
|
||||
|
||||
.effect-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $spacing-2;
|
||||
padding: $spacing-2 $spacing-3;
|
||||
background-color: $color-parchment-light;
|
||||
border: 1px solid $color-border-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
.effect-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
object-fit: cover;
|
||||
border-radius: $radius-sm;
|
||||
}
|
||||
|
||||
.effect-name {
|
||||
flex: 1;
|
||||
font-weight: $font-weight-medium;
|
||||
color: $color-text-primary;
|
||||
}
|
||||
|
||||
.effect-duration {
|
||||
font-size: $font-size-xs;
|
||||
padding: $spacing-1 $spacing-2;
|
||||
background-color: rgba($color-warning, 0.15);
|
||||
border-radius: $radius-sm;
|
||||
color: $color-warning;
|
||||
}
|
||||
|
||||
.effect-source {
|
||||
font-size: $font-size-xs;
|
||||
color: $color-text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive abilities layout
|
||||
@container sheet-content (max-width: 500px) {
|
||||
.ability-item {
|
||||
grid-template-columns: auto 1fr;
|
||||
|
||||
.ability-description {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.item-delete {
|
||||
position: absolute;
|
||||
top: $spacing-2;
|
||||
right: $spacing-2;
|
||||
}
|
||||
}
|
||||
|
||||
.ancestry-block .ancestry-header {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
|
||||
.ancestry-info {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
|
||||
@ -66,8 +66,8 @@
|
||||
<img class="ability-img" src="{{this.img}}" alt="{{this.name}}" />
|
||||
<div class="ability-info">
|
||||
<span class="ability-name" data-action="itemEdit">{{this.name}}</span>
|
||||
{{#if this.system.prerequisites}}
|
||||
<span class="ability-prereqs">{{this.system.prerequisites}}</span>
|
||||
{{#if this.prerequisiteString}}
|
||||
<span class="ability-prereqs">{{this.prerequisiteString}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="ability-description">{{{this.system.description}}}</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user