valtech-components 4.0.428 → 4.0.430

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -58,7 +58,7 @@ import fixWebmDuration from 'fix-webm-duration';
58
58
  * Current version of valtech-components.
59
59
  * This is automatically updated during the publish process.
60
60
  */
61
- const VERSION = '4.0.428';
61
+ const VERSION = '4.0.430';
62
62
 
63
63
  // Control de estado de refresco (singleton a nivel de módulo)
64
64
  let isRefreshing = false;
@@ -62464,6 +62464,7 @@ const MINI_GAMES_I18N = {
62464
62464
  christianityHand: 'Mano',
62465
62465
  christianityOpponentBattle: 'Zona de batalla rival',
62466
62466
  christianityYourBattle: 'Tu zona de batalla',
62467
+ christianityOpponentHand: 'Mano rival',
62467
62468
  christianitySharedZone: 'Zona compartida',
62468
62469
  christianityHistory: 'Historia',
62469
62470
  christianityDeck: 'Mazo',
@@ -62471,14 +62472,27 @@ const MINI_GAMES_I18N = {
62471
62472
  christianityEmpty: 'Vacío',
62472
62473
  christianityYourHand: 'Tu mano',
62473
62474
  christianityCost: 'Coste',
62475
+ christianityOfferingCard: 'Ofrenda',
62476
+ christianityCharacterCard: 'Personaje',
62477
+ christianityLeaderCard: 'Líder',
62478
+ christianityHiddenCard: 'Carta oculta',
62474
62479
  christianityEndTurn: 'Terminar turno',
62475
62480
  christianityPlayCard: 'Jugar carta',
62476
62481
  christianityReset: 'Reiniciar mock',
62477
62482
  christianityWaitTurn: 'Espera el turno rival.',
62478
62483
  christianityChooseTarget: 'Elige un objetivo para atacar.',
62484
+ christianityChooseCharacterTarget: 'El rival tiene personajes: debes atacarlos antes que al líder.',
62479
62485
  christianityReadyToPlay: 'Puedes jugar esta carta.',
62480
62486
  christianityNeedOfferings: 'Necesitas más ofrendas para jugar esa carta.',
62481
62487
  christianityChooseCard: 'Elige una carta o un personaje listo para actuar.',
62488
+ christianityLeaderProtected: 'No puedes atacar directamente al líder mientras tenga personajes en batalla.',
62489
+ christianityLeaderBody: 'Si su vida llega a 0, la partida termina.',
62490
+ christianityOfferingReady: 'Lista',
62491
+ christianityOfferingExhausted: 'Agotada',
62492
+ christianityOfferingBody: 'Se agota para pagar costes y vuelve a estar lista al comenzar tu turno.',
62493
+ christianityCharacterBody: 'Entra a batalla y debe esperar un turno para atacar.',
62494
+ christianityCharacterReady: 'Listo para atacar.',
62495
+ christianityCharacterExhausted: 'No puede atacar todavía.',
62482
62496
  christianityHistoryEmpty: 'Todavía no hay cartas en historia.',
62483
62497
  soonTitle: 'Próximamente',
62484
62498
  openGame: 'Jugar',
@@ -62868,6 +62882,7 @@ const MINI_GAMES_I18N = {
62868
62882
  christianityHand: 'Hand',
62869
62883
  christianityOpponentBattle: 'Opponent battle zone',
62870
62884
  christianityYourBattle: 'Your battle zone',
62885
+ christianityOpponentHand: 'Opponent hand',
62871
62886
  christianitySharedZone: 'Shared zone',
62872
62887
  christianityHistory: 'History',
62873
62888
  christianityDeck: 'Deck',
@@ -62875,14 +62890,27 @@ const MINI_GAMES_I18N = {
62875
62890
  christianityEmpty: 'Empty',
62876
62891
  christianityYourHand: 'Your hand',
62877
62892
  christianityCost: 'Cost',
62893
+ christianityOfferingCard: 'Offering',
62894
+ christianityCharacterCard: 'Character',
62895
+ christianityLeaderCard: 'Leader',
62896
+ christianityHiddenCard: 'Hidden card',
62878
62897
  christianityEndTurn: 'End turn',
62879
62898
  christianityPlayCard: 'Play card',
62880
62899
  christianityReset: 'Reset mock',
62881
62900
  christianityWaitTurn: 'Wait for the opponent turn.',
62882
62901
  christianityChooseTarget: 'Choose a target to attack.',
62902
+ christianityChooseCharacterTarget: 'The opponent has characters: attack them before the leader.',
62883
62903
  christianityReadyToPlay: 'You can play this card.',
62884
62904
  christianityNeedOfferings: 'You need more offerings to play that card.',
62885
62905
  christianityChooseCard: 'Choose a card or a ready character.',
62906
+ christianityLeaderProtected: 'You cannot attack the leader directly while they have characters in battle.',
62907
+ christianityLeaderBody: 'If this leader reaches 0 life, the game ends.',
62908
+ christianityOfferingReady: 'Ready',
62909
+ christianityOfferingExhausted: 'Exhausted',
62910
+ christianityOfferingBody: 'Exhaust it to pay costs. It readies again at the start of your turn.',
62911
+ christianityCharacterBody: 'Enters battle and must wait one turn before attacking.',
62912
+ christianityCharacterReady: 'Ready to attack.',
62913
+ christianityCharacterExhausted: 'Cannot attack yet.',
62886
62914
  christianityHistoryEmpty: 'There are no cards in history yet.',
62887
62915
  soonTitle: 'Coming soon',
62888
62916
  openGame: 'Play',
@@ -67882,11 +67910,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
67882
67910
  }] } });
67883
67911
 
67884
67912
  const STARTER_CARDS = {
67885
- p_scout: { id: 'p_scout', name: 'Scout', cost: 1, attack: 1, life: 1 },
67886
- p_guard: { id: 'p_guard', name: 'Guard', cost: 2, attack: 1, life: 3 },
67887
- p_warrior: { id: 'p_warrior', name: 'Warrior', cost: 2, attack: 2, life: 2 },
67888
- p_elder: { id: 'p_elder', name: 'Elder', cost: 3, attack: 2, life: 4 },
67889
- p_champion: { id: 'p_champion', name: 'Champion', cost: 4, attack: 4, life: 4 },
67913
+ o_simple: { id: 'o_simple', name: 'Ofrenda simple', type: 'offering', cost: 0, attack: 0, life: 1 },
67914
+ p_scout: { id: 'p_scout', name: 'Scout', type: 'character', cost: 1, attack: 1, life: 1 },
67915
+ p_guard: { id: 'p_guard', name: 'Guard', type: 'character', cost: 2, attack: 1, life: 3 },
67916
+ p_warrior: { id: 'p_warrior', name: 'Warrior', type: 'character', cost: 2, attack: 2, life: 2 },
67917
+ p_elder: { id: 'p_elder', name: 'Elder', type: 'character', cost: 3, attack: 2, life: 4 },
67918
+ p_champion: { id: 'p_champion', name: 'Champion', type: 'character', cost: 4, attack: 4, life: 4 },
67890
67919
  };
67891
67920
  const STARTING_GAME = {
67892
67921
  gameId: 'mock-christianity',
@@ -67904,9 +67933,9 @@ const STARTING_GAME = {
67904
67933
  leaderName: 'Adam',
67905
67934
  leaderHp: 15,
67906
67935
  leaderMaxHp: 15,
67907
- maxOfferings: 3,
67908
- offeringPoints: 3,
67909
- hand: ['p_scout', 'p_warrior', 'p_guard', 'p_elder'],
67936
+ offerings: [{ instanceId: 'p1_offering_001', cardId: 'o_simple', name: 'Ofrenda simple', owner: 'P1', ready: true, value: 1 }],
67937
+ offeringPlayedThisTurn: false,
67938
+ hand: ['o_simple', 'p_scout', 'p_warrior', 'p_guard'],
67910
67939
  battleZone: [],
67911
67940
  },
67912
67941
  P2: {
@@ -67915,8 +67944,8 @@ const STARTING_GAME = {
67915
67944
  leaderName: 'Noah',
67916
67945
  leaderHp: 15,
67917
67946
  leaderMaxHp: 15,
67918
- maxOfferings: 3,
67919
- offeringPoints: 3,
67947
+ offerings: [{ instanceId: 'p2_offering_001', cardId: 'o_simple', name: 'Ofrenda simple', owner: 'P2', ready: true, value: 1 }],
67948
+ offeringPlayedThisTurn: false,
67920
67949
  handCount: 4,
67921
67950
  battleZone: [
67922
67951
  {
@@ -67941,11 +67970,13 @@ class ChristianityGameComponent {
67941
67970
  this.game = signal(structuredClone(STARTING_GAME));
67942
67971
  this.selectedHandCard = signal(null);
67943
67972
  this.selectedAttacker = signal(null);
67973
+ this.selectedPreview = signal(null);
67944
67974
  this.showHistory = signal(false);
67945
67975
  this.player = computed(() => this.game().players.P1);
67946
67976
  this.opponent = computed(() => this.game().players.P2);
67947
67977
  this.currentPlayer = computed(() => this.game().players[this.game().turnOwner]);
67948
67978
  this.isOwnTurn = computed(() => this.game().turnOwner === 'P1');
67979
+ this.hasOpponentGuards = computed(() => this.opponent().battleZone.length > 0);
67949
67980
  this.opponentHandCount = computed(() => this.opponent().handCount ?? this.opponent().hand?.length ?? 0);
67950
67981
  this.statusText = computed(() => {
67951
67982
  const attacker = this.selectedAttacker();
@@ -67954,7 +67985,7 @@ class ChristianityGameComponent {
67954
67985
  return this.t('christianityWaitTurn');
67955
67986
  }
67956
67987
  if (attacker) {
67957
- return this.t('christianityChooseTarget');
67988
+ return this.hasOpponentGuards() ? this.t('christianityChooseCharacterTarget') : this.t('christianityChooseTarget');
67958
67989
  }
67959
67990
  if (handCard) {
67960
67991
  const card = this.cardDefinition(handCard);
@@ -67973,16 +68004,33 @@ class ChristianityGameComponent {
67973
68004
  }
67974
68005
  battleSlots(seat) {
67975
68006
  const cards = this.game().players[seat].battleZone;
67976
- return Array.from({ length: 5 }, (_, index) => ({
68007
+ return Array.from({ length: 4 }, (_, index) => ({
67977
68008
  trackId: cards[index]?.instanceId ?? `${seat}-empty-${index}`,
67978
68009
  card: cards[index],
67979
68010
  }));
67980
68011
  }
67981
- offeringCards(player) {
67982
- return Array.from({ length: Math.max(0, player.maxOfferings) });
68012
+ hiddenHandCards(count) {
68013
+ return Array.from({ length: count });
68014
+ }
68015
+ fanTransform(index, total, opponent) {
68016
+ if (total <= 1)
68017
+ return opponent ? 'rotate(180deg)' : 'none';
68018
+ const center = (total - 1) / 2;
68019
+ const offset = index - center;
68020
+ const rotate = offset * 5;
68021
+ const lift = Math.abs(offset) * 0.25;
68022
+ const base = opponent ? 'rotate(180deg)' : '';
68023
+ return `${base} translateY(${lift}rem) rotate(${rotate}deg)`;
68024
+ }
68025
+ readyOfferings(player) {
68026
+ return player.offerings.reduce((total, offering) => total + (offering.ready ? offering.value : 0), 0);
67983
68027
  }
67984
68028
  canPlay(card) {
67985
- return this.isOwnTurn() && this.player().offeringPoints >= card.cost && this.player().battleZone.length < 5;
68029
+ if (!this.isOwnTurn())
68030
+ return false;
68031
+ if (card.type === 'offering')
68032
+ return !this.player().offeringPlayedThisTurn;
68033
+ return this.readyOfferings(this.player()) >= card.cost && this.player().battleZone.length < 4;
67986
68034
  }
67987
68035
  canPlaySelected() {
67988
68036
  const selected = this.selectedHandCard();
@@ -67991,6 +68039,7 @@ class ChristianityGameComponent {
67991
68039
  selectHandCard(cardId) {
67992
68040
  this.selectedAttacker.set(null);
67993
68041
  this.selectedHandCard.set(this.selectedHandCard() === cardId ? null : cardId);
68042
+ this.inspectHandCard(cardId);
67994
68043
  }
67995
68044
  playSelectedCard() {
67996
68045
  const cardId = this.selectedHandCard();
@@ -68006,34 +68055,72 @@ class ChristianityGameComponent {
68006
68055
  if (handIndex < 0 || !player.hand)
68007
68056
  return game;
68008
68057
  player.hand.splice(handIndex, 1);
68009
- player.offeringPoints -= card.cost;
68010
- player.battleZone.push({
68011
- instanceId: `p1_${next.revision + 1}_${player.battleZone.length}`,
68012
- cardId: card.id,
68013
- name: card.name,
68014
- owner: 'P1',
68015
- controller: 'P1',
68016
- attack: card.attack,
68017
- currentHp: card.life,
68018
- maxHp: card.life,
68019
- canAttack: false,
68020
- });
68058
+ if (card.type === 'offering') {
68059
+ player.offerings.push({
68060
+ instanceId: `p1_offering_${next.revision + 1}`,
68061
+ cardId: card.id,
68062
+ name: card.name,
68063
+ owner: 'P1',
68064
+ ready: true,
68065
+ value: card.life,
68066
+ });
68067
+ player.offeringPlayedThisTurn = true;
68068
+ }
68069
+ else {
68070
+ this.spendOfferings(player, card.cost);
68071
+ player.battleZone.push({
68072
+ instanceId: `p1_${next.revision + 1}_${player.battleZone.length}`,
68073
+ cardId: card.id,
68074
+ name: card.name,
68075
+ owner: 'P1',
68076
+ controller: 'P1',
68077
+ attack: card.attack,
68078
+ currentHp: card.life,
68079
+ maxHp: card.life,
68080
+ canAttack: false,
68081
+ });
68082
+ }
68021
68083
  next.revision++;
68022
- next.log = [`${card.name} entra en batalla.`, ...next.log].slice(0, 4);
68084
+ next.log = [
68085
+ card.type === 'offering' ? `${card.name} queda lista como ofrenda.` : `${card.name} entra en batalla.`,
68086
+ ...next.log,
68087
+ ].slice(0, 4);
68023
68088
  return next;
68024
68089
  });
68025
68090
  this.selectedHandCard.set(null);
68026
68091
  }
68027
68092
  selectAttacker(card) {
68028
68093
  this.selectedHandCard.set(null);
68094
+ this.inspectCharacter(card);
68029
68095
  if (!this.isOwnTurn() || !card.canAttack)
68030
68096
  return;
68031
68097
  this.selectedAttacker.set(this.selectedAttacker()?.instanceId === card.instanceId ? null : card);
68032
68098
  }
68099
+ handleOpponentCharacter(card) {
68100
+ this.inspectCharacter(card);
68101
+ if (this.selectedAttacker()) {
68102
+ this.attackCharacter(card);
68103
+ }
68104
+ }
68105
+ handleOpponentLeader() {
68106
+ this.inspectLeader('P2');
68107
+ if (this.selectedAttacker() && !this.hasOpponentGuards()) {
68108
+ this.attackLeader();
68109
+ }
68110
+ }
68033
68111
  attackLeader() {
68034
68112
  const attacker = this.selectedAttacker();
68035
68113
  if (!attacker)
68036
68114
  return;
68115
+ if (this.hasOpponentGuards()) {
68116
+ this.selectedPreview.set({
68117
+ title: this.opponent().leaderName,
68118
+ eyebrow: this.t('christianityLeaderCard'),
68119
+ meta: `${this.opponent().leaderHp}/${this.opponent().leaderMaxHp}`,
68120
+ body: this.t('christianityLeaderProtected'),
68121
+ });
68122
+ return;
68123
+ }
68037
68124
  this.game.update(game => {
68038
68125
  const next = structuredClone(game);
68039
68126
  const liveAttacker = next.players.P1.battleZone.find(card => card.instanceId === attacker.instanceId);
@@ -68076,8 +68163,8 @@ class ChristianityGameComponent {
68076
68163
  next.turnOwner = next.turnOwner === 'P1' ? 'P2' : 'P1';
68077
68164
  next.turnCount++;
68078
68165
  const current = next.players[next.turnOwner];
68079
- current.maxOfferings = Math.min(10, current.maxOfferings + 1);
68080
- current.offeringPoints = current.maxOfferings;
68166
+ current.offeringPlayedThisTurn = false;
68167
+ current.offerings = current.offerings.map(offering => ({ ...offering, ready: true }));
68081
68168
  current.battleZone = current.battleZone.map(card => ({ ...card, canAttack: true }));
68082
68169
  next.revision++;
68083
68170
  next.log = [`Turno de ${current.displayName}.`, ...next.log].slice(0, 4);
@@ -68088,6 +68175,7 @@ class ChristianityGameComponent {
68088
68175
  this.game.set(structuredClone(STARTING_GAME));
68089
68176
  this.selectedHandCard.set(null);
68090
68177
  this.selectedAttacker.set(null);
68178
+ this.selectedPreview.set(null);
68091
68179
  }
68092
68180
  historyNames() {
68093
68181
  return this.game()
@@ -68101,6 +68189,49 @@ class ChristianityGameComponent {
68101
68189
  game.historyZone.push(...destroyed.map(card => card.cardId));
68102
68190
  player.battleZone = player.battleZone.filter(card => card.currentHp > 0);
68103
68191
  }
68192
+ inspectLeader(seat) {
68193
+ const player = this.game().players[seat];
68194
+ this.selectedPreview.set({
68195
+ title: player.leaderName,
68196
+ eyebrow: this.t('christianityLeaderCard'),
68197
+ meta: `${player.leaderHp}/${player.leaderMaxHp}`,
68198
+ body: seat === 'P2' && this.hasOpponentGuards() ? this.t('christianityLeaderProtected') : this.t('christianityLeaderBody'),
68199
+ });
68200
+ }
68201
+ inspectOffering(offering) {
68202
+ this.selectedPreview.set({
68203
+ title: offering.name,
68204
+ eyebrow: this.t('christianityOfferingCard'),
68205
+ meta: offering.ready ? this.t('christianityOfferingReady') : this.t('christianityOfferingExhausted'),
68206
+ body: this.t('christianityOfferingBody'),
68207
+ });
68208
+ }
68209
+ inspectHandCard(cardId) {
68210
+ const card = this.cardDefinition(cardId);
68211
+ this.selectedPreview.set({
68212
+ title: card.name,
68213
+ eyebrow: card.type === 'offering' ? this.t('christianityOfferingCard') : this.t('christianityCharacterCard'),
68214
+ meta: card.type === 'offering' ? `+${card.life}` : `${this.t('christianityCost')} ${card.cost} · ${card.attack}/${card.life}`,
68215
+ body: card.type === 'offering' ? this.t('christianityOfferingBody') : this.t('christianityCharacterBody'),
68216
+ });
68217
+ }
68218
+ inspectCharacter(card) {
68219
+ this.selectedPreview.set({
68220
+ title: card.name,
68221
+ eyebrow: this.t('christianityCharacterCard'),
68222
+ meta: `${card.attack}/${card.currentHp}`,
68223
+ body: card.canAttack ? this.t('christianityCharacterReady') : this.t('christianityCharacterExhausted'),
68224
+ });
68225
+ }
68226
+ spendOfferings(player, cost) {
68227
+ let remaining = cost;
68228
+ player.offerings = player.offerings.map(offering => {
68229
+ if (remaining <= 0 || !offering.ready)
68230
+ return offering;
68231
+ remaining -= offering.value;
68232
+ return { ...offering, ready: false };
68233
+ });
68234
+ }
68104
68235
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChristianityGameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
68105
68236
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ChristianityGameComponent, isStandalone: true, selector: "val-christianity-game", ngImport: i0, template: `
68106
68237
  <main class="christianity-shell">
@@ -68115,118 +68246,153 @@ class ChristianityGameComponent {
68115
68246
  </div>
68116
68247
  </section>
68117
68248
 
68249
+ <section class="christianity-hand-fan christianity-hand-fan--opponent" [attr.aria-label]="t('christianityOpponentHand')">
68250
+ @for (_ of hiddenHandCards(opponentHandCount()); track $index) {
68251
+ <button
68252
+ type="button"
68253
+ class="christianity-card-preview-card christianity-card-preview-card--back"
68254
+ [style.transform]="fanTransform($index, opponentHandCount(), true)"
68255
+ [attr.aria-label]="t('christianityHiddenCard')"
68256
+ ></button>
68257
+ }
68258
+ </section>
68259
+
68118
68260
  <section class="christianity-table" [attr.aria-label]="t('christianityTable')">
68119
- <section class="christianity-player christianity-player--opponent">
68120
- <div class="christianity-player__summary">
68121
- <div class="christianity-leader">
68122
- <span>{{ opponent().leaderName }}</span>
68123
- <strong>{{ opponent().leaderHp }}/{{ opponent().leaderMaxHp }}</strong>
68124
- </div>
68125
- <div class="christianity-offerings">
68126
- <span>{{ t('christianityOfferings') }}</span>
68127
- <strong>{{ opponent().offeringPoints }}/{{ opponent().maxOfferings }}</strong>
68128
- <div class="christianity-offering-cards" aria-hidden="true">
68129
- @for (_ of offeringCards(opponent()); track $index) {
68130
- <i [class.is-used]="$index >= opponent().offeringPoints"></i>
68131
- }
68132
- </div>
68133
- </div>
68134
- <div class="christianity-hidden-hand">
68135
- <span>{{ t('christianityHand') }}</span>
68136
- <strong>{{ opponentHandCount() }}</strong>
68137
- </div>
68138
- </div>
68139
- <div class="christianity-battle-zone" [attr.aria-label]="t('christianityOpponentBattle')">
68140
- @for (slot of battleSlots('P2'); track slot.trackId) {
68141
- @if (slot.card) {
68142
- <button
68143
- type="button"
68144
- class="christianity-card christianity-card--battle"
68145
- [class.is-target]="selectedAttacker()"
68146
- (click)="attackCharacter(slot.card)"
68147
- >
68148
- <span>{{ slot.card.name }}</span>
68149
- <strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
68150
- </button>
68151
- } @else {
68152
- <span class="christianity-slot"></span>
68153
- }
68261
+ <section class="christianity-player-rack christianity-player-rack--opponent">
68262
+ <div class="christianity-offerings-zone">
68263
+ @for (offering of opponent().offerings; track offering.instanceId) {
68264
+ <button
68265
+ type="button"
68266
+ class="christianity-card-mini christianity-card-mini--offering"
68267
+ [class.is-exhausted]="!offering.ready"
68268
+ (click)="inspectOffering(offering)"
68269
+ >
68270
+ <span>{{ t('christianityOfferingCard') }}</span>
68271
+ <strong>+{{ offering.value }}</strong>
68272
+ </button>
68154
68273
  }
68155
68274
  </div>
68275
+ <button type="button" class="christianity-leader-card" [class.is-target]="selectedAttacker() && !hasOpponentGuards()" (click)="handleOpponentLeader()">
68276
+ <span>{{ opponent().leaderName }}</span>
68277
+ <strong>{{ opponent().leaderHp }}/{{ opponent().leaderMaxHp }}</strong>
68278
+ </button>
68279
+ </section>
68280
+
68281
+ <section class="christianity-battle-zone christianity-battle-zone--opponent" [attr.aria-label]="t('christianityOpponentBattle')">
68282
+ @for (slot of battleSlots('P2'); track slot.trackId) {
68283
+ @if (slot.card) {
68284
+ <button
68285
+ type="button"
68286
+ class="christianity-card-preview-card christianity-card-preview-card--battle"
68287
+ [class.is-target]="selectedAttacker()"
68288
+ (click)="handleOpponentCharacter(slot.card)"
68289
+ >
68290
+ <span>{{ slot.card.name }}</span>
68291
+ <strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
68292
+ </button>
68293
+ } @else {
68294
+ <span class="christianity-slot"></span>
68295
+ }
68296
+ }
68156
68297
  </section>
68157
68298
 
68158
68299
  <section class="christianity-shared-zone" [attr.aria-label]="t('christianitySharedZone')">
68159
- <button type="button" class="christianity-pile" (click)="showHistory.set(!showHistory())">
68300
+ <button type="button" class="christianity-zone-card" (click)="showHistory.set(!showHistory())">
68160
68301
  <span>{{ t('christianityHistory') }}</span>
68161
68302
  <strong>{{ game().historyZone.length }}</strong>
68162
68303
  </button>
68163
- <div class="christianity-deck" aria-live="polite">
68304
+ <div class="christianity-zone-card" aria-live="polite">
68164
68305
  <span>{{ t('christianityDeck') }}</span>
68165
68306
  <strong>{{ game().sharedDeckCount }}</strong>
68166
68307
  </div>
68167
- <div class="christianity-place">
68308
+ <div class="christianity-zone-card">
68168
68309
  <span>{{ t('christianityPlace') }}</span>
68169
68310
  <strong>{{ t('christianityEmpty') }}</strong>
68170
68311
  </div>
68171
68312
  </section>
68172
68313
 
68173
- <section class="christianity-player">
68174
- <div class="christianity-battle-zone" [attr.aria-label]="t('christianityYourBattle')">
68175
- @for (slot of battleSlots('P1'); track slot.trackId) {
68176
- @if (slot.card) {
68177
- <button
68178
- type="button"
68179
- class="christianity-card christianity-card--battle"
68180
- [class.is-selected]="selectedAttacker()?.instanceId === slot.card.instanceId"
68181
- [class.is-exhausted]="!slot.card.canAttack"
68182
- (click)="selectAttacker(slot.card)"
68183
- >
68184
- <span>{{ slot.card.name }}</span>
68185
- <strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
68186
- </button>
68187
- } @else {
68188
- <span class="christianity-slot"></span>
68189
- }
68314
+ <section class="christianity-battle-zone" [attr.aria-label]="t('christianityYourBattle')">
68315
+ @for (slot of battleSlots('P1'); track slot.trackId) {
68316
+ @if (slot.card) {
68317
+ <button
68318
+ type="button"
68319
+ class="christianity-card-preview-card christianity-card-preview-card--battle"
68320
+ [class.is-selected]="selectedAttacker()?.instanceId === slot.card.instanceId"
68321
+ [class.is-exhausted]="!slot.card.canAttack"
68322
+ (click)="selectAttacker(slot.card)"
68323
+ >
68324
+ <span>{{ slot.card.name }}</span>
68325
+ <strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
68326
+ </button>
68327
+ } @else {
68328
+ <span class="christianity-slot"></span>
68329
+ }
68330
+ }
68331
+ </section>
68332
+
68333
+ <section class="christianity-player-rack">
68334
+ <div class="christianity-offerings-zone">
68335
+ @for (offering of player().offerings; track offering.instanceId) {
68336
+ <button
68337
+ type="button"
68338
+ class="christianity-card-mini christianity-card-mini--offering"
68339
+ [class.is-exhausted]="!offering.ready"
68340
+ (click)="inspectOffering(offering)"
68341
+ >
68342
+ <span>{{ t('christianityOfferingCard') }}</span>
68343
+ <strong>+{{ offering.value }}</strong>
68344
+ </button>
68190
68345
  }
68191
68346
  </div>
68192
- <div class="christianity-player__summary">
68193
- <div class="christianity-offerings">
68194
- <span>{{ t('christianityOfferings') }}</span>
68195
- <strong>{{ player().offeringPoints }}/{{ player().maxOfferings }}</strong>
68196
- <div class="christianity-offering-cards" aria-hidden="true">
68197
- @for (_ of offeringCards(player()); track $index) {
68198
- <i [class.is-used]="$index >= player().offeringPoints"></i>
68199
- }
68200
- </div>
68201
- </div>
68202
- <button type="button" class="christianity-leader christianity-leader--target" (click)="attackLeader()">
68203
- <span>{{ player().leaderName }}</span>
68204
- <strong>{{ player().leaderHp }}/{{ player().leaderMaxHp }}</strong>
68205
- </button>
68206
- <button type="button" class="christianity-end-turn" (click)="endTurn()">
68207
- {{ t('christianityEndTurn') }}
68208
- </button>
68209
- </div>
68347
+ <button type="button" class="christianity-leader-card" (click)="inspectLeader('P1')">
68348
+ <span>{{ player().leaderName }}</span>
68349
+ <strong>{{ player().leaderHp }}/{{ player().leaderMaxHp }}</strong>
68350
+ </button>
68351
+ <button type="button" class="christianity-end-turn" (click)="endTurn()">
68352
+ {{ t('christianityEndTurn') }}
68353
+ </button>
68210
68354
  </section>
68211
68355
  </section>
68212
68356
 
68213
- <section class="christianity-hand" [attr.aria-label]="t('christianityYourHand')">
68357
+ <section class="christianity-hand-fan" [attr.aria-label]="t('christianityYourHand')">
68214
68358
  @for (cardId of player().hand ?? []; track cardId + $index) {
68215
68359
  @let card = cardDefinition(cardId);
68216
68360
  <button
68217
68361
  type="button"
68218
- class="christianity-card christianity-card--hand"
68362
+ class="christianity-card-preview-card christianity-card-preview-card--hand"
68219
68363
  [class.is-selected]="selectedHandCard() === cardId"
68220
68364
  [class.is-disabled]="!canPlay(card)"
68365
+ [style.transform]="fanTransform($index, player().hand?.length ?? 0, false)"
68221
68366
  (click)="selectHandCard(cardId)"
68222
68367
  >
68223
- <small>{{ t('christianityCost') }} {{ card.cost }}</small>
68368
+ <small>
68369
+ @if (card.type === 'offering') {
68370
+ {{ t('christianityOfferingCard') }}
68371
+ } @else {
68372
+ {{ t('christianityCost') }} {{ card.cost }}
68373
+ }
68374
+ </small>
68224
68375
  <span>{{ card.name }}</span>
68225
- <strong>{{ card.attack }} / {{ card.life }}</strong>
68376
+ <strong>
68377
+ @if (card.type === 'offering') {
68378
+ +{{ card.life }}
68379
+ } @else {
68380
+ {{ card.attack }} / {{ card.life }}
68381
+ }
68382
+ </strong>
68226
68383
  </button>
68227
68384
  }
68228
68385
  </section>
68229
68386
 
68387
+ @if (selectedPreview()) {
68388
+ <aside class="christianity-floating-card" aria-live="polite">
68389
+ <small>{{ selectedPreview()?.eyebrow }}</small>
68390
+ <strong>{{ selectedPreview()?.title }}</strong>
68391
+ <span>{{ selectedPreview()?.meta }}</span>
68392
+ <p>{{ selectedPreview()?.body }}</p>
68393
+ </aside>
68394
+ }
68395
+
68230
68396
  <section class="christianity-actions" aria-live="polite">
68231
68397
  <p>{{ statusText() }}</p>
68232
68398
  <div>
@@ -68250,7 +68416,7 @@ class ChristianityGameComponent {
68250
68416
  </section>
68251
68417
  }
68252
68418
  </main>
68253
- `, isInline: true, styles: [":host{display:block;color:var(--val-text-color, #1f2933)}.christianity-shell{display:grid;gap:.875rem;padding:.75rem .25rem;border:1px solid rgba(36,48,68,.12);border-radius:.75rem;background:#f6f8fb}.christianity-header,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{display:flex;align-items:center;justify-content:space-between;gap:.75rem}.christianity-header h1,.christianity-header p,.christianity-history h2,.christianity-actions p{margin:0}.christianity-header h1{font-size:1.35rem;line-height:1.1}.christianity-header p,.christianity-turn span,.christianity-offerings span,.christianity-hidden-hand span,.christianity-deck span,.christianity-place span,.christianity-pile span,.christianity-leader span{color:#1f2933a3;font-size:.75rem}.christianity-turn,.christianity-leader,.christianity-offerings,.christianity-hidden-hand,.christianity-pile,.christianity-deck,.christianity-place{display:grid;gap:.15rem;min-width:5.25rem;padding:.55rem .65rem;border:1px solid rgba(36,48,68,.12);border-radius:.5rem;background:#fff}.christianity-turn.is-own-turn{border-color:#12806c59;background:#ecfdf5}.christianity-table{display:grid;gap:.75rem;padding:.55rem .35rem;border-radius:.75rem;background:#dceafb}.christianity-player{display:grid;gap:.65rem}.christianity-battle-zone{display:grid;grid-template-columns:repeat(5,minmax(4.2rem,1fr));gap:.5rem;min-height:7rem;padding:.55rem .4rem;border-radius:.75rem;background:#ffffffc2}.christianity-shared-zone{padding:.55rem .4rem;border-radius:.75rem;background:#ffffffe6}.christianity-card,.christianity-end-turn,.christianity-actions button,.christianity-pile,.christianity-leader--target{border:1px solid rgba(36,48,68,.16);border-radius:.5rem;background:#fff;color:inherit;font:inherit}.christianity-card{display:grid;align-content:space-between;min-height:5.8rem;padding:.5rem;text-align:left;box-shadow:0 .5rem 1.25rem #24304414}.christianity-card span{font-weight:700}.christianity-card strong{justify-self:end;padding:.15rem .35rem;border-radius:999px;background:#edf2f7;font-size:.8rem}.christianity-card.is-selected{border-color:#2563eb;box-shadow:0 0 0 .2rem #2563eb29}.christianity-card.is-disabled,.christianity-card.is-exhausted{opacity:.55}.christianity-card.is-target{border-color:#dc2626}.christianity-offering-cards{display:grid;grid-auto-flow:column;grid-auto-columns:.7rem;gap:.16rem;align-items:end;min-height:1.05rem}.christianity-offering-cards i{display:block;width:.65rem;height:.95rem;border:1px solid rgba(16,42,67,.22);border-radius:.18rem;background:#f8fafc}.christianity-offering-cards i.is-used{background:#cbd5e1;transform:rotate(90deg);transform-origin:center}.christianity-slot{min-height:5.8rem;border:1px dashed rgba(36,48,68,.22);border-radius:.5rem;background:#ffffff73}.christianity-hand{display:grid;grid-auto-columns:minmax(6rem,8rem);grid-auto-flow:column;gap:.55rem;overflow-x:auto;padding-bottom:.25rem}.christianity-actions{align-items:flex-start;padding:.75rem;border-radius:.75rem;background:#fff}.christianity-actions div{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:flex-end}.christianity-actions button,.christianity-end-turn{min-height:2.4rem;padding:0 .75rem;font-weight:700}.christianity-actions button:not(:disabled),.christianity-end-turn{background:#102a43;color:#fff}.christianity-history{padding:.75rem;border-radius:.75rem;background:#fff}button{cursor:pointer}button:disabled{cursor:not-allowed;opacity:.55}button:focus-visible{outline:.1875rem solid rgba(37,99,235,.24);outline-offset:.125rem}@media (max-width: 720px){.christianity-shell{padding:.55rem 0;border-right:0;border-left:0;border-radius:0}.christianity-header,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{align-items:stretch;flex-direction:column}.christianity-battle-zone{grid-template-columns:repeat(5,minmax(3.8rem,1fr));overflow-x:auto}}\n"] }); }
68419
+ `, isInline: true, styles: [":host{display:block;color:var(--val-text-color, #1f2933)}.christianity-shell{display:grid;gap:.875rem;padding:.75rem .25rem;border:1px solid rgba(36,48,68,.12);border-radius:.75rem;background:#f6f8fb}.christianity-header,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{display:flex;align-items:center;justify-content:space-between;gap:.75rem}.christianity-header h1,.christianity-header p,.christianity-history h2,.christianity-actions p{margin:0}.christianity-header h1{font-size:1.35rem;line-height:1.1}.christianity-header p,.christianity-turn span,.christianity-offerings span,.christianity-hidden-hand span,.christianity-deck span,.christianity-place span,.christianity-pile span,.christianity-leader span{color:#1f2933a3;font-size:.75rem}.christianity-turn,.christianity-leader,.christianity-offerings,.christianity-hidden-hand,.christianity-pile,.christianity-deck,.christianity-place{display:grid;gap:.15rem;min-width:5.25rem;padding:.55rem .65rem;border:1px solid rgba(36,48,68,.12);border-radius:.5rem;background:#fff}.christianity-turn.is-own-turn{border-color:#12806c59;background:#ecfdf5}.christianity-table{display:grid;gap:.75rem;padding:.55rem .35rem;border-radius:.75rem;background:#dceafb}.christianity-player{display:grid;gap:.65rem}.christianity-battle-zone{display:grid;grid-template-columns:repeat(5,minmax(4.2rem,1fr));gap:.5rem;min-height:7rem;padding:.55rem .4rem;border-radius:.75rem;background:#ffffffc2}.christianity-shared-zone{padding:.55rem .4rem;border-radius:.75rem;background:#ffffffe6}.christianity-card,.christianity-end-turn,.christianity-actions button,.christianity-pile,.christianity-leader--target{border:1px solid rgba(36,48,68,.16);border-radius:.5rem;background:#fff;color:inherit;font:inherit}.christianity-card{display:grid;align-content:space-between;min-height:5.8rem;padding:.5rem;text-align:left;box-shadow:0 .5rem 1.25rem #24304414}.christianity-card span{font-weight:700}.christianity-card strong{justify-self:end;padding:.15rem .35rem;border-radius:999px;background:#edf2f7;font-size:.8rem}.christianity-card.is-selected{border-color:#2563eb;box-shadow:0 0 0 .2rem #2563eb29}.christianity-card.is-disabled,.christianity-card.is-exhausted{opacity:.55}.christianity-card.is-target{border-color:#dc2626}.christianity-offering-cards{display:grid;grid-auto-flow:column;grid-auto-columns:.7rem;gap:.16rem;align-items:end;min-height:1.05rem}.christianity-offering-cards i{display:block;width:.65rem;height:.95rem;border:1px solid rgba(16,42,67,.22);border-radius:.18rem;background:#f8fafc}.christianity-offering-cards i.is-used{background:#cbd5e1;transform:rotate(90deg);transform-origin:center}.christianity-slot{min-height:5.8rem;border:1px dashed rgba(36,48,68,.22);border-radius:.5rem;background:#ffffff73}.christianity-hand{display:grid;grid-auto-columns:minmax(6rem,8rem);grid-auto-flow:column;gap:.55rem;overflow-x:auto;padding-bottom:.25rem}.christianity-actions{align-items:flex-start;padding:.75rem;border-radius:.75rem;background:#fff}.christianity-actions div{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:flex-end}.christianity-actions button,.christianity-end-turn{min-height:2.4rem;padding:0 .75rem;font-weight:700}.christianity-actions button:not(:disabled),.christianity-end-turn{background:#102a43;color:#fff}.christianity-history{padding:.75rem;border-radius:.75rem;background:#fff}.christianity-hand-fan{position:relative;display:flex;justify-content:center;min-height:7.4rem;padding:0 .25rem;isolation:isolate}.christianity-hand-fan--opponent{min-height:4.7rem;margin-bottom:-1.1rem}.christianity-card-preview-card,.christianity-card-mini,.christianity-leader-card,.christianity-zone-card,.christianity-end-turn{border:1px solid rgba(36,48,68,.16);border-radius:.5rem;background:#fff;color:inherit;font:inherit}.christianity-card-preview-card{display:grid;align-content:space-between;width:clamp(4.9rem,17vw,7.1rem);min-height:clamp(6.6rem,22vw,8.8rem);margin-inline:-.42rem;padding:.48rem;text-align:left;transform-origin:50% 115%;transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease;box-shadow:0 .5rem 1.25rem #2430441a}.christianity-card-preview-card--hand:hover,.christianity-card-preview-card--hand.is-selected{z-index:3;border-color:#2563eb;box-shadow:0 1rem 2rem #2563eb2e}.christianity-card-preview-card--back{min-height:4.8rem;background:linear-gradient(135deg,#102a431f,#102a4305),repeating-linear-gradient(45deg,#e2e8f0 0 .35rem,#f8fafc .35rem .7rem)}.christianity-card-preview-card--battle{width:100%;min-height:5.7rem;margin-inline:0}.christianity-card-preview-card span,.christianity-card-mini span,.christianity-leader-card span,.christianity-zone-card span{font-weight:700}.christianity-card-preview-card strong,.christianity-card-mini strong,.christianity-leader-card strong,.christianity-zone-card strong{justify-self:end;padding:.15rem .35rem;border-radius:999px;background:#edf2f7;font-size:.8rem}.christianity-player-rack{display:grid;grid-template-columns:minmax(4.2rem,1fr) minmax(5rem,6.5rem) minmax(4.2rem,1fr);gap:.55rem;align-items:end;justify-items:center}.christianity-player-rack--opponent{align-items:start}.christianity-offerings-zone{display:flex;flex-wrap:wrap;gap:.25rem;justify-content:flex-end;width:100%}.christianity-card-mini,.christianity-leader-card,.christianity-zone-card{display:grid;align-content:space-between;min-height:4.9rem;padding:.48rem;text-align:left}.christianity-card-mini{width:3.5rem}.christianity-leader-card{width:min(100%,6.5rem);min-height:5.8rem}.christianity-battle-zone{grid-template-columns:repeat(4,minmax(4rem,1fr))}.christianity-shared-zone{display:grid;grid-template-columns:repeat(3,minmax(4.3rem,1fr));align-items:stretch}.christianity-floating-card{position:fixed;right:max(.75rem,env(safe-area-inset-right));bottom:max(5.8rem,env(safe-area-inset-bottom));z-index:10;display:grid;gap:.28rem;width:min(14rem,calc(100vw - 1.5rem));min-height:10rem;padding:.8rem;border:1px solid rgba(36,48,68,.18);border-radius:.6rem;background:#fffffff5;box-shadow:0 1.25rem 2.5rem #102a432e}.christianity-floating-card small,.christianity-floating-card span{color:#1f2933a3}.christianity-floating-card strong{font-size:1.05rem}.christianity-floating-card p{margin:0;font-size:.86rem;line-height:1.35}button{cursor:pointer}button:disabled{cursor:not-allowed;opacity:.55}button:focus-visible{outline:.1875rem solid rgba(37,99,235,.24);outline-offset:.125rem}@media (max-width: 720px){.christianity-shell{padding:.55rem 0;border-right:0;border-left:0;border-radius:0}.christianity-header,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{align-items:stretch;flex-direction:column}.christianity-battle-zone{grid-template-columns:repeat(4,minmax(3.35rem,1fr));overflow-x:auto}.christianity-hand-fan{min-height:6.8rem;overflow-x:clip}.christianity-player-rack{grid-template-columns:minmax(3.6rem,1fr) minmax(4.8rem,5.6rem) minmax(3.6rem,1fr)}.christianity-shared-zone{grid-template-columns:repeat(3,minmax(3.7rem,1fr))}.christianity-card-preview-card{width:clamp(4.2rem,20vw,5.7rem);min-height:clamp(5.8rem,26vw,7.4rem)}.christianity-floating-card{right:.5rem;bottom:4.8rem}}\n"] }); }
68254
68420
  }
68255
68421
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChristianityGameComponent, decorators: [{
68256
68422
  type: Component,
@@ -68267,118 +68433,153 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
68267
68433
  </div>
68268
68434
  </section>
68269
68435
 
68436
+ <section class="christianity-hand-fan christianity-hand-fan--opponent" [attr.aria-label]="t('christianityOpponentHand')">
68437
+ @for (_ of hiddenHandCards(opponentHandCount()); track $index) {
68438
+ <button
68439
+ type="button"
68440
+ class="christianity-card-preview-card christianity-card-preview-card--back"
68441
+ [style.transform]="fanTransform($index, opponentHandCount(), true)"
68442
+ [attr.aria-label]="t('christianityHiddenCard')"
68443
+ ></button>
68444
+ }
68445
+ </section>
68446
+
68270
68447
  <section class="christianity-table" [attr.aria-label]="t('christianityTable')">
68271
- <section class="christianity-player christianity-player--opponent">
68272
- <div class="christianity-player__summary">
68273
- <div class="christianity-leader">
68274
- <span>{{ opponent().leaderName }}</span>
68275
- <strong>{{ opponent().leaderHp }}/{{ opponent().leaderMaxHp }}</strong>
68276
- </div>
68277
- <div class="christianity-offerings">
68278
- <span>{{ t('christianityOfferings') }}</span>
68279
- <strong>{{ opponent().offeringPoints }}/{{ opponent().maxOfferings }}</strong>
68280
- <div class="christianity-offering-cards" aria-hidden="true">
68281
- @for (_ of offeringCards(opponent()); track $index) {
68282
- <i [class.is-used]="$index >= opponent().offeringPoints"></i>
68283
- }
68284
- </div>
68285
- </div>
68286
- <div class="christianity-hidden-hand">
68287
- <span>{{ t('christianityHand') }}</span>
68288
- <strong>{{ opponentHandCount() }}</strong>
68289
- </div>
68290
- </div>
68291
- <div class="christianity-battle-zone" [attr.aria-label]="t('christianityOpponentBattle')">
68292
- @for (slot of battleSlots('P2'); track slot.trackId) {
68293
- @if (slot.card) {
68294
- <button
68295
- type="button"
68296
- class="christianity-card christianity-card--battle"
68297
- [class.is-target]="selectedAttacker()"
68298
- (click)="attackCharacter(slot.card)"
68299
- >
68300
- <span>{{ slot.card.name }}</span>
68301
- <strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
68302
- </button>
68303
- } @else {
68304
- <span class="christianity-slot"></span>
68305
- }
68448
+ <section class="christianity-player-rack christianity-player-rack--opponent">
68449
+ <div class="christianity-offerings-zone">
68450
+ @for (offering of opponent().offerings; track offering.instanceId) {
68451
+ <button
68452
+ type="button"
68453
+ class="christianity-card-mini christianity-card-mini--offering"
68454
+ [class.is-exhausted]="!offering.ready"
68455
+ (click)="inspectOffering(offering)"
68456
+ >
68457
+ <span>{{ t('christianityOfferingCard') }}</span>
68458
+ <strong>+{{ offering.value }}</strong>
68459
+ </button>
68306
68460
  }
68307
68461
  </div>
68462
+ <button type="button" class="christianity-leader-card" [class.is-target]="selectedAttacker() && !hasOpponentGuards()" (click)="handleOpponentLeader()">
68463
+ <span>{{ opponent().leaderName }}</span>
68464
+ <strong>{{ opponent().leaderHp }}/{{ opponent().leaderMaxHp }}</strong>
68465
+ </button>
68466
+ </section>
68467
+
68468
+ <section class="christianity-battle-zone christianity-battle-zone--opponent" [attr.aria-label]="t('christianityOpponentBattle')">
68469
+ @for (slot of battleSlots('P2'); track slot.trackId) {
68470
+ @if (slot.card) {
68471
+ <button
68472
+ type="button"
68473
+ class="christianity-card-preview-card christianity-card-preview-card--battle"
68474
+ [class.is-target]="selectedAttacker()"
68475
+ (click)="handleOpponentCharacter(slot.card)"
68476
+ >
68477
+ <span>{{ slot.card.name }}</span>
68478
+ <strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
68479
+ </button>
68480
+ } @else {
68481
+ <span class="christianity-slot"></span>
68482
+ }
68483
+ }
68308
68484
  </section>
68309
68485
 
68310
68486
  <section class="christianity-shared-zone" [attr.aria-label]="t('christianitySharedZone')">
68311
- <button type="button" class="christianity-pile" (click)="showHistory.set(!showHistory())">
68487
+ <button type="button" class="christianity-zone-card" (click)="showHistory.set(!showHistory())">
68312
68488
  <span>{{ t('christianityHistory') }}</span>
68313
68489
  <strong>{{ game().historyZone.length }}</strong>
68314
68490
  </button>
68315
- <div class="christianity-deck" aria-live="polite">
68491
+ <div class="christianity-zone-card" aria-live="polite">
68316
68492
  <span>{{ t('christianityDeck') }}</span>
68317
68493
  <strong>{{ game().sharedDeckCount }}</strong>
68318
68494
  </div>
68319
- <div class="christianity-place">
68495
+ <div class="christianity-zone-card">
68320
68496
  <span>{{ t('christianityPlace') }}</span>
68321
68497
  <strong>{{ t('christianityEmpty') }}</strong>
68322
68498
  </div>
68323
68499
  </section>
68324
68500
 
68325
- <section class="christianity-player">
68326
- <div class="christianity-battle-zone" [attr.aria-label]="t('christianityYourBattle')">
68327
- @for (slot of battleSlots('P1'); track slot.trackId) {
68328
- @if (slot.card) {
68329
- <button
68330
- type="button"
68331
- class="christianity-card christianity-card--battle"
68332
- [class.is-selected]="selectedAttacker()?.instanceId === slot.card.instanceId"
68333
- [class.is-exhausted]="!slot.card.canAttack"
68334
- (click)="selectAttacker(slot.card)"
68335
- >
68336
- <span>{{ slot.card.name }}</span>
68337
- <strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
68338
- </button>
68339
- } @else {
68340
- <span class="christianity-slot"></span>
68341
- }
68501
+ <section class="christianity-battle-zone" [attr.aria-label]="t('christianityYourBattle')">
68502
+ @for (slot of battleSlots('P1'); track slot.trackId) {
68503
+ @if (slot.card) {
68504
+ <button
68505
+ type="button"
68506
+ class="christianity-card-preview-card christianity-card-preview-card--battle"
68507
+ [class.is-selected]="selectedAttacker()?.instanceId === slot.card.instanceId"
68508
+ [class.is-exhausted]="!slot.card.canAttack"
68509
+ (click)="selectAttacker(slot.card)"
68510
+ >
68511
+ <span>{{ slot.card.name }}</span>
68512
+ <strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
68513
+ </button>
68514
+ } @else {
68515
+ <span class="christianity-slot"></span>
68516
+ }
68517
+ }
68518
+ </section>
68519
+
68520
+ <section class="christianity-player-rack">
68521
+ <div class="christianity-offerings-zone">
68522
+ @for (offering of player().offerings; track offering.instanceId) {
68523
+ <button
68524
+ type="button"
68525
+ class="christianity-card-mini christianity-card-mini--offering"
68526
+ [class.is-exhausted]="!offering.ready"
68527
+ (click)="inspectOffering(offering)"
68528
+ >
68529
+ <span>{{ t('christianityOfferingCard') }}</span>
68530
+ <strong>+{{ offering.value }}</strong>
68531
+ </button>
68342
68532
  }
68343
68533
  </div>
68344
- <div class="christianity-player__summary">
68345
- <div class="christianity-offerings">
68346
- <span>{{ t('christianityOfferings') }}</span>
68347
- <strong>{{ player().offeringPoints }}/{{ player().maxOfferings }}</strong>
68348
- <div class="christianity-offering-cards" aria-hidden="true">
68349
- @for (_ of offeringCards(player()); track $index) {
68350
- <i [class.is-used]="$index >= player().offeringPoints"></i>
68351
- }
68352
- </div>
68353
- </div>
68354
- <button type="button" class="christianity-leader christianity-leader--target" (click)="attackLeader()">
68355
- <span>{{ player().leaderName }}</span>
68356
- <strong>{{ player().leaderHp }}/{{ player().leaderMaxHp }}</strong>
68357
- </button>
68358
- <button type="button" class="christianity-end-turn" (click)="endTurn()">
68359
- {{ t('christianityEndTurn') }}
68360
- </button>
68361
- </div>
68534
+ <button type="button" class="christianity-leader-card" (click)="inspectLeader('P1')">
68535
+ <span>{{ player().leaderName }}</span>
68536
+ <strong>{{ player().leaderHp }}/{{ player().leaderMaxHp }}</strong>
68537
+ </button>
68538
+ <button type="button" class="christianity-end-turn" (click)="endTurn()">
68539
+ {{ t('christianityEndTurn') }}
68540
+ </button>
68362
68541
  </section>
68363
68542
  </section>
68364
68543
 
68365
- <section class="christianity-hand" [attr.aria-label]="t('christianityYourHand')">
68544
+ <section class="christianity-hand-fan" [attr.aria-label]="t('christianityYourHand')">
68366
68545
  @for (cardId of player().hand ?? []; track cardId + $index) {
68367
68546
  @let card = cardDefinition(cardId);
68368
68547
  <button
68369
68548
  type="button"
68370
- class="christianity-card christianity-card--hand"
68549
+ class="christianity-card-preview-card christianity-card-preview-card--hand"
68371
68550
  [class.is-selected]="selectedHandCard() === cardId"
68372
68551
  [class.is-disabled]="!canPlay(card)"
68552
+ [style.transform]="fanTransform($index, player().hand?.length ?? 0, false)"
68373
68553
  (click)="selectHandCard(cardId)"
68374
68554
  >
68375
- <small>{{ t('christianityCost') }} {{ card.cost }}</small>
68555
+ <small>
68556
+ @if (card.type === 'offering') {
68557
+ {{ t('christianityOfferingCard') }}
68558
+ } @else {
68559
+ {{ t('christianityCost') }} {{ card.cost }}
68560
+ }
68561
+ </small>
68376
68562
  <span>{{ card.name }}</span>
68377
- <strong>{{ card.attack }} / {{ card.life }}</strong>
68563
+ <strong>
68564
+ @if (card.type === 'offering') {
68565
+ +{{ card.life }}
68566
+ } @else {
68567
+ {{ card.attack }} / {{ card.life }}
68568
+ }
68569
+ </strong>
68378
68570
  </button>
68379
68571
  }
68380
68572
  </section>
68381
68573
 
68574
+ @if (selectedPreview()) {
68575
+ <aside class="christianity-floating-card" aria-live="polite">
68576
+ <small>{{ selectedPreview()?.eyebrow }}</small>
68577
+ <strong>{{ selectedPreview()?.title }}</strong>
68578
+ <span>{{ selectedPreview()?.meta }}</span>
68579
+ <p>{{ selectedPreview()?.body }}</p>
68580
+ </aside>
68581
+ }
68582
+
68382
68583
  <section class="christianity-actions" aria-live="polite">
68383
68584
  <p>{{ statusText() }}</p>
68384
68585
  <div>
@@ -68402,7 +68603,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
68402
68603
  </section>
68403
68604
  }
68404
68605
  </main>
68405
- `, styles: [":host{display:block;color:var(--val-text-color, #1f2933)}.christianity-shell{display:grid;gap:.875rem;padding:.75rem .25rem;border:1px solid rgba(36,48,68,.12);border-radius:.75rem;background:#f6f8fb}.christianity-header,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{display:flex;align-items:center;justify-content:space-between;gap:.75rem}.christianity-header h1,.christianity-header p,.christianity-history h2,.christianity-actions p{margin:0}.christianity-header h1{font-size:1.35rem;line-height:1.1}.christianity-header p,.christianity-turn span,.christianity-offerings span,.christianity-hidden-hand span,.christianity-deck span,.christianity-place span,.christianity-pile span,.christianity-leader span{color:#1f2933a3;font-size:.75rem}.christianity-turn,.christianity-leader,.christianity-offerings,.christianity-hidden-hand,.christianity-pile,.christianity-deck,.christianity-place{display:grid;gap:.15rem;min-width:5.25rem;padding:.55rem .65rem;border:1px solid rgba(36,48,68,.12);border-radius:.5rem;background:#fff}.christianity-turn.is-own-turn{border-color:#12806c59;background:#ecfdf5}.christianity-table{display:grid;gap:.75rem;padding:.55rem .35rem;border-radius:.75rem;background:#dceafb}.christianity-player{display:grid;gap:.65rem}.christianity-battle-zone{display:grid;grid-template-columns:repeat(5,minmax(4.2rem,1fr));gap:.5rem;min-height:7rem;padding:.55rem .4rem;border-radius:.75rem;background:#ffffffc2}.christianity-shared-zone{padding:.55rem .4rem;border-radius:.75rem;background:#ffffffe6}.christianity-card,.christianity-end-turn,.christianity-actions button,.christianity-pile,.christianity-leader--target{border:1px solid rgba(36,48,68,.16);border-radius:.5rem;background:#fff;color:inherit;font:inherit}.christianity-card{display:grid;align-content:space-between;min-height:5.8rem;padding:.5rem;text-align:left;box-shadow:0 .5rem 1.25rem #24304414}.christianity-card span{font-weight:700}.christianity-card strong{justify-self:end;padding:.15rem .35rem;border-radius:999px;background:#edf2f7;font-size:.8rem}.christianity-card.is-selected{border-color:#2563eb;box-shadow:0 0 0 .2rem #2563eb29}.christianity-card.is-disabled,.christianity-card.is-exhausted{opacity:.55}.christianity-card.is-target{border-color:#dc2626}.christianity-offering-cards{display:grid;grid-auto-flow:column;grid-auto-columns:.7rem;gap:.16rem;align-items:end;min-height:1.05rem}.christianity-offering-cards i{display:block;width:.65rem;height:.95rem;border:1px solid rgba(16,42,67,.22);border-radius:.18rem;background:#f8fafc}.christianity-offering-cards i.is-used{background:#cbd5e1;transform:rotate(90deg);transform-origin:center}.christianity-slot{min-height:5.8rem;border:1px dashed rgba(36,48,68,.22);border-radius:.5rem;background:#ffffff73}.christianity-hand{display:grid;grid-auto-columns:minmax(6rem,8rem);grid-auto-flow:column;gap:.55rem;overflow-x:auto;padding-bottom:.25rem}.christianity-actions{align-items:flex-start;padding:.75rem;border-radius:.75rem;background:#fff}.christianity-actions div{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:flex-end}.christianity-actions button,.christianity-end-turn{min-height:2.4rem;padding:0 .75rem;font-weight:700}.christianity-actions button:not(:disabled),.christianity-end-turn{background:#102a43;color:#fff}.christianity-history{padding:.75rem;border-radius:.75rem;background:#fff}button{cursor:pointer}button:disabled{cursor:not-allowed;opacity:.55}button:focus-visible{outline:.1875rem solid rgba(37,99,235,.24);outline-offset:.125rem}@media (max-width: 720px){.christianity-shell{padding:.55rem 0;border-right:0;border-left:0;border-radius:0}.christianity-header,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{align-items:stretch;flex-direction:column}.christianity-battle-zone{grid-template-columns:repeat(5,minmax(3.8rem,1fr));overflow-x:auto}}\n"] }]
68606
+ `, styles: [":host{display:block;color:var(--val-text-color, #1f2933)}.christianity-shell{display:grid;gap:.875rem;padding:.75rem .25rem;border:1px solid rgba(36,48,68,.12);border-radius:.75rem;background:#f6f8fb}.christianity-header,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{display:flex;align-items:center;justify-content:space-between;gap:.75rem}.christianity-header h1,.christianity-header p,.christianity-history h2,.christianity-actions p{margin:0}.christianity-header h1{font-size:1.35rem;line-height:1.1}.christianity-header p,.christianity-turn span,.christianity-offerings span,.christianity-hidden-hand span,.christianity-deck span,.christianity-place span,.christianity-pile span,.christianity-leader span{color:#1f2933a3;font-size:.75rem}.christianity-turn,.christianity-leader,.christianity-offerings,.christianity-hidden-hand,.christianity-pile,.christianity-deck,.christianity-place{display:grid;gap:.15rem;min-width:5.25rem;padding:.55rem .65rem;border:1px solid rgba(36,48,68,.12);border-radius:.5rem;background:#fff}.christianity-turn.is-own-turn{border-color:#12806c59;background:#ecfdf5}.christianity-table{display:grid;gap:.75rem;padding:.55rem .35rem;border-radius:.75rem;background:#dceafb}.christianity-player{display:grid;gap:.65rem}.christianity-battle-zone{display:grid;grid-template-columns:repeat(5,minmax(4.2rem,1fr));gap:.5rem;min-height:7rem;padding:.55rem .4rem;border-radius:.75rem;background:#ffffffc2}.christianity-shared-zone{padding:.55rem .4rem;border-radius:.75rem;background:#ffffffe6}.christianity-card,.christianity-end-turn,.christianity-actions button,.christianity-pile,.christianity-leader--target{border:1px solid rgba(36,48,68,.16);border-radius:.5rem;background:#fff;color:inherit;font:inherit}.christianity-card{display:grid;align-content:space-between;min-height:5.8rem;padding:.5rem;text-align:left;box-shadow:0 .5rem 1.25rem #24304414}.christianity-card span{font-weight:700}.christianity-card strong{justify-self:end;padding:.15rem .35rem;border-radius:999px;background:#edf2f7;font-size:.8rem}.christianity-card.is-selected{border-color:#2563eb;box-shadow:0 0 0 .2rem #2563eb29}.christianity-card.is-disabled,.christianity-card.is-exhausted{opacity:.55}.christianity-card.is-target{border-color:#dc2626}.christianity-offering-cards{display:grid;grid-auto-flow:column;grid-auto-columns:.7rem;gap:.16rem;align-items:end;min-height:1.05rem}.christianity-offering-cards i{display:block;width:.65rem;height:.95rem;border:1px solid rgba(16,42,67,.22);border-radius:.18rem;background:#f8fafc}.christianity-offering-cards i.is-used{background:#cbd5e1;transform:rotate(90deg);transform-origin:center}.christianity-slot{min-height:5.8rem;border:1px dashed rgba(36,48,68,.22);border-radius:.5rem;background:#ffffff73}.christianity-hand{display:grid;grid-auto-columns:minmax(6rem,8rem);grid-auto-flow:column;gap:.55rem;overflow-x:auto;padding-bottom:.25rem}.christianity-actions{align-items:flex-start;padding:.75rem;border-radius:.75rem;background:#fff}.christianity-actions div{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:flex-end}.christianity-actions button,.christianity-end-turn{min-height:2.4rem;padding:0 .75rem;font-weight:700}.christianity-actions button:not(:disabled),.christianity-end-turn{background:#102a43;color:#fff}.christianity-history{padding:.75rem;border-radius:.75rem;background:#fff}.christianity-hand-fan{position:relative;display:flex;justify-content:center;min-height:7.4rem;padding:0 .25rem;isolation:isolate}.christianity-hand-fan--opponent{min-height:4.7rem;margin-bottom:-1.1rem}.christianity-card-preview-card,.christianity-card-mini,.christianity-leader-card,.christianity-zone-card,.christianity-end-turn{border:1px solid rgba(36,48,68,.16);border-radius:.5rem;background:#fff;color:inherit;font:inherit}.christianity-card-preview-card{display:grid;align-content:space-between;width:clamp(4.9rem,17vw,7.1rem);min-height:clamp(6.6rem,22vw,8.8rem);margin-inline:-.42rem;padding:.48rem;text-align:left;transform-origin:50% 115%;transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease;box-shadow:0 .5rem 1.25rem #2430441a}.christianity-card-preview-card--hand:hover,.christianity-card-preview-card--hand.is-selected{z-index:3;border-color:#2563eb;box-shadow:0 1rem 2rem #2563eb2e}.christianity-card-preview-card--back{min-height:4.8rem;background:linear-gradient(135deg,#102a431f,#102a4305),repeating-linear-gradient(45deg,#e2e8f0 0 .35rem,#f8fafc .35rem .7rem)}.christianity-card-preview-card--battle{width:100%;min-height:5.7rem;margin-inline:0}.christianity-card-preview-card span,.christianity-card-mini span,.christianity-leader-card span,.christianity-zone-card span{font-weight:700}.christianity-card-preview-card strong,.christianity-card-mini strong,.christianity-leader-card strong,.christianity-zone-card strong{justify-self:end;padding:.15rem .35rem;border-radius:999px;background:#edf2f7;font-size:.8rem}.christianity-player-rack{display:grid;grid-template-columns:minmax(4.2rem,1fr) minmax(5rem,6.5rem) minmax(4.2rem,1fr);gap:.55rem;align-items:end;justify-items:center}.christianity-player-rack--opponent{align-items:start}.christianity-offerings-zone{display:flex;flex-wrap:wrap;gap:.25rem;justify-content:flex-end;width:100%}.christianity-card-mini,.christianity-leader-card,.christianity-zone-card{display:grid;align-content:space-between;min-height:4.9rem;padding:.48rem;text-align:left}.christianity-card-mini{width:3.5rem}.christianity-leader-card{width:min(100%,6.5rem);min-height:5.8rem}.christianity-battle-zone{grid-template-columns:repeat(4,minmax(4rem,1fr))}.christianity-shared-zone{display:grid;grid-template-columns:repeat(3,minmax(4.3rem,1fr));align-items:stretch}.christianity-floating-card{position:fixed;right:max(.75rem,env(safe-area-inset-right));bottom:max(5.8rem,env(safe-area-inset-bottom));z-index:10;display:grid;gap:.28rem;width:min(14rem,calc(100vw - 1.5rem));min-height:10rem;padding:.8rem;border:1px solid rgba(36,48,68,.18);border-radius:.6rem;background:#fffffff5;box-shadow:0 1.25rem 2.5rem #102a432e}.christianity-floating-card small,.christianity-floating-card span{color:#1f2933a3}.christianity-floating-card strong{font-size:1.05rem}.christianity-floating-card p{margin:0;font-size:.86rem;line-height:1.35}button{cursor:pointer}button:disabled{cursor:not-allowed;opacity:.55}button:focus-visible{outline:.1875rem solid rgba(37,99,235,.24);outline-offset:.125rem}@media (max-width: 720px){.christianity-shell{padding:.55rem 0;border-right:0;border-left:0;border-radius:0}.christianity-header,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{align-items:stretch;flex-direction:column}.christianity-battle-zone{grid-template-columns:repeat(4,minmax(3.35rem,1fr));overflow-x:auto}.christianity-hand-fan{min-height:6.8rem;overflow-x:clip}.christianity-player-rack{grid-template-columns:minmax(3.6rem,1fr) minmax(4.8rem,5.6rem) minmax(3.6rem,1fr)}.christianity-shared-zone{grid-template-columns:repeat(3,minmax(3.7rem,1fr))}.christianity-card-preview-card{width:clamp(4.2rem,20vw,5.7rem);min-height:clamp(5.8rem,26vw,7.4rem)}.christianity-floating-card{right:.5rem;bottom:4.8rem}}\n"] }]
68406
68607
  }], ctorParameters: () => [] });
68407
68608
 
68408
68609
  addIcons({ refreshOutline, sparklesOutline, trophyOutline });