import { css, html, nothing } from 'lit'; import { property } from 'lit/decorators.js'; import { divisionalChartEndpoints } from '../generated/endpoint-defaults.js'; import { planetGlyph } from '../tokens/index.js'; import type { DivisionalChartResponse, NavamsaResponse, } from '../types/index.js'; import { RoxyDataElement } from '../utils/base-element.js'; import { baseStyles } from '../utils/base-styles.js'; import { ChartViewport, chartViewportStyles } from '../utils/chart-viewport.js'; import { customElement } from '../utils/define.js'; import { disclosureStyles } from '../utils/disclosure.js'; import { distinctSanskrit } from '../utils/format.js'; import { frameCaptionStyles, renderFrameCaption } from '../utils/frame.js'; import { type ChartStyle, type KundliViewModel, renderKundliCaptions, renderKundliStyleTablist, renderKundliSvg, renderVargaReferenceTable, toKundliViewModel, } from '../utils/kundli-render.js'; import { kundliStyles } from '../utils/kundli-styles.js'; import { tablistStyles } from '../utils/tablist.js'; /** The two responses this card draws: a chosen division, which names itself, and the navamsa, which is D9 by definition. */ type DivisionalData = DivisionalChartResponse | NavamsaResponse; type Division = Partial & Pick; /** * The navamsa endpoint is the ninth division by definition, so its response carries no `division` block of its own; this is the one the divisional endpoint prints for D9, in every language, and it is what the card labels a navamsa response with. */ const NAVAMSA: Division = { number: 9, name: 'Navamsa' }; const divisionOf = (d: DivisionalData): Division => 'division' in d && d.division ? d.division : NAVAMSA; /** * Divisional chart renderer (D2-D60). Accepts a DivisionalChartResponse or a * NavamsaResponse and renders the same South / North / East kundli grid as the * birth chart, plus division metadata and Vargottama planet pills. A visible * tablist lets the end user switch styles at runtime. The varga response * carries a graha-keyed `chart.meta` map (no per-rashi buckets), so houses are * bucketed from that map. */ @customElement('roxy-divisional-chart') export class RoxyDivisionalChart extends RoxyDataElement { static endpoints = divisionalChartEndpoints; private readonly chartViewport = new ChartViewport(this); static styles = [ baseStyles, chartViewportStyles, frameCaptionStyles, kundliStyles, disclosureStyles, tablistStyles, css` .division-meta { font-size: var(--roxy-text-sm, 0.875rem); color: var(--roxy-muted, #71717a); margin: 0; } .significance { font-size: var(--roxy-text-sm, 0.875rem); color: var(--roxy-muted, #71717a); border-left: 2px solid var(--roxy-border, #e4e4e7); padding-left: var(--roxy-space-sm, 0.5rem); margin: 0; } .vargottama-row { display: flex; flex-wrap: wrap; gap: var(--roxy-space-xs, 0.25rem); align-items: center; } .vargottama-label { font-size: var(--roxy-text-sm, 0.875rem); color: var(--roxy-muted, #71717a); font-weight: 500; margin-right: var(--roxy-space-xs, 0.25rem); } .vargottama-pill { display: inline-flex; align-items: center; gap: 0.2em; font-size: var(--roxy-text-sm, 0.875rem); font-weight: 600; padding: 0.15em 0.6em; border-radius: 999px; background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 22%, transparent); color: var(--roxy-fg, #0a0a0a); border: 1px solid color-mix(in srgb, var(--roxy-accent, #f59e0b) 45%, transparent); } `, ]; @property({ type: String, reflect: true, attribute: 'chart-style' }) chartStyle: ChartStyle = 'north'; private setStyle = (next: ChartStyle) => { this.chartStyle = next; }; private viewModel(): KundliViewModel | null { if (!this.data?.chart?.meta) return null; const division = divisionOf(this.data); const label = `D${division.number} ${division.name}`; return toKundliViewModel(this.data.chart.meta, { divisionLabel: label, natalReference: true, }); } protected renderData(d: DivisionalData) { const vm = this.viewModel(); if (!vm) return this.renderEmpty(); const division = divisionOf(d); const { vargottama } = d; return html`

D${division.number} ${division.name} ${ distinctSanskrit(division.name, division.sanskritName) ? html` ยท ${division.sanskritName}` : nothing }

${ division.significance ? html`

${division.significance}

` : nothing } ${renderFrameCaption(this.effectiveLang(), d.frame, this.translator)} ${renderKundliCaptions(vm, this.translator)}
${renderKundliStyleTablist(this.chartStyle, this.setStyle, this.translator)}
${this.chartViewport.renderChartViewport( html` D${division.number} ${division.name} ${renderKundliSvg(vm, this.chartStyle, this.translator)} `, `D${division.number} ${division.name}`, this.translator, )}
${renderVargaReferenceTable(d.chart.meta, division.number, this.effectiveLang(), this.translator)} ${ vargottama && vargottama.length > 0 ? html`
${this.t('Vargottama')}: ${vargottama.map( (planet) => html` ${planetGlyph(planet) ?? ''} ${planet} `, )}
` : nothing }
`; } } declare global { interface HTMLElementTagNameMap { 'roxy-divisional-chart': RoxyDivisionalChart; } }