<script setup>
import {
  checkWhatsappTemplateMessageApi,
  checkWhatsappTemplateNameApi,
  createWhatsappTemplateApi,
  getWhatsappTemplatesApi,
  translateWhatsappTemplateContentApi,
  updateWhatsappTemplateApi,
} from "@/api/whatsappTemplateApi";
import { getFranchiseeCampaignLanguagesApi } from "@/api/franchiseeCampaignApi";
import EntityTranslationToolbar from "@/components/EntityTranslationToolbar.vue";
import { extractErrorMessage, extractResponseData, showToast } from "@/composables/useStoreHelpers";
import { useAuthStore } from "@/stores/authStore";
import { storeToRefs } from "pinia";
import { computed, nextTick, onMounted, reactive, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";

const route = useRoute();
const router = useRouter();

const authStore = useAuthStore();
const { user: authUser } = storeToRefs(authStore);
const isSuperAdmin = computed(() => authUser.value?.data?.role === "super_admin");

const editingId = computed(() => route.params.id);
const isEditing = computed(() => !!editingId.value);
const loading = ref(false);
const submitting = ref(false);
const formRef = ref(null);

// WhatsApp-supported template languages (admin authoring dropdown; code as Meta expects).
const languages = [
  { title: "English (US)", value: "en_US" },
  { title: "English (UK)", value: "en_GB" },
  { title: "English", value: "en" },
  { title: "Spanish", value: "es" },
  { title: "Spanish (Spain)", value: "es_ES" },
  { title: "Spanish (Mexico)", value: "es_MX" },
  { title: "Portuguese (Brazil)", value: "pt_BR" },
  { title: "Portuguese (Portugal)", value: "pt_PT" },
  { title: "French", value: "fr" },
  { title: "German", value: "de" },
  { title: "Italian", value: "it" },
  { title: "Dutch", value: "nl" },
  { title: "Arabic", value: "ar" },
  { title: "Hebrew", value: "he" },
  { title: "Hindi", value: "hi" },
  { title: "Indonesian", value: "id" },
  { title: "Russian", value: "ru" },
  { title: "Turkish", value: "tr" },
  { title: "Chinese (Simplified)", value: "zh_CN" },
  { title: "Chinese (Traditional)", value: "zh_TW" },
  { title: "Japanese", value: "ja" },
  { title: "Korean", value: "ko" },
];

// Validation rules shared by the form fields (mirrors the backend rules()).
const rules = {
  required: (v) => (v !== null && v !== undefined && String(v).trim() !== "") || "This field is required.",
  max: (n) => (v) => !v || String(v).length <= n || `Must be ${n} characters or less.`,
};

// ----- Formatting rules that mirror what Meta rejects on review -----
const letterCount = (v) => (String(v || "").match(/\p{L}/gu) || []).length;
const varNumbers = (v) => [...String(v || "").matchAll(/\{\{\s*(\d+)\s*\}\}/g)].map((m) => Number(m[1]));
const hasVariable = (v) => /\{\{\s*\d+\s*\}\}/.test(String(v || ""));

const namePattern = (v) =>
  !v || /^[a-z0-9_]+$/.test(v) || "Only lowercase letters, numbers and underscores are allowed.";
const noTabs = (v) => !v || !/\t/.test(v) || "Tab characters are not allowed.";
const singleLine = (v) => !v || !/[\r\n]/.test(v) || "Must be a single line (no line breaks).";
const noLongRuns = (v) =>
  !v || !/( {4,}|\n{3,})/.test(v) || "Remove long runs of spaces or blank lines — Meta will reject it.";
const meaningfulText = (min) => (v) =>
  !v ||
  letterCount(v) >= min ||
  `Write a real message — at least ${min} letters. Symbol-only text gets rejected by Meta.`;
const headerOneVar = (v) =>
  !v || varNumbers(v).length <= 1 || "The header can contain at most one variable.";
const noVariables = (v) =>
  !v || !hasVariable(v) || "Variables aren't allowed in the footer.";
const bodyVariablesValid = (v) => {
  if (!v) return true;
  const text = String(v);
  const nums = varNumbers(v);
  if (nums.length) {
    const ordered = [...new Set(nums)].sort((a, b) => a - b);
    for (let i = 0; i < ordered.length; i++) {
      if (ordered[i] !== i + 1) {
        return "Number variables in order starting at {{1}} with no gaps (e.g. {{1}}, {{2}}).";
      }
    }
    const trimmed = text.trim();
    if (/^\{\{\s*\d+\s*\}\}/.test(trimmed)) return "The message can't start with a variable — add text before {{1}}.";
    if (/\{\{\s*\d+\s*\}\}$/.test(trimmed)) return "The message can't end with a variable — add text after it.";
    if (/\}\}\s*\{\{/.test(text)) return "Two variables can't be next to each other — put text between them.";
  }
  return true;
};

const labelRules = [rules.required, rules.max(512), namePattern];
const languageRules = [rules.required];
const headerRules = [rules.max(60), noTabs, singleLine, headerOneVar, meaningfulText(1)];
const bodyRules = [rules.required, rules.max(1024), noTabs, noLongRuns, meaningfulText(3), bodyVariablesValid];
const footerRules = [rules.max(60), noTabs, singleLine, noVariables, meaningfulText(1)];

const form = reactive({
  label: "",
  language: null,
  category: "UTILITY",
  header_text: "",
  body_text: "",
  footer_text: "",
});

const examples = reactive({});

// Only these predefined variables can be inserted (keeps templates consistent).
const VARIABLES = [
  { token: "parent_first_name", label: "Parent first name", example: "John" },
  { token: "parent_last_name", label: "Parent last name", example: "Doe" },
  { token: "parent_email", label: "Parent email", example: "john@example.com" },
];

const usedVariables = computed(() => {
  const found = [...String(form.body_text || "").matchAll(/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g)].map((m) => m[1]);
  return VARIABLES.filter((v) => found.includes(v.token));
});

const bodyRef = ref(null);
const variablePick = ref(null);

const insertVariable = (token) => {
  const insert = `{{${token}}}`;
  const el = bodyRef.value?.$el?.querySelector("textarea");
  const text = form.body_text || "";
  if (!el) {
    form.body_text = text + insert;
    return;
  }
  const start = el.selectionStart ?? text.length;
  const end = el.selectionEnd ?? start;
  form.body_text = text.slice(0, start) + insert + text.slice(end);
  nextTick(() => {
    el.focus();
    const pos = start + insert.length;
    el.setSelectionRange(pos, pos);
  });
};

const onPickVariable = (token) => {
  if (!token) return;
  insertVariable(token);
  variablePick.value = null;
};

// ---- Live name availability (super-admin authoring only; franchisee names are auto-derived) ----
const nameCheck = reactive({ checking: false, available: null, message: "" });
let nameCheckTimer = null;
let nameCheckToken = 0;

const runNameCheck = async (label) => {
  const token = ++nameCheckToken;
  try {
    nameCheck.checking = true;
    // Exclude the row being edited from the "taken" check: admin → the template id;
    // franchisee → their own per-language row id (NOT the source global id, which would 403).
    const checkId = isSuperAdmin.value
      ? (isEditing.value ? editingId.value : null)
      : (activeRow.value?.id || null);
    const res = await checkWhatsappTemplateNameApi(label, checkId);
    const data = extractResponseData(res) || {};
    if (token !== nameCheckToken) return;
    nameCheck.available = !!data.available;
    nameCheck.message = data.message || "";
  } catch (error) {
    if (token !== nameCheckToken) return;
    nameCheck.available = null;
    nameCheck.message = extractErrorMessage(error);
  } finally {
    if (token === nameCheckToken) nameCheck.checking = false;
  }
};

const sanitizeName = (val) =>
  String(val || "")
    .toLowerCase()
    .replace(/\s+/g, "_")
    .replace(/[^a-z0-9_]/g, "")
    .replace(/_{2,}/g, "_");

watch(
  () => form.label,
  (label) => {
    // Keep the name a valid Meta name for everyone; only super admin gets the live check.
    const clean = sanitizeName(label);
    if (clean !== label) {
      form.label = clean;
      return;
    }
    if (nameCheckTimer) clearTimeout(nameCheckTimer);
    if (!clean) {
      nameCheck.checking = false;
      nameCheck.available = null;
      nameCheck.message = "";
      nameCheckToken++;
      return;
    }
    nameCheckTimer = setTimeout(() => runNameCheck(clean), 450);
  },
);

const nameHint = computed(() => {
  if (nameCheck.checking) return "Checking availability…";
  if (nameCheck.message) return nameCheck.message;
  return isSuperAdmin.value
    ? "Lowercase letters, numbers and underscores only."
    : "Lowercase letters, numbers and underscores — this exact name is sent to WhatsApp.";
});

// ---- Franchisee translate mode ----
const sourceTemplate = ref(null); // admin default being translated
const ownRows = ref([]); // franchisee per-language template rows
const utmLanguages = ref([]); // [{code,name}]
const activeLang = ref("en");

const langTabs = computed(() =>
  utmLanguages.value.map((l) => ({ code: l.code, label: l.name })),
);
const selectedLabel = computed(
  () => langTabs.value.find((t) => t.code === activeLang.value)?.label || activeLang.value,
);

const toLangCode = (lang) => String(lang || "").split(/[_-]/)[0].toLowerCase();
// Only rows that are translations OF THIS source template — so unrelated/legacy templates
// (e.g. a standalone en_GB one with no source) don't hijack a language tab.
const sourceRows = computed(() =>
  (ownRows.value || []).filter((r) => r.source_template_id && r.source_template_id === sourceTemplate.value?.id),
);
const activeRow = computed(
  () => sourceRows.value.find((r) => toLangCode(r.language) === activeLang.value) || null,
);
const statusByLanguage = computed(() => {
  const map = {};
  sourceRows.value.forEach((r) => {
    map[toLangCode(r.language)] = r.status;
  });
  return map;
});
// Editable when there's no row yet, or the existing one is draft/rejected (Meta forbids editing approved/pending).
const activeEditable = computed(() => {
  const r = activeRow.value;
  return !r || ["draft", "rejected"].includes(r.status);
});

// The franchisee name field holds the full Meta name; we pre-fill a sensible default
// ({source}_{franchise}_{lang}) which they can edit. It's sent to Meta verbatim.
const slugify = (s) =>
  String(s || "").toLowerCase().replace(/\s+/g, "_").replace(/[^a-z0-9_]/g, "").replace(/_{2,}/g, "_");
const franchiseSlug = computed(() => slugify(authUser.value?.data?.franchisee?.name) || "franchise");
const defaultFranchiseeName = () => {
  const base = slugify(sourceTemplate.value?.meta_name || sourceTemplate.value?.label || "template") || "template";
  return `${base}_${franchiseSlug.value}_${activeLang.value}`;
};

const fillContentFrom = (t) => {
  form.header_text = t?.header_text ?? "";
  form.body_text = t?.body_text ?? "";
  form.footer_text = t?.footer_text ?? "";
  Object.keys(examples).forEach((k) => delete examples[k]);
  const stored = t?.components?.find((c) => c.type === "BODY")?.example?.body_text?.[0] ?? [];
  stored.forEach((val, i) => {
    examples[i + 1] = val;
  });
};

const loadFranchiseeTab = () => {
  const row = activeRow.value;
  // Show the actual Meta name: the existing row's name, or the default for a new translation.
  form.label = row?.meta_name ?? defaultFranchiseeName();
  fillContentFrom(row || sourceTemplate.value); // seed content from the admin source when not yet translated
};

// AI-translate the header/body/footer into the active language (variables preserved).
const translating = ref(false);
const aiTranslate = async () => {
  try {
    translating.value = true;
    const data =
      extractResponseData(
        await translateWhatsappTemplateContentApi({
          language: activeLang.value,
          header_text: form.header_text,
          body_text: form.body_text,
          footer_text: form.footer_text,
        }),
      ) || {};
    form.header_text = data.header_text ?? form.header_text;
    form.body_text = data.body_text ?? form.body_text;
    form.footer_text = data.footer_text ?? form.footer_text;
    showToast("success", "", `Translated to ${selectedLabel.value} — review and submit.`);
  } catch (error) {
    showToast("error", "", extractErrorMessage(error));
  } finally {
    translating.value = false;
  }
};

const onLang = (code) => {
  activeLang.value = code;
  loadFranchiseeTab();
};

const loadEditor = async () => {
  loading.value = true;
  try {
    const data = extractResponseData(await getWhatsappTemplatesApi()) || {};

    if (isSuperAdmin.value) {
      if (isEditing.value) {
        const src = (data.templates || []).find((t) => String(t.id) === String(editingId.value));
        if (!src) {
          showToast("error", "", "Template not found.");
          router.push("/whatsapp");
          return;
        }
        form.label = src.label ?? "";
        form.language = src.language ?? "en_US";
        form.category = src.category ?? "UTILITY";
        fillContentFrom(src);
      }
      return;
    }

    // Franchisee translate mode: source = admin default, tabs = UTM languages.
    utmLanguages.value = data.languages || [];
    ownRows.value = data.own || [];
    const globals = data.global || [];
    sourceTemplate.value =
      globals.find((t) => String(t.id) === String(editingId.value)) || globals[0] || null;
    form.category = sourceTemplate.value?.category ?? "UTILITY";

    if (langTabs.value.length) {
      const wanted = String(route.query.lang || "");
      activeLang.value = langTabs.value.find((t) => t.code === wanted)?.code || langTabs.value[0].code;
      loadFranchiseeTab();
    }
  } catch (error) {
    showToast("error", "", extractErrorMessage(error));
  } finally {
    loading.value = false;
  }
};

const reloadOwn = async () => {
  const data = extractResponseData(await getWhatsappTemplatesApi()) || {};
  ownRows.value = data.own || [];
  loadFranchiseeTab();
};

onMounted(loadEditor);

const goBack = () => {
  router.push({ path: "/whatsapp", query: { tab: "templates" } });
};

const canSave = computed(() => {
  if (isSuperAdmin.value) return true;
  return langTabs.value.length > 0 && activeEditable.value;
});

const saveLabel = computed(() => {
  if (isSuperAdmin.value) return isEditing.value ? "Resubmit for approval" : "Submit for approval";
  return activeRow.value ? `Resubmit ${selectedLabel.value}` : `Submit ${selectedLabel.value}`;
});

const submit = async () => {
  const { valid } = formRef.value ? await formRef.value.validate() : { valid: true };
  if (!valid) {
    showToast("warning", "", "Please fix the highlighted fields before submitting.");
    return;
  }

  if (nameCheck.available === false) {
    showToast("warning", "", "That template name is already taken — choose a different name.");
    return;
  }

  // Abusive-language / profanity gate (header + body + footer), per language.
  try {
    submitting.value = true;
    const moderationText = [form.header_text, form.body_text, form.footer_text]
      .filter((t) => t && t.trim())
      .join("\n");
    const moderation = extractResponseData(await checkWhatsappTemplateMessageApi(moderationText)) || {};
    if (moderation.pass === false) {
      showToast("error", "", moderation.reason || "Your message contains content that isn't allowed.");
      return;
    }
  } catch (error) {
    showToast("error", "", extractErrorMessage(error));
    return;
  } finally {
    submitting.value = false;
  }

  const body_examples = {};
  usedVariables.value.forEach((v) => {
    body_examples[v.token] = v.example;
  });

  try {
    submitting.value = true;

    if (isSuperAdmin.value) {
      const payload = { ...form, body_examples };
      if (isEditing.value) {
        await updateWhatsappTemplateApi(editingId.value, payload);
        showToast("success", "", "Template resubmitted to Meta for approval.");
      } else {
        await createWhatsappTemplateApi(payload);
        showToast("success", "", "Template submitted to Meta for approval.");
      }
      goBack();
      return;
    }

    // Franchisee: create/update the per-language template derived from the admin source.
    const payload = {
      label: form.label,
      language: activeLang.value,
      source_template_id: sourceTemplate.value?.id || null,
      category: form.category,
      header_text: form.header_text,
      body_text: form.body_text,
      footer_text: form.footer_text,
      body_examples,
    };
    if (activeRow.value) {
      await updateWhatsappTemplateApi(activeRow.value.id, payload);
    } else {
      await createWhatsappTemplateApi(payload);
    }
    showToast("success", "", `${selectedLabel.value} template submitted to Meta for approval.`);
    await reloadOwn();
  } catch (error) {
    showToast("error", "", extractErrorMessage(error));
  } finally {
    submitting.value = false;
  }
};
</script>

<template>
  <div class="template-editor-page">
    <div class="d-flex align-center gap-3 mb-6">
      <VBtn icon="bx-arrow-back" variant="tonal" size="small" @click="goBack" />
      <div>
        <h2 class="text-h5 font-weight-bold mb-0">
          {{ isSuperAdmin ? (isEditing ? "Edit Template" : "Create Template") : "Translate Template" }}
        </h2>
        <span v-if="!isSuperAdmin" class="text-body-2 text-medium-emphasis">
          Translate the platform welcome template into each of your campaign languages.
        </span>
      </div>
    </div>

    <div v-if="loading" class="content-grid">
      <div class="main-content">
        <VCard class="form-card pa-6 pa-md-8" variant="flat" border>
          <VSkeletonLoader type="heading, paragraph, article" />
        </VCard>
      </div>
      <div class="side-content">
        <div class="sticky-wrapper">
          <div class="sidebar-card">
            <VSkeletonLoader type="heading, text, button, button" />
          </div>
        </div>
      </div>
    </div>

    <div v-else class="content-grid">
      <div class="main-content">
        <!-- Franchisee: language tabs (one per UTM campaign language) -->
        <EntityTranslationToolbar
          v-if="!isSuperAdmin && langTabs.length"
          :model-value="activeLang"
          :tabs="langTabs"
          :selected-label="selectedLabel"
          :status-by-language="statusByLanguage"
          :translating="translating"
          class="mb-4"
          @update:model-value="onLang"
          @translate="aiTranslate"
        />

        <VAlert
          v-if="!isSuperAdmin && !langTabs.length"
          type="info"
          variant="tonal"
          density="comfortable"
          class="mb-4"
        >
          No campaign languages found for your account. Add UTM campaigns in the CRM to translate this template.
        </VAlert>

        <VCard class="form-card pa-6 pa-md-8" variant="flat" border>
          <VForm ref="formRef" @submit.prevent="submit">
            <VRow>
              <VCol cols="12" class="pb-1">
                <div class="section-label">
                  <VIcon icon="bx-detail" size="16" class="me-1" />Template details
                </div>
              </VCol>

              <!-- Template name: editable for both, with a live "already taken?" check. -->
              <VCol cols="12" md="6">
                <VTextField
                  v-model="form.label"
                  label="Template name"
                  placeholder="welcome_message"
                  prepend-inner-icon="bx-purchase-tag"
                  variant="outlined"
                  density="comfortable"
                  persistent-hint
                  :rules="labelRules"
                  :hint="nameHint"
                  :loading="nameCheck.checking"
                  :error="nameCheck.available === false"
                  :base-color="nameCheck.available === true ? 'success' : undefined"
                  :color="nameCheck.available === true ? 'success' : undefined"
                >
                  <template v-if="!nameCheck.checking && nameCheck.available !== null" #append-inner>
                    <VIcon
                      :icon="nameCheck.available ? 'bx-check-circle' : 'bx-error-circle'"
                      :color="nameCheck.available ? 'success' : 'error'"
                    />
                  </template>
                </VTextField>
              </VCol>
              <VCol v-if="isSuperAdmin" cols="12" md="6">
                <VAutocomplete
                  v-model="form.language"
                  :items="languages"
                  item-title="title"
                  item-value="value"
                  label="Choose language"
                  prepend-inner-icon="bx-globe"
                  variant="outlined"
                  density="comfortable"
                  :rules="languageRules"
                  auto-select-first
                />
              </VCol>

              <VCol cols="12" md="6">
                <VTextField
                  v-model="form.header_text"
                  label="Header (optional)"
                  placeholder="Add a title or greeting"
                  prepend-inner-icon="bx-heading"
                  counter="60"
                  maxlength="60"
                  variant="outlined"
                  density="comfortable"
                  :rules="headerRules"
                />
              </VCol>
              <VCol cols="12" md="6">
                <VTextField
                  v-model="form.footer_text"
                  label="Footer (optional)"
                  placeholder="Add a short footer text"
                  prepend-inner-icon="bx-dock-bottom"
                  counter="60"
                  maxlength="60"
                  variant="outlined"
                  density="comfortable"
                  :rules="footerRules"
                />
              </VCol>

              <VCol cols="12" class="pb-1 mt-2">
                <div class="section-label">
                  <VIcon icon="bx-message-square-detail" size="16" class="me-1" />Message content
                </div>
              </VCol>
              <VCol cols="12">
                <div class="d-flex align-center justify-space-between flex-wrap gap-2 mb-2">
                  <span class="text-subtitle-2 font-weight-bold">Body</span>
                  <VSelect
                    v-model="variablePick"
                    :items="VARIABLES"
                    item-title="label"
                    item-value="token"
                    placeholder="Insert variable"
                    prepend-inner-icon="bx-code-curly"
                    variant="outlined"
                    density="compact"
                    hide-details
                    style="max-width: 220px"
                    @update:model-value="onPickVariable"
                  />
                </div>
                <VTextarea
                  ref="bodyRef"
                  v-model="form.body_text"
                  placeholder="Hi {{parent_first_name}}, welcome to Young Engineers!"
                  rows="6"
                  counter="1024"
                  maxlength="1024"
                  hint="Insert variables from the dropdown (e.g. {{parent_first_name}}). Sample values are filled automatically."
                  persistent-hint
                  variant="outlined"
                  density="comfortable"
                  :rules="bodyRules"
                />

                <div v-if="usedVariables.length" class="d-flex flex-wrap align-center gap-2 mt-2">
                  <span class="text-caption text-medium-emphasis">Variables:</span>
                  <VChip v-for="v in usedVariables" :key="v.token" size="small" color="primary" variant="tonal">
                    {{ v.label }}
                  </VChip>
                </div>
              </VCol>
            </VRow>
          </VForm>
        </VCard>
      </div>

      <div class="side-content">
        <div class="sticky-wrapper">
          <div class="sidebar-card">
            <h3 class="sidebar-title">
              {{ isSuperAdmin ? (isEditing ? "Edit template" : "New template") : selectedLabel }}
            </h3>
            <p class="sidebar-text">
              <template v-if="isSuperAdmin">Submitted to Meta for approval.</template>
              <template v-else-if="!langTabs.length">No campaign languages to translate into yet.</template>
              <template v-else-if="!activeEditable">
                This {{ selectedLabel }} template is {{ activeRow?.status }} on Meta — delete it to recreate.
              </template>
              <template v-else>Submitted to Meta as a separate {{ selectedLabel }} template.</template>
            </p>

            <VBtn
              block
              color="primary"
              variant="flat"
              class="sidebar-btn sidebar-btn-main mb-3"
              :loading="submitting"
              :disabled="!canSave"
              @click="submit"
            >
              {{ saveLabel }}
            </VBtn>
            <VBtn block variant="outlined" color="secondary" class="sidebar-btn" :disabled="submitting" @click="goBack">
              Cancel
            </VBtn>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.template-editor-page {
  max-width: 1200px;
  margin: 0 auto;
}

.form-card {
  border-radius: 16px;
  background: rgb(var(--v-theme-surface));
  box-shadow: 0 6px 28px rgba(0, 0, 0, 0.05);
}

/* Small section captions that group the form fields. */
.section-label {
  display: inline-flex;
  align-items: center;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgb(var(--v-theme-primary));
}

/* Two-column layout with a sticky action sidecard (matches the message/program editors). */
.content-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 24px;
  align-items: start;
}
.main-content {
  display: flex;
  flex-direction: column;
}
.side-content {
  height: 100%;
}
.sticky-wrapper {
  position: sticky;
  top: 24px;
}
.sidebar-card {
  background: rgb(var(--v-theme-surface));
  border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.sidebar-title {
  font-size: 16px;
  font-weight: 700;
  color: rgb(var(--v-theme-on-surface));
  margin: 0 0 6px 0;
}
.sidebar-text {
  font-size: 13px;
  color: rgb(var(--v-theme-on-surface), 0.7);
  margin: 0 0 16px 0;
}
.sidebar-btn {
  height: 38px !important;
  border-radius: 10px !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  text-transform: none !important;
}
.sidebar-btn-main {
  font-weight: 700 !important;
  background: var(--ye-brand, #003b6f) !important;
  border-color: var(--ye-brand, #003b6f) !important;
  color: var(--ye-brand-on, #fff) !important;
}

@media (max-width: 960px) {
  .content-grid {
    grid-template-columns: 1fr;
  }
  .sticky-wrapper {
    position: static;
  }
  .side-content {
    order: -1;
  }
}
</style>
