${display(animal, 'name')}
${d.interpretation}
` : nothing } ${ 'conventions' in d ? renderConventionsCaption( d.conventions, this.translator, this.effectiveLang(), ) : nothing }${d.interpretation}
` : nothing } ${ 'conventions' in d ? renderConventionsCaption( d.conventions, this.translator, this.effectiveLang(), ) : nothing }${d.overview}
` : nothing }${d.love}
${d.career}
${d.advice}
${year.note}
` : nothing }`; } /** The reference read of one animal: its trine, its three partner animals, and the lists that describe it. */ private renderReference(d: ZodiacData) { if (!('trine' in d) && !('secretFriend' in d)) return nothing; const ref = d as GetZodiacAnimalResponse; return html`${ ref.trine ? html`${ref.summary}
` : nothing } ${ ref.traits?.length ? html`${ref.compatibilitySummary}
` : nothing }` }`; } /** * The three animals the tradition pairs this one with, and it names all three roles. * * @remarks * The secret friend and the clash are opposite verdicts on the same axis, so a card that shows * one and not the other reads as advice rather than as the structure it is. All three or none. */ private renderPartners(ref: GetZodiacAnimalResponse) { const rows: Array<[ChromeString, ZodiacAnimal | undefined]> = [ ['Secret friend', ref.secretFriend], ['Clash', ref.clashPartner], ['Harm', ref.harmPartner], ]; const present = rows.filter(([, who]) => who?.name); if (present.length === 0) return nothing; return html`${d.summary}
` : nothing } ${this.bullets(this.t('Strengths'), d.strengths)} ${this.bullets(this.t('Frictions'), d.frictions)} ${d.advice ? html`${d.advice}
` : nothing}` }