---
import {
  resolvePublicApiBaseUrl,
  resolvePublicCommentTurnstileSiteKey,
  resolvePublicWebPushVapidPublicKey,
} from '../lib/api/client';
import type { SiteSettings } from '../lib/types';

interface Props {
  requestUrl?: string | URL;
  siteSettings: SiteSettings;
}

const { requestUrl, siteSettings } = Astro.props as Props;
const subscribeApiUrl = `${resolvePublicApiBaseUrl(requestUrl)}/subscriptions`;
const combinedSubscribeApiUrl = `${resolvePublicApiBaseUrl(requestUrl)}/subscriptions/combined`;
const browserPushApiUrl = `${resolvePublicApiBaseUrl(requestUrl)}/subscriptions/browser-push`;
const captchaApiUrl = `${resolvePublicApiBaseUrl(requestUrl)}/comments/captcha`;
const popupSettings = siteSettings.subscriptions;
const verificationMode = popupSettings.verificationMode;
const turnstileSiteKey = verificationMode === 'turnstile'
  ? popupSettings.turnstileSiteKey || resolvePublicCommentTurnstileSiteKey()
  : '';
const webPushPublicKey = popupSettings.webPushVapidPublicKey || resolvePublicWebPushVapidPublicKey() || '';
const webPushAvailable = Boolean(webPushPublicKey);
---

{popupSettings.popupEnabled && (
  <div
    class="subscription-popup-root"
    data-subscription-popup-root
    data-api-url={subscribeApiUrl}
    data-combined-api-url={combinedSubscribeApiUrl}
    data-browser-push-api-url={browserPushApiUrl}
    data-captcha-url={captchaApiUrl}
    data-delay-ms={String(Math.max(popupSettings.popupDelaySeconds, 3) * 1000)}
    data-verification-mode={verificationMode}
    data-turnstile-site-key={turnstileSiteKey || undefined}
    data-web-push-public-key={webPushPublicKey || undefined}
    hidden
  >
    <section
      class="subscription-popup-panel terminal-panel"
      data-subscription-popup-panel
      role="dialog"
      aria-labelledby="subscription-popup-title"
      aria-describedby="subscription-popup-description"
    >
      <button
        type="button"
        class="subscription-popup-close"
        data-subscription-popup-close
        aria-label="关闭订阅提示"
      >
        <i class="fas fa-xmark"></i>
      </button>

      <div class="subscription-popup-main">
        <div class="subscription-popup-copy">
          <div class="subscription-popup-copy-surface">
            <div class="subscription-popup-copy-head">
              <div class="subscription-popup-copy-mark">
                <span class="subscription-popup-icon" aria-hidden="true">
                  <i class="fas fa-paper-plane"></i>
                </span>
                <div class="subscription-popup-copy-body">
                  <p class="terminal-kicker">reader updates</p>
                  <h3 id="subscription-popup-title">{popupSettings.popupTitle}</h3>
                  <p id="subscription-popup-description">{popupSettings.popupDescription}</p>
                </div>
              </div>

              <div class="subscription-popup-badges" aria-hidden="true">
                {webPushAvailable && <span class="subscription-popup-badge">即时提醒</span>}
                <span class="subscription-popup-badge">新文章</span>
                <span class="subscription-popup-badge">低频提醒</span>
              </div>
            </div>

            <ul class="subscription-popup-points" aria-hidden="true">
              <li>
                <span class="subscription-popup-point-icon"><i class="fas fa-check"></i></span>
                <span>只在有新内容或值得提醒的时候通知你，不做高频打扰</span>
              </li>
              <li>
                <span class="subscription-popup-point-icon"><i class="fas fa-check"></i></span>
                <span>支持即时提醒和邮件备份两种方式</span>
              </li>
              <li>
                <span class="subscription-popup-point-icon"><i class="fas fa-check"></i></span>
                <span>可随时暂停、管理或退订</span>
              </li>
            </ul>

            <div class="subscription-popup-preview" aria-hidden="true">
              <div class="subscription-popup-preview-window">
                <div class="subscription-popup-preview-topbar">
                  <span class="subscription-popup-preview-dot"></span>
                  <span class="subscription-popup-preview-dot"></span>
                  <span class="subscription-popup-preview-dot"></span>
                </div>
                <div class="subscription-popup-preview-card">
                  <span class="subscription-popup-preview-kicker">instant update</span>
                  <strong>有新内容时第一时间提醒你</strong>
                  <p>新的文章、专题整理或精选内容发布后，你会更快收到通知。</p>
                  <div class="subscription-popup-preview-tags">
                    <span>文章更新</span>
                    <span>汇总简报</span>
                    <span>可退订</span>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div class="subscription-popup-meta">
            {webPushAvailable && (
              <span class="terminal-stat-pill">
                <i class="fas fa-bell text-[var(--primary)]"></i>
                开启后生效
              </span>
            )}
            <span class="terminal-stat-pill">
              <i class="fas fa-newspaper text-[var(--primary)]"></i>
              新文章 / 汇总简报
            </span>
            <span class="terminal-stat-pill">
              <i class="fas fa-envelope-open-text text-[var(--primary)]"></i>
              邮箱确认后生效
            </span>
            <span class="terminal-stat-pill">
              <i class="fas fa-user-shield text-[var(--primary)]"></i>
              随时可退订
            </span>
          </div>
        </div>

        <div class="subscription-popup-side">
          <form class="subscription-popup-form subscription-popup-channel-card" data-subscription-popup-form>
            <div class="subscription-popup-side-intro">
              <div class="subscription-popup-side-intro-copy">
                <p class="subscription-popup-channel-kicker">optional email</p>
                <h4>浏览器提醒会默认开启</h4>
                <p>如果你还想额外留一个邮箱备份，可以再补开邮件订阅。</p>
              </div>

              <div class="subscription-popup-channel-selector">
                <button
                  type="button"
                  class="subscription-popup-channel-toggle subscription-popup-channel-toggle--email"
                  data-subscription-popup-channel-toggle="email"
                  aria-pressed="false"
                >
                  <span class="subscription-popup-channel-toggle-icon" aria-hidden="true">
                    <i class="fas fa-envelope-open-text"></i>
                  </span>
                  <span class="subscription-popup-channel-toggle-copy">
                    <span class="subscription-popup-channel-toggle-title" data-subscription-popup-channel-toggle-label>
                      开启邮件订阅
                    </span>
                    <span class="subscription-popup-channel-toggle-description">
                      需要时再补一个邮箱备份
                    </span>
                  </span>
                </button>
              </div>
            </div>

            <p class="subscription-popup-channel-helper">
              浏览器提醒依然是必选主流程；邮件只作为额外备份。
            </p>

            {webPushAvailable ? (
              <div
                class="subscription-popup-channel-card terminal-panel-muted"
                data-subscription-popup-channel-card="browser"
              >
                <div class="subscription-popup-channel-head">
                  <span class="subscription-popup-channel-icon" aria-hidden="true">
                    <i class="fas fa-bell"></i>
                  </span>
                  <div>
                    <p class="subscription-popup-channel-kicker">instant updates</p>
                    <h4>开启即时提醒</h4>
                  </div>
                </div>
                <p class="subscription-popup-channel-copy">
                  开启后，有新内容时你会更快收到提醒。
                </p>
                <p class="subscription-popup-channel-note" data-subscription-popup-browser-note>
                  默认优先推荐这个方式；只选它时点确定即可，不需要填写额外信息。
                </p>
              </div>
            ) : (
              <div class="subscription-popup-channel-card terminal-panel-muted">
                <div class="subscription-popup-channel-head">
                  <span class="subscription-popup-channel-icon" aria-hidden="true">
                    <i class="fas fa-bell-slash"></i>
                  </span>
                  <div>
                    <p class="subscription-popup-channel-kicker">instant updates</p>
                    <h4>即时提醒暂不可用</h4>
                  </div>
                </div>
                <p class="subscription-popup-channel-copy">
                  当前暂时还不能开启即时提醒，请稍后再试。
                </p>
                <p class="subscription-popup-channel-note" data-subscription-popup-browser-note>
                  订阅时即时提醒是主方式，这里不会再退回成邮件主流程。
                </p>
              </div>
            )}

            <div class="subscription-popup-channel-card" data-subscription-popup-channel-card="email" hidden>
              <div class="subscription-popup-channel-head">
                <span class="subscription-popup-channel-icon subscription-popup-channel-icon--mail" aria-hidden="true">
                  <i class="fas fa-envelope-open-text"></i>
                </span>
                <div>
                  <p class="subscription-popup-channel-kicker">backup mail</p>
                  <h4>邮箱备份</h4>
                </div>
              </div>

              <p class="subscription-popup-channel-copy">
                勾选后作为备用通知渠道；万一错过提醒，邮箱里也会留一份。
              </p>

              <label class="subscription-popup-field">
                <span class="subscription-popup-field-label">称呼</span>
                <input
                  type="text"
                  name="displayName"
                  placeholder="怎么称呼你（可选）"
                  autocomplete="name"
                />
              </label>

              <label class="subscription-popup-field">
                <span class="subscription-popup-field-label">邮箱地址</span>
                <input
                  type="email"
                  name="email"
                  placeholder="name@example.com"
                  autocomplete="email"
                  data-subscription-popup-email
                />
              </label>
            </div>

            {verificationMode !== 'off' && (
              <div class="subscription-popup-human-check" data-subscription-popup-human-check hidden>
                <div class="flex items-center justify-between gap-3">
                  <p class="text-xs font-semibold uppercase tracking-[0.18em] text-[var(--text-tertiary)]">
                    人机验证
                  </p>
                  {verificationMode === 'turnstile' ? (
                    <span class="text-xs text-[var(--text-tertiary)]">安全校验</span>
                  ) : (
                    <button
                      type="button"
                      class="terminal-action-button px-3 py-2 text-xs"
                      data-subscription-popup-refresh-captcha
                    >
                      <i class="fas fa-rotate-right"></i>
                      <span>刷新</span>
                    </button>
                  )}
                </div>
                {verificationMode === 'turnstile' ? (
                  <>
                    <div class="mt-3" data-subscription-popup-turnstile></div>
                    <input type="hidden" name="turnstileToken" />
                  </>
                ) : (
                  <>
                    <p
                      class="mt-3 text-sm text-[var(--text-secondary)]"
                      data-subscription-popup-captcha-question
                    >
                      加载中...
                    </p>
                    <input type="hidden" name="captchaToken" />
                    <input
                      type="text"
                      name="captchaAnswer"
                      inputmode="numeric"
                      placeholder="请输入上方答案"
                      class="mt-3 terminal-form-input"
                    />
                  </>
                )}
              </div>
            )}

            <div class="subscription-popup-actions">
              <button
                type="submit"
                class="subscription-popup-channel-toggle subscription-popup-channel-toggle--primary subscription-popup-primary-button"
                data-subscription-popup-submit
              >
                <span class="subscription-popup-channel-toggle-icon" aria-hidden="true">
                  <i class="fas fa-bell"></i>
                </span>
                <span class="subscription-popup-channel-toggle-copy">
                  <span class="subscription-popup-channel-toggle-title" data-subscription-popup-submit-label>
                    开启即时提醒
                  </span>
                  <span class="subscription-popup-channel-toggle-description">
                    默认点一下就能完成浏览器订阅
                  </span>
                </span>
              </button>
              <button
                type="button"
                class="subscription-popup-channel-toggle subscription-popup-channel-toggle--ghost"
                data-subscription-popup-dismiss
              >
                <span class="subscription-popup-channel-toggle-icon" aria-hidden="true">
                  <i class="fas fa-clock"></i>
                </span>
                <span class="subscription-popup-channel-toggle-copy">
                  <span class="subscription-popup-channel-toggle-title">稍后提醒</span>
                  <span class="subscription-popup-channel-toggle-description">
                    先继续浏览，之后再决定
                  </span>
                </span>
              </button>
            </div>
          </form>
        </div>
      </div>

      <p class="subscription-popup-status" data-subscription-popup-status aria-live="polite">
        只在有新文章或汇总简报时发送提醒，不会把它做成高频打扰。
      </p>
    </section>
  </div>
)}

<script>
  import { mountTurnstile, type MountedTurnstile } from '../lib/utils/turnstile';
  import {
    ensureBrowserPushSubscription,
    getBrowserPushSubscription,
    supportsBrowserPush,
  } from '../lib/utils/web-push';

  (() => {
    const DISMISS_KEY = 'termi:subscription-popup:dismiss-until';
    const SUBSCRIBED_KEY = 'termi:subscription-popup:subscribed-at';
    const DISMISS_TTL_MS = 7 * 24 * 60 * 60 * 1000;

    document.querySelectorAll('[data-subscription-popup-root]').forEach((root) => {
      if (!(root instanceof HTMLElement)) {
        return;
      }

      const form = root.querySelector('[data-subscription-popup-form]');
      const status = root.querySelector('[data-subscription-popup-status]');
      const emailInput = root.querySelector('[data-subscription-popup-email]');
      const dismissButton = root.querySelector('[data-subscription-popup-dismiss]');
      const apiUrl = root.getAttribute('data-api-url');
      const combinedApiUrl = root.getAttribute('data-combined-api-url') || apiUrl;
      const captchaApiUrl = root.getAttribute('data-captcha-url') || '/api/comments/captcha';
      const browserPushPublicKey = root.getAttribute('data-web-push-public-key') || '';
      const submitButton = root.querySelector(
        '[data-subscription-popup-submit]',
      ) as HTMLButtonElement | null;
      const submitButtonLabel = submitButton?.querySelector(
        '[data-subscription-popup-submit-label]',
      ) as HTMLElement | null;
      const emailToggleButton = root.querySelector(
        '[data-subscription-popup-channel-toggle="email"]',
      ) as HTMLButtonElement | null;
      const emailToggleLabel = emailToggleButton?.querySelector(
        '[data-subscription-popup-channel-toggle-label]',
      ) as HTMLElement | null;
      const browserCard = root.querySelector(
        '[data-subscription-popup-channel-card="browser"]',
      ) as HTMLElement | null;
      const emailCard = root.querySelector(
        '[data-subscription-popup-channel-card="email"]',
      ) as HTMLElement | null;
      const browserNote = root.querySelector(
        '[data-subscription-popup-browser-note]',
      ) as HTMLElement | null;
      const humanCheckCard = root.querySelector(
        '[data-subscription-popup-human-check]',
      ) as HTMLElement | null;
      const verificationMode = root.getAttribute('data-verification-mode') || 'off';
      const useTurnstile = verificationMode === 'turnstile';
      const useCaptcha = verificationMode === 'captcha';
      const turnstileSiteKey = root.getAttribute('data-turnstile-site-key') || '';
      const turnstileContainer = root.querySelector(
        '[data-subscription-popup-turnstile]',
      ) as HTMLElement | null;
      const turnstileTokenInput = form?.querySelector(
        'input[name="turnstileToken"]',
      ) as HTMLInputElement | null;
      const captchaQuestion = root.querySelector(
        '[data-subscription-popup-captcha-question]',
      ) as HTMLElement | null;
      const refreshCaptchaButton = root.querySelector(
        '[data-subscription-popup-refresh-captcha]',
      ) as HTMLButtonElement | null;
      const captchaTokenInput = form?.querySelector(
        'input[name="captchaToken"]',
      ) as HTMLInputElement | null;
      const captchaAnswerInput = form?.querySelector(
        'input[name="captchaAnswer"]',
      ) as HTMLInputElement | null;
      const pathname = window.location.pathname || '/';
      const delayMs = Math.max(3000, Number(root.getAttribute('data-delay-ms') || '18000'));
      const defaultStatus = status instanceof HTMLElement ? status.textContent?.trim() || '' : '';
      const isAutomatedBrowser = window.navigator.webdriver === true;

      if (
        !(form instanceof HTMLFormElement) ||
        !(status instanceof HTMLElement) ||
        !(emailInput instanceof HTMLInputElement) ||
        !(dismissButton instanceof HTMLButtonElement) ||
        !combinedApiUrl ||
        pathname.startsWith('/subscriptions/')
      ) {
        return;
      }

      let opened = false;
      let autoReady = false;
      let engaged = false;
      let autoOpened = false;
      let hideTimer = 0;
      let successTimer = 0;
      let turnstileWidget: MountedTurnstile | null = null;
      const browserRequired = browserCard instanceof HTMLElement;
      let emailSelected = false;
      let browserSubscribed = false;
      let browserSelectable = browserRequired;
      const header = document.querySelector('header');

      const shouldFocusEmail = () =>
        window.matchMedia('(hover: hover) and (pointer: fine)').matches;

      const syncPopupOffset = () => {
        const headerBottom =
          header instanceof HTMLElement ? Math.round(header.getBoundingClientRect().bottom) : 0;
        const offset = Math.max(14, headerBottom + 14);
        root.style.setProperty('--subscription-popup-offset', `${offset}px`);
      };

      const hasDismissed = () => {
        try {
          return Number(window.localStorage.getItem(DISMISS_KEY) || '0') > Date.now();
        } catch {
          return false;
        }
      };

      const hasSubmitted = () => {
        try {
          return Boolean(window.localStorage.getItem(SUBSCRIBED_KEY));
        } catch {
          return false;
        }
      };

      const rememberDismiss = () => {
        try {
          window.localStorage.setItem(DISMISS_KEY, String(Date.now() + DISMISS_TTL_MS));
        } catch {
          // Ignore storage failures.
        }
      };

      const rememberSubmitted = () => {
        try {
          window.localStorage.setItem(SUBSCRIBED_KEY, new Date().toISOString());
        } catch {
          // Ignore storage failures.
        }
      };

      const resetStatus = () => {
        delete status.dataset.state;
        status.textContent = defaultStatus;
      };

      const setPending = (message: string) => {
        status.dataset.state = 'pending';
        status.textContent = message;
      };

      const setError = (message: string) => {
        status.dataset.state = 'error';
        status.textContent = message;
      };

      const setSuccess = (message: string) => {
        status.dataset.state = 'success';
        status.textContent = message;
      };

      const setSubmitButtonState = (label: string, disabled = false) => {
        if (!(submitButton instanceof HTMLButtonElement)) {
          return;
        }

        if (submitButtonLabel instanceof HTMLElement) {
          submitButtonLabel.textContent = label;
        } else {
          submitButton.textContent = label;
        }

        submitButton.disabled = disabled;
      };

      const setToggleState = (
        button: HTMLButtonElement | null,
        active: boolean,
        disabled = false,
      ) => {
        if (!(button instanceof HTMLButtonElement)) {
          return;
        }

        button.setAttribute('aria-pressed', String(active));
        button.disabled = disabled;
        button.classList.toggle('is-active', active);
        button.classList.toggle('is-disabled', disabled);
      };

      const getPrimaryActionLabel = () => {
        if (!browserRequired) {
          return '提醒功能暂不可用';
        }

        if (emailSelected) {
          return '开启提醒 + 邮箱备份';
        }

        return browserSubscribed ? '更新提醒设置' : '开启即时提醒';
      };

      const clearHumanCheckFields = () => {
        if (turnstileTokenInput) {
          turnstileTokenInput.value = '';
        }

        if (captchaTokenInput) {
          captchaTokenInput.value = '';
        }

        if (captchaAnswerInput) {
          captchaAnswerInput.value = '';
        }
      };

      const syncChannelSelection = ({ focusEmail = false } = {}) => {
        if (browserCard instanceof HTMLElement) {
          browserCard.hidden = false;
        }

        if (emailCard instanceof HTMLElement) {
          emailCard.hidden = !emailSelected;
        }

        if (humanCheckCard instanceof HTMLElement) {
          humanCheckCard.hidden = !emailSelected || verificationMode === 'off';
        }

        emailInput.required = emailSelected;

        if (emailToggleLabel instanceof HTMLElement) {
          emailToggleLabel.textContent = emailSelected ? '收起邮件订阅' : '开启邮件订阅';
        }

        setToggleState(emailToggleButton, emailSelected, !browserRequired);
        setSubmitButtonState(getPrimaryActionLabel(), !browserRequired || !browserSelectable);

        if (emailSelected && opened) {
          if (useTurnstile) {
            void ensureTurnstile(false);
          } else if (useCaptcha) {
            void loadCaptcha(false);
          }
        } else if (!emailSelected) {
          clearHumanCheckFields();
        }

        if (focusEmail && emailSelected && shouldFocusEmail()) {
          emailInput.focus({ preventScroll: true });
        }
      };

      const setBrowserAvailability = ({
        selectable,
        note,
        subscribed = false,
      }: {
        selectable: boolean;
        note: string;
        subscribed?: boolean;
      }) => {
        browserSelectable = selectable;
        browserSubscribed = subscribed;

        if (browserNote instanceof HTMLElement) {
          browserNote.textContent = note;
        }

        syncChannelSelection();
      };

      const openPopup = ({ focusEmail = false, force = false } = {}) => {
        if (opened || (!force && hasSubmitted())) {
          return;
        }

        syncPopupOffset();
        window.clearTimeout(hideTimer);
        if (status.dataset.state !== 'pending') {
          resetStatus();
        }

        opened = true;
        root.hidden = false;

        window.requestAnimationFrame(() => {
          root.classList.add('is-visible');
          syncChannelSelection({ focusEmail });
        });
      };

      const closePopup = (remember = true) => {
        if (!opened) {
          return;
        }

        opened = false;
        window.clearTimeout(successTimer);
        root.classList.remove('is-visible');

        if (remember) {
          rememberDismiss();
        }

        hideTimer = window.setTimeout(() => {
          if (!opened) {
            root.hidden = true;
          }
        }, 260);
      };

      const maybeAutoOpen = () => {
        if (autoOpened || !autoReady || !engaged || hasDismissed() || hasSubmitted()) {
          return;
        }

        autoOpened = true;
        openPopup();
      };

      const markEngaged = () => {
        engaged = true;
        maybeAutoOpen();
      };

      const handleScroll = () => {
        const doc = document.documentElement;
        const maxScroll = Math.max(doc.scrollHeight - window.innerHeight, 1);
        const progress = (window.scrollY / maxScroll) * 100;

        if (progress >= 35) {
          markEngaged();
          window.removeEventListener('scroll', handleScroll);
        }
      };

      const ensureTurnstile = async (showError = true) => {
        if (!turnstileSiteKey || !turnstileContainer || !turnstileTokenInput) {
          return;
        }

        turnstileTokenInput.value = '';

        if (turnstileWidget) {
          turnstileWidget.reset();
          return;
        }

        try {
          turnstileWidget = await mountTurnstile(turnstileContainer, {
            siteKey: turnstileSiteKey,
            onToken(token) {
              turnstileTokenInput.value = token;
            },
            onExpire() {
              turnstileTokenInput.value = '';
            },
            onError() {
              turnstileTokenInput.value = '';
              if (showError) {
                setError('加载人机验证失败，请刷新页面后重试。');
              }
            },
          });
        } catch (error) {
          if (showError) {
            setError(error instanceof Error ? error.message : '加载人机验证失败，请刷新页面后重试。');
          }
        }
      };

      const loadCaptcha = async (showError = true) => {
        if (!captchaQuestion || !captchaTokenInput || !captchaAnswerInput) {
          return;
        }

        captchaQuestion.textContent = '加载中...';
        captchaTokenInput.value = '';
        captchaAnswerInput.value = '';

        try {
          const response = await fetch(captchaApiUrl);
          if (!response.ok) {
            throw new Error(await response.text());
          }

          const payload = (await response.json()) as { token?: string; question?: string };
          captchaTokenInput.value = payload.token || '';
          captchaQuestion.textContent = payload.question || '请刷新验证码';
        } catch (error) {
          captchaQuestion.textContent = '验证码加载失败，请刷新重试';
          if (showError) {
            setError(error instanceof Error ? error.message : '验证码加载失败，请刷新后重试。');
          }
        }
      };

      const resetHumanCheck = () => {
        if (!emailSelected) {
          clearHumanCheckFields();
          return;
        }

        if (useTurnstile && turnstileTokenInput) {
          turnstileTokenInput.value = '';
          turnstileWidget?.reset();
          return;
        }

        if (useCaptcha) {
          void loadCaptcha(false);
        }
      };

      const syncBrowserPushState = async () => {
        if (!browserRequired) {
          return;
        }

        if (!browserPushPublicKey) {
          setBrowserAvailability({
            selectable: false,
            note: '当前提醒功能还没有准备好，因此现在无法开始订阅。',
          });
          return;
        }

        if (!supportsBrowserPush()) {
          setBrowserAvailability({
            selectable: false,
            note: '当前设备暂时无法开启即时提醒，因此现在不能开始订阅。',
          });
          return;
        }

        try {
          const subscription = await getBrowserPushSubscription();
          if (subscription) {
            rememberSubmitted();
            setBrowserAvailability({
              selectable: true,
              subscribed: true,
              note: '你已经开启了提醒；如果愿意，也可以再补一个邮箱备份。',
            });
            if (!opened) {
              root.hidden = true;
            }
          } else if (Notification.permission === 'denied') {
            setBrowserAvailability({
              selectable: true,
              note: '提醒功能当前没有开启；请先允许提醒后再试一次。',
            });
          } else {
            setBrowserAvailability({
              selectable: true,
              note: '推荐默认使用这个方式；开启后新内容会更快提醒你。',
            });
          }
        } catch {
          setBrowserAvailability({
            selectable: true,
            note: '当前无法确认提醒状态，你仍然可以继续尝试开启。',
          });
        }
      };

      syncPopupOffset();
      syncChannelSelection();
      void syncBrowserPushState();
      root.dataset.subscriptionPopupReady = 'true';
      window.__termiSubscriptionPopupReady = true;

      if (header instanceof HTMLElement && typeof ResizeObserver !== 'undefined') {
        const observer = new ResizeObserver(() => syncPopupOffset());
        observer.observe(header);
      }

      window.addEventListener('resize', syncPopupOffset, { passive: true });

      if (!isAutomatedBrowser) {
        window.addEventListener('scroll', handleScroll, { passive: true });
        window.addEventListener('pointerdown', markEngaged, { once: true, passive: true });
        window.addEventListener('keydown', markEngaged, { once: true });
        window.setTimeout(() => {
          autoReady = true;
          maybeAutoOpen();
        }, delayMs);
      }

      document.addEventListener('click', (event) => {
        const trigger =
          event.target instanceof Element
            ? event.target.closest('[data-subscription-popup-open]')
            : null;

        if (!trigger) {
          return;
        }

        event.preventDefault();
        openPopup({ force: true });
      });

      root.querySelectorAll('[data-subscription-popup-close]').forEach((button) => {
        button.addEventListener('click', () => closePopup(true));
      });

      dismissButton.addEventListener('click', () => closePopup(true));
      refreshCaptchaButton?.addEventListener('click', () => {
        void loadCaptcha(false);
      });

      window.addEventListener('keydown', (event) => {
        if (event.key === 'Escape' && opened) {
          closePopup(true);
        }
      });

      emailToggleButton?.addEventListener('click', () => {
        if (!browserRequired) {
          return;
        }

        if (emailSelected) {
          emailSelected = false;
          syncChannelSelection();
          return;
        }

        emailSelected = true;
        syncChannelSelection({ focusEmail: true });
      });

      form.addEventListener('submit', async (event) => {
        event.preventDefault();

        const formData = new FormData(form);
        const email = String(formData.get('email') || '').trim();
        const displayName = String(formData.get('displayName') || '').trim();
        const wantsBrowser = browserRequired;
        const wantsEmail = emailSelected;

        if (!browserRequired) {
          setError('当前暂时还不能开启即时提醒，请稍后再试。');
          return;
        }

        if (!browserSelectable) {
          setError('当前设备暂时无法开启提醒，请先允许提醒后再试。');
          return;
        }

        if (wantsEmail && !email) {
          setError('请输入邮箱地址。');
          emailInput.focus();
          return;
        }

        if (wantsEmail && useTurnstile) {
          const token = String(formData.get('turnstileToken') || '').trim();
          if (!token) {
            setError('请先完成人机验证。');
            return;
          }
        } else if (wantsEmail && useCaptcha) {
          const captchaToken = String(formData.get('captchaToken') || '').trim();
          const captchaAnswer = String(formData.get('captchaAnswer') || '').trim();
          if (!captchaToken) {
            setError('验证码加载失败，请刷新后重试。');
            return;
          }
          if (!captchaAnswer) {
            setError('请先填写验证码答案。');
            captchaAnswerInput?.focus();
            return;
          }
        }

        let browserSubscription: unknown = undefined;

        try {
          if (wantsBrowser) {
            if (!browserPushPublicKey) {
              throw new Error('当前暂时还不能开启即时提醒，请稍后再试。');
            }

            if (!supportsBrowserPush()) {
              throw new Error('当前设备暂时无法开启即时提醒。');
            }

            setPending(
              wantsEmail ? '正在开启提醒，并准备邮箱备份...' : '正在开启提醒...',
            );
            setSubmitButtonState('处理中...', true);
            browserSubscription = await ensureBrowserPushSubscription(browserPushPublicKey);
          }

          setPending(
            wantsBrowser && wantsEmail
              ? '正在同时保存提醒和邮箱备份...'
              : wantsBrowser
                ? '正在开启提醒...'
                : '正在提交邮箱订阅...',
          );
          setSubmitButtonState('处理中...', true);

          const response = await fetch(combinedApiUrl, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              channels: [
                ...(wantsBrowser ? ['browser_push'] : []),
                ...(wantsEmail ? ['email'] : []),
              ],
              email: wantsEmail ? email : undefined,
              displayName: wantsEmail ? displayName : undefined,
              subscription: wantsBrowser ? browserSubscription : undefined,
              source: 'frontend-popup',
              turnstileToken: wantsEmail ? formData.get('turnstileToken') : undefined,
              captchaToken: wantsEmail ? formData.get('captchaToken') : undefined,
              captchaAnswer: wantsEmail ? formData.get('captchaAnswer') : undefined,
            }),
          });

          const payload = await response.json().catch(() => ({}));
          if (!response.ok) {
            throw new Error(payload?.message || payload?.description || '订阅失败，请稍后再试。');
          }

          rememberSubmitted();
          browserSubscribed = Array.isArray(payload?.channels)
            ? payload.channels.some((item: { channel_type?: string }) => item?.channel_type === 'web_push')
            : browserSubscribed || wantsBrowser;
          form.reset();
          resetHumanCheck();
          syncChannelSelection();
          setSuccess(
            payload?.message ||
              (wantsBrowser && wantsEmail
                ? '提醒已开启，邮箱备份也已提交。'
                : wantsBrowser
                  ? '提醒已开启，后续有新内容时会及时通知你。'
                  : '邮箱订阅已提交，请前往邮箱确认后生效。'),
          );
          successTimer = window.setTimeout(() => closePopup(false), 2200);
        } catch (error) {
          resetHumanCheck();
          setError(error instanceof Error ? error.message : '订阅失败，请稍后重试。');
          setSubmitButtonState(getPrimaryActionLabel(), false);
        }
      });
    });
  })();
</script>

<style>
  .subscription-popup-root {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: grid;
    align-items: start;
    justify-items: center;
    padding: 0 max(1rem, env(safe-area-inset-right, 0px)) 0 max(1rem, env(safe-area-inset-left, 0px));
    pointer-events: none;
  }

  .subscription-popup-root[hidden] {
    display: none !important;
  }

  .subscription-popup-panel {
    position: relative;
    width: min(100%, 58rem);
    display: grid;
    gap: 1rem;
    margin-top: var(--subscription-popup-offset, calc(env(safe-area-inset-top, 0px) + 5.25rem));
    padding: 1.1rem;
    border-radius: 1.7rem;
    opacity: 0;
    transform: translateY(-1rem) scale(0.985);
    transition:
      opacity 0.24s ease,
      transform 0.24s ease;
    pointer-events: auto;
    overflow: hidden;
    backdrop-filter: blur(16px) saturate(135%);
    background:
      radial-gradient(circle at top left, rgba(var(--primary-rgb), 0.15), transparent 26%),
      radial-gradient(circle at bottom right, rgba(var(--secondary-rgb, var(--primary-rgb)), 0.1), transparent 28%),
      linear-gradient(
        180deg,
        color-mix(in oklab, var(--terminal-bg) 99%, white),
        color-mix(in oklab, var(--header-bg) 93%, white)
      );
    box-shadow:
      0 28px 70px rgba(var(--text-rgb), 0.14),
      inset 0 1px 0 rgba(255, 255, 255, 0.34);
  }

  .subscription-popup-panel::before {
    content: '';
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background:
      linear-gradient(
        90deg,
        color-mix(in oklab, var(--primary) 88%, white),
        color-mix(in oklab, var(--secondary) 80%, white)
      );
    opacity: 0.92;
  }

  .subscription-popup-root.is-visible .subscription-popup-panel {
    opacity: 1;
    transform: translateY(0) scale(1);
  }

  .subscription-popup-close {
    position: absolute;
    top: 0.8rem;
    right: 0.8rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.15rem;
    height: 2.15rem;
    border-radius: 999px;
    border: 1px solid color-mix(in oklab, var(--primary) 12%, var(--border-color));
    background: color-mix(in oklab, var(--terminal-bg) 94%, transparent);
    color: var(--text-tertiary);
    cursor: pointer;
    transition:
      border-color 0.2s ease,
      color 0.2s ease,
      transform 0.2s ease;
  }

  .subscription-popup-close:hover {
    color: var(--title-color);
    border-color: color-mix(in oklab, var(--primary) 24%, var(--border-color));
    transform: translateY(-1px);
  }

  .subscription-popup-copy {
    display: grid;
    gap: 0.95rem;
    min-width: 0;
  }

  .subscription-popup-main {
    display: grid;
    gap: 1rem;
  }

  .subscription-popup-copy-surface,
  .subscription-popup-channel-card {
    position: relative;
    overflow: hidden;
    border-radius: 1.35rem;
    border: 1px solid color-mix(in oklab, var(--primary) 10%, var(--border-color));
    background:
      linear-gradient(
        180deg,
        color-mix(in oklab, var(--terminal-bg) 99%, white),
        color-mix(in oklab, var(--header-bg) 94%, white)
      );
    box-shadow:
      0 12px 30px rgba(var(--text-rgb), 0.05),
      inset 0 1px 0 rgba(255, 255, 255, 0.42);
  }

  .subscription-popup-copy-surface {
    padding: 1.15rem;
  }

  .subscription-popup-side {
    display: grid;
    gap: 0.9rem;
    align-content: start;
  }

  .subscription-popup-side-intro {
    display: grid;
    gap: 0.85rem;
  }

  .subscription-popup-side-intro-copy {
    display: grid;
    gap: 0.28rem;
    min-width: 0;
  }

  .subscription-popup-side-intro-copy h4 {
    margin: 0;
    color: var(--title-color);
    font-size: 0.98rem;
    line-height: 1.45;
  }

  .subscription-popup-side-intro-copy p:last-child {
    margin: 0;
    color: var(--text-tertiary);
    font-size: 0.82rem;
    line-height: 1.65;
  }

  .subscription-popup-channel-selector {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    width: 100%;
  }

  .subscription-popup-channel-toggle {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.8rem;
    width: 100%;
    min-height: 3.35rem;
    border-radius: 1rem;
    border: 1px solid color-mix(in oklab, var(--primary) 12%, var(--border-color));
    background: color-mix(in oklab, var(--terminal-bg) 98%, white);
    color: var(--text-secondary);
    padding: 0.85rem 1rem;
    text-align: left;
    cursor: pointer;
    transition:
      border-color 0.2s ease,
      color 0.2s ease,
      background 0.2s ease,
      transform 0.2s ease,
      box-shadow 0.2s ease;
  }

  .subscription-popup-channel-toggle-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.35rem;
    height: 2.35rem;
    flex-shrink: 0;
    border-radius: 0.85rem;
    border: 1px solid color-mix(in oklab, var(--primary) 12%, var(--border-color));
    background: color-mix(in oklab, var(--primary) 10%, var(--terminal-bg));
    color: var(--primary);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.34);
  }

  .subscription-popup-channel-toggle-copy {
    display: grid;
    gap: 0.18rem;
    min-width: 0;
  }

  .subscription-popup-channel-toggle-title {
    display: block;
    color: var(--title-color);
    font-size: 0.92rem;
    font-weight: 700;
    line-height: 1.35;
  }

  .subscription-popup-channel-toggle-description {
    display: block;
    color: var(--text-tertiary);
    font-size: 0.78rem;
    line-height: 1.55;
  }

  .subscription-popup-channel-toggle:hover {
    transform: translateY(-1px);
    border-color: color-mix(in oklab, var(--primary) 22%, var(--border-color));
    color: var(--title-color);
    box-shadow: 0 14px 28px rgba(var(--text-rgb), 0.08);
  }

  .subscription-popup-channel-toggle.is-active {
    border-color: color-mix(in oklab, var(--primary) 28%, var(--border-color));
    background:
      linear-gradient(
        180deg,
        color-mix(in oklab, var(--primary) 10%, var(--terminal-bg)),
        color-mix(in oklab, var(--primary) 5%, var(--header-bg))
      );
    color: color-mix(in oklab, var(--primary) 76%, var(--title-color));
    box-shadow:
      inset 0 0 0 1px rgba(var(--primary-rgb), 0.08),
      0 10px 22px rgba(var(--primary-rgb), 0.08);
  }

  .subscription-popup-channel-toggle.is-active .subscription-popup-channel-toggle-icon {
    background: color-mix(in oklab, var(--primary) 16%, var(--terminal-bg));
  }

  .subscription-popup-channel-toggle--primary {
    border-color: color-mix(in oklab, var(--primary) 52%, white);
    background:
      linear-gradient(
        180deg,
        color-mix(in oklab, var(--primary) 88%, white),
        color-mix(in oklab, var(--primary) 72%, var(--header-bg))
      );
    color: white;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.24),
      0 18px 38px rgba(var(--primary-rgb), 0.24);
  }

  .subscription-popup-channel-toggle--primary .subscription-popup-channel-toggle-icon {
    border-color: rgba(255, 255, 255, 0.22);
    background: rgba(255, 255, 255, 0.14);
    color: white;
  }

  .subscription-popup-channel-toggle--primary .subscription-popup-channel-toggle-title {
    color: white;
  }

  .subscription-popup-channel-toggle--primary .subscription-popup-channel-toggle-description {
    color: rgba(255, 255, 255, 0.82);
  }

  .subscription-popup-channel-toggle--primary:hover {
    border-color: color-mix(in oklab, var(--primary) 68%, white);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.28),
      0 20px 42px rgba(var(--primary-rgb), 0.28);
  }

  .subscription-popup-channel-toggle--email,
  .subscription-popup-channel-toggle--email.is-active {
    border-color: color-mix(
      in oklab,
      var(--secondary, var(--primary)) 42%,
      var(--border-color)
    );
    background:
      linear-gradient(
        180deg,
        color-mix(in oklab, var(--secondary, var(--primary)) 26%, white),
        color-mix(in oklab, var(--secondary, var(--primary)) 14%, var(--header-bg))
      );
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.3),
      0 16px 34px rgba(var(--primary-rgb), 0.14);
  }

  .subscription-popup-channel-toggle--email .subscription-popup-channel-toggle-icon,
  .subscription-popup-channel-toggle--email.is-active .subscription-popup-channel-toggle-icon {
    border-color: color-mix(
      in oklab,
      var(--secondary, var(--primary)) 26%,
      var(--border-color)
    );
    background: color-mix(
      in oklab,
      var(--secondary, var(--primary)) 18%,
      var(--terminal-bg)
    );
    color: color-mix(
      in oklab,
      var(--secondary, var(--primary)) 70%,
      var(--title-color)
    );
  }

  .subscription-popup-channel-toggle--email .subscription-popup-channel-toggle-title,
  .subscription-popup-channel-toggle--email.is-active .subscription-popup-channel-toggle-title {
    color: color-mix(
      in oklab,
      var(--secondary, var(--primary)) 62%,
      var(--title-color)
    );
  }

  .subscription-popup-channel-toggle--email .subscription-popup-channel-toggle-description,
  .subscription-popup-channel-toggle--email.is-active .subscription-popup-channel-toggle-description {
    color: color-mix(
      in oklab,
      var(--secondary, var(--primary)) 34%,
      var(--text-secondary)
    );
  }

  .subscription-popup-channel-toggle--email:hover {
    border-color: color-mix(
      in oklab,
      var(--secondary, var(--primary)) 56%,
      var(--border-color)
    );
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.34),
      0 18px 36px rgba(var(--primary-rgb), 0.16);
  }

  .subscription-popup-channel-toggle--ghost .subscription-popup-channel-toggle-icon {
    background: color-mix(in oklab, var(--header-bg) 90%, white);
    color: var(--text-secondary);
  }

  .subscription-popup-channel-toggle.is-disabled,
  .subscription-popup-channel-toggle:disabled {
    cursor: not-allowed;
    opacity: 0.55;
    transform: none;
    box-shadow: none;
  }

  .subscription-popup-channel-helper {
    margin: -0.05rem 0 0;
    color: var(--text-tertiary);
    font-size: 0.82rem;
    line-height: 1.65;
  }

  .subscription-popup-copy-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.8rem;
  }

  .subscription-popup-copy-mark {
    display: flex;
    align-items: flex-start;
    gap: 0.95rem;
    min-width: 0;
    padding-right: 0.25rem;
  }

  .subscription-popup-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    flex-shrink: 0;
    border-radius: 1.1rem;
    border: 1px solid color-mix(in oklab, var(--primary) 14%, var(--border-color));
    background:
      linear-gradient(
        180deg,
        color-mix(in oklab, var(--primary) 15%, var(--terminal-bg)),
        color-mix(in oklab, var(--primary) 7%, var(--header-bg))
      );
    color: var(--primary);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.24),
      0 14px 28px rgba(var(--primary-rgb), 0.12);
  }

  .subscription-popup-copy-body {
    min-width: 0;
  }

  .subscription-popup-copy-body .terminal-kicker {
    margin: 0 0 0.55rem;
  }

  .subscription-popup-copy h3 {
    margin: 0;
    font-size: 1.28rem;
    line-height: 1.28;
    color: var(--title-color);
  }

  .subscription-popup-copy p:last-child {
    margin: 0.5rem 0 0;
    color: var(--text-secondary);
    line-height: 1.7;
    font-size: 0.95rem;
  }

  .subscription-popup-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.65rem;
  }

  .subscription-popup-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    padding-right: 2.55rem;
  }

  .subscription-popup-badge {
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    border: 1px solid color-mix(in oklab, var(--primary) 12%, var(--border-color));
    background: color-mix(in oklab, var(--primary) 6%, var(--terminal-bg));
    color: var(--text-secondary);
    padding: 0.28rem 0.7rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
  }

  .subscription-popup-points {
    display: grid;
    gap: 0.55rem;
    margin: 1rem 0 0;
    padding: 0;
    list-style: none;
  }

  .subscription-popup-points li {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    color: var(--text-secondary);
    font-size: 0.92rem;
    line-height: 1.6;
  }

  .subscription-popup-point-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.3rem;
    height: 1.3rem;
    flex-shrink: 0;
    border-radius: 999px;
    background: color-mix(in oklab, var(--primary) 12%, var(--terminal-bg));
    color: var(--primary);
    font-size: 0.68rem;
    margin-top: 0.05rem;
  }

  .subscription-popup-preview {
    margin-top: 1.1rem;
  }

  .subscription-popup-preview-window {
    position: relative;
    overflow: hidden;
    border-radius: 1.2rem;
    border: 1px solid color-mix(in oklab, var(--primary) 12%, var(--border-color));
    background:
      linear-gradient(
        180deg,
        color-mix(in oklab, var(--header-bg) 96%, white),
        color-mix(in oklab, var(--terminal-bg) 98%, white)
      );
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.45),
      0 14px 32px rgba(var(--text-rgb), 0.05);
  }

  .subscription-popup-preview-topbar {
    display: flex;
    gap: 0.38rem;
    padding: 0.9rem 1rem 0;
  }

  .subscription-popup-preview-dot {
    width: 0.56rem;
    height: 0.56rem;
    border-radius: 999px;
    background: color-mix(in oklab, var(--primary) 18%, var(--border-color));
  }

  .subscription-popup-preview-card {
    padding: 0.95rem 1rem 1rem;
    display: grid;
    gap: 0.45rem;
  }

  .subscription-popup-preview-kicker,
  .subscription-popup-channel-kicker {
    margin: 0;
    color: var(--text-tertiary);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
  }

  .subscription-popup-preview-card strong {
    color: var(--title-color);
    font-size: 1rem;
    line-height: 1.4;
  }

  .subscription-popup-preview-card p {
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.87rem;
    line-height: 1.7;
  }

  .subscription-popup-preview-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin-top: 0.25rem;
  }

  .subscription-popup-preview-tags span {
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    padding: 0.28rem 0.6rem;
    background: color-mix(in oklab, var(--primary) 7%, var(--terminal-bg));
    color: var(--text-secondary);
    font-size: 0.72rem;
    border: 1px solid color-mix(in oklab, var(--primary) 10%, var(--border-color));
  }

  .subscription-popup-channel-card {
    display: grid;
    gap: 0.85rem;
    padding: 1rem;
  }

  .subscription-popup-channel-head {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    min-width: 0;
  }

  .subscription-popup-channel-head h4 {
    margin: 0.18rem 0 0;
    color: var(--title-color);
    font-size: 1rem;
    line-height: 1.35;
  }

  .subscription-popup-channel-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    flex-shrink: 0;
    border-radius: 0.95rem;
    border: 1px solid color-mix(in oklab, var(--primary) 14%, var(--border-color));
    background: color-mix(in oklab, var(--primary) 10%, var(--terminal-bg));
    color: var(--primary);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.34);
  }

  .subscription-popup-channel-icon--mail {
    background: color-mix(in oklab, var(--secondary, var(--primary)) 10%, var(--terminal-bg));
    color: color-mix(in oklab, var(--secondary, var(--primary)) 68%, var(--title-color));
  }

  .subscription-popup-channel-copy {
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.9rem;
    line-height: 1.65;
  }

  .subscription-popup-channel-note {
    margin: -0.1rem 0 0;
    color: var(--text-tertiary);
    font-size: 0.8rem;
    line-height: 1.65;
  }

  .subscription-popup-human-check {
    margin-top: 0.15rem;
    border-radius: 1.05rem;
    border: 1px solid color-mix(in oklab, var(--primary) 10%, var(--border-color));
    background: color-mix(in oklab, var(--header-bg) 65%, white);
    padding: 0.9rem 0.95rem;
  }

  .subscription-popup-form {
    display: grid;
    gap: 0.8rem;
  }

  .subscription-popup-form [hidden] {
    display: none !important;
  }

  .subscription-popup-field {
    display: grid;
    gap: 0.45rem;
    min-width: 0;
  }

  .subscription-popup-field-label {
    color: var(--text-tertiary);
    font-size: 0.72rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }

  .subscription-popup-form input {
    width: 100%;
    min-height: 3rem;
    border-radius: 1rem;
    border: 1px solid color-mix(in oklab, var(--primary) 12%, var(--border-color));
    background: color-mix(in oklab, var(--terminal-bg) 96%, transparent);
    color: var(--title-color);
    padding: 0.9rem 1rem;
    transition:
      border-color 0.2s ease,
      box-shadow 0.2s ease,
      background 0.2s ease;
  }

  .subscription-popup-form input::placeholder {
    color: var(--text-tertiary);
  }

  .subscription-popup-form input:focus-visible {
    outline: none;
    border-color: color-mix(in oklab, var(--primary) 28%, var(--border-color));
    background: color-mix(in oklab, var(--terminal-bg) 98%, transparent);
    box-shadow: 0 0 0 4px rgba(var(--primary-rgb), 0.08);
  }

  .subscription-popup-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.65rem;
    margin-top: 0.1rem;
    align-items: stretch;
  }

  .subscription-popup-actions .subscription-popup-channel-toggle {
    min-height: 3.4rem;
  }

  .subscription-popup-primary-button {
    box-shadow:
      0 12px 24px rgba(var(--primary-rgb), 0.16),
      inset 0 1px 0 rgba(255, 255, 255, 0.28);
  }

  .subscription-popup-status {
    margin: 0;
    padding: 0.85rem 1rem;
    border-radius: 1rem;
    border: 1px solid color-mix(in oklab, var(--primary) 10%, var(--border-color));
    background: color-mix(in oklab, var(--primary) 5%, var(--terminal-bg));
    color: var(--text-secondary);
    font-size: 0.9rem;
    line-height: 1.7;
  }

  .subscription-popup-status[data-state='pending'] {
    color: var(--primary);
    border-color: color-mix(in oklab, var(--primary) 26%, var(--border-color));
    background: color-mix(in oklab, var(--primary) 8%, var(--terminal-bg));
  }

  .subscription-popup-status[data-state='success'] {
    color: var(--success-dark);
    border-color: color-mix(in oklab, var(--success) 24%, var(--border-color));
    background: color-mix(in oklab, var(--success) 10%, var(--terminal-bg));
  }

  .subscription-popup-status[data-state='error'] {
    color: var(--danger);
    border-color: color-mix(in oklab, var(--danger) 24%, var(--border-color));
    background: color-mix(in oklab, var(--danger) 8%, var(--terminal-bg));
  }

  @media (min-width: 960px) {
    .subscription-popup-main {
      grid-template-columns: minmax(0, 1.08fr) minmax(19rem, 0.92fr);
      align-items: start;
      gap: 1rem 1.15rem;
    }

    .subscription-popup-panel {
      padding: 1.15rem;
    }

    .subscription-popup-status {
      grid-column: 1 / -1;
    }
  }

  @media (max-width: 767px) {
    .subscription-popup-root {
      padding-inline: 0.75rem;
    }

    .subscription-popup-panel {
      gap: 0.9rem;
      padding: 0.95rem 0.9rem 0.95rem;
    }

    .subscription-popup-copy-mark {
      gap: 0.75rem;
      padding-right: 0;
    }

    .subscription-popup-icon {
      width: 2.65rem;
      height: 2.65rem;
      border-radius: 0.9rem;
    }

    .subscription-popup-badges {
      padding-right: 2.15rem;
    }

    .subscription-popup-copy-surface,
    .subscription-popup-channel-card {
      border-radius: 1.2rem;
    }

    .subscription-popup-copy-surface {
      padding: 1rem;
    }

    .subscription-popup-actions {
      grid-template-columns: 1fr;
    }

    .subscription-popup-actions .subscription-popup-channel-toggle {
      width: 100%;
    }
  }
</style>
