<script lang="ts">
  import {
    fetchAllRows,
    fetchDatasetConfigYaml,
    type DatasetConfigYaml,
  } from "./huggingfaceApi";
  import type {
    TermDefinition,
    EquivalencyScore,
    GradingTemplateEntry,
  } from "./types";
  import { marked } from "marked";
  import { config, getDatasetName } from "./config";

  // Configuration from centralized config
  const availableJurisdictions = config.jurisdictions;
  const dataset = getDatasetName("structured-answers");
  const scoresDataset = getDatasetName("equivalency-scores");
  const gradingTemplatesDataset = getDatasetName("grading-templates");
  const directTranslations = config.directTranslations;
  const equivalencyScoreLabels = config.equivalencyScoreLabels;

  // Create bidirectional lookup map (both English->Swedish and Swedish->English)
  const translationMap = new Map<string, string>();
  Object.entries(directTranslations).forEach(([en, sv]) => {
    translationMap.set(en.toLowerCase(), sv.toLowerCase());
    translationMap.set(sv.toLowerCase(), en.toLowerCase());
  });

  // Form inputs
  let jurisdiction1 = $state<string>(config.defaults.jurisdiction1);
  let jurisdiction2 = $state<string>(config.defaults.jurisdiction2);

  // Data state
  let data1 = $state<TermDefinition[]>([]);
  let data2 = $state<TermDefinition[]>([]);
  let equivalencyScores = $state<EquivalencyScore[]>([]);
  let selectedTerm1 = $state<string | null>(null);
  let selectedTerm2 = $state<string | null>(null);
  let datasetConfig = $state<DatasetConfigYaml | null>(null);
  let gradingTemplates_j1 = $state<GradingTemplateEntry[]>([]);
  let gradingTemplates_j2 = $state<GradingTemplateEntry[]>([]);

  // Track previous selected terms for detecting user-initiated changes (loop prevention)
  let prevSelectedTerm1 = $state<string | null>(null);
  let prevSelectedTerm2 = $state<string | null>(null);

  // UI state
  let loading = $state(false);
  let error = $state("");
  let hasLoaded = $state(false);
  let loadingDetails = $state(false);
  let selectedCategory = $state<string>("All");

  // Track previous values to detect changes
  let prevJurisdiction1 = $state<string>(config.defaults.jurisdiction1);
  let prevJurisdiction2 = $state<string>(config.defaults.jurisdiction2);

  // Reload when jurisdictions change
  $effect(() => {
    const j1 = jurisdiction1;
    const j2 = jurisdiction2;

    if (hasLoaded && (j1 !== prevJurisdiction1 || j2 !== prevJurisdiction2)) {
      prevJurisdiction1 = j1;
      prevJurisdiction2 = j2;
      loadComparison();
    }
  });

  async function loadComparison() {
    if (jurisdiction1 === jurisdiction2) {
      error = "Please select two different jurisdictions";
      return;
    }

    loading = true;
    error = "";
    data1 = [];
    data2 = [];
    equivalencyScores = [];
    selectedTerm1 = null;
    selectedTerm2 = null;
    prevSelectedTerm1 = null;
    prevSelectedTerm2 = null;
    hasLoaded = false;

    // Start loading grading templates/details concurrently to reduce wait time
    const detailsPromise = loadDetails();

    try {
      // Determine the config name for equivalency scores (alphabetically sorted)
      const sortedJurisdictions = [jurisdiction1, jurisdiction2].sort();
      const scoresConfig = `${sortedJurisdictions[0]}_${sortedJurisdictions[1]}`;

      // Fetch both jurisdictions and equivalency scores in parallel
      const [rows1, rows2, scoresRows] = await Promise.all([
        fetchAllRows(dataset, jurisdiction1, "train", undefined),
        fetchAllRows(dataset, jurisdiction2, "train", undefined),
        fetchAllRows(scoresDataset, scoresConfig, "train", undefined),
      ]);

      data1 = (rows1 as TermDefinition[]).sort((a, b) =>
        a.term.localeCompare(b.term)
      );
      data2 = (rows2 as TermDefinition[]).sort((a, b) =>
        a.term.localeCompare(b.term)
      );
      equivalencyScores = scoresRows as EquivalencyScore[];

      hasLoaded = true;

      // Fetch config.yaml for this jurisdiction pair
      try {
        const configPath = `${jurisdiction1}_${jurisdiction2}/config.yaml`;
        datasetConfig = await fetchDatasetConfigYaml(
          scoresDataset,
          configPath,
          "main",
          undefined
        );
      } catch (e) {
        datasetConfig = null;
        console.warn("Could not load dataset config.yaml", e);
      }

      // Auto-select first term from jurisdiction 1 and its equivalent in jurisdiction 2
      if (data1.length > 0) {
        const firstTerm = data1[0].term;
        selectedTerm1 = firstTerm;
        prevSelectedTerm1 = firstTerm;

        // Try to find direct translation equivalent in jurisdiction 2
        if (data2.length > 0) {
          const translation = getDirectTranslation(firstTerm);
          const matchingTerm = translation
            ? findTermInData(translation, data2)
            : null;

          if (matchingTerm) {
            selectedTerm2 = matchingTerm;
            prevSelectedTerm2 = matchingTerm;
          } else {
            selectedTerm2 = data2[0].term;
            prevSelectedTerm2 = data2[0].term;
          }
        }
      } else if (data2.length > 0) {
        selectedTerm2 = data2[0].term;
        prevSelectedTerm2 = data2[0].term;
      }
    } catch (e) {
      error = e instanceof Error ? e.message : "Failed to load jurisdictions";
      console.error("Jurisdiction loading error:", e);
    } finally {
      loading = false;
      // Ensure details loading finishes (any error already handled in loadDetails)
      try {
        await detailsPromise;
      } catch (e) {
        console.warn("loadDetails failed:", e);
      }
    }
  }

  async function loadDetails() {
    loadingDetails = true;
    try {
      const [rows_j1, rows_j2] = await Promise.all([
        fetchAllRows(
          gradingTemplatesDataset,
          jurisdiction1,
          "train",
          undefined
        ),
        fetchAllRows(
          gradingTemplatesDataset,
          jurisdiction2,
          "train",
          undefined
        ),
      ]);
      gradingTemplates_j1 = rows_j1 as GradingTemplateEntry[];
      gradingTemplates_j2 = rows_j2 as GradingTemplateEntry[];
    } catch (e) {
      // Non-fatal: templates may not exist for all jurisdictions
      gradingTemplates_j1 = [];
      gradingTemplates_j2 = [];
      console.warn("Failed to load grading templates:", e);
    } finally {
      loadingDetails = false;
    }
  }

  function getSelectedDefinition1(): string {
    if (!selectedTerm1) return "";
    const found = data1.find((item) => item.term === selectedTerm1);
    return found?.definition || "";
  }

  function getSelectedDefinition2(): string {
    if (!selectedTerm2) return "";
    const found = data2.find((item) => item.term === selectedTerm2);
    return found?.definition || "";
  }

  function normalizeTermForComparison(term: string | undefined): string {
    if (term === undefined) return "";
    // Replace underscores with spaces and normalize whitespace for comparison
    return term.replace(/_/g, " ").replace(/\s+/g, " ").trim().toLowerCase();
  }
  function formatCategoryName(name: string): string {
    // Replace underscores with spaces for display
    return name.replace(/_/g, " ");
  }
  // Get direct translation equivalent for a term
  function getDirectTranslation(term: string): string | null {
    const normalized = normalizeTermForComparison(term);
    return translationMap.get(normalized) || null;
  }

  // Find a term in a data array by its normalized form
  function findTermInData(
    normalizedTarget: string,
    data: TermDefinition[]
  ): string | null {
    const found = data.find(
      (item) => normalizeTermForComparison(item.term) === normalizedTarget
    );
    return found?.term || null;
  }

  // Auto-select direct translation when selectedTerm1 changes (user-initiated)
  $effect(() => {
    const current = selectedTerm1;
    if (current && current !== prevSelectedTerm1 && data2.length > 0) {
      const translation = getDirectTranslation(current);
      if (translation) {
        const matchingTerm = findTermInData(translation, data2);
        if (matchingTerm && matchingTerm !== selectedTerm2) {
          selectedTerm2 = matchingTerm;
          prevSelectedTerm2 = matchingTerm;
        }
      }
      prevSelectedTerm1 = current;
    }
  });

  // Auto-select direct translation when selectedTerm2 changes (user-initiated)
  $effect(() => {
    const current = selectedTerm2;
    if (current && current !== prevSelectedTerm2 && data1.length > 0) {
      const translation = getDirectTranslation(current);
      if (translation) {
        const matchingTerm = findTermInData(translation, data1);
        if (matchingTerm && matchingTerm !== selectedTerm1) {
          selectedTerm1 = matchingTerm;
          prevSelectedTerm1 = matchingTerm;
        }
      }
      prevSelectedTerm2 = current;
    }
  });

  // Check if a term should be highlighted based on the selected term in the other jurisdiction
  function shouldHighlightTerm(
    term: string,
    selectedInOtherJurisdiction: string | null
  ): boolean {
    if (!selectedInOtherJurisdiction) return false;

    const equivalentOfSelected = getDirectTranslation(
      selectedInOtherJurisdiction
    );
    if (!equivalentOfSelected) return false;

    const normalizedTerm = normalizeTermForComparison(term);
    return normalizedTerm === equivalentOfSelected;
  }

  function getSimilarityScore(): EquivalencyScore | null {
    if (!selectedTerm1 || !selectedTerm2 || equivalencyScores.length === 0) {
      return null;
    }

    // Normalize selected terms for comparison
    const normalizedTerm1 = normalizeTermForComparison(selectedTerm1);
    const normalizedTerm2 = normalizeTermForComparison(selectedTerm2);

    // Look for the score in both directions, comparing normalized terms
    const score = equivalencyScores.find((s) => {
      const normalizedJ1 = normalizeTermForComparison(s.term_j1);
      const normalizedJ2 = normalizeTermForComparison(s.term_j2);

      return (
        (normalizedJ1 === normalizedTerm1 &&
          normalizedJ2 === normalizedTerm2) ||
        (normalizedJ1 === normalizedTerm2 && normalizedJ2 === normalizedTerm1)
      );
    });

    return score || null;
  }

  // Get unique categories from comparisons
  function getUniqueCategories(score: EquivalencyScore | null): string[] {
    if (!score || !score.comparisons) return [];
    const categories = new Set(score.comparisons.map((c) => c.category));
    return Array.from(categories).sort();
  }

  // Get label for equivalency score based on configured ranges
  function getScoreLabel(scoreValue: number): string {
    const match = equivalencyScoreLabels.find(
      (range) => scoreValue >= range.min && scoreValue < range.max
    );
    // Handle edge case for max score (5.0)
    if (!match && scoreValue >= 5.0) {
      return equivalencyScoreLabels[equivalencyScoreLabels.length - 1].label;
    }
    return match?.label || "";
  }

  // Return a CSS class name for coloring scores (low/medium/high)
  function getScoreClass(scoreValue: number): string {
    // More fine-grained buckets across the 1.0-5.0 range
    // 1.0 - 1.99 -> very-low
    // 2.0 - 2.49 -> low
    // 2.5 - 2.99 -> medium-low
    // 3.0 - 3.49 -> medium
    // 3.5 - 3.99 -> medium-high
    // 4.0 - 4.49 -> high
    // 4.5 - 5.0+ -> very-high
    if (scoreValue >= 4.5) return "score-very-high";
    if (scoreValue >= 4.0) return "score-high";
    if (scoreValue >= 3.5) return "score-medium-high";
    if (scoreValue >= 3.0) return "score-medium";
    if (scoreValue >= 2.5) return "score-medium-low";
    if (scoreValue >= 2.0) return "score-low";
    return "score-very-low";
  }

  // Filter comparisons by selected category
  function getFilteredComparisons(score: EquivalencyScore | null) {
    if (!score || !score.comparisons) return [];
    if (selectedCategory === "All") return score.comparisons;
    return score.comparisons.filter((c) => c.category === selectedCategory);
  }

  // Find a grading template entry matching a comparison's category/subcategory and optional term
  function findGradingTemplate(
    category: string,
    subcategory: string | undefined,
    templates: GradingTemplateEntry[],
    term?: string
  ): GradingTemplateEntry | null {
    if (!templates || templates.length === 0) return null;

    const normalizedTarget = term ? normalizeTermForComparison(term) : null;

    return (
      templates.find((t) => {
        const catMatch =
          t.category === category &&
          (t.subcategory || "") === (subcategory || "");
        if (!catMatch) return false;
        if (!normalizedTarget) return true;
        return normalizeTermForComparison(t.term) === normalizedTarget;
      }) || null
    );
  }

  // Helper getters for templates + question text to avoid {@const} in template
  function getTemplateJ1(comparison: {
    category: string;
    subcategory?: string;
    term_j1?: string;
  }) {
    return findGradingTemplate(
      comparison.category,
      comparison.subcategory,
      gradingTemplates_j1,
      comparison.term_j1
    );
  }
  function getTemplateJ2(comparison: {
    category: string;
    subcategory?: string;
    term_j2?: string;
  }) {
    return findGradingTemplate(
      comparison.category,
      comparison.subcategory,
      gradingTemplates_j2,
      comparison.term_j2
    );
  }
  function getQuestionText(comparison: {
    category: string;
    subcategory?: string;
    term_j1?: string;
    term_j2?: string;
  }) {
    return (
      getTemplateJ1(comparison)?.question ||
      getTemplateJ2(comparison)?.question ||
      ""
    );
  }
</script>

<div class="jurisdiction-comparison">
  <h2>Jurisdiction Term Comparison</h2>

  <!-- Model Info Display -->
  {#if datasetConfig}
    <div class="dataset-model-info subtle">
      <span class="info-tooltip-inline">
        <strong>Scoring Model:</strong>
        {datasetConfig.scoring_model}
        <span class="tooltip-content-inline">
          <strong>Scoring Model</strong> is the model used to compute the equivalency
          score between terms. It uses a language model to assess how closely terms
          from different jurisdictions match in meaning.
        </span>
      </span>
      <span class="sep">|</span>
      <span class="info-tooltip-inline">
        <strong>Synthesis Model:</strong>
        {datasetConfig.synthesis_model}
        <span class="tooltip-content-inline">
          <strong>Synthesis Model</strong> is the model used to synthesize comparative
          law notes. Generative AI is used to assess and explain the similarities
          and differences between terms from different jurisdictions.
        </span>
      </span>
      <span class="sep">|</span>
      <span>
        <strong>Last Updated:</strong>
        {datasetConfig.generation_date || "N/A"}
      </span>
    </div>
  {/if}

  <div class="form">
    <div class="form-row">
      <div class="form-group">
        <label for="jurisdiction1">Jurisdiction 1:</label>
        <select
          id="jurisdiction1"
          bind:value={jurisdiction1}
          disabled={loading}
        >
          {#each availableJurisdictions as jur}
            <option value={jur.code}>{jur.label}</option>
          {/each}
        </select>
      </div>

      <div class="form-group">
        <label for="jurisdiction2">Jurisdiction 2:</label>
        <select
          id="jurisdiction2"
          bind:value={jurisdiction2}
          disabled={loading}
        >
          {#each availableJurisdictions as jur}
            <option value={jur.code}>{jur.label}</option>
          {/each}
        </select>
      </div>
    </div>

    {#if !hasLoaded}
      <button onclick={loadComparison} disabled={loading}>
        {loading ? "Loading..." : "Load Comparison"}
      </button>
    {/if}
  </div>

  {#if error}
    <div class="error">
      <strong>Error:</strong>
      {error}
    </div>
  {/if}

  {#if hasLoaded}
    <div class="comparison-container">
      <!-- Jurisdiction 1 -->
      <div class="jurisdiction-column">
        <h3>
          {availableJurisdictions.find((j) => j.code === jurisdiction1)?.label}
        </h3>
        <div class="term-selector">
          <label for="term1">Select Term:</label>
          <select id="term1" bind:value={selectedTerm1}>
            {#each data1 as item}
              <option value={item.term}>
                {shouldHighlightTerm(item.term, selectedTerm2)
                  ? "★ "
                  : ""}{item.term}
              </option>
            {/each}
          </select>
          <small class="translation-hint"
            >★ = Direct translation of the term selected in the opposite
            jurisdiction</small
          >
        </div>
        {#if selectedTerm1}
          <div class="definition-box">
            <h4>Definition:</h4>
            <div class="markdown-content">
              {@html marked(getSelectedDefinition1())}
            </div>
          </div>
        {/if}
        <div class="info">
          <small>{data1.length} terms available</small>
        </div>
      </div>

      <!-- Jurisdiction 2 -->
      <div class="jurisdiction-column">
        <h3>
          {availableJurisdictions.find((j) => j.code === jurisdiction2)?.label}
        </h3>
        <div class="term-selector">
          <label for="term2">Select Term:</label>
          <select id="term2" bind:value={selectedTerm2}>
            {#each data2 as item}
              <option value={item.term}>
                {shouldHighlightTerm(item.term, selectedTerm1)
                  ? "★ "
                  : ""}{item.term}
              </option>
            {/each}
          </select>
          <small class="translation-hint"
            >★ = Direct translation of the term selected in the opposite
            jurisdiction</small
          >
        </div>
        {#if selectedTerm2}
          <div class="definition-box">
            <h4>Definition:</h4>
            <div class="markdown-content">
              {@html marked(getSelectedDefinition2())}
            </div>
          </div>
        {/if}
        <div class="info">
          <small>{data2.length} terms available</small>
        </div>
      </div>
    </div>

    <!-- Similarity Score Display -->
    {#if selectedTerm1 && selectedTerm2}
      {@const score = getSimilarityScore()}
      {#if score}
        <div class="similarity-score">
          <h3>Equivalency Score</h3>
          <div class="score-display">
            <span class="score-label">
              {getScoreLabel(score.aggregated_similarity_score)}
              <!-- Info icon with tooltip -->
              <span class="info-tooltip">
                <svg
                  class="info-icon"
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="2"
                  stroke-linecap="round"
                  stroke-linejoin="round"
                >
                  <circle cx="12" cy="12" r="10"></circle>
                  <line x1="12" y1="16" x2="12" y2="12"></line>
                  <line x1="12" y1="8" x2="12.01" y2="8"></line>
                </svg>
                <span class="tooltip-content">
                  <strong>Score Legend (1 – 5)</strong>
                  {#each equivalencyScoreLabels as range}
                    <span class="tooltip-row">
                      <span class="tooltip-range"
                        >{range.min.toFixed(2)}–{range.max.toFixed(2)}</span
                      >
                      <span>{range.label}</span>
                    </span>
                  {/each}
                </span>
              </span>
            </span>
            <strong class={getScoreClass(score.aggregated_similarity_score)}
              >{score.aggregated_similarity_score.toFixed(2)}</strong
            >
          </div>

          {#if score.comparative_law_note}
            <div class="comparative-note">
              <div class="markdown-content">
                {@html marked(score.comparative_law_note)}
              </div>
            </div>
          {/if}

          {#if score.comparisons && score.comparisons.length > 0}
            {@const categories = getUniqueCategories(score)}
            {@const filteredComparisons = getFilteredComparisons(score)}
            <div class="comparisons-section">
              <h3>Detailed Comparisons</h3>

              {#if loadingDetails}
                <div class="details-loading">
                  <div class="spinner" aria-hidden="true"></div>
                  <div class="spinner-label">Loading details…</div>
                </div>
              {:else}
                <!-- Category Filter Pills -->
                {#if categories.length > 0}
                  <div class="category-filters">
                    <button
                      class="filter-pill"
                      class:active={selectedCategory === "All"}
                      onclick={() => (selectedCategory = "All")}
                    >
                      All ({score.comparisons.length})
                    </button>
                    {#each categories as category}
                      {@const count = score.comparisons.filter(
                        (c) => c.category === category
                      ).length}
                      <button
                        class="filter-pill"
                        class:active={selectedCategory === category}
                        onclick={() => (selectedCategory = category)}
                      >
                        {formatCategoryName(category)} ({count})
                      </button>
                    {/each}
                  </div>
                {/if}

                <div class="comparisons-list">
                  {#if selectedTerm1 || selectedTerm2}
                    <div class="comparisons-header">
                      <div class="header-column left">
                        <div class="detail-term">
                          {normalizeTermForComparison(selectedTerm1)}
                        </div>
                      </div>
                      <div class="header-column center">
                        <div class="detail-term">Comparison</div>
                      </div>
                      <div class="header-column right">
                        <div class="detail-term">
                          {normalizeTermForComparison(selectedTerm2)}
                        </div>
                      </div>
                    </div>
                  {/if}

                  {#each filteredComparisons as comparison}
                    <div class="comparison-item">
                      <div class="comparison-header">
                        <span class="comparison-category">
                          {formatCategoryName(comparison.category)}
                        </span>
                        {#if comparison.subcategory}
                          <span class="comparison-subcategory">
                            › {formatCategoryName(comparison.subcategory)}
                          </span>
                        {/if}
                        <div class="category-meta">
                          <span class="category-weight"
                            >Weight: {comparison.weight.toFixed(2)}</span
                          >
                          <span class="category-weighted"
                            >Weighted Score: {comparison.weighted_similarity_score.toFixed(
                              2
                            )}</span
                          >
                        </div>
                        <span
                          class={"comparison-score " +
                            getScoreClass(comparison.similarity_score)}
                          >{comparison.similarity_score.toFixed(2)}</span
                        >
                      </div>

                      {#if getQuestionText(comparison)}
                        <div class="detail-question-single">
                          {getQuestionText(comparison)}
                        </div>
                      {/if}

                      <div class="comparison-details">
                        <div class="detail-column left">
                          {#if getTemplateJ1(comparison)}
                            <div class="detail-answer">
                              {getTemplateJ1(comparison)?.answer}
                            </div>
                          {:else}
                            <div class="detail-empty">—</div>
                          {/if}
                        </div>

                        <div class="detail-column center">
                          {#if comparison.reasoning}
                            <div class="comparison-reasoning">
                              {comparison.reasoning}
                            </div>
                          {/if}
                        </div>

                        <div class="detail-column right">
                          {#if getTemplateJ2(comparison)}
                            <div class="detail-answer">
                              {getTemplateJ2(comparison)?.answer}
                            </div>
                          {:else}
                            <div class="detail-empty">—</div>
                          {/if}
                        </div>
                      </div>
                    </div>
                  {/each}
                </div>
              {/if}
            </div>
          {/if}
        </div>
      {:else}
        <div class="similarity-score no-score">
          <p>No equivalency score found for this term pair.</p>
        </div>
      {/if}
    {/if}
  {/if}
</div>

<style>
  .jurisdiction-comparison {
    max-width: 75%;
    margin: 0 auto;
    padding: 2rem;
    color: #333;
  }

  h2 {
    margin-bottom: 1.5rem;
    color: #333;
    text-align: center;
    background: none;
    font-weight: 700;
    letter-spacing: 0.02em;
  }
  @media (prefers-color-scheme: dark) {
    h2 {
      color: #f7f7f7;
    }
  }

  h3 {
    margin: 0 0 1rem 0;
    color: #444;
    font-size: 1.25rem;
  }

  h4 {
    margin: 0 0 0.5rem 0;
    color: #555;
    font-size: 1rem;
    font-weight: 600;
  }

  .form {
    background: #f5f5f5;
    padding: 1.5rem;
    border-radius: 8px;
    margin-bottom: 2rem;
    color: #333;
  }

  .form-group {
    margin-bottom: 1rem;
  }

  .form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
  }

  label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: 500;
    color: #555;
  }

  select {
    width: 100%;
    padding: 0.5rem;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 1rem;
    box-sizing: border-box;
    background: white;
    color: #333;
  }

  select:disabled {
    background: #e9e9e9;
    cursor: not-allowed;
  }

  button {
    background: #646cff;
    color: white;
    padding: 0.75rem 1.5rem;
    border: none;
    border-radius: 4px;
    font-size: 1rem;
    cursor: pointer;
    transition: background 0.2s;
    width: 100%;
  }

  button:hover:not(:disabled) {
    background: #535bf2;
  }

  button:disabled {
    background: #ccc;
    cursor: not-allowed;
  }

  .error {
    background: #fee;
    color: #c33;
    padding: 1rem;
    border-radius: 4px;
    margin-bottom: 1rem;
    border: 1px solid #fcc;
  }

  .comparison-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2rem;
    margin-top: 2rem;
  }

  .jurisdiction-column {
    background: white;
    padding: 1.5rem;
    border-radius: 8px;
    border: 1px solid #ddd;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
    color: #333;
  }

  .term-selector {
    margin-bottom: 1.5rem;
  }

  .term-selector select {
    font-size: 1rem;
    padding: 0.75rem;
  }

  .definition-box {
    background: #f9f9f9;
    padding: 1.25rem;
    border-radius: 6px;
    border-left: 4px solid #646cff;
    margin-bottom: 1rem;
    min-height: 100px;
  }

  .info {
    color: #666;
    font-size: 0.875rem;
  }

  .info small {
    font-size: 0.875rem;
  }

  .similarity-score {
    background: white;
    padding: 1.5rem;
    border-radius: 8px;
    border: 2px solid #646cff;
    margin-top: 2rem;
    color: #333;
  }

  .similarity-score h3 {
    margin-top: 0;
    margin-bottom: 1rem;
    color: #646cff;
    text-align: center;
  }

  .similarity-score.no-score {
    border-color: #ddd;
    background: #f9f9f9;
    text-align: center;
  }

  .similarity-score.no-score p {
    margin: 0;
    color: #666;
  }

  .score-display {
    text-align: center;
  }

  .score-display .score-label {
    display: block;
    font-size: 1.1rem;
    color: #555;
    font-weight: 500;
    margin-bottom: 0.25rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }

  .score-display strong {
    display: block;
    font-size: 3rem;
    color: #646cff;
    font-weight: 600;
  }

  /* Info Tooltip Styles */
  .info-tooltip {
    position: relative;
    display: inline-flex;
    align-items: center;
    margin-left: 0.35rem;
    cursor: help;
  }

  .info-icon {
    color: #888;
    vertical-align: middle;
    transition: color 0.2s;
  }

  .info-tooltip:hover .info-icon {
    color: #646cff;
  }

  .tooltip-content {
    display: none;
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    background: #333;
    color: white;
    padding: 0.75rem 1rem;
    border-radius: 6px;
    font-size: 0.8rem;
    white-space: nowrap;
    z-index: 100;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
    text-transform: none;
    letter-spacing: normal;
    text-align: left;
  }

  .tooltip-content::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 6px solid transparent;
    border-top-color: #333;
  }

  .info-tooltip:hover .tooltip-content {
    display: block;
  }

  .tooltip-content strong {
    display: block;
    font-size: 0.85rem;
    margin-bottom: 0.5rem;
    color: #fff;
    border-bottom: 1px solid #555;
    padding-bottom: 0.4rem;
  }

  .tooltip-row {
    display: flex;
    gap: 0.75rem;
    padding: 0.2rem 0;
    font-weight: normal;
  }

  .tooltip-range {
    font-family: monospace;
    color: #a5a8ff;
    min-width: 70px;
  }

  .comparative-note {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid #e0e0e0;
  }

  .markdown-content {
    line-height: 1.6;
    color: #333;
    text-align: left;
  }

  .markdown-content :global(h1),
  .markdown-content :global(h2),
  .markdown-content :global(h3),
  .markdown-content :global(h4),
  .markdown-content :global(h5),
  .markdown-content :global(h6) {
    margin-top: 1em;
    margin-bottom: 0.5em;
    font-weight: 600;
  }

  .markdown-content :global(p) {
    margin: 0 0 1em 0;
  }

  .markdown-content :global(ul),
  .markdown-content :global(ol) {
    margin: 0 0 1em 0;
    padding-left: 2em;
  }

  .markdown-content :global(code) {
    background: #f5f5f5;
    padding: 0.2em 0.4em;
    border-radius: 3px;
    font-family: monospace;
    font-size: 0.9em;
  }

  .markdown-content :global(pre) {
    background: #f5f5f5;
    padding: 1em;
    border-radius: 4px;
    overflow-x: auto;
  }

  .markdown-content :global(pre code) {
    background: none;
    padding: 0;
  }

  .markdown-content :global(blockquote) {
    border-left: 4px solid #646cff;
    padding-left: 1em;
    margin: 0 0 1em 0;
    color: #666;
  }

  .markdown-content :global(a) {
    color: #646cff;
    text-decoration: none;
  }

  .markdown-content :global(a:hover) {
    text-decoration: underline;
  }

  @media (max-width: 768px) {
    .comparison-container {
      grid-template-columns: 1fr;
      gap: 1.5rem;
    }

    .form-row {
      grid-template-columns: 1fr;
    }
  }

  .translation-hint {
    display: block;
    margin-top: 0.25rem;
    color: #666;
    font-style: italic;
  }

  /* Comparisons section styling */
  .comparisons-section {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid #e0e0e0;
  }

  .comparisons-header {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 1rem;
    margin-bottom: 0.75rem;
    align-items: center;
  }

  .comparisons-header .header-column {
    background: none;
    padding: 0.5rem 0.75rem;
    color: #333;
    font-weight: 700;
  }

  .comparisons-header .header-column.left {
    text-align: left;
    padding-left: 0.5rem;
    border-right: 1px solid #e0e0e0;
  }

  .comparisons-header .header-column.center {
    text-align: center;
    border-right: 1px solid #e0e0e0;
  }

  .comparisons-header .header-column.right {
    text-align: right;
    padding-right: 0.5rem;
  }

  .comparisons-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  .comparison-item {
    background: #f9f9f9;
    border: 1px solid #e0e0e0;
    border-radius: 6px;
    padding: 1rem;
    transition: box-shadow 0.2s;
  }

  .comparison-item:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }

  .comparison-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
    flex-wrap: wrap;
  }

  .comparison-details {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 1rem;
    margin-top: 0.75rem;
    align-items: start;
  }

  .detail-column {
    background: #fff;
    padding: 0.75rem;
    border-radius: 6px;
    border: 1px solid #f0f0f0;
    min-height: 70px;
  }

  .detail-column.left {
    border-left: 3px solid #646cff;
  }
  .detail-column.right {
    border-right: 3px solid #646cff;
  }

  .detail-term {
    font-weight: 600;
    margin-bottom: 0.35rem;
    color: #333;
  }
  .detail-question {
    font-size: 0.95rem;
    color: #555;
    margin-bottom: 0.5rem;
  }
  .detail-answer {
    font-size: 0.9rem;
    color: #444;
  }
  .detail-empty {
    color: #888;
    font-style: italic;
  }

  @media (max-width: 900px) {
    .comparison-details {
      grid-template-columns: 1fr;
    }
    .comparisons-header {
      grid-template-columns: 1fr;
    }
    .comparisons-header .header-column {
      border-right: none;
      text-align: left;
      padding: 0.25rem 0.5rem;
    }
  }

  .comparison-category {
    font-weight: 600;
    color: #646cff;
    font-size: 0.95rem;
  }

  .comparison-subcategory {
    color: #464444;
    font-size: 0.9rem;
  }

  .comparison-score {
    padding: 0.25rem 0.75rem;
    border-radius: 12px;
    font-weight: 600;
    font-size: 0.9rem;
  }

  .category-meta {
    margin-left: auto;
    display: flex;
    gap: 0.5rem;
    align-items: center;
    color: #666;
    font-size: 0.9rem;
  }
  .category-weight,
  .category-weighted {
    background: #f0f0f0;
    padding: 0.15rem 0.5rem;
    border-radius: 6px;
    font-weight: 600;
    color: #444;
  }

  /* Score color variants */
  .comparison-score.score-high {
    background: #1a7f37;
    color: white;
  }
  .comparison-score.score-medium {
    background: #d98200;
    color: white;
  }
  .comparison-score.score-low {
    background: #c33;
    color: white;
  }

  .score-high {
    color: #1a7f37;
  }
  .score-medium {
    color: #d98200;
  }
  .score-low {
    color: #c33;
  }
  /* Fine-grained score variants */
  .comparison-score.score-very-high {
    background: #0f6b2d;
    color: white;
  }
  .comparison-score.score-medium-high {
    background: #2e9a44;
    color: white;
  }
  .comparison-score.score-medium-low {
    background: #f39c12;
    color: white;
  }
  .comparison-score.score-very-low {
    background: #9b1f1f;
    color: white;
  }

  .score-very-high {
    color: #0f6b2d;
  }
  .score-medium-high {
    color: #2e9a44;
  }
  .score-medium-low {
    color: #f39c12;
  }
  .score-very-low {
    color: #9b1f1f;
  }

  .comparison-meta {
    display: flex;
    gap: 1rem;
    margin-bottom: 0.5rem;
    font-size: 0.85rem;
    color: #666;
  }

  .comparison-weight,
  .comparison-weighted-score {
    background: #f0f0f0;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
  }

  .comparison-reasoning {
    margin-top: 0.5rem;
    padding: 0.75rem;
    background: white;
    border-radius: 4px;
    font-size: 0.9rem;
    line-height: 1.5;
    color: #444;
    text-align: left;
  }

  /* Category filter pills */
  .category-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid #e0e0e0;
  }

  .filter-pill {
    background: #f0f0f0;
    color: #555;
    border: 1px solid #ddd;
    border-radius: 20px;
    padding: 0.5rem 1rem;
    font-size: 0.9rem;
    cursor: pointer;
    transition: all 0.2s;
    width: auto;
  }

  .filter-pill:hover {
    background: #e0e0e0;
    border-color: #999;
  }

  .filter-pill.active {
    background: #646cff;
    color: white;
    border-color: #646cff;
    font-weight: 600;
  }

  .filter-pill.active:hover {
    background: #535bf2;
    border-color: #535bf2;
  }

  .dataset-model-info.subtle {
    background: none;
    border: none;
    padding: 2rem 0;
    margin: 0 0 0.5rem 0;
    max-width: 100%;
    color: #888;
    font-size: 0.92rem;
    text-align: left;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
  }
  .dataset-model-info.subtle strong {
    color: #888;
    font-weight: 500;
    margin-right: 0.15em;
  }
  .dataset-model-info.subtle .sep {
    color: #ccc;
    font-size: 1.1em;
    margin: 0 0.5em;
  }
  .info-tooltip-inline {
    position: relative;
    display: inline-flex;
    align-items: center;
    cursor: help;
  }
  .info-tooltip-inline strong {
    margin-right: 0.15em;
  }
  .info-tooltip-inline:hover .tooltip-content-inline {
    display: block;
  }
  .tooltip-content-inline {
    display: none;
    position: absolute;
    bottom: calc(100% + 8px);
    left: 0;
    background: #333;
    color: white;
    padding: 0.75rem 1rem;
    border-radius: 6px;
    font-size: 0.8rem;
    white-space: normal;
    z-index: 100;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
    text-align: left;
    min-width: 220px;
    max-width: 320px;
  }
  .tooltip-content-inline strong {
    display: block;
    font-size: 0.85rem;
    margin-bottom: 0.5rem;
    color: #fff;
    border-bottom: 1px solid #555;
    padding-bottom: 0.4rem;
  }
  /* Details loading spinner */
  .details-loading {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 1rem 0;
    justify-content: center;
    color: #666;
  }
  .spinner {
    width: 28px;
    height: 28px;
    border: 4px solid #e6e6ff;
    border-top-color: #646cff;
    border-radius: 50%;
    animation: spin 1s linear infinite;
  }
  .spinner-label {
    font-size: 0.95rem;
    color: #444;
  }
  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }
</style>
