@import url('https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;0,6..72,600;0,6..72,700;0,6..72,800;1,6..72,400;1,6..72,500&display=swap');

@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
    U+FE2E-FE2F;
}

@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-roman-cyrillic.C5lxZ8CY.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-roman-greek-ext.CqjqNYQ-.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}

@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-roman-greek.BBVDIX6e.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1,
    U+03A3-03FF;
}

@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-roman-vietnamese.BjW4sHH5.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
    U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
    U+0329, U+1EA0-1EF9, U+20AB;
}

@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-roman-latin-ext.4ZJIpNVo.woff2') format('woff2');
  unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-roman-latin.Di8DUHzh.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: Inter;
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-italic-cyrillic-ext.r48I6akx.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
    U+FE2E-FE2F;
}

@font-face {
  font-family: Inter;
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-italic-cyrillic.By2_1cv3.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: Inter;
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-italic-greek-ext.1u6EdAuj.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}

@font-face {
  font-family: Inter;
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-italic-greek.DJ8dCoTZ.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1,
    U+03A3-03FF;
}

@font-face {
  font-family: Inter;
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-italic-vietnamese.BSbpV94h.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
    U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
    U+0329, U+1EA0-1EF9, U+20AB;
}

@font-face {
  font-family: Inter;
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-italic-latin-ext.CN1xVJS-.woff2') format('woff2');
  unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: Inter;
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/inter-italic-latin.C2AdPX0b.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Punctuation SC';
  font-weight: 400;
  src: local('PingFang SC Regular'), local('Noto Sans CJK SC'),
    local('Microsoft YaHei');
  unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026,
    U+00B7, U+007E, U+002F;
}

@font-face {
  font-family: 'Punctuation SC';
  font-weight: 500;
  src: local('PingFang SC Medium'), local('Noto Sans CJK SC'),
    local('Microsoft YaHei');
  unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026,
    U+00B7, U+007E, U+002F;
}

@font-face {
  font-family: 'Punctuation SC';
  font-weight: 600;
  src: local('PingFang SC Semibold'), local('Noto Sans CJK SC Bold'),
    local('Microsoft YaHei Bold');
  unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026,
    U+00B7, U+007E, U+002F;
}

@font-face {
  font-family: 'Punctuation SC';
  font-weight: 700;
  src: local('PingFang SC Semibold'), local('Noto Sans CJK SC Bold'),
    local('Microsoft YaHei Bold');
  unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026,
    U+00B7, U+007E, U+002F;
}

/* Generate the subsetted fonts using: `pyftsubset <file>.woff2 --unicodes="<range>" --output-file="inter-<style>-<subset>.woff2" --flavor=woff2` */
/**
 * Colors: Solid
 * -------------------------------------------------------------------------- */

:root {
  --vp-c-white: #ffffff;
  --vp-c-black: #000000;

  --vp-c-neutral: var(--vp-c-black);
  --vp-c-neutral-inverse: var(--vp-c-white);
}

.dark {
  --vp-c-neutral: var(--vp-c-white);
  --vp-c-neutral-inverse: var(--vp-c-black);
}

/**
 * Colors: Palette
 *
 * The primitive colors used for accent colors. These colors are referenced
 * by functional colors such as "Text", "Background", or "Brand".
 *
 * Each colors have exact same color scale system with 3 levels of solid
 * colors with different brightness, and 1 soft color.
 *
 * - `XXX-1`: The most solid color used mainly for colored text. It must
 *   satisfy the contrast ratio against when used on top of `XXX-soft`.
 *
 * - `XXX-2`: The color used mainly for hover state of the button.
 *
 * - `XXX-3`: The color for solid background, such as bg color of the button.
 *    It must satisfy the contrast ratio with pure white (#ffffff) text on
 *    top of it.
 *
 * - `XXX-soft`: The color used for subtle background such as custom container
 *    or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
 *    on top of it.
 *
 *    The soft color must be semi transparent alpha channel. This is crucial
 *    because it allows adding multiple "soft" colors on top of each other
 *    to create a accent, such as when having inline code block inside
 *    custom containers.
 * -------------------------------------------------------------------------- */

:root {
  --vp-c-gray-1: #dddde3;
  --vp-c-gray-2: #e4e4e9;
  --vp-c-gray-3: #ebebef;
  --vp-c-gray-soft: rgba(142, 150, 170, 0.14);

  --vp-c-indigo-1: #3451b2;
  --vp-c-indigo-2: #3a5ccc;
  --vp-c-indigo-3: #5672cd;
  --vp-c-indigo-soft: rgba(100, 108, 255, 0.14);

  --vp-c-purple-1: #6f42c1;
  --vp-c-purple-2: #7e4cc9;
  --vp-c-purple-3: #8e5cd9;
  --vp-c-purple-soft: rgba(159, 122, 234, 0.14);

  --vp-c-green-1: #18794e;
  --vp-c-green-2: #299764;
  --vp-c-green-3: #30a46c;
  --vp-c-green-soft: rgba(16, 185, 129, 0.14);

  --vp-c-yellow-1: #915930;
  --vp-c-yellow-2: #946300;
  --vp-c-yellow-3: #9f6a00;
  --vp-c-yellow-soft: rgba(234, 179, 8, 0.14);

  --vp-c-red-1: #b8272c;
  --vp-c-red-2: #d5393e;
  --vp-c-red-3: #e0575b;
  --vp-c-red-soft: rgba(244, 63, 94, 0.14);

  --vp-c-sponsor: #db2777;
}

.dark {
  --vp-c-gray-1: #515c67;
  --vp-c-gray-2: #414853;
  --vp-c-gray-3: #32363f;
  --vp-c-gray-soft: rgba(101, 117, 133, 0.16);

  --vp-c-indigo-1: #a8b1ff;
  --vp-c-indigo-2: #5c73e7;
  --vp-c-indigo-3: #3e63dd;
  --vp-c-indigo-soft: rgba(100, 108, 255, 0.16);

  --vp-c-purple-1: #c8abfa;
  --vp-c-purple-2: #a879e6;
  --vp-c-purple-3: #8e5cd9;
  --vp-c-purple-soft: rgba(159, 122, 234, 0.16);

  --vp-c-green-1: #3dd68c;
  --vp-c-green-2: #30a46c;
  --vp-c-green-3: #298459;
  --vp-c-green-soft: rgba(16, 185, 129, 0.16);

  --vp-c-yellow-1: #f9b44e;
  --vp-c-yellow-2: #da8b17;
  --vp-c-yellow-3: #a46a0a;
  --vp-c-yellow-soft: rgba(234, 179, 8, 0.16);

  --vp-c-red-1: #f66f81;
  --vp-c-red-2: #f14158;
  --vp-c-red-3: #b62a3c;
  --vp-c-red-soft: rgba(244, 63, 94, 0.16);
}

/**
 * Colors: Background
 *
 * - `bg`: The bg color used for main screen.
 *
 * - `bg-alt`: The alternative bg color used in places such as "sidebar",
 *   or "code block".
 *
 * - `bg-elv`: The elevated bg color. This is used at parts where it "floats",
 *   such as "dialog".
 *
 * - `bg-soft`: The bg color to slightly distinguish some components from
 *   the page. Used for things like "carbon ads" or "table".
 * -------------------------------------------------------------------------- */

:root {
  --vp-c-bg: #ffffff;
  --vp-c-bg-alt: #f6f6f7;
  --vp-c-bg-elv: #ffffff;
  --vp-c-bg-soft: #f6f6f7;
}

.dark {
  --vp-c-bg: #1b1b1f;
  --vp-c-bg-alt: #161618;
  --vp-c-bg-elv: #202127;
  --vp-c-bg-soft: #202127;
}

/**
 * Colors: Borders
 *
 * - `divider`: This is used for separators. This is used to divide sections
 *   within the same components, such as having separator on "h2" heading.
 *
 * - `border`: This is designed for borders on interactive components.
 *   For example this should be used for a button outline.
 *
 * - `gutter`: This is used to divide components in the page. For example
 *   the header and the lest of the page.
 * -------------------------------------------------------------------------- */

:root {
  --vp-c-border: #c2c2c4;
  --vp-c-divider: #e2e2e3;
  --vp-c-gutter: #e2e2e3;
}

.dark {
  --vp-c-border: #3c3f44;
  --vp-c-divider: #2e2e32;
  --vp-c-gutter: #000000;
}

/**
 * Colors: Text
 *
 * - `text-1`: Used for primary text.
 *
 * - `text-2`: Used for muted texts, such as "inactive menu" or "info texts".
 *
 * - `text-3`: Used for subtle texts, such as "placeholders" or "caret icon".
 * -------------------------------------------------------------------------- */

:root {
  --vp-c-text-1: #3c3c43;
  --vp-c-text-2: #67676c;
  --vp-c-text-3: #929295;
}

.dark {
  --vp-c-text-1: #dfdfd6;
  --vp-c-text-2: #98989f;
  --vp-c-text-3: #6a6a71;
}

/**
 * Colors: Function
 *
 * - `default`: The color used purely for subtle indication without any
 *   special meanings attached to it such as bg color for menu hover state.
 *
 * - `brand`: Used for primary brand colors, such as link text, button with
 *   brand theme, etc.
 *
 * - `tip`: Used to indicate useful information. The default theme uses the
 *   brand color for this by default.
 *
 * - `warning`: Used to indicate warning to the users. Used in custom
 *   container, badges, etc.
 *
 * - `danger`: Used to show error, or dangerous message to the users. Used
 *   in custom container, badges, etc.
 *
 * To understand the scaling system, refer to "Colors: Palette" section.
 * -------------------------------------------------------------------------- */

:root {
  --vp-c-default-1: var(--vp-c-gray-1);
  --vp-c-default-2: var(--vp-c-gray-2);
  --vp-c-default-3: var(--vp-c-gray-3);
  --vp-c-default-soft: var(--vp-c-gray-soft);

  --vp-c-brand-1: var(--vp-c-indigo-1);
  --vp-c-brand-2: var(--vp-c-indigo-2);
  --vp-c-brand-3: var(--vp-c-indigo-3);
  --vp-c-brand-soft: var(--vp-c-indigo-soft);

  /* DEPRECATED: Use `--vp-c-brand-1` instead. */
  --vp-c-brand: var(--vp-c-brand-1);

  --vp-c-tip-1: var(--vp-c-brand-1);
  --vp-c-tip-2: var(--vp-c-brand-2);
  --vp-c-tip-3: var(--vp-c-brand-3);
  --vp-c-tip-soft: var(--vp-c-brand-soft);

  --vp-c-note-1: var(--vp-c-brand-1);
  --vp-c-note-2: var(--vp-c-brand-2);
  --vp-c-note-3: var(--vp-c-brand-3);
  --vp-c-note-soft: var(--vp-c-brand-soft);

  --vp-c-success-1: var(--vp-c-green-1);
  --vp-c-success-2: var(--vp-c-green-2);
  --vp-c-success-3: var(--vp-c-green-3);
  --vp-c-success-soft: var(--vp-c-green-soft);

  --vp-c-important-1: var(--vp-c-purple-1);
  --vp-c-important-2: var(--vp-c-purple-2);
  --vp-c-important-3: var(--vp-c-purple-3);
  --vp-c-important-soft: var(--vp-c-purple-soft);

  --vp-c-warning-1: var(--vp-c-yellow-1);
  --vp-c-warning-2: var(--vp-c-yellow-2);
  --vp-c-warning-3: var(--vp-c-yellow-3);
  --vp-c-warning-soft: var(--vp-c-yellow-soft);

  --vp-c-danger-1: var(--vp-c-red-1);
  --vp-c-danger-2: var(--vp-c-red-2);
  --vp-c-danger-3: var(--vp-c-red-3);
  --vp-c-danger-soft: var(--vp-c-red-soft);

  --vp-c-caution-1: var(--vp-c-red-1);
  --vp-c-caution-2: var(--vp-c-red-2);
  --vp-c-caution-3: var(--vp-c-red-3);
  --vp-c-caution-soft: var(--vp-c-red-soft);
}

/**
 * Typography
 * -------------------------------------------------------------------------- */

:root {
  --vp-font-family-base: 'Inter', ui-sans-serif, system-ui, sans-serif,
    'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
  --vp-font-family-mono: ui-monospace, 'Menlo', 'Monaco', 'Consolas',
    'Liberation Mono', 'Courier New', monospace;
  font-optical-sizing: auto;
}

:root:where(:lang(zh)) {
  --vp-font-family-base: 'Punctuation SC', 'Inter', ui-sans-serif, system-ui,
    sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
    'Noto Color Emoji';
}

/**
 * Shadows
 * -------------------------------------------------------------------------- */

:root {
  --vp-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06);
  --vp-shadow-2: 0 3px 12px rgba(0, 0, 0, 0.07), 0 1px 4px rgba(0, 0, 0, 0.07);
  --vp-shadow-3: 0 12px 32px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08);
  --vp-shadow-4: 0 14px 44px rgba(0, 0, 0, 0.12), 0 3px 9px rgba(0, 0, 0, 0.12);
  --vp-shadow-5: 0 18px 56px rgba(0, 0, 0, 0.16), 0 4px 12px rgba(0, 0, 0, 0.16);
}

/**
 * Z-indexes
 * -------------------------------------------------------------------------- */

:root {
  --vp-z-index-footer: 10;
  --vp-z-index-local-nav: 20;
  --vp-z-index-nav: 30;
  --vp-z-index-layout-top: 40;
  --vp-z-index-backdrop: 50;
  --vp-z-index-sidebar: 60;
}

@media (min-width: 960px) {
  :root {
    --vp-z-index-sidebar: 25;
  }
}

/**
 * Layouts
 * -------------------------------------------------------------------------- */

:root {
  --vp-layout-max-width: 1440px;
}

/**
 * Component: Header Anchor
 * -------------------------------------------------------------------------- */

:root {
  --vp-header-anchor-symbol: '#';
}

/**
 * Component: Code
 * -------------------------------------------------------------------------- */

:root {
  --vp-code-line-height: 1.7;
  --vp-code-font-size: 0.875em;
  --vp-code-color: var(--vp-c-brand-1);
  --vp-code-link-color: var(--vp-c-brand-1);
  --vp-code-link-hover-color: var(--vp-c-brand-2);
  --vp-code-bg: var(--vp-c-default-soft);

  --vp-code-block-color: var(--vp-c-text-2);
  --vp-code-block-bg: var(--vp-c-bg-alt);
  --vp-code-block-divider-color: var(--vp-c-gutter);

  --vp-code-lang-color: var(--vp-c-text-3);

  --vp-code-line-highlight-color: var(--vp-c-default-soft);
  --vp-code-line-number-color: var(--vp-c-text-3);

  --vp-code-line-diff-add-color: var(--vp-c-success-soft);
  --vp-code-line-diff-add-symbol-color: var(--vp-c-success-1);

  --vp-code-line-diff-remove-color: var(--vp-c-danger-soft);
  --vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1);

  --vp-code-line-warning-color: var(--vp-c-warning-soft);
  --vp-code-line-error-color: var(--vp-c-danger-soft);

  --vp-code-copy-code-border-color: var(--vp-c-divider);
  --vp-code-copy-code-bg: var(--vp-c-bg-soft);
  --vp-code-copy-code-hover-border-color: var(--vp-c-divider);
  --vp-code-copy-code-hover-bg: var(--vp-c-bg);
  --vp-code-copy-code-active-text: var(--vp-c-text-2);
  --vp-code-copy-copied-text-content: 'Copied';

  --vp-code-tab-divider: var(--vp-code-block-divider-color);
  --vp-code-tab-text-color: var(--vp-c-text-2);
  --vp-code-tab-bg: var(--vp-code-block-bg);
  --vp-code-tab-hover-text-color: var(--vp-c-text-1);
  --vp-code-tab-active-text-color: var(--vp-c-text-1);
  --vp-code-tab-active-bar-color: var(--vp-c-brand-1);
}

:lang(es),
:lang(pt) {
  --vp-code-copy-copied-text-content: 'Copiado';
}
:lang(fa) {
  --vp-code-copy-copied-text-content: 'کپی شد';
}
:lang(ko) {
  --vp-code-copy-copied-text-content: '복사됨';
}
:lang(ru) {
  --vp-code-copy-copied-text-content: 'Скопировано';
}
:lang(zh) {
  --vp-code-copy-copied-text-content: '已复制';
}

/**
 * Component: Button
 * -------------------------------------------------------------------------- */

:root {
  --vp-button-brand-border: transparent;
  --vp-button-brand-text: var(--vp-c-white);
  --vp-button-brand-bg: var(--vp-c-brand-3);
  --vp-button-brand-hover-border: transparent;
  --vp-button-brand-hover-text: var(--vp-c-white);
  --vp-button-brand-hover-bg: var(--vp-c-brand-2);
  --vp-button-brand-active-border: transparent;
  --vp-button-brand-active-text: var(--vp-c-white);
  --vp-button-brand-active-bg: var(--vp-c-brand-1);

  --vp-button-alt-border: transparent;
  --vp-button-alt-text: var(--vp-c-text-1);
  --vp-button-alt-bg: var(--vp-c-default-3);
  --vp-button-alt-hover-border: transparent;
  --vp-button-alt-hover-text: var(--vp-c-text-1);
  --vp-button-alt-hover-bg: var(--vp-c-default-2);
  --vp-button-alt-active-border: transparent;
  --vp-button-alt-active-text: var(--vp-c-text-1);
  --vp-button-alt-active-bg: var(--vp-c-default-1);

  --vp-button-sponsor-border: var(--vp-c-text-2);
  --vp-button-sponsor-text: var(--vp-c-text-2);
  --vp-button-sponsor-bg: transparent;
  --vp-button-sponsor-hover-border: var(--vp-c-sponsor);
  --vp-button-sponsor-hover-text: var(--vp-c-sponsor);
  --vp-button-sponsor-hover-bg: transparent;
  --vp-button-sponsor-active-border: var(--vp-c-sponsor);
  --vp-button-sponsor-active-text: var(--vp-c-sponsor);
  --vp-button-sponsor-active-bg: transparent;
}

/**
 * Component: Custom Block
 * -------------------------------------------------------------------------- */

:root {
  --vp-custom-block-font-size: 14px;
  --vp-custom-block-code-font-size: 13px;

  --vp-custom-block-info-border: transparent;
  --vp-custom-block-info-text: var(--vp-c-text-1);
  --vp-custom-block-info-bg: var(--vp-c-default-soft);
  --vp-custom-block-info-code-bg: var(--vp-c-default-soft);

  --vp-custom-block-note-border: transparent;
  --vp-custom-block-note-text: var(--vp-c-text-1);
  --vp-custom-block-note-bg: var(--vp-c-default-soft);
  --vp-custom-block-note-code-bg: var(--vp-c-default-soft);

  --vp-custom-block-tip-border: transparent;
  --vp-custom-block-tip-text: var(--vp-c-text-1);
  --vp-custom-block-tip-bg: var(--vp-c-tip-soft);
  --vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);

  --vp-custom-block-important-border: transparent;
  --vp-custom-block-important-text: var(--vp-c-text-1);
  --vp-custom-block-important-bg: var(--vp-c-important-soft);
  --vp-custom-block-important-code-bg: var(--vp-c-important-soft);

  --vp-custom-block-warning-border: transparent;
  --vp-custom-block-warning-text: var(--vp-c-text-1);
  --vp-custom-block-warning-bg: var(--vp-c-warning-soft);
  --vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);

  --vp-custom-block-danger-border: transparent;
  --vp-custom-block-danger-text: var(--vp-c-text-1);
  --vp-custom-block-danger-bg: var(--vp-c-danger-soft);
  --vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);

  --vp-custom-block-caution-border: transparent;
  --vp-custom-block-caution-text: var(--vp-c-text-1);
  --vp-custom-block-caution-bg: var(--vp-c-caution-soft);
  --vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);

  --vp-custom-block-details-border: var(--vp-custom-block-info-border);
  --vp-custom-block-details-text: var(--vp-custom-block-info-text);
  --vp-custom-block-details-bg: var(--vp-custom-block-info-bg);
  --vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg);
}

/**
 * Component: Input
 * -------------------------------------------------------------------------- */

:root {
  --vp-input-border-color: var(--vp-c-border);
  --vp-input-bg-color: var(--vp-c-bg-alt);

  --vp-input-switch-bg-color: var(--vp-c-default-soft);
}

/**
 * Component: Nav
 * -------------------------------------------------------------------------- */

:root {
  --vp-nav-height: 64px;
  --vp-nav-bg-color: var(--vp-c-bg);
  --vp-nav-screen-bg-color: var(--vp-c-bg);
  --vp-nav-logo-height: 24px;
}

.hide-nav {
  --vp-nav-height: 0px;
}

.hide-nav .VPSidebar {
  --vp-nav-height: 22px;
}

/**
 * Component: Local Nav
 * -------------------------------------------------------------------------- */

:root {
  --vp-local-nav-bg-color: var(--vp-c-bg);
}

/**
 * Component: Sidebar
 * -------------------------------------------------------------------------- */

:root {
  --vp-sidebar-width: 272px;
  --vp-sidebar-bg-color: var(--vp-c-bg-alt);
}

/**
 * Colors Backdrop
 * -------------------------------------------------------------------------- */

:root {
  --vp-backdrop-bg-color: rgba(0, 0, 0, 0.6);
}

/**
 * Component: Home
 * -------------------------------------------------------------------------- */

:root {
  --vp-home-hero-name-color: var(--vp-c-brand-1);
  --vp-home-hero-name-background: transparent;

  --vp-home-hero-image-background-image: none;
  --vp-home-hero-image-filter: none;
}

/**
 * Component: Badge
 * -------------------------------------------------------------------------- */

:root {
  --vp-badge-info-border: transparent;
  --vp-badge-info-text: var(--vp-c-text-2);
  --vp-badge-info-bg: var(--vp-c-default-soft);

  --vp-badge-tip-border: transparent;
  --vp-badge-tip-text: var(--vp-c-tip-1);
  --vp-badge-tip-bg: var(--vp-c-tip-soft);

  --vp-badge-warning-border: transparent;
  --vp-badge-warning-text: var(--vp-c-warning-1);
  --vp-badge-warning-bg: var(--vp-c-warning-soft);

  --vp-badge-danger-border: transparent;
  --vp-badge-danger-text: var(--vp-c-danger-1);
  --vp-badge-danger-bg: var(--vp-c-danger-soft);
}

/**
 * Component: Carbon Ads
 * -------------------------------------------------------------------------- */

:root {
  --vp-carbon-ads-text-color: var(--vp-c-text-1);
  --vp-carbon-ads-poweredby-color: var(--vp-c-text-2);
  --vp-carbon-ads-bg-color: var(--vp-c-bg-soft);
  --vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);
  --vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1);
}

/**
  * Component: Local Search
  * -------------------------------------------------------------------------- */

:root {
  --vp-local-search-bg: var(--vp-c-bg);
  --vp-local-search-result-bg: var(--vp-c-bg);
  --vp-local-search-result-border: var(--vp-c-divider);
  --vp-local-search-result-selected-bg: var(--vp-c-bg);
  --vp-local-search-result-selected-border: var(--vp-c-brand-1);
  --vp-local-search-highlight-bg: var(--vp-c-brand-1);
  --vp-local-search-highlight-text: var(--vp-c-neutral-inverse);
}
@media (prefers-reduced-motion: reduce) {
  *,
  ::before,
  ::after {
    animation-delay: -1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    background-attachment: initial !important;
    scroll-behavior: auto !important;
    transition-duration: 0s !important;
    transition-delay: 0s !important;
  }
}

*,
::before,
::after {
  box-sizing: border-box;
}

html {
  line-height: 1.4;
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
}

html.dark {
  color-scheme: dark;
}

body {
  margin: 0;
  width: 100%;
  min-width: 320px;
  min-height: 100vh;
  line-height: 24px;
  font-family: var(--vp-font-family-base);
  font-size: 16px;
  font-weight: 400;
  color: var(--vp-c-text-1);
  background-color: var(--vp-c-bg);
  font-synthesis: style;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

main {
  display: block;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0;
  line-height: 24px;
  font-size: 16px;
  font-weight: 400;
}

p {
  margin: 0;
}

strong,
b {
  font-weight: 600;
}

/**
 * Avoid 300ms click delay on touch devices that support the `touch-action`
 * CSS property.
 *
 * In particular, unlike most other browsers, IE11+Edge on Windows 10 on
 * touch devices and IE Mobile 10-11 DON'T remove the click delay when
 * `<meta name="viewport" content="width=device-width">` is present.
 * However, they DO support removing the click delay via
 * `touch-action: manipulation`.
 *
 * See:
 * - http://v4-alpha.getbootstrap.com/content/reboot/#click-delay-optimization-for-touch
 * - http://caniuse.com/#feat=css-touch-action
 * - http://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay
 */
a,
area,
button,
[role='button'],
input,
label,
select,
summary,
textarea {
  touch-action: manipulation;
}

a {
  color: inherit;
  text-decoration: inherit;
}

ol,
ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

blockquote {
  margin: 0;
}

pre,
code,
kbd,
samp {
  font-family: var(--vp-font-family-mono);
}

img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
  display: block;
}

figure {
  margin: 0;
}

img,
video {
  max-width: 100%;
  height: auto;
}

button,
input,
optgroup,
select,
textarea {
  border: 0;
  padding: 0;
  line-height: inherit;
  color: inherit;
}

button {
  padding: 0;
  font-family: inherit;
  background-color: transparent;
  background-image: none;
}

button:enabled,
[role='button']:enabled {
  cursor: pointer;
}

button:focus,
button:focus-visible {
  outline: 1px dotted;
  outline: 4px auto -webkit-focus-ring-color;
}

button:focus:not(:focus-visible) {
  outline: none !important;
}

input:focus,
textarea:focus,
select:focus {
  outline: none;
}

table {
  border-collapse: collapse;
}

input {
  background-color: transparent;
}

input:-ms-input-placeholder,
textarea:-ms-input-placeholder {
  color: var(--vp-c-text-3);
}

input::-ms-input-placeholder,
textarea::-ms-input-placeholder {
  color: var(--vp-c-text-3);
}

input::placeholder,
textarea::placeholder {
  color: var(--vp-c-text-3);
}

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

input[type='number'] {
  -moz-appearance: textfield;
}

textarea {
  resize: vertical;
}

select {
  -webkit-appearance: none;
}

fieldset {
  margin: 0;
  padding: 0;
}

h1,
h2,
h3,
h4,
h5,
h6,
li,
p {
  overflow-wrap: break-word;
}

vite-error-overlay {
  z-index: 9999;
}

mjx-container {
  overflow-x: auto;
}

mjx-container > svg {
  display: inline-block;
  margin: auto;
}
[class^='vpi-'],
[class*=' vpi-'],
.vp-icon {
  width: 1em;
  height: 1em;
}
[class^='vpi-'].bg,
[class*=' vpi-'].bg,
.vp-icon.bg {
  background-size: 100% 100%;
  background-color: transparent;
}
[class^='vpi-']:not(.bg),
[class*=' vpi-']:not(.bg),
.vp-icon:not(.bg) {
  -webkit-mask: var(--icon) no-repeat;
  mask: var(--icon) no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  background-color: currentColor;
  color: inherit;
}

/* internal icons - used under ISC from https://lucide.dev/ */
.vpi-align-left {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M21 6H3M15 12H3M17 18H3'/%3E%3C/svg%3E");
}
.vpi-arrow-right,
.vpi-arrow-down,
.vpi-arrow-left,
.vpi-arrow-up {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E");
}
.vpi-chevron-right,
.vpi-chevron-down,
.vpi-chevron-left,
.vpi-chevron-up {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
}
.vpi-chevron-down,
.vpi-arrow-down {
  /*rtl:ignore*/
  transform: rotate(90deg);
}
.vpi-chevron-left,
.vpi-arrow-left {
  /*rtl:ignore*/
  transform: rotate(180deg);
}
.vpi-chevron-up,
.vpi-arrow-up {
  /*rtl:ignore*/
  transform: rotate(-90deg);
}
.vpi-square-pen {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='M18.375 2.625a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z'/%3E%3C/svg%3E");
}
.vpi-plus {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5v14'/%3E%3C/svg%3E");
}
.vpi-sun {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E");
}
.vpi-moon {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E");
}
.vpi-more-horizontal {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='19' cy='12' r='1'/%3E%3Ccircle cx='5' cy='12' r='1'/%3E%3C/svg%3E");
}
.vpi-languages {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E");
}
.vpi-heart {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E");
}
.vpi-search {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
}
.vpi-layout-list {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3Cpath d='M14 4h7M14 9h7M14 15h7M14 20h7'/%3E%3C/svg%3E");
}
.vpi-delete {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2ZM18 9l-6 6M12 9l6 6'/%3E%3C/svg%3E");
}
.vpi-corner-down-left {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 10-5 5 5 5'/%3E%3Cpath d='M20 4v7a4 4 0 0 1-4 4H4'/%3E%3C/svg%3E");
}
:root {
  /* clipboard */
  --vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");
  /* clipboard-copy */
  --vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E");
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  white-space: nowrap;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  overflow: hidden;
}
.custom-block {
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 16px 16px 8px;
  line-height: 24px;
  font-size: var(--vp-custom-block-font-size);
  color: var(--vp-c-text-2);
}

.custom-block.info {
  border-color: var(--vp-custom-block-info-border);
  color: var(--vp-custom-block-info-text);
  background-color: var(--vp-custom-block-info-bg);
}

.custom-block.info a,
.custom-block.info code {
  color: var(--vp-c-brand-1);
}

.custom-block.info a:hover,
.custom-block.info a:hover > code {
  color: var(--vp-c-brand-2);
}

.custom-block.info code {
  background-color: var(--vp-custom-block-info-code-bg);
}

.custom-block.note {
  border-color: var(--vp-custom-block-note-border);
  color: var(--vp-custom-block-note-text);
  background-color: var(--vp-custom-block-note-bg);
}

.custom-block.note a,
.custom-block.note code {
  color: var(--vp-c-brand-1);
}

.custom-block.note a:hover,
.custom-block.note a:hover > code {
  color: var(--vp-c-brand-2);
}

.custom-block.note code {
  background-color: var(--vp-custom-block-note-code-bg);
}

.custom-block.tip {
  border-color: var(--vp-custom-block-tip-border);
  color: var(--vp-custom-block-tip-text);
  background-color: var(--vp-custom-block-tip-bg);
}

.custom-block.tip a,
.custom-block.tip code {
  color: var(--vp-c-tip-1);
}

.custom-block.tip a:hover,
.custom-block.tip a:hover > code {
  color: var(--vp-c-tip-2);
}

.custom-block.tip code {
  background-color: var(--vp-custom-block-tip-code-bg);
}

.custom-block.important {
  border-color: var(--vp-custom-block-important-border);
  color: var(--vp-custom-block-important-text);
  background-color: var(--vp-custom-block-important-bg);
}

.custom-block.important a,
.custom-block.important code {
  color: var(--vp-c-important-1);
}

.custom-block.important a:hover,
.custom-block.important a:hover > code {
  color: var(--vp-c-important-2);
}

.custom-block.important code {
  background-color: var(--vp-custom-block-important-code-bg);
}

.custom-block.warning {
  border-color: var(--vp-custom-block-warning-border);
  color: var(--vp-custom-block-warning-text);
  background-color: var(--vp-custom-block-warning-bg);
}

.custom-block.warning a,
.custom-block.warning code {
  color: var(--vp-c-warning-1);
}

.custom-block.warning a:hover,
.custom-block.warning a:hover > code {
  color: var(--vp-c-warning-2);
}

.custom-block.warning code {
  background-color: var(--vp-custom-block-warning-code-bg);
}

.custom-block.danger {
  border-color: var(--vp-custom-block-danger-border);
  color: var(--vp-custom-block-danger-text);
  background-color: var(--vp-custom-block-danger-bg);
}

.custom-block.danger a,
.custom-block.danger code {
  color: var(--vp-c-danger-1);
}

.custom-block.danger a:hover,
.custom-block.danger a:hover > code {
  color: var(--vp-c-danger-2);
}

.custom-block.danger code {
  background-color: var(--vp-custom-block-danger-code-bg);
}

.custom-block.caution {
  border-color: var(--vp-custom-block-caution-border);
  color: var(--vp-custom-block-caution-text);
  background-color: var(--vp-custom-block-caution-bg);
}

.custom-block.caution a,
.custom-block.caution code {
  color: var(--vp-c-caution-1);
}

.custom-block.caution a:hover,
.custom-block.caution a:hover > code {
  color: var(--vp-c-caution-2);
}

.custom-block.caution code {
  background-color: var(--vp-custom-block-caution-code-bg);
}

.custom-block.details {
  border-color: var(--vp-custom-block-details-border);
  color: var(--vp-custom-block-details-text);
  background-color: var(--vp-custom-block-details-bg);
}

.custom-block.details a {
  color: var(--vp-c-brand-1);
}

.custom-block.details a:hover,
.custom-block.details a:hover > code {
  color: var(--vp-c-brand-2);
}

.custom-block.details code {
  background-color: var(--vp-custom-block-details-code-bg);
}

.custom-block-title {
  font-weight: 600;
}

.custom-block p + p {
  margin: 8px 0;
}

.custom-block.details summary {
  margin: 0 0 8px;
  font-weight: 700;
  cursor: pointer;
  user-select: none;
}

.custom-block.details summary + p {
  margin: 8px 0;
}

.custom-block a {
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: opacity 0.25s;
}

.custom-block a:hover {
  opacity: 0.75;
}

.custom-block code {
  font-size: var(--vp-custom-block-code-font-size);
}

.custom-block.custom-block th,
.custom-block.custom-block blockquote > p {
  font-size: var(--vp-custom-block-font-size);
  color: inherit;
}
.dark .vp-code span {
  color: var(--shiki-dark, inherit);
}

html:not(.dark) .vp-code span {
  color: var(--shiki-light, inherit);
}
.vp-code-group {
  margin-top: 16px;
}

.vp-code-group .tabs {
  position: relative;
  display: flex;
  margin-right: -24px;
  margin-left: -24px;
  padding: 0 12px;
  background-color: var(--vp-code-tab-bg);
  overflow-x: auto;
  overflow-y: hidden;
  box-shadow: inset 0 -1px var(--vp-code-tab-divider);
}

@media (min-width: 640px) {
  .vp-code-group .tabs {
    margin-right: 0;
    margin-left: 0;
    border-radius: 8px 8px 0 0;
  }
}

.vp-code-group .tabs input {
  position: fixed;
  opacity: 0;
  pointer-events: none;
}

.vp-code-group .tabs label {
  position: relative;
  display: inline-block;
  border-bottom: 1px solid transparent;
  padding: 0 12px;
  line-height: 48px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-code-tab-text-color);
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.25s;
}

.vp-code-group .tabs label::after {
  position: absolute;
  right: 8px;
  bottom: -1px;
  left: 8px;
  z-index: 1;
  height: 2px;
  border-radius: 2px;
  content: '';
  background-color: transparent;
  transition: background-color 0.25s;
}

.vp-code-group label:hover {
  color: var(--vp-code-tab-hover-text-color);
}

.vp-code-group input:checked + label {
  color: var(--vp-code-tab-active-text-color);
}

.vp-code-group input:checked + label::after {
  background-color: var(--vp-code-tab-active-bar-color);
}

.vp-code-group div[class*='language-'],
.vp-block {
  display: none;
  margin-top: 0 !important;
  border-top-left-radius: 0 !important;
  border-top-right-radius: 0 !important;
}

.vp-code-group div[class*='language-'].active,
.vp-block.active {
  display: block;
}

.vp-block {
  padding: 20px 24px;
}
/**
 * Headings
 * -------------------------------------------------------------------------- */

.vp-doc h1,
.vp-doc h2,
.vp-doc h3,
.vp-doc h4,
.vp-doc h5,
.vp-doc h6 {
  position: relative;
  font-weight: 600;
  outline: none;
}

.vp-doc h1 {
  letter-spacing: -0.02em;
  line-height: 40px;
  font-size: 28px;
}

.vp-doc h2 {
  margin: 48px 0 16px;
  border-top: 1px solid var(--vp-c-divider);
  padding-top: 24px;
  letter-spacing: -0.02em;
  line-height: 32px;
  font-size: 24px;
}

.vp-doc h3 {
  margin: 32px 0 0;
  letter-spacing: -0.01em;
  line-height: 28px;
  font-size: 20px;
}

.vp-doc h4 {
  margin: 24px 0 0;
  letter-spacing: -0.01em;
  line-height: 24px;
  font-size: 18px;
}

.vp-doc .header-anchor {
  position: absolute;
  top: 0;
  left: 0;
  margin-left: -0.87em;
  font-weight: 500;
  user-select: none;
  opacity: 0;
  text-decoration: none;
  transition:
    color 0.25s,
    opacity 0.25s;
}

.vp-doc .header-anchor:before {
  content: var(--vp-header-anchor-symbol);
}

.vp-doc h1:hover .header-anchor,
.vp-doc h1 .header-anchor:focus,
.vp-doc h2:hover .header-anchor,
.vp-doc h2 .header-anchor:focus,
.vp-doc h3:hover .header-anchor,
.vp-doc h3 .header-anchor:focus,
.vp-doc h4:hover .header-anchor,
.vp-doc h4 .header-anchor:focus,
.vp-doc h5:hover .header-anchor,
.vp-doc h5 .header-anchor:focus,
.vp-doc h6:hover .header-anchor,
.vp-doc h6 .header-anchor:focus {
  opacity: 1;
}

@media (min-width: 768px) {
  .vp-doc h1 {
    letter-spacing: -0.02em;
    line-height: 40px;
    font-size: 32px;
  }
}

.vp-doc h2 .header-anchor {
  top: 24px;
}

/**
 * Paragraph and inline elements
 * -------------------------------------------------------------------------- */

.vp-doc p,
.vp-doc summary {
  margin: 16px 0;
}

.vp-doc p {
  line-height: 28px;
}

.vp-doc blockquote {
  margin: 16px 0;
  border-left: 2px solid var(--vp-c-divider);
  padding-left: 16px;
  transition: border-color 0.5s;
  color: var(--vp-c-text-2);
}

.vp-doc blockquote > p {
  margin: 0;
  font-size: 16px;
  transition: color 0.5s;
}

.vp-doc a {
  font-weight: 500;
  color: var(--vp-c-brand-1);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition:
    color 0.25s,
    opacity 0.25s;
}

.vp-doc a:hover {
  color: var(--vp-c-brand-2);
}

.vp-doc strong {
  font-weight: 600;
}

/**
 * Lists
 * -------------------------------------------------------------------------- */

.vp-doc ul,
.vp-doc ol {
  padding-left: 1.25rem;
  margin: 16px 0;
}

.vp-doc ul {
  list-style: disc;
}

.vp-doc ol {
  list-style: decimal;
}

.vp-doc li + li {
  margin-top: 8px;
}

.vp-doc li > ol,
.vp-doc li > ul {
  margin: 8px 0 0;
}

/**
 * Table
 * -------------------------------------------------------------------------- */

.vp-doc table {
  display: block;
  border-collapse: collapse;
  margin: 20px 0;
  overflow-x: auto;
}

.vp-doc tr {
  background-color: var(--vp-c-bg);
  border-top: 1px solid var(--vp-c-divider);
  transition: background-color 0.5s;
}

.vp-doc tr:nth-child(2n) {
  background-color: var(--vp-c-bg-soft);
}

.vp-doc th,
.vp-doc td {
  border: 1px solid var(--vp-c-divider);
  padding: 8px 16px;
}

.vp-doc th {
  text-align: left;
  font-size: 14px;
  font-weight: 600;
  color: var(--vp-c-text-2);
  background-color: var(--vp-c-bg-soft);
}

.vp-doc td {
  font-size: 14px;
}

/**
 * Decorational elements
 * -------------------------------------------------------------------------- */

.vp-doc hr {
  margin: 16px 0;
  border: none;
  border-top: 1px solid var(--vp-c-divider);
}

/**
 * Custom Block
 * -------------------------------------------------------------------------- */

.vp-doc .custom-block {
  margin: 16px 0;
}

.vp-doc .custom-block p {
  margin: 8px 0;
  line-height: 24px;
}

.vp-doc .custom-block p:first-child {
  margin: 0;
}

.vp-doc .custom-block div[class*='language-'] {
  margin: 8px 0;
  border-radius: 8px;
}

.vp-doc .custom-block div[class*='language-'] code {
  font-weight: 400;
  background-color: transparent;
}

.vp-doc .custom-block .vp-code-group .tabs {
  margin: 0;
  border-radius: 8px 8px 0 0;
}

/**
 * Code
 * -------------------------------------------------------------------------- */

/* inline code */
.vp-doc :not(pre, h1, h2, h3, h4, h5, h6) > code {
  font-size: var(--vp-code-font-size);
  color: var(--vp-code-color);
}

.vp-doc :not(pre) > code {
  border-radius: 4px;
  padding: 3px 6px;
  background-color: var(--vp-code-bg);
  transition:
    color 0.25s,
    background-color 0.5s;
}

.vp-doc a > code {
  color: var(--vp-code-link-color);
}

.vp-doc a:hover > code {
  color: var(--vp-code-link-hover-color);
}

.vp-doc h1 > code,
.vp-doc h2 > code,
.vp-doc h3 > code,
.vp-doc h4 > code {
  font-size: 0.9em;
}

.vp-doc div[class*='language-'],
.vp-block {
  position: relative;
  margin: 16px -24px;
  background-color: var(--vp-code-block-bg);
  overflow-x: auto;
  transition: background-color 0.5s;
}

@media (min-width: 640px) {
  .vp-doc div[class*='language-'],
  .vp-block {
    border-radius: 8px;
    margin: 16px 0;
  }
}

@media (max-width: 639px) {
  .vp-doc li div[class*='language-'] {
    border-radius: 8px 0 0 8px;
  }
}

.vp-doc div[class*='language-'] + div[class*='language-'],
.vp-doc div[class$='-api'] + div[class*='language-'],
.vp-doc div[class*='language-'] + div[class$='-api'] > div[class*='language-'] {
  margin-top: -8px;
}

.vp-doc [class*='language-'] pre,
.vp-doc [class*='language-'] code {
  /*rtl:ignore*/
  direction: ltr;
  /*rtl:ignore*/
  text-align: left;
  white-space: pre;
  word-spacing: normal;
  word-break: normal;
  word-wrap: normal;
  -moz-tab-size: 4;
  -o-tab-size: 4;
  tab-size: 4;
  -webkit-hyphens: none;
  -moz-hyphens: none;
  -ms-hyphens: none;
  hyphens: none;
}

.vp-doc [class*='language-'] pre {
  position: relative;
  z-index: 1;
  margin: 0;
  padding: 20px 0;
  background: transparent;
  overflow-x: auto;
}

.vp-doc [class*='language-'] code {
  display: block;
  padding: 0 24px;
  width: fit-content;
  min-width: 100%;
  line-height: var(--vp-code-line-height);
  font-size: var(--vp-code-font-size);
  color: var(--vp-code-block-color);
  transition: color 0.5s;
}

.vp-doc [class*='language-'] code .highlighted {
  background-color: var(--vp-code-line-highlight-color);
  transition: background-color 0.5s;
  margin: 0 -24px;
  padding: 0 24px;
  width: calc(100% + 2 * 24px);
  display: inline-block;
}

.vp-doc [class*='language-'] code .highlighted.error {
  background-color: var(--vp-code-line-error-color);
}

.vp-doc [class*='language-'] code .highlighted.warning {
  background-color: var(--vp-code-line-warning-color);
}

.vp-doc [class*='language-'] code .diff {
  transition: background-color 0.5s;
  margin: 0 -24px;
  padding: 0 24px;
  width: calc(100% + 2 * 24px);
  display: inline-block;
}

.vp-doc [class*='language-'] code .diff::before {
  position: absolute;
  left: 10px;
}

.vp-doc [class*='language-'] .has-focused-lines .line:not(.has-focus) {
  filter: blur(0.095rem);
  opacity: 0.4;
  transition:
    filter 0.35s,
    opacity 0.35s;
}

.vp-doc [class*='language-'] .has-focused-lines .line:not(.has-focus) {
  opacity: 0.7;
  transition:
    filter 0.35s,
    opacity 0.35s;
}

.vp-doc [class*='language-']:hover .has-focused-lines .line:not(.has-focus) {
  filter: blur(0);
  opacity: 1;
}

.vp-doc [class*='language-'] code .diff.remove {
  background-color: var(--vp-code-line-diff-remove-color);
  opacity: 0.7;
}

.vp-doc [class*='language-'] code .diff.remove::before {
  content: '-';
  color: var(--vp-code-line-diff-remove-symbol-color);
}

.vp-doc [class*='language-'] code .diff.add {
  background-color: var(--vp-code-line-diff-add-color);
}

.vp-doc [class*='language-'] code .diff.add::before {
  content: '+';
  color: var(--vp-code-line-diff-add-symbol-color);
}

.vp-doc div[class*='language-'].line-numbers-mode {
  /*rtl:ignore*/
  padding-left: 32px;
}

.vp-doc .line-numbers-wrapper {
  position: absolute;
  top: 0;
  bottom: 0;
  /*rtl:ignore*/
  left: 0;
  z-index: 3;
  /*rtl:ignore*/
  border-right: 1px solid var(--vp-code-block-divider-color);
  padding-top: 20px;
  width: 32px;
  text-align: center;
  font-family: var(--vp-font-family-mono);
  line-height: var(--vp-code-line-height);
  font-size: var(--vp-code-font-size);
  color: var(--vp-code-line-number-color);
  transition:
    border-color 0.5s,
    color 0.5s;
}

.vp-doc [class*='language-'] > button.copy {
  /*rtl:ignore*/
  direction: ltr;
  position: absolute;
  top: 12px;
  /*rtl:ignore*/
  right: 12px;
  z-index: 3;
  border: 1px solid var(--vp-code-copy-code-border-color);
  border-radius: 4px;
  width: 40px;
  height: 40px;
  background-color: var(--vp-code-copy-code-bg);
  opacity: 0;
  cursor: pointer;
  background-image: var(--vp-icon-copy);
  background-position: 50%;
  background-size: 20px;
  background-repeat: no-repeat;
  transition:
    border-color 0.25s,
    background-color 0.25s,
    opacity 0.25s;
}

.vp-doc [class*='language-']:hover > button.copy,
.vp-doc [class*='language-'] > button.copy:focus {
  opacity: 1;
}

.vp-doc [class*='language-'] > button.copy:hover,
.vp-doc [class*='language-'] > button.copy.copied {
  border-color: var(--vp-code-copy-code-hover-border-color);
  background-color: var(--vp-code-copy-code-hover-bg);
}

.vp-doc [class*='language-'] > button.copy.copied,
.vp-doc [class*='language-'] > button.copy:hover.copied {
  /*rtl:ignore*/
  border-radius: 0 4px 4px 0;
  background-color: var(--vp-code-copy-code-hover-bg);
  background-image: var(--vp-icon-copied);
}

.vp-doc [class*='language-'] > button.copy.copied::before,
.vp-doc [class*='language-'] > button.copy:hover.copied::before {
  position: relative;
  top: -1px;
  /*rtl:ignore*/
  transform: translateX(calc(-100% - 1px));
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid var(--vp-code-copy-code-hover-border-color);
  /*rtl:ignore*/
  border-right: 0;
  /*rtl:ignore*/
  border-radius: 4px 0 0 4px;
  padding: 0 10px;
  width: fit-content;
  height: 40px;
  text-align: center;
  font-size: 12px;
  font-weight: 500;
  color: var(--vp-code-copy-code-active-text);
  background-color: var(--vp-code-copy-code-hover-bg);
  white-space: nowrap;
  content: var(--vp-code-copy-copied-text-content);
}

.vp-doc [class*='language-'] > span.lang {
  position: absolute;
  top: 2px;
  /*rtl:ignore*/
  right: 8px;
  z-index: 2;
  font-size: 12px;
  font-weight: 500;
  user-select: none;
  color: var(--vp-code-lang-color);
  transition:
    color 0.4s,
    opacity 0.4s;
}

.vp-doc [class*='language-']:hover > button.copy + span.lang,
.vp-doc [class*='language-'] > button.copy:focus + span.lang {
  opacity: 0;
}

/**
 * Component: Team
 * -------------------------------------------------------------------------- */

.vp-doc .VPTeamMembers {
  margin-top: 24px;
}

.vp-doc .VPTeamMembers.small.count-1 .container {
  margin: 0 !important;
  max-width: calc((100% - 24px) / 2) !important;
}

.vp-doc .VPTeamMembers.small.count-2 .container,
.vp-doc .VPTeamMembers.small.count-3 .container {
  max-width: 100% !important;
}

.vp-doc .VPTeamMembers.medium.count-1 .container {
  margin: 0 !important;
  max-width: calc((100% - 24px) / 2) !important;
}

/**
 * External links
 * -------------------------------------------------------------------------- */

/* prettier-ignore */
:is(.vp-external-link-icon, .vp-doc a[href*='://'], .vp-doc a[target='_blank']):not(:is(.no-icon, svg a, :has(img, svg)))::after {
  display: inline-block;
  margin-top: -1px;
  margin-left: 4px;
  width: 11px;
  height: 11px;
  background: currentColor;
  color: var(--vp-c-text-3);
  flex-shrink: 0;
  --icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");
  -webkit-mask-image: var(--icon);
  mask-image: var(--icon);
  /*rtl:raw:transform: scaleX(-1);*/
}

.vp-external-link-icon::after {
  content: '';
}

/* prettier-ignore */
.external-link-icon-enabled :is(.vp-doc a[href*='://'], .vp-doc a[target='_blank']):not(:is(.no-icon, svg a, :has(img, svg)))::after {
  content: '';
  color: currentColor;
}
/**
 * VPSponsors styles are defined as global because a new class gets
 * allied in onMounted` hook and we can't use scoped style.
 */
.vp-sponsor {
  border-radius: 16px;
  overflow: hidden;
}

.vp-sponsor.aside {
  border-radius: 12px;
}

.vp-sponsor-section + .vp-sponsor-section {
  margin-top: 4px;
}

.vp-sponsor-tier {
  margin: 0 0 4px !important;
  text-align: center;
  letter-spacing: 1px !important;
  line-height: 24px;
  width: 100%;
  font-weight: 600;
  color: var(--vp-c-text-2);
  background-color: var(--vp-c-bg-soft);
}

.vp-sponsor.normal .vp-sponsor-tier {
  padding: 13px 0 11px;
  font-size: 14px;
}

.vp-sponsor.aside .vp-sponsor-tier {
  padding: 9px 0 7px;
  font-size: 12px;
}

.vp-sponsor-grid + .vp-sponsor-tier {
  margin-top: 4px;
}

.vp-sponsor-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.vp-sponsor-grid.xmini .vp-sponsor-grid-link {
  height: 64px;
}
.vp-sponsor-grid.xmini .vp-sponsor-grid-image {
  max-width: 64px;
  max-height: 22px;
}

.vp-sponsor-grid.mini .vp-sponsor-grid-link {
  height: 72px;
}
.vp-sponsor-grid.mini .vp-sponsor-grid-image {
  max-width: 96px;
  max-height: 24px;
}

.vp-sponsor-grid.small .vp-sponsor-grid-link {
  height: 96px;
}
.vp-sponsor-grid.small .vp-sponsor-grid-image {
  max-width: 96px;
  max-height: 24px;
}

.vp-sponsor-grid.medium .vp-sponsor-grid-link {
  height: 112px;
}
.vp-sponsor-grid.medium .vp-sponsor-grid-image {
  max-width: 120px;
  max-height: 36px;
}

.vp-sponsor-grid.big .vp-sponsor-grid-link {
  height: 184px;
}
.vp-sponsor-grid.big .vp-sponsor-grid-image {
  max-width: 192px;
  max-height: 56px;
}

.vp-sponsor-grid[data-vp-grid='2'] .vp-sponsor-grid-item {
  width: calc((100% - 4px) / 2);
}

.vp-sponsor-grid[data-vp-grid='3'] .vp-sponsor-grid-item {
  width: calc((100% - 4px * 2) / 3);
}

.vp-sponsor-grid[data-vp-grid='4'] .vp-sponsor-grid-item {
  width: calc((100% - 4px * 3) / 4);
}

.vp-sponsor-grid[data-vp-grid='5'] .vp-sponsor-grid-item {
  width: calc((100% - 4px * 4) / 5);
}

.vp-sponsor-grid[data-vp-grid='6'] .vp-sponsor-grid-item {
  width: calc((100% - 4px * 5) / 6);
}

.vp-sponsor-grid-item {
  flex-shrink: 0;
  width: 100%;
  background-color: var(--vp-c-bg-soft);
  transition: background-color 0.25s;
}

.vp-sponsor-grid-item:hover {
  background-color: var(--vp-c-default-soft);
}

.vp-sponsor-grid-item:hover .vp-sponsor-grid-image {
  filter: grayscale(0) invert(0);
}

.vp-sponsor-grid-item.empty:hover {
  background-color: var(--vp-c-bg-soft);
}

.dark .vp-sponsor-grid-item:hover {
  background-color: var(--vp-c-white);
}

.dark .vp-sponsor-grid-item.empty:hover {
  background-color: var(--vp-c-bg-soft);
}

.vp-sponsor-grid-link {
  display: flex;
}

.vp-sponsor-grid-box {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
}

.vp-sponsor-grid-image {
  max-width: 100%;
  filter: grayscale(1);
  transition: filter 0.25s;
}

.dark .vp-sponsor-grid-image {
  filter: grayscale(1) invert(1);
}

.VPBadge {
  display: inline-block;
  margin-left: 2px;
  border: 1px solid transparent;
  border-radius: 12px;
  padding: 0 10px;
  line-height: 22px;
  font-size: 12px;
  font-weight: 500;
  transform: translateY(-2px);
}
.VPBadge.small {
  padding: 0 6px;
  line-height: 18px;
  font-size: 10px;
  transform: translateY(-8px);
}
.VPDocFooter .VPBadge {
  display: none;
}
.vp-doc h1 > .VPBadge {
  margin-top: 4px;
  vertical-align: top;
}
.vp-doc h2 > .VPBadge {
  margin-top: 3px;
  padding: 0 8px;
  vertical-align: top;
}
.vp-doc h3 > .VPBadge {
  vertical-align: middle;
}
.vp-doc h4 > .VPBadge,
.vp-doc h5 > .VPBadge,
.vp-doc h6 > .VPBadge {
  vertical-align: middle;
  line-height: 18px;
}
.VPBadge.info {
  border-color: var(--vp-badge-info-border);
  color: var(--vp-badge-info-text);
  background-color: var(--vp-badge-info-bg);
}
.VPBadge.tip {
  border-color: var(--vp-badge-tip-border);
  color: var(--vp-badge-tip-text);
  background-color: var(--vp-badge-tip-bg);
}
.VPBadge.warning {
  border-color: var(--vp-badge-warning-border);
  color: var(--vp-badge-warning-text);
  background-color: var(--vp-badge-warning-bg);
}
.VPBadge.danger {
  border-color: var(--vp-badge-danger-border);
  color: var(--vp-badge-danger-text);
  background-color: var(--vp-badge-danger-bg);
}

.VPBackdrop[data-v-c79a1216] {
  position: fixed;
  top: 0;
  /*rtl:ignore*/
  right: 0;
  bottom: 0;
  /*rtl:ignore*/
  left: 0;
  z-index: var(--vp-z-index-backdrop);
  background: var(--vp-backdrop-bg-color);
  transition: opacity 0.5s;
}
.VPBackdrop.fade-enter-from[data-v-c79a1216],
.VPBackdrop.fade-leave-to[data-v-c79a1216] {
  opacity: 0;
}
.VPBackdrop.fade-leave-active[data-v-c79a1216] {
  transition-duration: .25s;
}
@media (min-width: 1280px) {
.VPBackdrop[data-v-c79a1216] {
    display: none;
}
}

.NotFound[data-v-d6be1790] {
  padding: 64px 24px 96px;
  text-align: center;
}
@media (min-width: 768px) {
.NotFound[data-v-d6be1790] {
    padding: 96px 32px 168px;
}
}
.code[data-v-d6be1790] {
  line-height: 64px;
  font-size: 64px;
  font-weight: 600;
}
.title[data-v-d6be1790] {
  padding-top: 12px;
  letter-spacing: 2px;
  line-height: 20px;
  font-size: 20px;
  font-weight: 700;
}
.divider[data-v-d6be1790] {
  margin: 24px auto 18px;
  width: 64px;
  height: 1px;
  background-color: var(--vp-c-divider);
}
.quote[data-v-d6be1790] {
  margin: 0 auto;
  max-width: 256px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-text-2);
}
.action[data-v-d6be1790] {
  padding-top: 20px;
}
.link[data-v-d6be1790] {
  display: inline-block;
  border: 1px solid var(--vp-c-brand-1);
  border-radius: 16px;
  padding: 3px 16px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-brand-1);
  transition:
    border-color 0.25s,
    color 0.25s;
}
.link[data-v-d6be1790]:hover {
  border-color: var(--vp-c-brand-2);
  color: var(--vp-c-brand-2);
}

.root[data-v-b933a997] {
  position: relative;
  z-index: 1;
}
.nested[data-v-b933a997] {
  padding-right: 16px;
  padding-left: 16px;
}
.outline-link[data-v-b933a997] {
  display: block;
  line-height: 32px;
  font-size: 14px;
  font-weight: 400;
  color: var(--vp-c-text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 0.5s;
}
.outline-link[data-v-b933a997]:hover,
.outline-link.active[data-v-b933a997] {
  color: var(--vp-c-text-1);
  transition: color 0.25s;
}
.outline-link.nested[data-v-b933a997] {
  padding-left: 13px;
}

.VPDocAsideOutline[data-v-a5bbad30] {
  display: none;
}
.VPDocAsideOutline.has-outline[data-v-a5bbad30] {
  display: block;
}
.content[data-v-a5bbad30] {
  position: relative;
  border-left: 1px solid var(--vp-c-divider);
  padding-left: 16px;
  font-size: 13px;
  font-weight: 500;
}
.outline-marker[data-v-a5bbad30] {
  position: absolute;
  top: 32px;
  left: -1px;
  z-index: 0;
  opacity: 0;
  width: 2px;
  border-radius: 2px;
  height: 18px;
  background-color: var(--vp-c-brand-1);
  transition:
    top 0.25s cubic-bezier(0, 1, 0.5, 1),
    background-color 0.5s,
    opacity 0.25s;
}
.outline-title[data-v-a5bbad30] {
  line-height: 32px;
  font-size: 14px;
  font-weight: 600;
}

.VPDocAside[data-v-3f215769] {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}
.spacer[data-v-3f215769] {
  flex-grow: 1;
}
.VPDocAside[data-v-3f215769] .spacer + .VPDocAsideSponsors,
.VPDocAside[data-v-3f215769] .spacer + .VPDocAsideCarbonAds {
  margin-top: 24px;
}
.VPDocAside[data-v-3f215769] .VPDocAsideSponsors + .VPDocAsideCarbonAds {
  margin-top: 16px;
}

.VPLastUpdated[data-v-e98dd255] {
  line-height: 24px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-text-2);
}
@media (min-width: 640px) {
.VPLastUpdated[data-v-e98dd255] {
    line-height: 32px;
    font-size: 14px;
    font-weight: 500;
}
}

.VPDocFooter[data-v-e257564d] {
  margin-top: 64px;
}
.edit-info[data-v-e257564d] {
  padding-bottom: 18px;
}
@media (min-width: 640px) {
.edit-info[data-v-e257564d] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: 14px;
}
}
.edit-link-button[data-v-e257564d] {
  display: flex;
  align-items: center;
  border: 0;
  line-height: 32px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-brand-1);
  transition: color 0.25s;
}
.edit-link-button[data-v-e257564d]:hover {
  color: var(--vp-c-brand-2);
}
.edit-link-icon[data-v-e257564d] {
  margin-right: 8px;
}
.prev-next[data-v-e257564d] {
  border-top: 1px solid var(--vp-c-divider);
  padding-top: 24px;
  display: grid;
  grid-row-gap: 8px;
}
@media (min-width: 640px) {
.prev-next[data-v-e257564d] {
    grid-template-columns: repeat(2, 1fr);
    grid-column-gap: 16px;
}
}
.pager-link[data-v-e257564d] {
  display: block;
  border: 1px solid var(--vp-c-divider);
  border-radius: 8px;
  padding: 11px 16px 13px;
  width: 100%;
  height: 100%;
  transition: border-color 0.25s;
}
.pager-link[data-v-e257564d]:hover {
  border-color: var(--vp-c-brand-1);
}
.pager-link.next[data-v-e257564d] {
  margin-left: auto;
  text-align: right;
}
.desc[data-v-e257564d] {
  display: block;
  line-height: 20px;
  font-size: 12px;
  font-weight: 500;
  color: var(--vp-c-text-2);
}
.title[data-v-e257564d] {
  display: block;
  line-height: 20px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-brand-1);
  transition: color 0.25s;
}

.VPDoc[data-v-39a288b8] {
  padding: 32px 24px 96px;
  width: 100%;
}
@media (min-width: 768px) {
.VPDoc[data-v-39a288b8] {
    padding: 48px 32px 128px;
}
}
@media (min-width: 960px) {
.VPDoc[data-v-39a288b8] {
    padding: 48px 32px 0;
}
.VPDoc:not(.has-sidebar) .container[data-v-39a288b8] {
    display: flex;
    justify-content: center;
    max-width: 992px;
}
.VPDoc:not(.has-sidebar) .content[data-v-39a288b8] {
    max-width: 752px;
}
}
@media (min-width: 1280px) {
.VPDoc .container[data-v-39a288b8] {
    display: flex;
    justify-content: center;
}
.VPDoc .aside[data-v-39a288b8] {
    display: block;
}
}
@media (min-width: 1440px) {
.VPDoc:not(.has-sidebar) .content[data-v-39a288b8] {
    max-width: 784px;
}
.VPDoc:not(.has-sidebar) .container[data-v-39a288b8] {
    max-width: 1104px;
}
}
.container[data-v-39a288b8] {
  margin: 0 auto;
  width: 100%;
}
.aside[data-v-39a288b8] {
  position: relative;
  display: none;
  order: 2;
  flex-grow: 1;
  padding-left: 32px;
  width: 100%;
  max-width: 256px;
}
.left-aside[data-v-39a288b8] {
  order: 1;
  padding-left: unset;
  padding-right: 32px;
}
.aside-container[data-v-39a288b8] {
  position: fixed;
  top: 0;
  padding-top: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px);
  width: 224px;
  height: 100vh;
  overflow-x: hidden;
  overflow-y: auto;
  scrollbar-width: none;
}
.aside-container[data-v-39a288b8]::-webkit-scrollbar {
  display: none;
}
.aside-curtain[data-v-39a288b8] {
  position: fixed;
  bottom: 0;
  z-index: 10;
  width: 224px;
  height: 32px;
  background: linear-gradient(transparent, var(--vp-c-bg) 70%);
}
.aside-content[data-v-39a288b8] {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px));
  padding-bottom: 32px;
}
.content[data-v-39a288b8] {
  position: relative;
  margin: 0 auto;
  width: 100%;
}
@media (min-width: 960px) {
.content[data-v-39a288b8] {
    padding: 0 32px 128px;
}
}
@media (min-width: 1280px) {
.content[data-v-39a288b8] {
    order: 1;
    margin: 0;
    min-width: 640px;
}
}
.content-container[data-v-39a288b8] {
  margin: 0 auto;
}
.VPDoc.has-aside .content-container[data-v-39a288b8] {
  max-width: 688px;
}

.VPButton[data-v-fa7799d5] {
  display: inline-block;
  border: 1px solid transparent;
  text-align: center;
  font-weight: 600;
  white-space: nowrap;
  transition: color 0.25s, border-color 0.25s, background-color 0.25s;
}
.VPButton[data-v-fa7799d5]:active {
  transition: color 0.1s, border-color 0.1s, background-color 0.1s;
}
.VPButton.medium[data-v-fa7799d5] {
  border-radius: 20px;
  padding: 0 20px;
  line-height: 38px;
  font-size: 14px;
}
.VPButton.big[data-v-fa7799d5] {
  border-radius: 24px;
  padding: 0 24px;
  line-height: 46px;
  font-size: 16px;
}
.VPButton.brand[data-v-fa7799d5] {
  border-color: var(--vp-button-brand-border);
  color: var(--vp-button-brand-text);
  background-color: var(--vp-button-brand-bg);
}
.VPButton.brand[data-v-fa7799d5]:hover {
  border-color: var(--vp-button-brand-hover-border);
  color: var(--vp-button-brand-hover-text);
  background-color: var(--vp-button-brand-hover-bg);
}
.VPButton.brand[data-v-fa7799d5]:active {
  border-color: var(--vp-button-brand-active-border);
  color: var(--vp-button-brand-active-text);
  background-color: var(--vp-button-brand-active-bg);
}
.VPButton.alt[data-v-fa7799d5] {
  border-color: var(--vp-button-alt-border);
  color: var(--vp-button-alt-text);
  background-color: var(--vp-button-alt-bg);
}
.VPButton.alt[data-v-fa7799d5]:hover {
  border-color: var(--vp-button-alt-hover-border);
  color: var(--vp-button-alt-hover-text);
  background-color: var(--vp-button-alt-hover-bg);
}
.VPButton.alt[data-v-fa7799d5]:active {
  border-color: var(--vp-button-alt-active-border);
  color: var(--vp-button-alt-active-text);
  background-color: var(--vp-button-alt-active-bg);
}
.VPButton.sponsor[data-v-fa7799d5] {
  border-color: var(--vp-button-sponsor-border);
  color: var(--vp-button-sponsor-text);
  background-color: var(--vp-button-sponsor-bg);
}
.VPButton.sponsor[data-v-fa7799d5]:hover {
  border-color: var(--vp-button-sponsor-hover-border);
  color: var(--vp-button-sponsor-hover-text);
  background-color: var(--vp-button-sponsor-hover-bg);
}
.VPButton.sponsor[data-v-fa7799d5]:active {
  border-color: var(--vp-button-sponsor-active-border);
  color: var(--vp-button-sponsor-active-text);
  background-color: var(--vp-button-sponsor-active-bg);
}

html:not(.dark) .VPImage.dark[data-v-8426fc1a] {
  display: none;
}
.dark .VPImage.light[data-v-8426fc1a] {
  display: none;
}

.VPHero[data-v-4f9c455b] {
  margin-top: calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);
  padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px;
}
@media (min-width: 640px) {
.VPHero[data-v-4f9c455b] {
    padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px;
}
}
@media (min-width: 960px) {
.VPHero[data-v-4f9c455b] {
    padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px;
}
}
.container[data-v-4f9c455b] {
  display: flex;
  flex-direction: column;
  margin: 0 auto;
  max-width: 1152px;
}
@media (min-width: 960px) {
.container[data-v-4f9c455b] {
    flex-direction: row;
}
}
.main[data-v-4f9c455b] {
  position: relative;
  z-index: 10;
  order: 2;
  flex-grow: 1;
  flex-shrink: 0;
}
.VPHero.has-image .container[data-v-4f9c455b] {
  text-align: center;
}
@media (min-width: 960px) {
.VPHero.has-image .container[data-v-4f9c455b] {
    text-align: left;
}
}
@media (min-width: 960px) {
.main[data-v-4f9c455b] {
    order: 1;
    width: calc((100% / 3) * 2);
}
.VPHero.has-image .main[data-v-4f9c455b] {
    max-width: 592px;
}
}
.heading[data-v-4f9c455b] {
  display: flex;
  flex-direction: column;
}
.name[data-v-4f9c455b],
.text[data-v-4f9c455b] {
  width: fit-content;
  max-width: 392px;
  letter-spacing: -0.4px;
  line-height: 40px;
  font-size: 32px;
  font-weight: 700;
  white-space: pre-wrap;
}
.VPHero.has-image .name[data-v-4f9c455b],
.VPHero.has-image .text[data-v-4f9c455b] {
  margin: 0 auto;
}
.name[data-v-4f9c455b] {
  color: var(--vp-home-hero-name-color);
}
.clip[data-v-4f9c455b] {
  background: var(--vp-home-hero-name-background);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: var(--vp-home-hero-name-color);
}
@media (min-width: 640px) {
.name[data-v-4f9c455b],
  .text[data-v-4f9c455b] {
    max-width: 576px;
    line-height: 56px;
    font-size: 48px;
}
}
@media (min-width: 960px) {
.name[data-v-4f9c455b],
  .text[data-v-4f9c455b] {
    line-height: 64px;
    font-size: 56px;
}
.VPHero.has-image .name[data-v-4f9c455b],
  .VPHero.has-image .text[data-v-4f9c455b] {
    margin: 0;
}
}
.tagline[data-v-4f9c455b] {
  padding-top: 8px;
  max-width: 392px;
  line-height: 28px;
  font-size: 18px;
  font-weight: 500;
  white-space: pre-wrap;
  color: var(--vp-c-text-2);
}
.VPHero.has-image .tagline[data-v-4f9c455b] {
  margin: 0 auto;
}
@media (min-width: 640px) {
.tagline[data-v-4f9c455b] {
    padding-top: 12px;
    max-width: 576px;
    line-height: 32px;
    font-size: 20px;
}
}
@media (min-width: 960px) {
.tagline[data-v-4f9c455b] {
    line-height: 36px;
    font-size: 24px;
}
.VPHero.has-image .tagline[data-v-4f9c455b] {
    margin: 0;
}
}
.actions[data-v-4f9c455b] {
  display: flex;
  flex-wrap: wrap;
  margin: -6px;
  padding-top: 24px;
}
.VPHero.has-image .actions[data-v-4f9c455b] {
  justify-content: center;
}
@media (min-width: 640px) {
.actions[data-v-4f9c455b] {
    padding-top: 32px;
}
}
@media (min-width: 960px) {
.VPHero.has-image .actions[data-v-4f9c455b] {
    justify-content: flex-start;
}
}
.action[data-v-4f9c455b] {
  flex-shrink: 0;
  padding: 6px;
}
.image[data-v-4f9c455b] {
  order: 1;
  margin: -76px -24px -48px;
}
@media (min-width: 640px) {
.image[data-v-4f9c455b] {
    margin: -108px -24px -48px;
}
}
@media (min-width: 960px) {
.image[data-v-4f9c455b] {
    flex-grow: 1;
    order: 2;
    margin: 0;
    min-height: 100%;
}
}
.image-container[data-v-4f9c455b] {
  position: relative;
  margin: 0 auto;
  width: 320px;
  height: 320px;
}
@media (min-width: 640px) {
.image-container[data-v-4f9c455b] {
    width: 392px;
    height: 392px;
}
}
@media (min-width: 960px) {
.image-container[data-v-4f9c455b] {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    /*rtl:ignore*/
    transform: translate(-32px, -32px);
}
}
.image-bg[data-v-4f9c455b] {
  position: absolute;
  top: 50%;
  /*rtl:ignore*/
  left: 50%;
  border-radius: 50%;
  width: 192px;
  height: 192px;
  background-image: var(--vp-home-hero-image-background-image);
  filter: var(--vp-home-hero-image-filter);
  /*rtl:ignore*/
  transform: translate(-50%, -50%);
}
@media (min-width: 640px) {
.image-bg[data-v-4f9c455b] {
    width: 256px;
    height: 256px;
}
}
@media (min-width: 960px) {
.image-bg[data-v-4f9c455b] {
    width: 320px;
    height: 320px;
}
}
[data-v-4f9c455b] .image-src {
  position: absolute;
  top: 50%;
  /*rtl:ignore*/
  left: 50%;
  max-width: 192px;
  max-height: 192px;
  /*rtl:ignore*/
  transform: translate(-50%, -50%);
}
@media (min-width: 640px) {
[data-v-4f9c455b] .image-src {
    max-width: 256px;
    max-height: 256px;
}
}
@media (min-width: 960px) {
[data-v-4f9c455b] .image-src {
    max-width: 320px;
    max-height: 320px;
}
}

.VPFeature[data-v-a3976bdc] {
  display: block;
  border: 1px solid var(--vp-c-bg-soft);
  border-radius: 12px;
  height: 100%;
  background-color: var(--vp-c-bg-soft);
  transition: border-color 0.25s, background-color 0.25s;
}
.VPFeature.link[data-v-a3976bdc]:hover {
  border-color: var(--vp-c-brand-1);
}
.box[data-v-a3976bdc] {
  display: flex;
  flex-direction: column;
  padding: 24px;
  height: 100%;
}
.box[data-v-a3976bdc] >  .VPImage {
  margin-bottom: 20px;
}
.icon[data-v-a3976bdc] {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 20px;
  border-radius: 6px;
  background-color: var(--vp-c-default-soft);
  width: 48px;
  height: 48px;
  font-size: 24px;
  transition: background-color 0.25s;
}
.title[data-v-a3976bdc] {
  line-height: 24px;
  font-size: 16px;
  font-weight: 600;
}
.details[data-v-a3976bdc] {
  flex-grow: 1;
  padding-top: 8px;
  line-height: 24px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-text-2);
}
.link-text[data-v-a3976bdc] {
  padding-top: 8px;
}
.link-text-value[data-v-a3976bdc] {
  display: flex;
  align-items: center;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-brand-1);
}
.link-text-icon[data-v-a3976bdc] {
  margin-left: 6px;
}

.VPFeatures[data-v-a6181336] {
  position: relative;
  padding: 0 24px;
}
@media (min-width: 640px) {
.VPFeatures[data-v-a6181336] {
    padding: 0 48px;
}
}
@media (min-width: 960px) {
.VPFeatures[data-v-a6181336] {
    padding: 0 64px;
}
}
.container[data-v-a6181336] {
  margin: 0 auto;
  max-width: 1152px;
}
.items[data-v-a6181336] {
  display: flex;
  flex-wrap: wrap;
  margin: -8px;
}
.item[data-v-a6181336] {
  padding: 8px;
  width: 100%;
}
@media (min-width: 640px) {
.item.grid-2[data-v-a6181336],
  .item.grid-4[data-v-a6181336],
  .item.grid-6[data-v-a6181336] {
    width: calc(100% / 2);
}
}
@media (min-width: 768px) {
.item.grid-2[data-v-a6181336],
  .item.grid-4[data-v-a6181336] {
    width: calc(100% / 2);
}
.item.grid-3[data-v-a6181336],
  .item.grid-6[data-v-a6181336] {
    width: calc(100% / 3);
}
}
@media (min-width: 960px) {
.item.grid-4[data-v-a6181336] {
    width: calc(100% / 4);
}
}

.container[data-v-8e2d4988] {
  margin: auto;
  width: 100%;
  max-width: 1280px;
  padding: 0 24px;
}
@media (min-width: 640px) {
.container[data-v-8e2d4988] {
    padding: 0 48px;
}
}
@media (min-width: 960px) {
.container[data-v-8e2d4988] {
    width: 100%;
    padding: 0 64px;
}
}
.vp-doc[data-v-8e2d4988] .VPHomeSponsors,
.vp-doc[data-v-8e2d4988] .VPTeamPage {
  margin-left: var(--vp-offset, calc(50% - 50vw));
  margin-right: var(--vp-offset, calc(50% - 50vw));
}
.vp-doc[data-v-8e2d4988] .VPHomeSponsors h2 {
  border-top: none;
  letter-spacing: normal;
}
.vp-doc[data-v-8e2d4988] .VPHomeSponsors a,
.vp-doc[data-v-8e2d4988] .VPTeamPage a {
  text-decoration: none;
}

.VPHome[data-v-8b561e3d] {
  margin-bottom: 96px;
}
@media (min-width: 768px) {
.VPHome[data-v-8b561e3d] {
    margin-bottom: 128px;
}
}

.VPContent[data-v-1428d186] {
  flex-grow: 1;
  flex-shrink: 0;
  margin: var(--vp-layout-top-height, 0px) auto 0;
  width: 100%;
}
.VPContent.is-home[data-v-1428d186] {
  width: 100%;
  max-width: 100%;
}
.VPContent.has-sidebar[data-v-1428d186] {
  margin: 0;
}
@media (min-width: 960px) {
.VPContent[data-v-1428d186] {
    padding-top: var(--vp-nav-height);
}
.VPContent.has-sidebar[data-v-1428d186] {
    margin: var(--vp-layout-top-height, 0px) 0 0;
    padding-left: var(--vp-sidebar-width);
}
}
@media (min-width: 1440px) {
.VPContent.has-sidebar[data-v-1428d186] {
    padding-right: calc((100vw - var(--vp-layout-max-width)) / 2);
    padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width));
}
}

.VPFooter[data-v-e315a0ad] {
  position: relative;
  z-index: var(--vp-z-index-footer);
  border-top: 1px solid var(--vp-c-gutter);
  padding: 32px 24px;
  background-color: var(--vp-c-bg);
}
.VPFooter.has-sidebar[data-v-e315a0ad] {
  display: none;
}
.VPFooter[data-v-e315a0ad] a {
  text-decoration-line: underline;
  text-underline-offset: 2px;
  transition: color 0.25s;
}
.VPFooter[data-v-e315a0ad] a:hover {
  color: var(--vp-c-text-1);
}
@media (min-width: 768px) {
.VPFooter[data-v-e315a0ad] {
    padding: 32px;
}
}
.container[data-v-e315a0ad] {
  margin: 0 auto;
  max-width: var(--vp-layout-max-width);
  text-align: center;
}
.message[data-v-e315a0ad],
.copyright[data-v-e315a0ad] {
  line-height: 24px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-text-2);
}

.VPLocalNavOutlineDropdown[data-v-8a42e2b4] {
  padding: 12px 20px 11px;
}
@media (min-width: 960px) {
.VPLocalNavOutlineDropdown[data-v-8a42e2b4] {
    padding: 12px 36px 11px;
}
}
.VPLocalNavOutlineDropdown button[data-v-8a42e2b4] {
  display: block;
  font-size: 12px;
  font-weight: 500;
  line-height: 24px;
  color: var(--vp-c-text-2);
  transition: color 0.5s;
  position: relative;
}
.VPLocalNavOutlineDropdown button[data-v-8a42e2b4]:hover {
  color: var(--vp-c-text-1);
  transition: color 0.25s;
}
.VPLocalNavOutlineDropdown button.open[data-v-8a42e2b4] {
  color: var(--vp-c-text-1);
}
.icon[data-v-8a42e2b4] {
  display: inline-block;
  vertical-align: middle;
  margin-left: 2px;
  font-size: 14px;
  transform: rotate(0)/*rtl:rotate(180deg)*/;
  transition: transform 0.25s;
}
@media (min-width: 960px) {
.VPLocalNavOutlineDropdown button[data-v-8a42e2b4] {
    font-size: 14px;
}
.icon[data-v-8a42e2b4] {
    font-size: 16px;
}
}
.open > .icon[data-v-8a42e2b4] {
  /*rtl:ignore*/
  transform: rotate(90deg);
}
.items[data-v-8a42e2b4] {
  position: absolute;
  top: 40px;
  right: 16px;
  left: 16px;
  display: grid;
  gap: 1px;
  border: 1px solid var(--vp-c-border);
  border-radius: 8px;
  background-color: var(--vp-c-gutter);
  max-height: calc(var(--vp-vh, 100vh) - 86px);
  overflow: hidden auto;
  box-shadow: var(--vp-shadow-3);
}
@media (min-width: 960px) {
.items[data-v-8a42e2b4] {
    right: auto;
    left: calc(var(--vp-sidebar-width) + 32px);
    width: 320px;
}
}
.header[data-v-8a42e2b4] {
  background-color: var(--vp-c-bg-soft);
}
.top-link[data-v-8a42e2b4] {
  display: block;
  padding: 0 16px;
  line-height: 48px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-brand-1);
}
.outline[data-v-8a42e2b4] {
  padding: 8px 0;
  background-color: var(--vp-c-bg-soft);
}
.flyout-enter-active[data-v-8a42e2b4] {
  transition: all 0.2s ease-out;
}
.flyout-leave-active[data-v-8a42e2b4] {
  transition: all 0.15s ease-in;
}
.flyout-enter-from[data-v-8a42e2b4],
.flyout-leave-to[data-v-8a42e2b4] {
  opacity: 0;
  transform: translateY(-16px);
}

.VPLocalNav[data-v-a6f0e41e] {
  position: sticky;
  top: 0;
  /*rtl:ignore*/
  left: 0;
  z-index: var(--vp-z-index-local-nav);
  border-bottom: 1px solid var(--vp-c-gutter);
  padding-top: var(--vp-layout-top-height, 0px);
  width: 100%;
  background-color: var(--vp-local-nav-bg-color);
}
.VPLocalNav.fixed[data-v-a6f0e41e] {
  position: fixed;
}
@media (min-width: 960px) {
.VPLocalNav[data-v-a6f0e41e] {
    top: var(--vp-nav-height);
}
.VPLocalNav.has-sidebar[data-v-a6f0e41e] {
    padding-left: var(--vp-sidebar-width);
}
.VPLocalNav.empty[data-v-a6f0e41e] {
    display: none;
}
}
@media (min-width: 1280px) {
.VPLocalNav[data-v-a6f0e41e] {
    display: none;
}
}
@media (min-width: 1440px) {
.VPLocalNav.has-sidebar[data-v-a6f0e41e] {
    padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width));
}
}
.container[data-v-a6f0e41e] {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.menu[data-v-a6f0e41e] {
  display: flex;
  align-items: center;
  padding: 12px 24px 11px;
  line-height: 24px;
  font-size: 12px;
  font-weight: 500;
  color: var(--vp-c-text-2);
  transition: color 0.5s;
}
.menu[data-v-a6f0e41e]:hover {
  color: var(--vp-c-text-1);
  transition: color 0.25s;
}
@media (min-width: 768px) {
.menu[data-v-a6f0e41e] {
    padding: 0 32px;
}
}
@media (min-width: 960px) {
.menu[data-v-a6f0e41e] {
    display: none;
}
}
.menu-icon[data-v-a6f0e41e] {
  margin-right: 8px;
  font-size: 14px;
}
.VPOutlineDropdown[data-v-a6f0e41e] {
  padding: 12px 24px 11px;
}
@media (min-width: 768px) {
.VPOutlineDropdown[data-v-a6f0e41e] {
    padding: 12px 32px 11px;
}
}

.VPSwitch[data-v-1d5665e3] {
  position: relative;
  border-radius: 11px;
  display: block;
  width: 40px;
  height: 22px;
  flex-shrink: 0;
  border: 1px solid var(--vp-input-border-color);
  background-color: var(--vp-input-switch-bg-color);
  transition: border-color 0.25s !important;
}
.VPSwitch[data-v-1d5665e3]:hover {
  border-color: var(--vp-c-brand-1);
}
.check[data-v-1d5665e3] {
  position: absolute;
  top: 1px;
  /*rtl:ignore*/
  left: 1px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background-color: var(--vp-c-neutral-inverse);
  box-shadow: var(--vp-shadow-1);
  transition: transform 0.25s !important;
}
.icon[data-v-1d5665e3] {
  position: relative;
  display: block;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  overflow: hidden;
}
.icon[data-v-1d5665e3] [class^='vpi-'] {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 12px;
  height: 12px;
  color: var(--vp-c-text-2);
}
.dark .icon[data-v-1d5665e3] [class^='vpi-'] {
  color: var(--vp-c-text-1);
  transition: opacity 0.25s !important;
}

.sun[data-v-5337faa4] {
  opacity: 1;
}
.moon[data-v-5337faa4] {
  opacity: 0;
}
.dark .sun[data-v-5337faa4] {
  opacity: 0;
}
.dark .moon[data-v-5337faa4] {
  opacity: 1;
}
.dark .VPSwitchAppearance[data-v-5337faa4] .check {
  /*rtl:ignore*/
  transform: translateX(18px);
}

.VPNavBarAppearance[data-v-6c893767] {
  display: none;
}
@media (min-width: 1280px) {
.VPNavBarAppearance[data-v-6c893767] {
    display: flex;
    align-items: center;
}
}

.VPMenuGroup + .VPMenuLink[data-v-35975db6] {
  margin: 12px -12px 0;
  border-top: 1px solid var(--vp-c-divider);
  padding: 12px 12px 0;
}
.link[data-v-35975db6] {
  display: block;
  border-radius: 6px;
  padding: 0 12px;
  line-height: 32px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-text-1);
  white-space: nowrap;
  transition:
    background-color 0.25s,
    color 0.25s;
}
.link[data-v-35975db6]:hover {
  color: var(--vp-c-brand-1);
  background-color: var(--vp-c-default-soft);
}
.link.active[data-v-35975db6] {
  color: var(--vp-c-brand-1);
}

.VPMenuGroup[data-v-69e747b5] {
  margin: 12px -12px 0;
  border-top: 1px solid var(--vp-c-divider);
  padding: 12px 12px 0;
}
.VPMenuGroup[data-v-69e747b5]:first-child {
  margin-top: 0;
  border-top: 0;
  padding-top: 0;
}
.VPMenuGroup + .VPMenuGroup[data-v-69e747b5] {
  margin-top: 12px;
  border-top: 1px solid var(--vp-c-divider);
}
.title[data-v-69e747b5] {
  padding: 0 12px;
  line-height: 32px;
  font-size: 14px;
  font-weight: 600;
  color: var(--vp-c-text-2);
  white-space: nowrap;
  transition: color 0.25s;
}

.VPMenu[data-v-b98bc113] {
  border-radius: 12px;
  padding: 12px;
  min-width: 128px;
  border: 1px solid var(--vp-c-divider);
  background-color: var(--vp-c-bg-elv);
  box-shadow: var(--vp-shadow-3);
  transition: background-color 0.5s;
  max-height: calc(100vh - var(--vp-nav-height));
  overflow-y: auto;
}
.VPMenu[data-v-b98bc113] .group {
  margin: 0 -12px;
  padding: 0 12px 12px;
}
.VPMenu[data-v-b98bc113] .group + .group {
  border-top: 1px solid var(--vp-c-divider);
  padding: 11px 12px 12px;
}
.VPMenu[data-v-b98bc113] .group:last-child {
  padding-bottom: 0;
}
.VPMenu[data-v-b98bc113] .group + .item {
  border-top: 1px solid var(--vp-c-divider);
  padding: 11px 16px 0;
}
.VPMenu[data-v-b98bc113] .item {
  padding: 0 16px;
  white-space: nowrap;
}
.VPMenu[data-v-b98bc113] .label {
  flex-grow: 1;
  line-height: 28px;
  font-size: 12px;
  font-weight: 500;
  color: var(--vp-c-text-2);
  transition: color 0.5s;
}
.VPMenu[data-v-b98bc113] .action {
  padding-left: 24px;
}

.VPFlyout[data-v-cf11d7a2] {
  position: relative;
}
.VPFlyout[data-v-cf11d7a2]:hover {
  color: var(--vp-c-brand-1);
  transition: color 0.25s;
}
.VPFlyout:hover .text[data-v-cf11d7a2] {
  color: var(--vp-c-text-2);
}
.VPFlyout:hover .icon[data-v-cf11d7a2] {
  fill: var(--vp-c-text-2);
}
.VPFlyout.active .text[data-v-cf11d7a2] {
  color: var(--vp-c-brand-1);
}
.VPFlyout.active:hover .text[data-v-cf11d7a2] {
  color: var(--vp-c-brand-2);
}
.button[aria-expanded="false"] + .menu[data-v-cf11d7a2] {
  opacity: 0;
  visibility: hidden;
  transform: translateY(0);
}
.VPFlyout:hover .menu[data-v-cf11d7a2],
.button[aria-expanded="true"] + .menu[data-v-cf11d7a2] {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.button[data-v-cf11d7a2] {
  display: flex;
  align-items: center;
  padding: 0 12px;
  height: var(--vp-nav-height);
  color: var(--vp-c-text-1);
  transition: color 0.5s;
}
.text[data-v-cf11d7a2] {
  display: flex;
  align-items: center;
  line-height: var(--vp-nav-height);
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-text-1);
  transition: color 0.25s;
}
.option-icon[data-v-cf11d7a2] {
  margin-right: 0px;
  font-size: 16px;
}
.text-icon[data-v-cf11d7a2] {
  margin-left: 4px;
  font-size: 14px;
}
.icon[data-v-cf11d7a2] {
  font-size: 20px;
  transition: fill 0.25s;
}
.menu[data-v-cf11d7a2] {
  position: absolute;
  top: calc(var(--vp-nav-height) / 2 + 20px);
  right: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s, visibility 0.25s, transform 0.25s;
}

.VPSocialLink[data-v-bd121fe5] {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 36px;
  height: 36px;
  color: var(--vp-c-text-2);
  transition: color 0.5s;
}
.VPSocialLink[data-v-bd121fe5]:hover {
  color: var(--vp-c-text-1);
  transition: color 0.25s;
}
.VPSocialLink[data-v-bd121fe5] >  svg,
.VPSocialLink[data-v-bd121fe5] >  [class^="vpi-social-"] {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.VPSocialLinks[data-v-7bc22406] {
  display: flex;
  justify-content: center;
}

.VPNavBarExtra[data-v-bb2aa2f0] {
  display: none;
  margin-right: -12px;
}
@media (min-width: 768px) {
.VPNavBarExtra[data-v-bb2aa2f0] {
    display: block;
}
}
@media (min-width: 1280px) {
.VPNavBarExtra[data-v-bb2aa2f0] {
    display: none;
}
}
.trans-title[data-v-bb2aa2f0] {
  padding: 0 24px 0 12px;
  line-height: 32px;
  font-size: 14px;
  font-weight: 700;
  color: var(--vp-c-text-1);
}
.item.appearance[data-v-bb2aa2f0],
.item.social-links[data-v-bb2aa2f0] {
  display: flex;
  align-items: center;
  padding: 0 12px;
}
.item.appearance[data-v-bb2aa2f0] {
  min-width: 176px;
}
.appearance-action[data-v-bb2aa2f0] {
  margin-right: -2px;
}
.social-links-list[data-v-bb2aa2f0] {
  margin: -4px -8px;
}

.VPNavBarHamburger[data-v-e5dd9c1c] {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 48px;
  height: var(--vp-nav-height);
}
@media (min-width: 768px) {
.VPNavBarHamburger[data-v-e5dd9c1c] {
    display: none;
}
}
.container[data-v-e5dd9c1c] {
  position: relative;
  width: 16px;
  height: 14px;
  overflow: hidden;
}
.VPNavBarHamburger:hover .top[data-v-e5dd9c1c]    { top: 0; left: 0; transform: translateX(4px);
}
.VPNavBarHamburger:hover .middle[data-v-e5dd9c1c] { top: 6px; left: 0; transform: translateX(0);
}
.VPNavBarHamburger:hover .bottom[data-v-e5dd9c1c] { top: 12px; left: 0; transform: translateX(8px);
}
.VPNavBarHamburger.active .top[data-v-e5dd9c1c]    { top: 6px; transform: translateX(0) rotate(225deg);
}
.VPNavBarHamburger.active .middle[data-v-e5dd9c1c] { top: 6px; transform: translateX(16px);
}
.VPNavBarHamburger.active .bottom[data-v-e5dd9c1c] { top: 6px; transform: translateX(0) rotate(135deg);
}
.VPNavBarHamburger.active:hover .top[data-v-e5dd9c1c],
.VPNavBarHamburger.active:hover .middle[data-v-e5dd9c1c],
.VPNavBarHamburger.active:hover .bottom[data-v-e5dd9c1c] {
  background-color: var(--vp-c-text-2);
  transition: top .25s, background-color .25s, transform .25s;
}
.top[data-v-e5dd9c1c],
.middle[data-v-e5dd9c1c],
.bottom[data-v-e5dd9c1c] {
  position: absolute;
  width: 16px;
  height: 2px;
  background-color: var(--vp-c-text-1);
  transition: top .25s, background-color .5s, transform .25s;
}
.top[data-v-e5dd9c1c]    { top: 0; left: 0; transform: translateX(0);
}
.middle[data-v-e5dd9c1c] { top: 6px; left: 0; transform: translateX(8px);
}
.bottom[data-v-e5dd9c1c] { top: 12px; left: 0; transform: translateX(4px);
}

.VPNavBarMenuLink[data-v-e56f3d57] {
  display: flex;
  align-items: center;
  padding: 0 12px;
  line-height: var(--vp-nav-height);
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-text-1);
  transition: color 0.25s;
}
.VPNavBarMenuLink.active[data-v-e56f3d57] {
  color: var(--vp-c-brand-1);
}
.VPNavBarMenuLink[data-v-e56f3d57]:hover {
  color: var(--vp-c-brand-1);
}

.VPNavBarMenu[data-v-dc692963] {
  display: none;
}
@media (min-width: 768px) {
.VPNavBarMenu[data-v-dc692963] {
    display: flex;
}
}
/*! @docsearch/css 3.8.2 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */
:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 #0304094d;--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 2px;position:relative;top:-1px;width:20px}.DocSearch-Button-Key--pressed{box-shadow:var(--docsearch-key-pressed-shadow);transform:translate3d(0,1px,0)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:rgba(0,0,0,.2);transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:rgba(0,0,0,.2);transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:2px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}
[class*='DocSearch'] {
  --docsearch-primary-color: var(--vp-c-brand-1);
  --docsearch-highlight-color: var(--docsearch-primary-color);
  --docsearch-text-color: var(--vp-c-text-1);
  --docsearch-muted-color: var(--vp-c-text-2);
  --docsearch-searchbox-shadow: none;
  --docsearch-searchbox-background: transparent;
  --docsearch-searchbox-focus-background: transparent;
  --docsearch-key-gradient: transparent;
  --docsearch-key-shadow: none;
  --docsearch-modal-background: var(--vp-c-bg-soft);
  --docsearch-footer-background: var(--vp-c-bg);
}
.dark [class*='DocSearch'] {
  --docsearch-modal-shadow: none;
  --docsearch-footer-shadow: none;
  --docsearch-logo-color: var(--vp-c-text-2);
  --docsearch-hit-background: var(--vp-c-default-soft);
  --docsearch-hit-color: var(--vp-c-text-2);
  --docsearch-hit-shadow: none;
}
.DocSearch-Button {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0;
  padding: 0;
  width: 48px;
  height: 55px;
  background: transparent;
  transition: border-color 0.25s;
}
.DocSearch-Button:hover {
  background: transparent;
}
.DocSearch-Button:focus {
  outline: 1px dotted;
  outline: 5px auto -webkit-focus-ring-color;
}
.DocSearch-Button-Key--pressed {
  transform: none;
  box-shadow: none;
}
.DocSearch-Button:focus:not(:focus-visible) {
  outline: none !important;
}
@media (min-width: 768px) {
.DocSearch-Button {
    justify-content: flex-start;
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 0 10px 0 12px;
    width: 100%;
    height: 40px;
    background-color: var(--vp-c-bg-alt);
}
.DocSearch-Button:hover {
    border-color: var(--vp-c-brand-1);
    background: var(--vp-c-bg-alt);
}
}
.DocSearch-Button .DocSearch-Button-Container {
  display: flex;
  align-items: center;
}
.DocSearch-Button .DocSearch-Search-Icon {
  position: relative;
  width: 16px;
  height: 16px;
  color: var(--vp-c-text-1);
  fill: currentColor;
  transition: color 0.5s;
}
.DocSearch-Button:hover .DocSearch-Search-Icon {
  color: var(--vp-c-text-1);
}
@media (min-width: 768px) {
.DocSearch-Button .DocSearch-Search-Icon {
    top: 1px;
    margin-right: 8px;
    width: 14px;
    height: 14px;
    color: var(--vp-c-text-2);
}
}
.DocSearch-Button .DocSearch-Button-Placeholder {
  display: none;
  margin-top: 2px;
  padding: 0 16px 0 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--vp-c-text-2);
  transition: color 0.5s;
}
.DocSearch-Button:hover .DocSearch-Button-Placeholder {
  color: var(--vp-c-text-1);
}
@media (min-width: 768px) {
.DocSearch-Button .DocSearch-Button-Placeholder {
    display: inline-block;
}
}
.DocSearch-Button .DocSearch-Button-Keys {
  /*rtl:ignore*/
  direction: ltr;
  display: none;
  min-width: auto;
}
@media (min-width: 768px) {
.DocSearch-Button .DocSearch-Button-Keys {
    display: flex;
    align-items: center;
}
}
.DocSearch-Button .DocSearch-Button-Key {
  display: block;
  margin: 2px 0 0 0;
  border: 1px solid var(--vp-c-divider);
  /*rtl:begin:ignore*/
  border-right: none;
  border-radius: 4px 0 0 4px;
  padding-left: 6px;
  /*rtl:end:ignore*/
  min-width: 0;
  width: auto;
  height: 22px;
  line-height: 22px;
  font-family: var(--vp-font-family-base);
  font-size: 12px;
  font-weight: 500;
  transition: color 0.5s, border-color 0.5s;
}
.DocSearch-Button .DocSearch-Button-Key + .DocSearch-Button-Key {
  /*rtl:begin:ignore*/
  border-right: 1px solid var(--vp-c-divider);
  border-left: none;
  border-radius: 0 4px 4px 0;
  padding-left: 2px;
  padding-right: 6px;
  /*rtl:end:ignore*/
}
.DocSearch-Button .DocSearch-Button-Key:first-child {
  font-size: 0 !important;
}
.DocSearch-Button .DocSearch-Button-Key:first-child:after {
  content: 'Ctrl';
  font-size: 12px;
  letter-spacing: normal;
  color: var(--docsearch-muted-color);
}
.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after {
  content: '\2318';
}
.DocSearch-Button .DocSearch-Button-Key:first-child > * {
  display: none;
}
.DocSearch-Search-Icon {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke-width='1.6' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='m14.386 14.386 4.088 4.088-4.088-4.088A7.533 7.533 0 1 1 3.733 3.733a7.533 7.533 0 0 1 10.653 10.653z'/%3E%3C/svg%3E");
}

.VPNavBarSearch {
  display: flex;
  align-items: center;
}
@media (min-width: 768px) {
.VPNavBarSearch {
    flex-grow: 1;
    padding-left: 24px;
}
}
@media (min-width: 960px) {
.VPNavBarSearch {
    padding-left: 32px;
}
}
.dark .DocSearch-Footer {
  border-top: 1px solid var(--vp-c-divider);
}
.DocSearch-Form {
  border: 1px solid var(--vp-c-brand-1);
  background-color: var(--vp-c-white);
}
.dark .DocSearch-Form {
  background-color: var(--vp-c-default-soft);
}
.DocSearch-Screen-Icon > svg {
  margin: auto;
}

.VPNavBarSocialLinks[data-v-0394ad82] {
  display: none;
}
@media (min-width: 1280px) {
.VPNavBarSocialLinks[data-v-0394ad82] {
    display: flex;
    align-items: center;
}
}

.title[data-v-1168a8e4] {
  display: flex;
  align-items: center;
  border-bottom: 1px solid transparent;
  width: 100%;
  height: var(--vp-nav-height);
  font-size: 16px;
  font-weight: 600;
  color: var(--vp-c-text-1);
  transition: opacity 0.25s;
}
@media (min-width: 960px) {
.title[data-v-1168a8e4] {
    flex-shrink: 0;
}
.VPNavBarTitle.has-sidebar .title[data-v-1168a8e4] {
    border-bottom-color: var(--vp-c-divider);
}
}
[data-v-1168a8e4] .logo {
  margin-right: 8px;
  height: var(--vp-nav-logo-height);
}

.VPNavBarTranslations[data-v-88af2de4] {
  display: none;
}
@media (min-width: 1280px) {
.VPNavBarTranslations[data-v-88af2de4] {
    display: flex;
    align-items: center;
}
}
.title[data-v-88af2de4] {
  padding: 0 24px 0 12px;
  line-height: 32px;
  font-size: 14px;
  font-weight: 700;
  color: var(--vp-c-text-1);
}

.VPNavBar[data-v-6aa21345] {
  position: relative;
  height: var(--vp-nav-height);
  pointer-events: none;
  white-space: nowrap;
  transition: background-color 0.25s;
}
.VPNavBar.screen-open[data-v-6aa21345] {
  transition: none;
  background-color: var(--vp-nav-bg-color);
  border-bottom: 1px solid var(--vp-c-divider);
}
.VPNavBar[data-v-6aa21345]:not(.home) {
  background-color: var(--vp-nav-bg-color);
}
@media (min-width: 960px) {
.VPNavBar[data-v-6aa21345]:not(.home) {
    background-color: transparent;
}
.VPNavBar[data-v-6aa21345]:not(.has-sidebar):not(.home.top) {
    background-color: var(--vp-nav-bg-color);
}
}
.wrapper[data-v-6aa21345] {
  padding: 0 8px 0 24px;
}
@media (min-width: 768px) {
.wrapper[data-v-6aa21345] {
    padding: 0 32px;
}
}
@media (min-width: 960px) {
.VPNavBar.has-sidebar .wrapper[data-v-6aa21345] {
    padding: 0;
}
}
.container[data-v-6aa21345] {
  display: flex;
  justify-content: space-between;
  margin: 0 auto;
  max-width: calc(var(--vp-layout-max-width) - 64px);
  height: var(--vp-nav-height);
  pointer-events: none;
}
.container > .title[data-v-6aa21345],
.container > .content[data-v-6aa21345] {
  pointer-events: none;
}
.container[data-v-6aa21345] * {
  pointer-events: auto;
}
@media (min-width: 960px) {
.VPNavBar.has-sidebar .container[data-v-6aa21345] {
    max-width: 100%;
}
}
.title[data-v-6aa21345] {
  flex-shrink: 0;
  height: calc(var(--vp-nav-height) - 1px);
  transition: background-color 0.5s;
}
@media (min-width: 960px) {
.VPNavBar.has-sidebar .title[data-v-6aa21345] {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    padding: 0 32px;
    width: var(--vp-sidebar-width);
    height: var(--vp-nav-height);
    background-color: transparent;
}
}
@media (min-width: 1440px) {
.VPNavBar.has-sidebar .title[data-v-6aa21345] {
    padding-left: max(32px, calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));
    width: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px);
}
}
.content[data-v-6aa21345] {
  flex-grow: 1;
}
@media (min-width: 960px) {
.VPNavBar.has-sidebar .content[data-v-6aa21345] {
    position: relative;
    z-index: 1;
    padding-right: 32px;
    padding-left: var(--vp-sidebar-width);
}
}
@media (min-width: 1440px) {
.VPNavBar.has-sidebar .content[data-v-6aa21345] {
    padding-right: calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);
    padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width));
}
}
.content-body[data-v-6aa21345] {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  height: var(--vp-nav-height);
  transition: background-color 0.5s;
}
@media (min-width: 960px) {
.VPNavBar:not(.home.top) .content-body[data-v-6aa21345] {
    position: relative;
    background-color: var(--vp-nav-bg-color);
}
.VPNavBar:not(.has-sidebar):not(.home.top) .content-body[data-v-6aa21345] {
    background-color: transparent;
}
}
@media (max-width: 767px) {
.content-body[data-v-6aa21345] {
    column-gap: 0.5rem;
}
}
.menu + .translations[data-v-6aa21345]::before,
.menu + .appearance[data-v-6aa21345]::before,
.menu + .social-links[data-v-6aa21345]::before,
.translations + .appearance[data-v-6aa21345]::before,
.appearance + .social-links[data-v-6aa21345]::before {
  margin-right: 8px;
  margin-left: 8px;
  width: 1px;
  height: 24px;
  background-color: var(--vp-c-divider);
  content: "";
}
.menu + .appearance[data-v-6aa21345]::before,
.translations + .appearance[data-v-6aa21345]::before {
  margin-right: 16px;
}
.appearance + .social-links[data-v-6aa21345]::before {
  margin-left: 16px;
}
.social-links[data-v-6aa21345] {
  margin-right: -8px;
}
.divider[data-v-6aa21345] {
  width: 100%;
  height: 1px;
}
@media (min-width: 960px) {
.VPNavBar.has-sidebar .divider[data-v-6aa21345] {
    padding-left: var(--vp-sidebar-width);
}
}
@media (min-width: 1440px) {
.VPNavBar.has-sidebar .divider[data-v-6aa21345] {
    padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width));
}
}
.divider-line[data-v-6aa21345] {
  width: 100%;
  height: 1px;
  transition: background-color 0.5s;
}
.VPNavBar:not(.home) .divider-line[data-v-6aa21345] {
  background-color: var(--vp-c-gutter);
}
@media (min-width: 960px) {
.VPNavBar:not(.home.top) .divider-line[data-v-6aa21345] {
    background-color: var(--vp-c-gutter);
}
.VPNavBar:not(.has-sidebar):not(.home.top) .divider[data-v-6aa21345] {
    background-color: var(--vp-c-gutter);
}
}

.VPNavScreenAppearance[data-v-b44890b2] {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-radius: 8px;
  padding: 12px 14px 12px 16px;
  background-color: var(--vp-c-bg-soft);
}
.text[data-v-b44890b2] {
  line-height: 24px;
  font-size: 12px;
  font-weight: 500;
  color: var(--vp-c-text-2);
}

.VPNavScreenMenuLink[data-v-df37e6dd] {
  display: block;
  border-bottom: 1px solid var(--vp-c-divider);
  padding: 12px 0 11px;
  line-height: 24px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-text-1);
  transition:
    border-color 0.25s,
    color 0.25s;
}
.VPNavScreenMenuLink[data-v-df37e6dd]:hover {
  color: var(--vp-c-brand-1);
}

.VPNavScreenMenuGroupLink[data-v-3e9c20e4] {
  display: block;
  margin-left: 12px;
  line-height: 32px;
  font-size: 14px;
  font-weight: 400;
  color: var(--vp-c-text-1);
  transition: color 0.25s;
}
.VPNavScreenMenuGroupLink[data-v-3e9c20e4]:hover {
  color: var(--vp-c-brand-1);
}

.VPNavScreenMenuGroupSection[data-v-8133b170] {
  display: block;
}
.title[data-v-8133b170] {
  line-height: 32px;
  font-size: 13px;
  font-weight: 700;
  color: var(--vp-c-text-2);
  transition: color 0.25s;
}

.VPNavScreenMenuGroup[data-v-b9ab8c58] {
  border-bottom: 1px solid var(--vp-c-divider);
  height: 48px;
  overflow: hidden;
  transition: border-color 0.5s;
}
.VPNavScreenMenuGroup .items[data-v-b9ab8c58] {
  visibility: hidden;
}
.VPNavScreenMenuGroup.open .items[data-v-b9ab8c58] {
  visibility: visible;
}
.VPNavScreenMenuGroup.open[data-v-b9ab8c58] {
  padding-bottom: 10px;
  height: auto;
}
.VPNavScreenMenuGroup.open .button[data-v-b9ab8c58] {
  padding-bottom: 6px;
  color: var(--vp-c-brand-1);
}
.VPNavScreenMenuGroup.open .button-icon[data-v-b9ab8c58] {
  /*rtl:ignore*/
  transform: rotate(45deg);
}
.button[data-v-b9ab8c58] {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 4px 11px 0;
  width: 100%;
  line-height: 24px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-text-1);
  transition: color 0.25s;
}
.button[data-v-b9ab8c58]:hover {
  color: var(--vp-c-brand-1);
}
.button-icon[data-v-b9ab8c58] {
  transition: transform 0.25s;
}
.group[data-v-b9ab8c58]:first-child {
  padding-top: 0px;
}
.group + .group[data-v-b9ab8c58],
.group + .item[data-v-b9ab8c58] {
  padding-top: 4px;
}

.VPNavScreenTranslations[data-v-858fe1a4] {
  height: 24px;
  overflow: hidden;
}
.VPNavScreenTranslations.open[data-v-858fe1a4] {
  height: auto;
}
.title[data-v-858fe1a4] {
  display: flex;
  align-items: center;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-text-1);
}
.icon[data-v-858fe1a4] {
  font-size: 16px;
}
.icon.lang[data-v-858fe1a4] {
  margin-right: 8px;
}
.icon.chevron[data-v-858fe1a4] {
  margin-left: 4px;
}
.list[data-v-858fe1a4] {
  padding: 4px 0 0 24px;
}
.link[data-v-858fe1a4] {
  line-height: 32px;
  font-size: 13px;
  color: var(--vp-c-text-1);
}

.VPNavScreen[data-v-f2779853] {
  position: fixed;
  top: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px));
  /*rtl:ignore*/
  right: 0;
  bottom: 0;
  /*rtl:ignore*/
  left: 0;
  padding: 0 32px;
  width: 100%;
  background-color: var(--vp-nav-screen-bg-color);
  overflow-y: auto;
  transition: background-color 0.25s;
  pointer-events: auto;
}
.VPNavScreen.fade-enter-active[data-v-f2779853],
.VPNavScreen.fade-leave-active[data-v-f2779853] {
  transition: opacity 0.25s;
}
.VPNavScreen.fade-enter-active .container[data-v-f2779853],
.VPNavScreen.fade-leave-active .container[data-v-f2779853] {
  transition: transform 0.25s ease;
}
.VPNavScreen.fade-enter-from[data-v-f2779853],
.VPNavScreen.fade-leave-to[data-v-f2779853] {
  opacity: 0;
}
.VPNavScreen.fade-enter-from .container[data-v-f2779853],
.VPNavScreen.fade-leave-to .container[data-v-f2779853] {
  transform: translateY(-8px);
}
@media (min-width: 768px) {
.VPNavScreen[data-v-f2779853] {
    display: none;
}
}
.container[data-v-f2779853] {
  margin: 0 auto;
  padding: 24px 0 96px;
  max-width: 288px;
}
.menu + .translations[data-v-f2779853],
.menu + .appearance[data-v-f2779853],
.translations + .appearance[data-v-f2779853] {
  margin-top: 24px;
}
.menu + .social-links[data-v-f2779853] {
  margin-top: 16px;
}
.appearance + .social-links[data-v-f2779853] {
  margin-top: 16px;
}

.VPNav[data-v-ae24b3ad] {
  position: relative;
  top: var(--vp-layout-top-height, 0px);
  /*rtl:ignore*/
  left: 0;
  z-index: var(--vp-z-index-nav);
  width: 100%;
  pointer-events: none;
  transition: background-color 0.5s;
}
@media (min-width: 960px) {
.VPNav[data-v-ae24b3ad] {
    position: fixed;
}
}

.VPSidebarItem.level-0[data-v-b3fd67f8] {
  padding-bottom: 24px;
}
.VPSidebarItem.collapsed.level-0[data-v-b3fd67f8] {
  padding-bottom: 10px;
}
.item[data-v-b3fd67f8] {
  position: relative;
  display: flex;
  width: 100%;
}
.VPSidebarItem.collapsible > .item[data-v-b3fd67f8] {
  cursor: pointer;
}
.indicator[data-v-b3fd67f8] {
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: -17px;
  width: 2px;
  border-radius: 2px;
  transition: background-color 0.25s;
}
.VPSidebarItem.level-2.is-active > .item > .indicator[data-v-b3fd67f8],
.VPSidebarItem.level-3.is-active > .item > .indicator[data-v-b3fd67f8],
.VPSidebarItem.level-4.is-active > .item > .indicator[data-v-b3fd67f8],
.VPSidebarItem.level-5.is-active > .item > .indicator[data-v-b3fd67f8] {
  background-color: var(--vp-c-brand-1);
}
.link[data-v-b3fd67f8] {
  display: flex;
  align-items: center;
  flex-grow: 1;
}
.text[data-v-b3fd67f8] {
  flex-grow: 1;
  padding: 4px 0;
  line-height: 24px;
  font-size: 14px;
  transition: color 0.25s;
}
.VPSidebarItem.level-0 .text[data-v-b3fd67f8] {
  font-weight: 700;
  color: var(--vp-c-text-1);
}
.VPSidebarItem.level-1 .text[data-v-b3fd67f8],
.VPSidebarItem.level-2 .text[data-v-b3fd67f8],
.VPSidebarItem.level-3 .text[data-v-b3fd67f8],
.VPSidebarItem.level-4 .text[data-v-b3fd67f8],
.VPSidebarItem.level-5 .text[data-v-b3fd67f8] {
  font-weight: 500;
  color: var(--vp-c-text-2);
}
.VPSidebarItem.level-0.is-link > .item > .link:hover .text[data-v-b3fd67f8],
.VPSidebarItem.level-1.is-link > .item > .link:hover .text[data-v-b3fd67f8],
.VPSidebarItem.level-2.is-link > .item > .link:hover .text[data-v-b3fd67f8],
.VPSidebarItem.level-3.is-link > .item > .link:hover .text[data-v-b3fd67f8],
.VPSidebarItem.level-4.is-link > .item > .link:hover .text[data-v-b3fd67f8],
.VPSidebarItem.level-5.is-link > .item > .link:hover .text[data-v-b3fd67f8] {
  color: var(--vp-c-brand-1);
}
.VPSidebarItem.level-0.has-active > .item > .text[data-v-b3fd67f8],
.VPSidebarItem.level-1.has-active > .item > .text[data-v-b3fd67f8],
.VPSidebarItem.level-2.has-active > .item > .text[data-v-b3fd67f8],
.VPSidebarItem.level-3.has-active > .item > .text[data-v-b3fd67f8],
.VPSidebarItem.level-4.has-active > .item > .text[data-v-b3fd67f8],
.VPSidebarItem.level-5.has-active > .item > .text[data-v-b3fd67f8],
.VPSidebarItem.level-0.has-active > .item > .link > .text[data-v-b3fd67f8],
.VPSidebarItem.level-1.has-active > .item > .link > .text[data-v-b3fd67f8],
.VPSidebarItem.level-2.has-active > .item > .link > .text[data-v-b3fd67f8],
.VPSidebarItem.level-3.has-active > .item > .link > .text[data-v-b3fd67f8],
.VPSidebarItem.level-4.has-active > .item > .link > .text[data-v-b3fd67f8],
.VPSidebarItem.level-5.has-active > .item > .link > .text[data-v-b3fd67f8] {
  color: var(--vp-c-text-1);
}
.VPSidebarItem.level-0.is-active > .item .link > .text[data-v-b3fd67f8],
.VPSidebarItem.level-1.is-active > .item .link > .text[data-v-b3fd67f8],
.VPSidebarItem.level-2.is-active > .item .link > .text[data-v-b3fd67f8],
.VPSidebarItem.level-3.is-active > .item .link > .text[data-v-b3fd67f8],
.VPSidebarItem.level-4.is-active > .item .link > .text[data-v-b3fd67f8],
.VPSidebarItem.level-5.is-active > .item .link > .text[data-v-b3fd67f8] {
  color: var(--vp-c-brand-1);
}
.caret[data-v-b3fd67f8] {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-right: -7px;
  width: 32px;
  height: 32px;
  color: var(--vp-c-text-3);
  cursor: pointer;
  transition: color 0.25s;
  flex-shrink: 0;
}
.item:hover .caret[data-v-b3fd67f8] {
  color: var(--vp-c-text-2);
}
.item:hover .caret[data-v-b3fd67f8]:hover {
  color: var(--vp-c-text-1);
}
.caret-icon[data-v-b3fd67f8] {
  font-size: 18px;
  /*rtl:ignore*/
  transform: rotate(90deg);
  transition: transform 0.25s;
}
.VPSidebarItem.collapsed .caret-icon[data-v-b3fd67f8] {
  transform: rotate(0)/*rtl:rotate(180deg)*/;
}
.VPSidebarItem.level-1 .items[data-v-b3fd67f8],
.VPSidebarItem.level-2 .items[data-v-b3fd67f8],
.VPSidebarItem.level-3 .items[data-v-b3fd67f8],
.VPSidebarItem.level-4 .items[data-v-b3fd67f8],
.VPSidebarItem.level-5 .items[data-v-b3fd67f8] {
  border-left: 1px solid var(--vp-c-divider);
  padding-left: 16px;
}
.VPSidebarItem.collapsed .items[data-v-b3fd67f8] {
  display: none;
}

.no-transition[data-v-c40bc020] .caret-icon {
  transition: none;
}
.group + .group[data-v-c40bc020] {
  border-top: 1px solid var(--vp-c-divider);
  padding-top: 10px;
}
@media (min-width: 960px) {
.group[data-v-c40bc020] {
    padding-top: 10px;
    width: calc(var(--vp-sidebar-width) - 64px);
}
}

.VPSidebar[data-v-319d5ca6] {
  position: fixed;
  top: var(--vp-layout-top-height, 0px);
  bottom: 0;
  left: 0;
  z-index: var(--vp-z-index-sidebar);
  padding: 32px 32px 96px;
  width: calc(100vw - 64px);
  max-width: 320px;
  background-color: var(--vp-sidebar-bg-color);
  opacity: 0;
  box-shadow: var(--vp-c-shadow-3);
  overflow-x: hidden;
  overflow-y: auto;
  transform: translateX(-100%);
  transition: opacity 0.5s, transform 0.25s ease;
  overscroll-behavior: contain;
}
.VPSidebar.open[data-v-319d5ca6] {
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
  transition: opacity 0.25s,
    transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
}
.dark .VPSidebar[data-v-319d5ca6] {
  box-shadow: var(--vp-shadow-1);
}
@media (min-width: 960px) {
.VPSidebar[data-v-319d5ca6] {
    padding-top: var(--vp-nav-height);
    width: var(--vp-sidebar-width);
    max-width: 100%;
    background-color: var(--vp-sidebar-bg-color);
    opacity: 1;
    visibility: visible;
    box-shadow: none;
    transform: translateX(0);
}
}
@media (min-width: 1440px) {
.VPSidebar[data-v-319d5ca6] {
    padding-left: max(32px, calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));
    width: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px);
}
}
@media (min-width: 960px) {
.curtain[data-v-319d5ca6] {
    position: sticky;
    top: -64px;
    left: 0;
    z-index: 1;
    margin-top: calc(var(--vp-nav-height) * -1);
    margin-right: -32px;
    margin-left: -32px;
    height: var(--vp-nav-height);
    background-color: var(--vp-sidebar-bg-color);
}
}
.nav[data-v-319d5ca6] {
  outline: 0;
}

.VPSkipLink[data-v-0b0ada53] {
  top: 8px;
  left: 8px;
  padding: 8px 16px;
  z-index: 999;
  border-radius: 8px;
  font-size: 12px;
  font-weight: bold;
  text-decoration: none;
  color: var(--vp-c-brand-1);
  box-shadow: var(--vp-shadow-3);
  background-color: var(--vp-c-bg);
}
.VPSkipLink[data-v-0b0ada53]:focus {
  height: auto;
  width: auto;
  clip: auto;
  clip-path: none;
}
@media (min-width: 1280px) {
.VPSkipLink[data-v-0b0ada53] {
    top: 14px;
    left: 16px;
}
}

.Layout[data-v-5d98c3a5] {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.VPHomeSponsors[data-v-3d121b4a] {
  border-top: 1px solid var(--vp-c-gutter);
  padding-top: 88px !important;
}
.VPHomeSponsors[data-v-3d121b4a] {
  margin: 96px 0;
}
@media (min-width: 768px) {
.VPHomeSponsors[data-v-3d121b4a] {
    margin: 128px 0;
}
}
.VPHomeSponsors[data-v-3d121b4a] {
  padding: 0 24px;
}
@media (min-width: 768px) {
.VPHomeSponsors[data-v-3d121b4a] {
    padding: 0 48px;
}
}
@media (min-width: 960px) {
.VPHomeSponsors[data-v-3d121b4a] {
    padding: 0 64px;
}
}
.container[data-v-3d121b4a] {
  margin: 0 auto;
  max-width: 1152px;
}
.love[data-v-3d121b4a] {
  margin: 0 auto;
  width: fit-content;
  font-size: 28px;
  color: var(--vp-c-text-3);
}
.icon[data-v-3d121b4a] {
  display: inline-block;
}
.message[data-v-3d121b4a] {
  margin: 0 auto;
  padding-top: 10px;
  max-width: 320px;
  text-align: center;
  line-height: 24px;
  font-size: 16px;
  font-weight: 500;
  color: var(--vp-c-text-2);
}
.sponsors[data-v-3d121b4a] {
  padding-top: 32px;
}
.action[data-v-3d121b4a] {
  padding-top: 40px;
  text-align: center;
}

.VPTeamMembersItem[data-v-f3fa364a] {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-radius: 12px;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.VPTeamMembersItem.small .profile[data-v-f3fa364a] {
  padding: 32px;
}
.VPTeamMembersItem.small .data[data-v-f3fa364a] {
  padding-top: 20px;
}
.VPTeamMembersItem.small .avatar[data-v-f3fa364a] {
  width: 64px;
  height: 64px;
}
.VPTeamMembersItem.small .name[data-v-f3fa364a] {
  line-height: 24px;
  font-size: 16px;
}
.VPTeamMembersItem.small .affiliation[data-v-f3fa364a] {
  padding-top: 4px;
  line-height: 20px;
  font-size: 14px;
}
.VPTeamMembersItem.small .desc[data-v-f3fa364a] {
  padding-top: 12px;
  line-height: 20px;
  font-size: 14px;
}
.VPTeamMembersItem.small .links[data-v-f3fa364a] {
  margin: 0 -16px -20px;
  padding: 10px 0 0;
}
.VPTeamMembersItem.medium .profile[data-v-f3fa364a] {
  padding: 48px 32px;
}
.VPTeamMembersItem.medium .data[data-v-f3fa364a] {
  padding-top: 24px;
  text-align: center;
}
.VPTeamMembersItem.medium .avatar[data-v-f3fa364a] {
  width: 96px;
  height: 96px;
}
.VPTeamMembersItem.medium .name[data-v-f3fa364a] {
  letter-spacing: 0.15px;
  line-height: 28px;
  font-size: 20px;
}
.VPTeamMembersItem.medium .affiliation[data-v-f3fa364a] {
  padding-top: 4px;
  font-size: 16px;
}
.VPTeamMembersItem.medium .desc[data-v-f3fa364a] {
  padding-top: 16px;
  max-width: 288px;
  font-size: 16px;
}
.VPTeamMembersItem.medium .links[data-v-f3fa364a] {
  margin: 0 -16px -12px;
  padding: 16px 12px 0;
}
.profile[data-v-f3fa364a] {
  flex-grow: 1;
  background-color: var(--vp-c-bg-soft);
}
.data[data-v-f3fa364a] {
  text-align: center;
}
.avatar[data-v-f3fa364a] {
  position: relative;
  flex-shrink: 0;
  margin: 0 auto;
  border-radius: 50%;
  box-shadow: var(--vp-shadow-3);
}
.avatar-img[data-v-f3fa364a] {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  border-radius: 50%;
  object-fit: cover;
}
.name[data-v-f3fa364a] {
  margin: 0;
  font-weight: 600;
}
.affiliation[data-v-f3fa364a] {
  margin: 0;
  font-weight: 500;
  color: var(--vp-c-text-2);
}
.org.link[data-v-f3fa364a] {
  color: var(--vp-c-text-2);
  transition: color 0.25s;
}
.org.link[data-v-f3fa364a]:hover {
  color: var(--vp-c-brand-1);
}
.desc[data-v-f3fa364a] {
  margin: 0 auto;
}
.desc[data-v-f3fa364a] a {
  font-weight: 500;
  color: var(--vp-c-brand-1);
  text-decoration-style: dotted;
  transition: color 0.25s;
}
.links[data-v-f3fa364a] {
  display: flex;
  justify-content: center;
  height: 56px;
}
.sp-link[data-v-f3fa364a] {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 16px;
  font-size: 14px;
  font-weight: 500;
  color: var(--vp-c-sponsor);
  background-color: var(--vp-c-bg-soft);
  transition: color 0.25s, background-color 0.25s;
}
.sp .sp-link.link[data-v-f3fa364a]:hover,
.sp .sp-link.link[data-v-f3fa364a]:focus {
  outline: none;
  color: var(--vp-c-white);
  background-color: var(--vp-c-sponsor);
}
.sp-icon[data-v-f3fa364a] {
  margin-right: 8px;
  font-size: 16px;
}

.VPTeamMembers.small .container[data-v-6cb0dbc4] {
  grid-template-columns: repeat(auto-fit, minmax(224px, 1fr));
}
.VPTeamMembers.small.count-1 .container[data-v-6cb0dbc4] {
  max-width: 276px;
}
.VPTeamMembers.small.count-2 .container[data-v-6cb0dbc4] {
  max-width: calc(276px * 2 + 24px);
}
.VPTeamMembers.small.count-3 .container[data-v-6cb0dbc4] {
  max-width: calc(276px * 3 + 24px * 2);
}
.VPTeamMembers.medium .container[data-v-6cb0dbc4] {
  grid-template-columns: repeat(auto-fit, minmax(256px, 1fr));
}
@media (min-width: 375px) {
.VPTeamMembers.medium .container[data-v-6cb0dbc4] {
    grid-template-columns: repeat(auto-fit, minmax(288px, 1fr));
}
}
.VPTeamMembers.medium.count-1 .container[data-v-6cb0dbc4] {
  max-width: 368px;
}
.VPTeamMembers.medium.count-2 .container[data-v-6cb0dbc4] {
  max-width: calc(368px * 2 + 24px);
}
.container[data-v-6cb0dbc4] {
  display: grid;
  gap: 24px;
  margin: 0 auto;
  max-width: 1152px;
}

.VPTeamPage[data-v-7c57f839] {
  margin: 96px 0;
}
@media (min-width: 768px) {
.VPTeamPage[data-v-7c57f839] {
    margin: 128px 0;
}
}
.VPHome .VPTeamPageTitle[data-v-7c57f839-s] {
  border-top: 1px solid var(--vp-c-gutter);
  padding-top: 88px !important;
}
.VPTeamPageSection + .VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers + .VPTeamPageSection[data-v-7c57f839-s] {
  margin-top: 64px;
}
.VPTeamMembers + .VPTeamMembers[data-v-7c57f839-s] {
  margin-top: 24px;
}
@media (min-width: 768px) {
.VPTeamPageTitle + .VPTeamPageSection[data-v-7c57f839-s] {
    margin-top: 16px;
}
.VPTeamPageSection + .VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers + .VPTeamPageSection[data-v-7c57f839-s] {
    margin-top: 96px;
}
}
.VPTeamMembers[data-v-7c57f839-s] {
  padding: 0 24px;
}
@media (min-width: 768px) {
.VPTeamMembers[data-v-7c57f839-s] {
    padding: 0 48px;
}
}
@media (min-width: 960px) {
.VPTeamMembers[data-v-7c57f839-s] {
    padding: 0 64px;
}
}

.VPTeamPageSection[data-v-b1a88750] {
  padding: 0 32px;
}
@media (min-width: 768px) {
.VPTeamPageSection[data-v-b1a88750] {
    padding: 0 48px;
}
}
@media (min-width: 960px) {
.VPTeamPageSection[data-v-b1a88750] {
    padding: 0 64px;
}
}
.title[data-v-b1a88750] {
  position: relative;
  margin: 0 auto;
  max-width: 1152px;
  text-align: center;
  color: var(--vp-c-text-2);
}
.title-line[data-v-b1a88750] {
  position: absolute;
  top: 16px;
  left: 0;
  width: 100%;
  height: 1px;
  background-color: var(--vp-c-divider);
}
.title-text[data-v-b1a88750] {
  position: relative;
  display: inline-block;
  padding: 0 24px;
  letter-spacing: 0;
  line-height: 32px;
  font-size: 20px;
  font-weight: 500;
  background-color: var(--vp-c-bg);
}
.lead[data-v-b1a88750] {
  margin: 0 auto;
  max-width: 480px;
  padding-top: 12px;
  text-align: center;
  line-height: 24px;
  font-size: 16px;
  font-weight: 500;
  color: var(--vp-c-text-2);
}
.members[data-v-b1a88750] {
  padding-top: 40px;
}

.VPTeamPageTitle[data-v-bf2cbdac] {
  padding: 48px 32px;
  text-align: center;
}
@media (min-width: 768px) {
.VPTeamPageTitle[data-v-bf2cbdac] {
    padding: 64px 48px 48px;
}
}
@media (min-width: 960px) {
.VPTeamPageTitle[data-v-bf2cbdac] {
    padding: 80px 64px 48px;
}
}
.title[data-v-bf2cbdac] {
  letter-spacing: 0;
  line-height: 44px;
  font-size: 36px;
  font-weight: 500;
}
@media (min-width: 768px) {
.title[data-v-bf2cbdac] {
    letter-spacing: -0.5px;
    line-height: 56px;
    font-size: 48px;
}
}
.lead[data-v-bf2cbdac] {
  margin: 0 auto;
  max-width: 512px;
  padding-top: 12px;
  line-height: 24px;
  font-size: 16px;
  font-weight: 500;
  color: var(--vp-c-text-2);
}
@media (min-width: 768px) {
.lead[data-v-bf2cbdac] {
    max-width: 592px;
    letter-spacing: 0.15px;
    line-height: 28px;
    font-size: 20px;
}
}

.nb-wrap[data-v-2dcf0da3] { position: relative; display: inline-flex; align-items: center; margin-right: 8px;
}
.nb-btn[data-v-2dcf0da3] {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 8px;
  background: transparent; border: 1px solid var(--vp-c-divider);
  color: var(--vp-c-text-2); cursor: pointer;
  transition: color .15s, border-color .15s;
}
.nb-btn[data-v-2dcf0da3]:hover { color: var(--vp-c-text-1); border-color: var(--vp-c-text-3);
}
.nb-dot[data-v-2dcf0da3] {
  position: absolute; top: -4px; right: -4px;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px;
  background: #ef4444; color: #fff;
  font-size: 10.5px; font-weight: 600; line-height: 16px;
  text-align: center; letter-spacing: 0;
}
.nb-panel[data-v-2dcf0da3] {
  position: absolute; top: 40px; right: 0;
  width: 320px; max-width: 92vw;
  background: var(--vp-c-bg, #fff);
  border: 1px solid var(--vp-c-divider);
  border-radius: 12px;
  box-shadow: var(--shadow-4);
  padding: 6px;
  z-index: 200;
}
.nb-head[data-v-2dcf0da3] {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 8px 10px 10px; border-bottom: 1px solid var(--vp-c-divider);
  margin-bottom: 4px;
}
.nb-head strong[data-v-2dcf0da3] { font-size: 14px; color: var(--vp-c-text-1);
}
.nb-hint[data-v-2dcf0da3] { font-size: 11.5px; color: var(--vp-c-text-3);
}
.nb-list[data-v-2dcf0da3] { max-height: 400px; overflow-y: auto;
}
.nb-empty[data-v-2dcf0da3] { padding: 24px 10px; text-align: center; color: var(--vp-c-text-3); font-size: 13px;
}
.nb-item[data-v-2dcf0da3] {
  padding: 10px 10px;
  border-radius: 8px;
  cursor: default;
}
.nb-item.clickable[data-v-2dcf0da3] { cursor: pointer;
}
.nb-item.clickable[data-v-2dcf0da3]:hover { background: var(--vp-c-bg-soft);
}
.nb-item.unread[data-v-2dcf0da3] { background: rgba(107, 158, 44, 0.08);
}
.nb-title[data-v-2dcf0da3] { font-size: 13.5px; font-weight: 600; color: var(--vp-c-text-1);
}
.nb-body[data-v-2dcf0da3] { font-size: 12.5px; color: var(--vp-c-text-2); margin-top: 2px; line-height: 1.5;
}
.nb-time[data-v-2dcf0da3] { font-size: 11px; color: var(--vp-c-text-3); margin-top: 4px;
}
.nb-fade-enter-active[data-v-2dcf0da3], .nb-fade-leave-active[data-v-2dcf0da3] {
  transition: opacity 0.15s, transform 0.15s;
}
.nb-fade-enter-from[data-v-2dcf0da3], .nb-fade-leave-to[data-v-2dcf0da3] { opacity: 0; transform: translateY(-4px);
}

.user-nav[data-v-bcb3dc5a] {
  display: flex;
  align-items: center;
  margin-left: 16px;
}
.login-btn[data-v-bcb3dc5a] {
  height: 34px;
  padding: 0 18px;
  border: none;
  border-radius: 8px;
  /* Match the home CTA: lemon-green fill needs dark ink text in both themes,
     not white — white on lemon fails contrast. */
  background: var(--accent-fill, #c4f857);
  color: var(--accent-ink, #0a0b0f);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s;
  letter-spacing: 0.02em;
}
.login-btn[data-v-bcb3dc5a]:hover {
  background: var(--accent-fill-hover, #d5ff7a);
}
.user-menu[data-v-bcb3dc5a] {
  position: relative;
  cursor: pointer;
}
.avatar[data-v-bcb3dc5a] {
  position: relative;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  /* Olive gradient always present so there's never an empty
     circle — the letter + gradient are the fallback, and the
     uploaded <img> sits on top when it loads. */
  background: linear-gradient(135deg, #6b9e2c, #5a8426);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 600;
  overflow: hidden;
}
.avatar-letter[data-v-bcb3dc5a] {
  /* Letter pill is always rendered underneath the img so if the
     image load fails (403 / network error) the reader sees the
     brand fallback, not an empty circle. */
  line-height: 1;
  user-select: none;
}
.avatar-img[data-v-bcb3dc5a] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.dropdown[data-v-bcb3dc5a] {
  position: absolute;
  top: 40px;
  right: 0;
  width: 200px;
  background: var(--vp-c-bg, #fff);
  border: 1px solid var(--vp-c-divider, #e2e8f0);
  border-radius: 12px;
  /* Popover tier — dropdowns, floating UI. Automatically picks
     up the dark variant via the token definition in :root. */
  box-shadow: var(--shadow-4);
  padding: 8px;
  z-index: 100;
}
.dark {
  /* Dark variant adds a subtle hairline so the dropdown has a
     defined edge against the near-black page; token handles
     depth. */
  box-shadow: var(--shadow-4), 0 0 0 1px rgba(148, 163, 184, 0.08);
}
.dropdown-header[data-v-bcb3dc5a] {
  padding: 8px 12px 12px;
  border-bottom: 1px solid var(--vp-c-divider, #e2e8f0);
  margin-bottom: 4px;
}
.dropdown-header strong[data-v-bcb3dc5a] {
  display: block;
  font-size: 14px;
  color: var(--vp-c-text-1, #0f172a);
}
.dropdown-header span[data-v-bcb3dc5a] {
  font-size: 12px;
  color: var(--vp-c-text-3, #94a3b8);
}
.learning-summary[data-v-bcb3dc5a] {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 4px;
  padding: 10px 6px;
  margin: 4px 0 6px;
  /* Brand olive / lemon wash — replaces the pre-brand
     indigo→blue gradient that didn't belong on an olive-green
     site. Low alpha keeps it as a subtle section separator, not
     a hero color field. */
  background: linear-gradient(135deg,
    rgba(107, 158, 44, 0.08),
    rgba(196, 248, 87, 0.08));
  border-radius: 8px;
}
.dark {
  background: linear-gradient(135deg,
    rgba(196, 248, 87, 0.07),
    rgba(107, 158, 44, 0.09));
}
.ls-cell[data-v-bcb3dc5a] {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  text-align: center;
  min-width: 0;
}
.ls-num[data-v-bcb3dc5a] {
  font-size: 15px;
  font-weight: 700;
  /* Brand olive on light, lemon on dark (via :global below).
     Pre-brand blue (#3b82f6) didn't match the rest of the
     avatar dropdown. */
  color: var(--vp-c-brand-1);
  line-height: 1.1;
  letter-spacing: -0.02em;
  white-space: nowrap;
  /* Tabular so bootstrap → live swap doesn't shift the three
     stat columns; they stay visually locked. */
  font-variant-numeric: tabular-nums;
}
.dark {
  color: #c4f857;
}
.ls-label[data-v-bcb3dc5a] {
  font-size: 10.5px;
  color: var(--vp-c-text-3, #94a3b8);
  white-space: nowrap;
  letter-spacing: 0.02em;
}
.dropdown-item[data-v-bcb3dc5a] {
  display: block;
  width: 100%;
  padding: 8px 12px;
  border: none;
  background: none;
  text-align: left;
  font-size: 14px;
  color: var(--vp-c-text-1, #0f172a);
  border-radius: 6px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s;
}
.dropdown-item[data-v-bcb3dc5a]:hover {
  background: var(--vp-c-bg-soft, #f8fafc);
}
.dropdown-item.logout[data-v-bcb3dc5a] {
  color: #ef4444;
}
.dropdown-divider[data-v-bcb3dc5a] {
  height: 1px;
  background: var(--vp-c-divider, #e2e8f0);
  margin: 4px 0;
}

/* Only opacity + transform change between the from/to states
   below, so scope to them. Enter uses slow-out, leave uses fast-
   out so the dropdown "settles" in but "snaps" away. */
.dropdown-enter-active[data-v-bcb3dc5a] {
  transition:
    opacity   0.15s cubic-bezier(0.2, 0, 0, 1),
    transform 0.15s cubic-bezier(0.2, 0, 0, 1);
}
.dropdown-leave-active[data-v-bcb3dc5a] {
  transition:
    opacity   0.1s cubic-bezier(0.4, 0, 1, 1),
    transform 0.1s cubic-bezier(0.4, 0, 1, 1);
}
.dropdown-enter-from[data-v-bcb3dc5a], .dropdown-leave-to[data-v-bcb3dc5a] {
  opacity: 0;
  transform: translateY(-4px);
}

.book-cover-art[data-v-4ae45f1c] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* Sit under the existing .book-cover::after vignette so the
     top-left white glow still reads on top of the shapes. */
  z-index: 0;
}

/* ============================================================
   Local palette — reads from global tokens so dual-theme works
   ============================================================ */
.yyt-home[data-v-243b088e] {
  /* clip, not hidden — `overflow: hidden` on any ancestor kills
     `position: sticky` on descendants (like .ly-nav). `clip`
     prevents horizontal overflow without creating a containing
     block for sticky. Supported everywhere we care about. */
  overflow-x: clip;
  max-width: 100vw;
  --bg: var(--home-bg);
  --bg-1: var(--home-bg-alt);
  --bg-2: var(--home-card-bg);
  --bg-3: var(--reader-surface-alt);
  --line: var(--home-card-border);
  --line-2: var(--reader-border-strong);
  --ink: var(--home-text-1);
  --ink-d: var(--home-text-2);
  --ink-m: var(--home-text-3);
  --accent: var(--vp-c-brand-1);
  --accent-2: #8b5cf6;
  --accent-3: #3b82f6;
  --accent-4: #f97316;
  --fs: 'Inter', 'PingFang SC', 'HarmonyOS Sans', system-ui, sans-serif;
  --fm: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  --r-sm: 8px; --r-md: 12px; --r-lg: 18px; --r-xl: 24px;

  background: var(--bg);
  color: var(--ink);
  font-family: var(--fs);
  font-size: 15px;
  line-height: 1.55;
  min-height: 100vh;
  position: relative;
  -webkit-font-smoothing: antialiased;
}
.yyt-home a[data-v-243b088e] { color: inherit; text-decoration: none;
}

/* Ambient grid + soft orbs for the dark canvas */
.yyt-home[data-v-243b088e]::before {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(var(--hero-grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--hero-grid-line) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 120% 80% at 50% -10%, #000 35%, transparent 75%);
}
.yyt-home[data-v-243b088e]::after {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(900px 450px at 85% -5%, var(--hero-orb-1), transparent 60%),
    radial-gradient(700px 400px at 10% 5%, var(--hero-orb-2), transparent 65%);
}
.yyt-home[data-v-243b088e] > * { position: relative; z-index: 1;
}
.ly-wrap[data-v-243b088e] { max-width: 1280px; margin: 0 auto; padding: 0 32px;
}

/* ============================================================
   NAV — frosted-glass sticky bar with an editorial wordmark.
   ============================================================ */
.ly-nav[data-v-243b088e] {
  position: sticky; top: 0; z-index: 50;
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  background: color-mix(in oklab, var(--bg) 72%, transparent);
  border-bottom: 1px solid color-mix(in oklab, var(--line) 80%, transparent);
  /* Subtle inner hairline + shadow so the bar separates from the
     hero content without a heavy 1px rule. */
  box-shadow:
    0 1px 0 color-mix(in oklab, var(--ink) 4%, transparent),
    0 8px 24px -12px color-mix(in oklab, #000 16%, transparent);
}
.ly-nav-in[data-v-243b088e] { display: flex; align-items: center; justify-content: space-between; height: 64px;
}
.ly-brand[data-v-243b088e] {
  display: inline-flex; align-items: center;
  color: var(--ink); flex-shrink: 0;
}
.ly-brand-m[data-v-243b088e] {
  height: 36px; width: auto;
  display: block; flex-shrink: 0;
  background: transparent;
}
.ly-nav-c[data-v-243b088e] { display: flex; gap: 6px; align-items: center;
}
.ly-nav-c a[data-v-243b088e] {
  font-size: 13.5px; color: var(--ink-d); padding: 8px 14px; border-radius: 8px;
  transition: color .15s, background .15s;
  white-space: nowrap; flex-shrink: 0;
}
.ly-nav-c a[data-v-243b088e]:hover { color: var(--ink); background: rgba(255, 255, 255, 0.04);
}
.is-light .ly-nav-c a[data-v-243b088e]:hover { background: rgba(10, 10, 10, 0.04);
}
.ly-nav-r[data-v-243b088e] { display: flex; align-items: center; gap: 10px;
}
.ly-theme-btn[data-v-243b088e] {
  width: 32px; height: 32px; border-radius: 8px;
  border: 1px solid var(--line-2); background: var(--bg-1); color: var(--ink-d);
  display: grid; place-items: center; cursor: pointer; transition: border-color .15s, color .15s;
}
.ly-theme-btn[data-v-243b088e]:hover { border-color: var(--accent); color: var(--accent);
}
/* Bump selector specificity (a.X = 0,1,1) so it wins over
 * the broader `.yyt-home a { color: inherit }` reset above. */
a.ly-nav-cta[data-v-243b088e] {
  padding: 8px 16px; border-radius: 8px;
  background: var(--accent-fill); color: var(--accent-ink);
  font-weight: 600; font-size: 13px; font-family: var(--fm);
  transition: background .15s;
  white-space: nowrap;
}
.ly-nav-r > a[data-v-243b088e],
.ly-nav-r > button[data-v-243b088e] {
  white-space: nowrap;
}
a.ly-nav-cta[data-v-243b088e]:hover { background: var(--accent-fill-hover);
}

/* ============================================================
   HERO
   ============================================================ */
.ly-hero[data-v-243b088e] { padding: 96px 0 48px; position: relative;
}
.ly-hero-grid[data-v-243b088e] {
  display: grid; grid-template-columns: 1.1fr .9fr; gap: 56px; align-items: center;
}
.ly-eyebrow[data-v-243b088e] {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 6px 14px; border: 1px solid var(--line-2); border-radius: 999px;
  font-family: var(--fm); font-size: 12px; color: var(--ink-d);
  background: var(--bg-1);
}
.ly-eyebrow .d[data-v-243b088e] {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 10px var(--accent);
}
h1.ly-hero-t[data-v-243b088e] {
  font-size: clamp(44px, 5.8vw, 80px); line-height: 1.02; letter-spacing: -0.03em;
  font-weight: 800; margin: 24px 0 18px;
  /* Balance wraps so "深入原理源码 / 传递技术本质" never orphans a
     single glyph at a narrow viewport. */
  text-wrap: balance;
}
h1.ly-hero-t .l1[data-v-243b088e] { display: block; color: var(--ink);
}
h1.ly-hero-t .l2[data-v-243b088e] {
  display: block;
  background: linear-gradient(90deg, var(--accent) 0%, #8de3a3 50%, #61dafb 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.is-light h1.ly-hero-t .l2[data-v-243b088e] {
  background: linear-gradient(90deg, var(--hero-title-accent-from), var(--hero-title-accent-mid), var(--hero-title-accent-to));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.ly-hero-lede[data-v-243b088e] {
  font-size: 18px; color: var(--ink-d); max-width: 54ch;
  margin: 0 0 36px; line-height: 1.65;
  text-wrap: pretty;
}
.ly-hero-lede em[data-v-243b088e] { color: var(--ink); font-style: normal; font-weight: 500;
}
.ly-hero-ctas[data-v-243b088e] { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 40px;
}
.ly-btn[data-v-243b088e] {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 13px 20px; border-radius: 10px;
  font-size: 14px; font-weight: 600;
  border: 1px solid transparent; cursor: pointer;
  transition: transform .08s, background .15s, border-color .15s, color .15s;
}
.ly-btn[data-v-243b088e]:active { transform: translateY(1px);
}
a.ly-btn-p[data-v-243b088e], button.ly-btn-p[data-v-243b088e] { background: var(--accent-fill); color: var(--accent-ink);
}
a.ly-btn-p[data-v-243b088e]:hover, button.ly-btn-p[data-v-243b088e]:hover { background: var(--accent-fill-hover);
}
a.ly-btn-g[data-v-243b088e], button.ly-btn-g[data-v-243b088e] { background: transparent; border-color: var(--line-2); color: var(--ink);
}
a.ly-btn-g[data-v-243b088e]:hover, button.ly-btn-g[data-v-243b088e]:hover { border-color: var(--ink); color: var(--ink);
}
.is-light a.ly-btn-g[data-v-243b088e]:hover { background: rgba(10, 10, 10, 0.03);
}
.ly-hero-stats[data-v-243b088e] {
  display: flex; gap: 0;
  border-top: 1px solid var(--line); padding-top: 22px;
}
.hs[data-v-243b088e] { padding-right: 28px; margin-right: 28px; border-right: 1px solid var(--line);
}
.hs[data-v-243b088e]:last-child { border: 0;
}
.hs-n[data-v-243b088e] {
  font-family: var(--fm); font-size: 26px; font-weight: 600;
  color: var(--ink); letter-spacing: -.02em;
  /* Tabular numerals so numbers don't jitter when they update from
     bootstrap value → live value. Also looks more "dashboard" vs
     "prose". */
  font-variant-numeric: tabular-nums;
}
.hs-n .u[data-v-243b088e] { color: var(--ink-m); font-size: 14px; margin-left: 4px; font-weight: 400;
}
.hs-l[data-v-243b088e] { font-size: 12px; color: var(--ink-d); margin-top: 2px;
}

/* Book stack visual */
.ly-hero-vis[data-v-243b088e] { position: relative; height: 520px;
}
.stack[data-v-243b088e] { position: absolute; inset: 0; display: grid; place-items: center;
}
.bk[data-v-243b088e] {
  position: absolute; width: 220px; height: 300px; border-radius: 14px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.06) inset;
  padding: 22px; display: flex; flex-direction: column; justify-content: space-between;
  font-family: var(--fm); color: #fff; overflow: hidden;
  transition: transform .4s cubic-bezier(.2, .8, .2, 1);
}
.bk[data-v-243b088e]::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.13), transparent 45%, rgba(0, 0, 0, 0.27));
  pointer-events: none;
}
.bk .bk-slug[data-v-243b088e] { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; opacity: .85;
}
.bk .bk-t[data-v-243b088e] {
  font-size: 22px; font-weight: 700; line-height: 1.2; letter-spacing: -.01em;
  font-family: var(--fs); max-width: 14ch;
}
.bk .bk-meta[data-v-243b088e] { font-size: 11px; opacity: .9; display: flex; gap: 12px;
}
.bk .bk-meta b[data-v-243b088e] { font-weight: 600;
}
.bk-1[data-v-243b088e] { background: linear-gradient(135deg, #42d392, #647eff); transform: translate(-170px, 10px) rotate(-9deg);
}
.bk-2[data-v-243b088e] { background: linear-gradient(135deg, #3b82f6, #06b6d4); transform: translate(-60px, -40px) rotate(-3deg); z-index: 2;
}
.bk-3[data-v-243b088e] { background: linear-gradient(135deg, #f97316, #dc2626); transform: translate(55px, -15px) rotate(4deg); z-index: 3;
}
.bk-4[data-v-243b088e] { background: linear-gradient(135deg, #bd34fe, #ffd43b); transform: translate(165px, 30px) rotate(10deg); z-index: 2;
}
.ly-hero-vis:hover .bk-1[data-v-243b088e] { transform: translate(-200px, 0) rotate(-12deg);
}
.ly-hero-vis:hover .bk-2[data-v-243b088e] { transform: translate(-70px, -55px) rotate(-5deg);
}
.ly-hero-vis:hover .bk-3[data-v-243b088e] { transform: translate(65px, -25px) rotate(6deg);
}
.ly-hero-vis:hover .bk-4[data-v-243b088e] { transform: translate(195px, 20px) rotate(13deg);
}
.vis-cap[data-v-243b088e] {
  position: absolute; left: 50%; bottom: -6px; transform: translateX(-50%);
  font-family: var(--fm); font-size: 11px; color: var(--ink-m);
  letter-spacing: .14em; text-transform: uppercase; white-space: nowrap;
}

/* ============================================================
   Section base
   ============================================================ */
.ly-section[data-v-243b088e] { padding: 96px 0; position: relative;
}
.ly-section-tight[data-v-243b088e] { padding-top: 40px; padding-bottom: 96px;
}
.sec-head[data-v-243b088e] {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 40px; margin-bottom: 36px;
}
.sec-num[data-v-243b088e] {
  font-family: var(--fm); font-size: 11px; color: var(--ink-m);
  letter-spacing: .16em;
}
.sec-t[data-v-243b088e] {
  font-size: clamp(28px, 3.4vw, 42px); font-weight: 800; letter-spacing: -0.02em;
  margin: 10px 0 0; line-height: 1.1; color: var(--ink);
  /* Balance wraps so display titles never orphan a single word on
     narrow / translated viewports. Matches the hero h1 treatment. */
  text-wrap: balance;
}
.sec-d[data-v-243b088e] { color: var(--ink-d); max-width: 46ch; font-size: 15px;
}

/* Pillars */
.pillars[data-v-243b088e] { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
}
.pill[data-v-243b088e] {
  position: relative; padding: 28px;
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--bg-1); overflow: hidden; cursor: pointer;
  /* Unified easing / duration with .book so the pillars and the
     book grid both animate like they come from the same system.
     Generic `.2s ease` made the pills feel ever-so-slightly more
     "linear" than the adjacent cards — now they share the
     fast-out-slow-in curve. */
  transition:
    border-color 0.22s cubic-bezier(0.2, 0, 0, 1),
    transform    0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1);
  text-align: left; font: inherit; color: inherit; appearance: none;
  width: 100%;
  box-shadow: var(--shadow-1);
}
.pill[data-v-243b088e]:hover {
  border-color: var(--line-2);
  transform: translateY(-3px);
  /* tier-3 elevation + per-pillar accent rim (AI purple /
     Frontend blue / Rust orange, sourced from --pill-bg which
     each .pill sets inline). */
  box-shadow:
    var(--shadow-3),
    0 0 0 1px color-mix(in oklab, var(--pill-bg, var(--accent)) 14%, transparent);
}
.pill[data-v-243b088e]::before { content: ""; position: absolute; inset: 0; opacity: .08; background: var(--pill-bg); pointer-events: none;
}
.pill-bar[data-v-243b088e] { height: 3px; border-radius: 2px; background: var(--pill-bg); margin-bottom: 22px; width: 44px;
}
.pill-kind[data-v-243b088e] { font-family: var(--fm); font-size: 11px; letter-spacing: .14em; color: var(--ink-m);
}
.pill-t[data-v-243b088e] { font-size: 22px; font-weight: 700; margin: 4px 0 10px; letter-spacing: -.01em; color: var(--ink);
}
.pill-d[data-v-243b088e] { color: var(--ink-d); font-size: 13.5px; line-height: 1.6; min-height: 64px;
}
.pill-count[data-v-243b088e] { margin-top: 18px; display: flex; align-items: baseline; gap: 8px; font-family: var(--fm);
}
.pill-count .n[data-v-243b088e] { font-size: 32px; font-weight: 700; color: var(--ink);
}
.pill-count .u[data-v-243b088e] { font-size: 12px; color: var(--ink-m);
}
.pill-arrow[data-v-243b088e] {
  position: absolute; top: 28px; right: 28px; color: var(--ink-m);
  transition:
    color     0.22s cubic-bezier(0.2, 0, 0, 1),
    transform 0.22s cubic-bezier(0.2, 0, 0, 1);
}
.pill:hover .pill-arrow[data-v-243b088e] {
  color: var(--accent);
  /* 4px travel instead of 3px so the arrow reads as "follow me" at
     desktop pointer speed; still subtle enough to not distract. */
  transform: translateX(4px);
}

/* Numeric counts (e.g. "12 本") use the mono fs stack but default
   proportional figures, which can jitter if the count changes.
   Lock to tabular so the layout is byte-stable even mid-animation. */
.pill-count .n[data-v-243b088e] {
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   Filter row + book grid
   ============================================================ */
.filter-row[data-v-243b088e] {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; margin-bottom: 24px; flex-wrap: wrap;
}
.tabs[data-v-243b088e] {
  display: flex; gap: 6px; padding: 4px;
  background: var(--bg-1); border: 1px solid var(--line); border-radius: 10px;
  /* Allow horizontal scroll on narrow viewports so the full tab
     list stays reachable without wrapping to a second line. */
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none; /* Firefox */
}
.tabs[data-v-243b088e]::-webkit-scrollbar { display: none;
}
.tab[data-v-243b088e] {
  padding: 8px 16px; border-radius: 7px; font-size: 13px;
  color: var(--ink-d); cursor: pointer; font-family: var(--fm);
  transition:
    color      0.15s cubic-bezier(0.2, 0, 0, 1),
    background 0.15s cubic-bezier(0.2, 0, 0, 1);
  white-space: nowrap;
  border: none; background: transparent;
  flex-shrink: 0; /* resist collapsing when inside a scroll container */
}
.tab[data-v-243b088e]:hover { color: var(--ink);
}
.tab.on[data-v-243b088e] { background: var(--bg-3); color: var(--ink); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.04) inset;
}
.tab .c[data-v-243b088e] { color: var(--ink-m); margin-left: 6px; font-size: 11px;
}
.tab.on .c[data-v-243b088e] { color: var(--accent);
}
.filter-note[data-v-243b088e] {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; color: var(--ink-d); font-family: var(--fm);
}
.filter-note .p[data-v-243b088e] {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 10px var(--accent);
  animation: yyt-pulse-243b088e 1.8s ease-in-out infinite;
}
@keyframes yyt-pulse-243b088e {
0%, 100% { opacity: 1
}
50% { opacity: .4
}
}

/* ============================================================
   Book list — horizontal pagination
   Viewport clips; track slides. Side arrows float OUTSIDE the
   viewport so they don't cover cards. Dots sit below.
   ============================================================ */
.books-wrap[data-v-243b088e] {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  align-items: stretch;
}
.books-wrap.has-paging[data-v-243b088e] {
  /* Leave room on both sides for the floating arrow buttons — they
     overlap slightly but the margin keeps focus rings from clipping. */
  padding: 0 6px;
}
.books-viewport[data-v-243b088e] {
  overflow: hidden;
  border-radius: var(--r-lg);
  /* Slight negative margin pulls the focus outlines of inner book
     cards back inside the viewport — otherwise Chrome's default focus
     ring gets clipped by overflow:hidden on first-page keyboard tab. */
  margin: -2px;
  padding: 2px;
}
.books-track[data-v-243b088e] {
  display: flex;
  width: 100%;
  transition: transform 0.48s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}
.books-page[data-v-243b088e] {
  flex: 0 0 100%;
  min-width: 0;
}
.books[data-v-243b088e] { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px;
}

/* ---- Arrows ---- */
.books-nav[data-v-243b088e] {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--bg-1);
  border: 1px solid var(--line);
  color: var(--ink);
  display: grid;
  place-items: center;
  cursor: pointer;
  z-index: 3;
  box-shadow: var(--shadow-1);
  transition:
    background-color 0.18s ease,
    border-color 0.18s ease,
    transform 0.18s cubic-bezier(0.22, 0.61, 0.36, 1),
    box-shadow 0.18s ease,
    opacity 0.18s ease;
}
.books-nav[data-v-243b088e]:hover {
  background: var(--bg-2, var(--bg-1));
  border-color: var(--line-2);
  color: var(--ink-d);
  box-shadow: var(--shadow-2);
  transform: translateY(-50%) scale(1.06);
}
.books-nav[data-v-243b088e]:active { transform: translateY(-50%) scale(0.96);
}
.books-nav.is-disabled[data-v-243b088e],
.books-nav[disabled][data-v-243b088e] {
  opacity: 0.35;
  cursor: not-allowed;
  box-shadow: none;
  transform: translateY(-50%);
}
.books-nav.is-disabled[data-v-243b088e]:hover { background: var(--bg-1); border-color: var(--line);
}
.books-prev[data-v-243b088e] { left: -52px;
}
.books-next[data-v-243b088e] { right: -52px;
}
/* When the viewport would touch the arrow, tuck arrows inside the edge. */
@media (max-width: 1200px) {
.books-prev[data-v-243b088e] { left: 4px;
}
.books-next[data-v-243b088e] { right: 4px;
}
.books-nav[data-v-243b088e] { background: color-mix(in oklab, var(--bg-1) 92%, transparent); backdrop-filter: blur(6px);
}
}

/* ---- Dots ---- */
.books-dots[data-v-243b088e] {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 20px;
}
.books-dot[data-v-243b088e] {
  all: unset;
  cursor: pointer;
  padding: 6px 2px;
  display: inline-flex;
  align-items: center;
  outline: none;
}
.books-dot .d-bar[data-v-243b088e] {
  display: block;
  width: 20px;
  height: 3px;
  border-radius: 2px;
  background: var(--line);
  transition:
    width 0.32s cubic-bezier(0.22, 0.61, 0.36, 1),
    background-color 0.22s ease;
}
.books-dot:hover .d-bar[data-v-243b088e] { background: var(--line-2);
}
.books-dot.is-active .d-bar[data-v-243b088e] {
  width: 36px;
  background: var(--accent);
}
.books-dot:focus-visible .d-bar[data-v-243b088e] {
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--accent) 30%, transparent);
}
.book[data-v-243b088e] {
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--r-lg); overflow: hidden;
  display: flex; flex-direction: column;
  /* Fast-out-slow-in easing (macOS / Material) + matching duration
     on all three animated properties so the lift, border, and
     shadow all land together. The generic `ease` was close-enough
     on paper but makes the card feel "gummy" — the translateY and
     border finished at slightly different timings. */
  transition:
    border-color 0.22s cubic-bezier(0.2, 0, 0, 1),
    transform    0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1);
  cursor: pointer; position: relative;
  /* box-shadow at rest so the hover doesn't "pop in" a shadow from
     nothing — it just deepens. Near-invisible at 2% ink alpha. */
  box-shadow: var(--shadow-1);
}
.book[data-v-243b088e]:hover {
  border-color: var(--line-2);
  transform: translateY(-4px);
  /* Shared-scale tier-3 elevation + a subtle accent rim (low
     alpha — reads as "depth" not "selected"). The tier token
     auto-switches to pure-black alphas in dark mode. */
  box-shadow:
    var(--shadow-3),
    0 0 0 1px color-mix(in oklab, var(--accent) 12%, transparent);
}
.is-light .book[data-v-243b088e]:hover {
  /* Light mode keeps the shared token shadow but bumps the brand
     rim alpha a notch to stay visible against the lighter page. */
  box-shadow:
    var(--shadow-3),
    0 0 0 1px color-mix(in oklab, var(--accent) 16%, transparent);
}
.book-cover[data-v-243b088e] {
  aspect-ratio: 5/3;
  position: relative; padding: 18px; color: #fff;
  display: flex; flex-direction: column; justify-content: space-between;
  overflow: hidden;
}
.book-cover[data-v-243b088e]::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(120% 80% at 20% 0%, rgba(255, 255, 255, 0.15), transparent 50%),
    linear-gradient(180deg, transparent 50%, rgba(0, 0, 0, 0.28));
  pointer-events: none;
}
.bc-slug[data-v-243b088e] {
  font-family: var(--fm); font-size: 11px; letter-spacing: .2em;
  text-transform: uppercase; opacity: .78; z-index: 1;
}
.bc-bottom[data-v-243b088e] {
  display: flex; align-items: flex-end; justify-content: space-between;
  z-index: 1; position: relative;
}
.bc-stats[data-v-243b088e] { display: flex; gap: 14px; font-family: var(--fm); font-size: 11px;
}
.bc-stats .s[data-v-243b088e] { display: flex; flex-direction: column;
}
.bc-stats .s .n[data-v-243b088e] { font-size: 20px; font-weight: 700; line-height: 1; letter-spacing: -.02em;
}
.bc-stats .s .l[data-v-243b088e] { font-size: 10px; opacity: .8; margin-top: 2px;
}
.bc-pct[data-v-243b088e] { font-family: var(--fm); font-size: 11px; text-align: right; font-weight: 600; opacity: .95;
}
.bc-progress[data-v-243b088e] {
  position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: rgba(255, 255, 255, 0.13); z-index: 2;
}
.bc-progress .fill[data-v-243b088e] { height: 100%; background: #fff; opacity: .95;
}
.book-body[data-v-243b088e] { padding: 16px 18px 18px; flex: 1; display: flex; flex-direction: column;
}
.book-cat[data-v-243b088e] {
  font-family: var(--fm); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; padding: 3px 8px; border-radius: 4px;
  align-self: flex-start; margin-bottom: 10px;
}
.cat-ai[data-v-243b088e] { background: rgba(139, 92, 246, 0.12); color: #a78bfa;
}
.cat-frontend[data-v-243b088e] { background: rgba(59, 130, 246, 0.12); color: #60a5fa;
}
.cat-rust[data-v-243b088e] { background: rgba(249, 115, 22, 0.12); color: #fb923c;
}
.book-t[data-v-243b088e] {
  font-size: 16.5px; font-weight: 700; letter-spacing: -.005em;
  margin: 0 0 8px; line-height: 1.3; color: var(--ink);
}
.book-d[data-v-243b088e] {
  font-size: 12.5px; color: var(--ink-d); line-height: 1.55;
  margin: 0 0 14px; flex: 1;
}
.book-latest[data-v-243b088e] {
  display: flex; align-items: center; gap: 8px;
  padding-top: 12px;
  /* Solid hairline, not dashed — dashed reads as "provisional /
     cut-here" which fights the editorial feel of the card. */
  border-top: 1px solid var(--line);
  font-size: 11px; color: var(--ink-m); font-family: var(--fm);
}
.book-latest .ch[data-v-243b088e] { color: var(--ink-d); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.book-latest .dot[data-v-243b088e] {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 8px var(--accent);
  flex-shrink: 0;
}

/* ============================================================
   Recent updates marquee
   ============================================================ */
.ly-recent[data-v-243b088e] {
  padding: 48px 0;
  background: linear-gradient(to bottom, transparent, var(--bg-1) 30%, var(--bg-1) 70%, transparent);
}
.recent-head[data-v-243b088e] { display: flex; align-items: center; gap: 14px; margin-bottom: 22px;
}
.recent-head .pulse[data-v-243b088e] {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 12px var(--accent);
  animation: yyt-pulse-243b088e 1.6s ease-in-out infinite;
}
.recent-head .t[data-v-243b088e] { font-size: 14px; font-weight: 600; letter-spacing: -.005em; color: var(--ink);
}
.recent-head .sub[data-v-243b088e] { color: var(--ink-m); font-family: var(--fm); font-size: 12px; margin-left: auto;
}
/* Edge-fade indicators on the horizontal scroll row. The wrapper has
 * mask-image on both edges so content visibly fades in/out; the inner
 * .recent-scroll hides its scrollbar entirely. The reader gets a
 * scrollability hint from the fades plus the clipped cards. */
.recent-wrap[data-v-243b088e] {
  position: relative;
  mask-image: linear-gradient(
    to right, transparent 0, #000 40px, #000 calc(100% - 40px), transparent 100%
  );
  -webkit-mask-image: linear-gradient(
    to right, transparent 0, #000 40px, #000 calc(100% - 40px), transparent 100%
  );
}
.recent-scroll[data-v-243b088e] {
  display: flex; gap: 12px; overflow-x: auto; padding: 4px 40px;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-snap-type: x proximity;
}
.recent-scroll[data-v-243b088e]::-webkit-scrollbar { display: none; width: 0; height: 0;
}
.recent-scroll > .rc[data-v-243b088e] { scroll-snap-align: start;
}
.rc[data-v-243b088e] {
  min-width: 280px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 16px; position: relative; overflow: hidden;
  transition: border-color .2s, transform .2s;
}
.rc[data-v-243b088e]:hover { border-color: var(--line-2); transform: translateY(-2px);
}
.rc-stripe[data-v-243b088e] { position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--rc-c);
}
.rc-meta[data-v-243b088e] {
  display: flex; justify-content: space-between;
  font-family: var(--fm); font-size: 11px; color: var(--ink-m);
  margin-bottom: 10px; margin-left: 8px;
}
.rc-book[data-v-243b088e] { color: var(--ink-d);
}
.rc-title[data-v-243b088e] {
  font-size: 13.5px; line-height: 1.45; margin-left: 8px;
  color: var(--ink); letter-spacing: -.005em;
}
.rc-num[data-v-243b088e] {
  font-family: var(--fm); font-size: 11px; color: var(--ink-m);
  display: block; margin-bottom: 2px;
}

/* ============================================================
   Author
   ============================================================ */
.author[data-v-243b088e] {
  display: grid; grid-template-columns: 340px 1fr; gap: 40px;
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--r-xl); padding: 36px;
}
.ava-wrap[data-v-243b088e] {
  position: relative; aspect-ratio: 1; border-radius: var(--r-lg);
  overflow: hidden; border: 1px solid var(--line-2);
  background: repeating-linear-gradient(45deg, var(--bg-3) 0 12px, var(--bg-1) 12px 24px);
}
.mono-tag[data-v-243b088e] {
  position: absolute; top: 16px; left: 16px;
  font-family: var(--fm); font-size: 10px; color: var(--ink-m); letter-spacing: .2em;
}
.ring[data-v-243b088e] { position: absolute; inset: 12px; border-radius: 14px; border: 1px dashed rgba(255, 255, 255, 0.08);
}
.is-light .ring[data-v-243b088e] { border-color: rgba(10, 10, 10, 0.08);
}
.ava-img[data-v-243b088e] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.ins h3[data-v-243b088e] { font-size: 32px; margin: 0 0 4px; letter-spacing: -.02em; font-weight: 800; color: var(--ink);
}
.ins .ti[data-v-243b088e] {
  font-family: var(--fm); font-size: 12px; color: var(--accent);
  letter-spacing: .1em; text-transform: uppercase; margin-bottom: 20px;
}
.ins-bio[data-v-243b088e] {
  color: var(--ink-d); font-size: 15px; line-height: 1.7;
  margin: 0 0 24px; max-width: 58ch;
}
.ins-bio strong[data-v-243b088e] { color: var(--ink); font-weight: 600;
}
.cadence[data-v-243b088e] {
  display: flex; gap: 0; margin-bottom: 26px;
  border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden;
}
.cd[data-v-243b088e] {
  flex: 1; padding: 16px 20px;
  border-right: 1px solid var(--line); background: var(--bg-2);
}
.cd[data-v-243b088e]:last-child { border-right: 0;
}
.cd-n[data-v-243b088e] {
  font-family: var(--fm); font-size: 24px; font-weight: 700;
  color: var(--ink); letter-spacing: -.02em;
}
.cd-n small[data-v-243b088e] { font-size: 14px; color: var(--ink-m); margin-left: 2px;
}
.cd-l[data-v-243b088e] { font-size: 11.5px; color: var(--ink-d); margin-top: 4px; font-family: var(--fm);
}
.ins-tags[data-v-243b088e] { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 22px;
}
.ins-tag[data-v-243b088e] {
  padding: 5px 12px; border: 1px solid var(--line-2); border-radius: 999px;
  font-family: var(--fm); font-size: 11.5px; color: var(--ink-d); background: var(--bg-2);
}
.ins-actions[data-v-243b088e] { display: flex; gap: 10px; flex-wrap: wrap;
}

/* ============================================================
   Community
   ============================================================ */
.community[data-v-243b088e] { display: grid; grid-template-columns: 1.1fr .9fr; gap: 40px; align-items: center;
}
.co-eyebrow[data-v-243b088e] {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 6px 14px; border: 1px solid var(--line-2); border-radius: 999px;
  font-family: var(--fm); font-size: 12px; color: var(--ink-d);
  background: var(--bg-1); margin-bottom: 18px;
}
.co-eyebrow .d[data-v-243b088e] {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); animation: yyt-pulse-243b088e 1.8s infinite;
}
.co-t[data-v-243b088e] { font-size: 38px; font-weight: 800; letter-spacing: -.02em; margin: 0 0 14px; line-height: 1.1; color: var(--ink);
}
.co-lede[data-v-243b088e] { color: var(--ink-d); margin: 0 0 28px; font-size: 15.5px; line-height: 1.65; max-width: 52ch;
}
.bullets[data-v-243b088e] { list-style: none; padding: 0; margin: 0 0 28px; display: grid; gap: 14px;
}
.bullets li[data-v-243b088e] { display: flex; gap: 14px; align-items: flex-start;
}
.bi[data-v-243b088e] {
  width: 32px; height: 32px; border-radius: 8px;
  display: grid; place-items: center; flex-shrink: 0;
  color: #fff; font-family: var(--fm); font-weight: 700; font-size: 13px;
}
.b-txt strong[data-v-243b088e] { display: block; font-weight: 600; margin-bottom: 2px; color: var(--ink);
}
.b-txt span[data-v-243b088e] { color: var(--ink-d); font-size: 13.5px;
}
.qrs[data-v-243b088e] { display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
}
.qr-card[data-v-243b088e] {
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 22px; text-align: center;
  transition: border-color .2s;
}
.qr-card[data-v-243b088e]:hover { border-color: var(--accent);
}
.qr-box[data-v-243b088e] {
  aspect-ratio: 1; background: #fff; border-radius: 10px;
  display: grid; place-items: center; margin-bottom: 14px;
  position: relative; overflow: hidden;
}
.qr-box img[data-v-243b088e] {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.qr-t[data-v-243b088e] { font-weight: 600; margin-bottom: 2px; color: var(--ink);
}
.qr-d[data-v-243b088e] { color: var(--ink-d); font-size: 12.5px;
}

/* ============================================================
   FAQ — definition list with divider lines, feels editorial
   rather than "accordion UI". Supporting the FAQPage JSON-LD
   in config.ts, which requires the answer text to be visible
   on the page or Google discards the rich-result signal.
   ============================================================ */
.ly-faq[data-v-243b088e] { padding: 80px 0;
}
.faq-list[data-v-243b088e] {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  border-top: 1px solid var(--line);
}
.faq-item[data-v-243b088e] {
  padding: 22px 0;
  border-bottom: 1px solid var(--line);
}
.faq-q[data-v-243b088e] {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
  margin: 0 0 8px;
}
.faq-a[data-v-243b088e] {
  margin: 0;
  color: var(--ink-d);
  font-size: 14.5px;
  line-height: 1.75;
  max-width: 80ch;
}
.faq-a strong[data-v-243b088e] { color: var(--ink); font-weight: 600;
}
@media (max-width: 640px) {
.ly-faq[data-v-243b088e] { padding: 56px 0;
}
.faq-q[data-v-243b088e] { font-size: 15.5px;
}
.faq-a[data-v-243b088e] { font-size: 14px;
}
}

/* ============================================================
   Footer
   ============================================================ */
.ly-footer[data-v-243b088e] {
  border-top: 1px solid var(--line); padding: 56px 0 40px;
  color: var(--ink-d); font-size: 13px; margin-top: 64px;
}
.f-grid[data-v-243b088e] {
  display: grid; grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 40px; margin-bottom: 32px;
}
.f-brand .tagline[data-v-243b088e] {
  color: var(--ink-m); font-family: var(--fm); font-size: 12px;
  margin-top: 10px; letter-spacing: .02em;
}
.f-h[data-v-243b088e] {
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-m); margin-bottom: 14px; font-family: var(--fm);
}
.f-col a[data-v-243b088e] { display: block; padding: 4px 0; color: var(--ink-d); font-size: 13px; cursor: pointer;
}
.f-col a[data-v-243b088e]:hover { color: var(--accent);
}
.f-bottom[data-v-243b088e] {
  padding-top: 24px; border-top: 1px solid var(--line);
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  font-family: var(--fm); font-size: 12px; color: var(--ink-m);
}
.f-bottom a[data-v-243b088e]:hover { color: var(--ink-d);
}
.f-bottom .right[data-v-243b088e] { display: flex; gap: 18px; flex-wrap: wrap;
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 980px) {
.ly-hero-grid[data-v-243b088e], .author[data-v-243b088e], .community[data-v-243b088e] { grid-template-columns: 1fr;
}
.ly-hero-vis[data-v-243b088e] { height: 360px;
}
.pillars[data-v-243b088e] { grid-template-columns: 1fr;
}
  /* .books grid-template-columns controlled inline via :style binding
     from computed `columns` — kept as an extra fallback below. */
.books[data-v-243b088e] { grid-template-columns: repeat(2, 1fr);
}
.f-grid[data-v-243b088e] { grid-template-columns: 1fr 1fr;
}
  /* Middle nav links (书籍 / 领域 / 关于作者 / 社群) wrap per-character
     when the row is squeezed; hide them on tablets, the right-side
     CTA + hamburger/avatar give access to the same destinations. */
.ly-nav-c[data-v-243b088e] { display: none;
}
}
@media (max-width: 600px) {
.books[data-v-243b088e] { grid-template-columns: 1fr;
}
.ly-hero-stats[data-v-243b088e] { flex-wrap: wrap; gap: 14px;
}
.hs[data-v-243b088e] { border: 0; padding: 0; margin: 0; min-width: 45%;
}
.ly-nav-c[data-v-243b088e] { display: none;
}
  /* Hero book stack: hover fan-out has no trigger on touch and the
     360px placeholder takes up a screenful of vertical space, so
     drop it entirely on phones. */
.ly-hero-vis[data-v-243b088e] { display: none;
}
  /* Section head: stack heading on top of description so a long
     Chinese title doesn't get squeezed into a single-character
     column when the flex row collapses. */
.sec-head[data-v-243b088e] {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 28px;
}
.sec-d[data-v-243b088e] { max-width: 100%;
}
.sec-t[data-v-243b088e] { font-size: 28px;
}
  /* Nav row: tighten the wrap padding and hide the "开始阅读" CTA.
     On the homepage the page body itself is the book list, so the
     nav CTA is redundant on phones — dropping it buys the theme
     button + login/avatar enough room not to visually collide. */
.ly-nav .ly-wrap[data-v-243b088e] { padding: 0 16px;
}
.ly-nav-r[data-v-243b088e] { gap: 8px;
}
a.ly-nav-cta[data-v-243b088e] { display: none;
}
  /* Brand: keep visible on mobile (user prefers it shown) —
     shrink the horizontal wordmark mark so it doesn't crowd the CTAs. */
.ly-brand-m[data-v-243b088e] { height: 28px;
}
  /* Hero padding tighter on phones so the headline doesn't start
     mid-scroll. */
.ly-hero[data-v-243b088e] { padding: 40px 0 24px;
}
.ly-hero-stats[data-v-243b088e] { margin-top: 24px;
}
h1.ly-hero-t[data-v-243b088e] { font-size: clamp(30px, 8.5vw, 42px) !important; line-height: 1.15 !important;
}
.ly-hero-lede[data-v-243b088e] { font-size: 14.5px;
}
}
/* Touch devices without hover (most tablets + phones that fall
   above 600px width) — same reasoning: no hover, no payoff. */
@media (hover: none) and (pointer: coarse) {
.ly-hero-vis[data-v-243b088e] { display: none;
}
}

.custom-comment[data-v-4a30d58e] { max-width: 784px; margin: 32px auto 0; padding-top: 24px; border-top: 1px solid var(--vp-c-divider);
}
.comment-title[data-v-4a30d58e] { font-size: 18px; font-weight: 700; color: var(--vp-c-text-1); margin: 0 0 16px; display: flex; align-items: baseline; gap: 8px;
}
.comment-count[data-v-4a30d58e] {
  font-size: 13px;
  font-weight: 500;
  color: var(--vp-c-text-3);
  background: rgba(15, 23, 42, 0.05);
  padding: 2px 9px;
  border-radius: 10px;
}
.comment-form[data-v-4a30d58e] { margin-bottom: 24px; position: relative;
}
.form-tools[data-v-4a30d58e] { display: flex; align-items: center; gap: 12px;
}
.emoji-trigger[data-v-4a30d58e] {
  background: none;
  border: none;
  padding: 4px;
  cursor: pointer;
  color: var(--vp-c-text-3);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    color      0.15s cubic-bezier(0.2, 0, 0, 1),
    background 0.15s cubic-bezier(0.2, 0, 0, 1);
}
.emoji-trigger[data-v-4a30d58e]:hover { color: #f59e0b; background: rgba(245, 158, 11, 0.08);
}
.emoji-panel[data-v-4a30d58e] {
  position: absolute;
  bottom: 56px;
  left: 0;
  width: 320px;
  padding: 12px;
  background: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  border-radius: 12px;
  /* Popover elevation token (tier 4) — emoji picker floats above
     the comment composer, one tier below the confirm modal. */
  box-shadow: var(--shadow-4);
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 4px;
  z-index: 100;
}
.emoji-btn[data-v-4a30d58e] {
  background: none;
  border: none;
  font-size: 20px;
  cursor: pointer;
  padding: 4px;
  border-radius: 6px;
  transition: background 0.12s var(--ease-out);
  line-height: 1;
}
.emoji-btn[data-v-4a30d58e]:hover { background: rgba(15, 23, 42, 0.06);
}
.emoji-pop-enter-active[data-v-4a30d58e], .emoji-pop-leave-active[data-v-4a30d58e] {
  /* Opacity + transform are the only things changing between
     the from/to states, so scope — keeps the panel's final
     scale steady once open instead of retriggering layout. */
  transition:
    opacity   0.18s cubic-bezier(0.2, 0, 0, 1),
    transform 0.18s cubic-bezier(0.2, 0, 0, 1);
  transform-origin: bottom left;
}
.emoji-pop-enter-from[data-v-4a30d58e], .emoji-pop-leave-to[data-v-4a30d58e] { opacity: 0; transform: scale(0.9) translateY(4px);
}
.comment-textarea[data-v-4a30d58e] {
  width: 100%; padding: 12px; border: 1px solid var(--vp-c-divider); border-radius: 10px;
  font-size: 14px; color: var(--vp-c-text-1); background: var(--vp-c-bg); resize: vertical;
  outline: none; font-family: inherit; box-sizing: border-box;
}
.comment-textarea[data-v-4a30d58e]:focus {
  border-color: var(--vp-c-brand-1);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--vp-c-brand-1) 14%, transparent);
}
.form-footer[data-v-4a30d58e] { display: flex; justify-content: space-between; align-items: center; margin-top: 8px;
}
.char-count[data-v-4a30d58e] { font-size: 12px; color: var(--vp-c-text-3);
}
.btn-submit[data-v-4a30d58e] {
  padding: 6px 18px; background: var(--vp-c-brand-1); color: #fff; border: none;
  border-radius: 8px; font-size: 13px; font-weight: 500; cursor: pointer;
  transition: background 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.btn-submit[data-v-4a30d58e]:hover { background: var(--vp-c-brand-2);
}
.btn-submit[data-v-4a30d58e]:disabled { opacity: 0.5; cursor: not-allowed;
}
.login-hint[data-v-4a30d58e] {
  padding: 16px; background: var(--vp-c-bg-soft); border-radius: 10px;
  display: flex; align-items: center; justify-content: space-between; margin-bottom: 24px;
  font-size: 14px; color: var(--vp-c-text-2);
}
.btn-login[data-v-4a30d58e] {
  padding: 6px 16px; border: 1px solid var(--vp-c-brand-1); border-radius: 8px;
  background: transparent; color: var(--vp-c-brand-1); font-size: 13px; cursor: pointer;
  transition: background 0.18s cubic-bezier(0.2, 0, 0, 1), color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.btn-login[data-v-4a30d58e]:hover {
  background: var(--vp-c-brand-1);
  color: #fff;
}
.comment-item[data-v-4a30d58e] { display: flex; gap: 12px; margin-bottom: 20px; transition: opacity 0.2s var(--ease-out);
}
.comment-item.is-pending[data-v-4a30d58e] { opacity: 0.65;
}
.comment-item.is-pending .author[data-v-4a30d58e]::after,
.reply-item.is-pending .reply-author[data-v-4a30d58e]::after {
  content: '';
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-left: 6px;
  border-radius: 50%;
  background: var(--vp-c-brand-1);
  vertical-align: middle;
  animation: comment-pending-pulse-4a30d58e 1.2s ease-in-out infinite;
}
.reply-item.is-pending[data-v-4a30d58e] { opacity: 0.65;
}
@keyframes comment-pending-pulse-4a30d58e {
0%, 100% { opacity: 0.4; transform: scale(0.85);
}
50%      { opacity: 1;   transform: scale(1.15);
}
}
.comment-avatar[data-v-4a30d58e] {
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
  /* Olive → deeper-olive gradient so the default (no-avatar)
     comment chip sits inside the brand family instead of rendering
     the old indigo→purple gradient. Shows behind the first-char
     initial when no image avatar is set. */
  background: linear-gradient(135deg, #6b9e2c, #3b7e00);
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 600;
  /* When an avatar URL is present the inline <img> fills this
     background, so no extra wiring needed here. */
  background-size: cover;
  background-position: center;
}
.comment-body[data-v-4a30d58e] { flex: 1;
}
.comment-meta[data-v-4a30d58e] { display: flex; align-items: center; gap: 8px; margin-bottom: 4px;
}
.author[data-v-4a30d58e] { font-size: 14px; font-weight: 600; color: var(--vp-c-text-1);
}
.time[data-v-4a30d58e] { font-size: 12px; color: var(--vp-c-text-3);
}
.btn-delete[data-v-4a30d58e] { background: none; border: none; color: var(--vp-c-text-3); font-size: 12px; cursor: pointer; opacity: 0; transition: opacity 0.15s;
}
.comment-item:hover .btn-delete[data-v-4a30d58e] { opacity: 1;
}
.btn-delete[data-v-4a30d58e]:hover { color: #ef4444;
}
.comment-text[data-v-4a30d58e] { font-size: 14px; color: var(--vp-c-text-1); line-height: 1.6; margin: 0;
}
.reply-item[data-v-4a30d58e] {
  margin-top: 8px; padding: 8px 12px; background: var(--vp-c-bg-soft); border-radius: 8px; font-size: 13px;
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px;
}
.reply-author[data-v-4a30d58e] { font-weight: 600; color: var(--vp-c-text-1);
}
.reply-text[data-v-4a30d58e] { color: var(--vp-c-text-2);
}
.reply-time[data-v-4a30d58e] { color: var(--vp-c-text-3); font-size: 11px; margin-left: 4px;
}
.btn-delete-reply[data-v-4a30d58e] {
  background: none; border: none; color: var(--vp-c-text-3); font-size: 11px; cursor: pointer;
  margin-left: auto; opacity: 0; transition: opacity 0.15s;
}
.reply-item:hover .btn-delete-reply[data-v-4a30d58e] { opacity: 1;
}
.btn-delete-reply[data-v-4a30d58e]:hover { color: #ef4444;
}
.btn-reply[data-v-4a30d58e] {
  background: none; border: none; color: var(--vp-c-brand-1); font-size: 12px;
  cursor: pointer; margin-top: 6px; padding: 0;
  transition: color 0.15s cubic-bezier(0.2, 0, 0, 1);
}
.btn-reply[data-v-4a30d58e]:hover { color: var(--vp-c-brand-2); text-decoration: underline; text-underline-offset: 2px;
}
.reply-form[data-v-4a30d58e] { display: flex; gap: 8px; margin-top: 8px;
}
.reply-input[data-v-4a30d58e] {
  flex: 1; height: 34px; padding: 0 10px; border: 1px solid var(--vp-c-divider);
  border-radius: 8px; font-size: 13px; outline: none; background: var(--vp-c-bg);
  color: var(--vp-c-text-1); box-sizing: border-box;
}
.btn-submit-sm[data-v-4a30d58e] {
  padding: 0 14px; height: 34px; background: var(--vp-c-brand-1); color: #fff;
  border: none; border-radius: 8px; font-size: 13px; cursor: pointer;
  transition: background 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.btn-submit-sm[data-v-4a30d58e]:hover { background: var(--vp-c-brand-2);
}
.no-comments[data-v-4a30d58e] { text-align: center; padding: 40px; color: var(--vp-c-text-3); font-size: 14px;
}
.comment-load-error[data-v-4a30d58e] {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 32px;
  color: var(--vp-c-text-3);
  font-size: 14px;
}
.btn-retry[data-v-4a30d58e] {
  padding: 5px 14px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 6px;
  background: transparent;
  color: var(--vp-c-text-2);
  font-size: 13px;
  cursor: pointer;
  font-family: inherit;
  transition:
    border-color 0.15s cubic-bezier(0.2, 0, 0, 1),
    color        0.15s cubic-bezier(0.2, 0, 0, 1);
}
.btn-retry[data-v-4a30d58e]:hover {
  border-color: var(--vp-c-brand-1);
  color: var(--vp-c-brand-1);
}

/* Confirm Dialog */
.confirm-overlay[data-v-4a30d58e] {
  position: fixed; inset: 0; background: rgba(15,23,42,0.5); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; z-index: 999;
}
.confirm-dialog[data-v-4a30d58e] {
  background: var(--vp-c-bg, #fff); border-radius: 14px; padding: 24px 28px;
  /* Confirm-delete dialog — modal tier. */
  box-shadow: var(--shadow-5);
  text-align: center; max-width: 320px;
}
.confirm-dialog p[data-v-4a30d58e] { font-size: 15px; color: var(--vp-c-text-1); margin: 0 0 20px; font-weight: 500;
}
.confirm-actions[data-v-4a30d58e] { display: flex; gap: 12px; justify-content: center;
}
.confirm-cancel[data-v-4a30d58e] {
  padding: 8px 24px; border: 1px solid var(--vp-c-divider); border-radius: 8px;
  background: transparent; color: var(--vp-c-text-2); font-size: 14px; cursor: pointer;
}
.confirm-cancel[data-v-4a30d58e]:hover { border-color: var(--vp-c-text-3);
}
.confirm-ok[data-v-4a30d58e] {
  padding: 8px 24px; border: none; border-radius: 8px;
  background: #ef4444; color: #fff; font-size: 14px; font-weight: 500; cursor: pointer;
}
.confirm-ok[data-v-4a30d58e]:hover { background: #dc2626;
}
.modal-enter-active[data-v-4a30d58e] { transition: opacity 0.2s;
}
.modal-leave-active[data-v-4a30d58e] { transition: opacity 0.15s;
}
.modal-enter-from[data-v-4a30d58e], .modal-leave-to[data-v-4a30d58e] { opacity: 0;
}

.bp-container[data-v-a76292c8] {
  margin: 20px 0;
  border: 1px solid var(--vp-c-divider);
  border-radius: 12px;
  overflow: hidden;
  background: var(--vp-c-bg);
}
.bp-header[data-v-a76292c8] {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: var(--vp-c-bg-soft);
  border-bottom: 1px solid var(--vp-c-divider);
}
.bp-title[data-v-a76292c8] {
  font-weight: 600;
  font-size: 15px;
  color: var(--vp-c-text-1);
}
.bp-info[data-v-a76292c8] {
  font-size: 13px;
  color: var(--vp-c-text-3);
  font-variant-numeric: tabular-nums;
}
.bp-player[data-v-a76292c8] {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 */
  background: #000;
}
.bp-player iframe[data-v-a76292c8] {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.bp-current[data-v-a76292c8] {
  padding: 10px 16px;
  font-size: 14px;
  color: var(--vp-c-text-2);
  border-bottom: 1px solid var(--vp-c-divider);
}
.bp-controls[data-v-a76292c8] {
  display: flex;
  gap: 8px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--vp-c-divider);
}
.bp-btn[data-v-a76292c8] {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 8px;
  background: var(--vp-c-bg-soft);
  color: var(--vp-c-text-1);
  font-size: 13px;
  cursor: pointer;
  transition: all 0.2s ease;
}
.bp-btn[data-v-a76292c8]:hover:not(:disabled) {
  border-color: var(--vp-c-brand-1);
  color: var(--vp-c-brand-1);
  background: var(--vp-c-brand-soft);
}
.bp-btn[data-v-a76292c8]:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.bp-btn-list[data-v-a76292c8] {
  flex: 0.8;
}
.bp-list[data-v-a76292c8] {
  max-height: 320px;
  overflow-y: auto;
  padding: 8px;
}
.bp-list-item[data-v-a76292c8] {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.15s ease;
  font-size: 13px;
  color: var(--vp-c-text-2);
}
.bp-list-item[data-v-a76292c8]:hover {
  background: var(--vp-c-bg-soft);
}
.bp-list-item.active[data-v-a76292c8] {
  background: var(--vp-c-brand-soft);
  color: var(--vp-c-brand-1);
  font-weight: 500;
}
.bp-list-index[data-v-a76292c8] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 4px;
  background: var(--vp-c-bg-soft);
  font-size: 12px;
  font-weight: 500;
  flex-shrink: 0;
}
.bp-list-item.active .bp-list-index[data-v-a76292c8] {
  background: var(--vp-c-brand-1);
  color: #fff;
}
.bp-list-title[data-v-a76292c8] {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lm-overlay[data-v-47c5aeca] {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.6);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
  padding: 20px;
}
.lm-card[data-v-47c5aeca] {
  position: relative;
  width: 400px;
  max-width: 100%;
  background: var(--vp-c-bg, #fff);
  border: 1px solid var(--vp-c-divider, rgba(15,23,42,0.08));
  border-radius: 20px;
  padding: 0 32px 28px;
  overflow: hidden;
  /* Modal elevation (tier 5 on the shadow scale) + a subtle
     brand-olive rim (6% alpha) so the card's border reads as
     gently branded rather than pure neutral. The brand rim is
     a single inset-feel, so it's kept inline; the bulk of the
     lift comes from the shared --shadow-5 token. */
  box-shadow:
    0 0 0 1px rgba(107, 158, 44, 0.06),
    var(--shadow-5);
}
.lm-close[data-v-47c5aeca] {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: var(--vp-c-text-3, #94a3b8);
  cursor: pointer;
  border-radius: 8px;
  transition:
    background 0.15s cubic-bezier(0.2, 0, 0, 1),
    color      0.15s cubic-bezier(0.2, 0, 0, 1);
}
.lm-close[data-v-47c5aeca]:hover {
  background: var(--vp-c-bg-soft, #f8fafc);
  color: var(--vp-c-text-1, #0f172a);
}
.lm-brand[data-v-47c5aeca] {
  text-align: center;
  padding: 28px 0 24px;
}
.lm-owl[data-v-47c5aeca] {
  display: inline-flex;
  margin-bottom: 16px;
}
.lm-title[data-v-47c5aeca] {
  font-size: 22px;
  font-weight: 800;
  color: var(--vp-c-text-1, #0f172a);
  margin: 0 0 6px;
  letter-spacing: -0.02em;
}
.lm-subtitle[data-v-47c5aeca] {
  font-size: 14px;
  color: var(--vp-c-text-3, #94a3b8);
  margin: 0;
}

/* Form */
.lm-form[data-v-47c5aeca] {
  margin-bottom: 8px;
}
.lm-field[data-v-47c5aeca] {
  margin-bottom: 16px;
}
.lm-label[data-v-47c5aeca] {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--vp-c-text-2, #475569);
  margin-bottom: 6px;
  letter-spacing: 0.01em;
}
.lm-input-wrap[data-v-47c5aeca] {
  display: flex;
  align-items: stretch;
  border: 1.5px solid var(--vp-c-divider, #e2e8f0);
  border-radius: 12px;
  overflow: hidden;
  transition: border-color 0.2s, box-shadow 0.2s;
  background: var(--vp-c-bg, #fff);
}
.lm-input-wrap[data-v-47c5aeca]:focus-within {
  border-color: #6b9e2c;
  box-shadow: 0 0 0 3px rgba(107, 158, 44, 0.12);
}
.lm-input-prefix[data-v-47c5aeca] {
  display: flex;
  align-items: center;
  padding: 0 12px;
  font-size: 14px;
  font-weight: 600;
  color: var(--vp-c-text-3, #94a3b8);
  background: var(--vp-c-bg-soft, #f8fafc);
  border-right: 1.5px solid var(--vp-c-divider, #e2e8f0);
  user-select: none;
}
.lm-input[data-v-47c5aeca] {
  flex: 1;
  height: 46px;
  border: none;
  padding: 0 14px;
  font-size: 15px;
  font-weight: 500;
  color: var(--vp-c-text-1, #0f172a);
  background: transparent;
  outline: none;
  letter-spacing: 0.02em;
}
.lm-input[data-v-47c5aeca]::placeholder {
  color: var(--vp-c-text-3, #94a3b8);
  font-weight: 400;
}
.lm-code-input[data-v-47c5aeca] {
  border: 1.5px solid var(--vp-c-divider, #e2e8f0);
  border-radius: 12px;
  background: var(--vp-c-bg, #fff);
  transition: border-color 0.2s, box-shadow 0.2s;
  letter-spacing: 0.15em;
}
.lm-code-input[data-v-47c5aeca]:focus {
  border-color: #6b9e2c;
  box-shadow: 0 0 0 3px rgba(107, 158, 44, 0.12);
}
.lm-code-row[data-v-47c5aeca] {
  display: flex;
  gap: 10px;
}
.lm-code-row .lm-code-input[data-v-47c5aeca] { flex: 1;
}
.lm-resend[data-v-47c5aeca] {
  height: 46px;
  padding: 0 16px;
  border: 1.5px solid var(--vp-c-divider, #e2e8f0);
  border-radius: 12px;
  background: var(--vp-c-bg-soft, #f8fafc);
  color: var(--vp-c-text-2, #475569);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition:
    border-color 0.15s cubic-bezier(0.2, 0, 0, 1),
    color        0.15s cubic-bezier(0.2, 0, 0, 1),
    opacity      0.15s cubic-bezier(0.2, 0, 0, 1);
  flex-shrink: 0;
}
.lm-resend[data-v-47c5aeca]:hover:not(:disabled) {
  border-color: #6b9e2c;
  color: #6b9e2c;
}
.lm-resend[data-v-47c5aeca]:disabled { opacity: 0.5; cursor: not-allowed;
}
.lm-sent-hint[data-v-47c5aeca] {
  font-size: 13px;
  color: var(--vp-c-text-2, #475569);
  margin-bottom: 16px;
  padding: 10px 14px;
  background: rgba(107, 158, 44, 0.06);
  border-radius: 10px;
  border: 1px solid rgba(107, 158, 44, 0.12);
}
.lm-sent-hint strong[data-v-47c5aeca] {
  color: var(--vp-c-text-1, #0f172a);
  font-weight: 600;
}
.lm-change[data-v-47c5aeca] {
  background: none;
  border: none;
  color: #6b9e2c;
  font-size: 13px;
  cursor: pointer;
  padding: 0;
  margin-left: 4px;
  font-weight: 500;
}
.lm-change[data-v-47c5aeca]:hover { text-decoration: underline;
}

/* Submit button */
.lm-btn[data-v-47c5aeca] {
  width: 100%;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: none;
  border-radius: 12px;
  background: #6b9e2c;
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  /* Resting shadow so hover deepens elevation instead of popping a
     new shadow from 0. Unified cubic-bezier matches .book / .pill
     easing on the landing so the whole brand moves in one voice. */
  transition:
    background  0.18s cubic-bezier(0.2, 0, 0, 1),
    box-shadow  0.22s cubic-bezier(0.2, 0, 0, 1),
    transform   0.18s cubic-bezier(0.2, 0, 0, 1);
  margin-top: 4px;
  letter-spacing: 0.02em;
  box-shadow: 0 2px 6px rgba(107, 158, 44, 0.14);
}
.lm-btn[data-v-47c5aeca]:hover:not(.disabled) {
  background: #568620;
  box-shadow:
    0 8px 22px rgba(107, 158, 44, 0.30),
    0 2px 6px rgba(107, 158, 44, 0.18);
  transform: translateY(-1px);
}
.lm-btn[data-v-47c5aeca]:active:not(.disabled) {
  transform: translateY(0);
  transition-duration: 0.08s;
}
.lm-btn.disabled[data-v-47c5aeca] {
  opacity: 0.45;
  cursor: not-allowed;
  box-shadow: none;
}
.lm-btn svg[data-v-47c5aeca] {
  transition: transform 0.22s cubic-bezier(0.2, 0, 0, 1);
}
.lm-btn:hover:not(.disabled) svg[data-v-47c5aeca] {
  /* 3px instead of 2px so the arrow reads as "let's go" at pointer
     hover speed, still subtle enough not to look bouncy. */
  transform: translateX(3px);
}

/* Error */
.lm-error[data-v-47c5aeca] {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 12px;
  padding: 10px 14px;
  background: rgba(239, 68, 68, 0.06);
  border: 1px solid rgba(239, 68, 68, 0.1);
  color: #ef4444;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 500;
}

/* Footer */
.lm-footer[data-v-47c5aeca] {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--vp-c-divider, rgba(15,23,42,0.06));
  font-size: 12px;
  color: var(--vp-c-text-3, #94a3b8);
}
.lm-footer svg[data-v-47c5aeca] {
  opacity: 0.6;
}

/* Transitions */
.modal-enter-active[data-v-47c5aeca] {
  transition: opacity 0.25s var(--ease-out);
}
.modal-enter-active .lm-card[data-v-47c5aeca] {
  /* Card uses its own back-ease curve (slight overshoot) for the
     entrance pop; opacity tracks the backdrop's curve so the
     modal fades in alongside the darkening overlay. */
  transition:
    transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
    opacity   0.25s var(--ease-out);
}
.modal-leave-active[data-v-47c5aeca] {
  /* fast-out ease instead of plain `ease` so the overlay fades
     quickly at the start and trails off — matches how the enter
     curve resolves, so the modal feels like it retracts rather
     than vanishes. */
  transition: opacity 0.18s cubic-bezier(0.4, 0, 1, 1);
}
.modal-leave-active .lm-card[data-v-47c5aeca] {
  transition:
    transform 0.18s cubic-bezier(0.4, 0, 1, 1),
    opacity   0.18s cubic-bezier(0.4, 0, 1, 1);
}
.modal-enter-from[data-v-47c5aeca] {
  opacity: 0;
}
.modal-enter-from .lm-card[data-v-47c5aeca] {
  opacity: 0;
  transform: scale(0.92) translateY(10px);
}
.modal-leave-to[data-v-47c5aeca] {
  opacity: 0;
}
.modal-leave-to .lm-card[data-v-47c5aeca] {
  opacity: 0;
  transform: scale(0.96);
}

/* Honeypot — moved off-screen so a real human never sees or tabs to
   it. Kept in the form (not display:none) because some bots skip
   hidden fields but not off-canvas ones. */
.lm-honeypot[data-v-47c5aeca] {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px; height: 1px; overflow: hidden;
}

/* Hidden trigger the Aliyun SDK binds its click handler to —
   off-canvas so humans never see it. */
.lm-captcha-hidden-trigger[data-v-47c5aeca] {
  position: absolute;
  left: -9999px; top: -9999px;
  width: 1px; height: 1px;
  border: 0; padding: 0; background: transparent;
  overflow: hidden;
}
.lm-captcha-mount[data-v-47c5aeca] { min-height: 0;
}
.lm-captcha-hint[data-v-47c5aeca] {
  margin-top: 10px;
  padding: 8px 12px;
  font-size: 12.5px;
  color: var(--vp-c-text-2);
  background: rgba(234, 179, 8, 0.08);
  border: 1px solid rgba(234, 179, 8, 0.25);
  border-radius: 8px;
}

/* On narrow phones the 32px side-padding left inputs cramped against
   the card border — shrink it so the whole form breathes. */
@media (max-width: 480px) {
.lm-overlay[data-v-47c5aeca] { padding: 12px;
}
.lm-card[data-v-47c5aeca] { padding: 0 20px 22px; border-radius: 16px;
}
.lm-brand[data-v-47c5aeca] { padding: 24px 0 20px;
}
.lm-title[data-v-47c5aeca] { font-size: 20px;
}
.lm-input-prefix[data-v-47c5aeca] { padding: 0 10px; font-size: 13px;
}
.lm-input[data-v-47c5aeca] { height: 44px; font-size: 14px; padding: 0 12px;
}
.lm-btn[data-v-47c5aeca] { height: 44px; font-size: 14px;
}
.lm-resend[data-v-47c5aeca] { height: 44px; padding: 0 12px; font-size: 12px;
}
}

.ss-overlay[data-v-1d9c805b] {
  position: fixed;
  inset: 0;
  background: rgba(10, 11, 15, 0.6);
  backdrop-filter: blur(4px);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.ss-card[data-v-1d9c805b] {
  position: relative;
  width: min(420px, 100%);
  background: var(--vp-c-bg, #fff);
  color: var(--vp-c-text-1, #0f172a);
  border-radius: 16px;
  padding: 28px 24px 22px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.18);
}
.ss-close[data-v-1d9c805b] {
  position: absolute;
  top: 12px;
  right: 12px;
  background: transparent;
  border: none;
  color: var(--vp-c-text-2, #475569);
  cursor: pointer;
  padding: 6px;
  border-radius: 8px;
  transition: background 0.15s;
}
.ss-close[data-v-1d9c805b]:hover { background: var(--vp-c-bg-soft, #f8fafc);
}
.ss-head[data-v-1d9c805b] { text-align: center; padding-bottom: 18px;
}
.ss-title[data-v-1d9c805b] { font-size: 18px; font-weight: 700;
}
.ss-subtitle[data-v-1d9c805b] {
  font-size: 13px;
  color: var(--vp-c-text-2, #64748b);
  margin-top: 6px;
}
.ss-elide[data-v-1d9c805b] {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ss-grid[data-v-1d9c805b] {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 4px;
}
@media (max-width: 380px) {
.ss-grid[data-v-1d9c805b] { grid-template-columns: repeat(2, 1fr);
}
}
.ss-item[data-v-1d9c805b] {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 14px 6px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: transparent;
  cursor: pointer;
  font: inherit;
  color: var(--vp-c-text-1);
  transition: background 0.15s, transform 0.1s;
}
.ss-item[data-v-1d9c805b]:hover {
  background: var(--vp-c-bg-soft, #f8fafc);
}
.ss-item[data-v-1d9c805b]:active { transform: scale(0.97);
}
.ss-item[data-v-1d9c805b]:disabled { opacity: 0.5; cursor: wait;
}
.ss-icon[data-v-1d9c805b] {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 12px;
  color: var(--vp-c-text-1);
}
.ss-label[data-v-1d9c805b] { font-size: 12.5px;
}
.ss-qr-pane[data-v-1d9c805b] {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 0 4px;
}
.ss-qr-tip[data-v-1d9c805b] {
  font-size: 13px;
  color: var(--vp-c-text-2, #64748b);
  margin-bottom: 14px;
}
.ss-qr-wrap[data-v-1d9c805b] {
  padding: 12px;
  background: #fff;
  border-radius: 12px;
  border: 1px solid var(--vp-c-divider, #e2e8f0);
}
.ss-qr-url[data-v-1d9c805b] {
  font-size: 11.5px;
  color: var(--vp-c-text-3, #94a3b8);
  max-width: 100%;
  margin-top: 12px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.ss-back[data-v-1d9c805b] {
  margin-top: 16px;
  font-size: 13px;
  color: var(--vp-c-text-2);
  background: transparent;
  border: 1px solid var(--vp-c-divider, #e2e8f0);
  padding: 6px 18px;
  border-radius: 8px;
  cursor: pointer;
}
.ss-back[data-v-1d9c805b]:hover { background: var(--vp-c-bg-soft, #f8fafc);
}
.ss-err[data-v-1d9c805b] {
  margin-top: 12px;
  text-align: center;
  font-size: 13px;
  color: #ef4444;
}
.ss-fade-enter-active[data-v-1d9c805b], .ss-fade-leave-active[data-v-1d9c805b] {
  transition: opacity 0.18s;
}
.ss-fade-enter-from[data-v-1d9c805b], .ss-fade-leave-to[data-v-1d9c805b] { opacity: 0;
}

.article-header[data-v-a7f8b0d4] {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 16px 0 20px;
  margin: 0 0 20px;
  border-bottom: 1px solid var(--vp-c-divider);
  gap: 14px;
}

/* Eyebrow pill — purple dot + book title + chapter number.
   Matches mockup V3's "● 第二部分 · 协议基础 · Chapter 04"
   above-h1 kicker. */
.ah-eyebrow[data-v-a7f8b0d4] {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  align-self: flex-start;
  padding: 5px 14px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 999px;
  font-family: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', monospace;
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: var(--vp-c-text-2);
  background: var(--vp-c-bg-soft);
}
.ah-eyebrow-dot[data-v-a7f8b0d4] {
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  /* Brand olive on light, lemon on dark (see :global below). Pre-
     brand value was #8b5cf6 purple — clashed with the olive/lemon
     accent system used everywhere else. */
  background: var(--vp-c-brand-1);
  box-shadow: 0 0 10px color-mix(in oklab, var(--vp-c-brand-1) 55%, transparent);
  animation: ah-eyebrow-pulse-a7f8b0d4 2.2s ease-in-out infinite;
}
.ah-eyebrow-sep[data-v-a7f8b0d4] {
  color: var(--vp-c-text-3);
  opacity: 0.5;
}
.ah-eyebrow-chap[data-v-a7f8b0d4] {
  color: var(--vp-c-text-1);
  font-weight: 600;
  letter-spacing: 0.05em;
}
@keyframes ah-eyebrow-pulse-a7f8b0d4 {
0%, 100% { opacity: 0.85; transform: scale(1);
}
50%      { opacity: 1;    transform: scale(1.2);
}
}
.dark {
  background: #c4f857;
  box-shadow: 0 0 10px rgba(196, 248, 87, 0.55);
}

/* Lede — one-paragraph thesis, bigger and lighter than body
   prose. Sits between eyebrow and meta row to match mockup V3. */
.ah-lede[data-v-a7f8b0d4] {
  font-size: 17px;
  line-height: 1.6;
  color: var(--vp-c-text-2);
  font-weight: 400;
  margin: 2px 0 4px;
  max-width: 68ch;
  letter-spacing: 0.005em;
}
.dark {
  color: #c8ccd4;
}
@media (max-width: 640px) {
.ah-lede[data-v-a7f8b0d4] {
    font-size: 15px;
    line-height: 1.55;
}
}
.ah-author[data-v-a7f8b0d4] {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
}

/* Mockup V3 inline action row on the right of the author meta —
   for now just 分享. 收藏 will come once the API wiring is in
   a good state. Pushed right with margin-left: auto on .ah-meta
   or .ah-actions ordering; keeping it as a sibling after the
   avatar so it flows naturally in the row. */
.ah-actions[data-v-a7f8b0d4] {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  flex-shrink: 0;
  order: 99;
}
.ah-action[data-v-a7f8b0d4] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 999px;
  background: var(--vp-c-bg);
  color: var(--vp-c-text-2);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  transition:
    color        0.15s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.15s cubic-bezier(0.2, 0, 0, 1),
    background   0.15s cubic-bezier(0.2, 0, 0, 1);
}
.ah-action[data-v-a7f8b0d4]:hover {
  color: var(--vp-c-text-1);
  border-color: var(--vp-c-text-3);
}
.ah-action.is-ok[data-v-a7f8b0d4] {
  color: #059669;
  border-color: rgba(16, 185, 129, 0.45);
  background: rgba(16, 185, 129, 0.08);
}
.dark {
  color: #34d399;
  background: rgba(16, 185, 129, 0.12);
}
@media (max-width: 640px) {
.ah-actions[data-v-a7f8b0d4] {
    order: 0;
    margin-left: 0;
    margin-top: 4px;
}
.ah-action[data-v-a7f8b0d4] {
    padding: 6px 12px;
    font-size: 12px;
}
}
.ah-avatar[data-v-a7f8b0d4] {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  flex-shrink: 0;
  overflow: hidden;
  background: #f1f5f9;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.06), 0 4px 12px rgba(15, 23, 42, 0.08);
  position: relative;
}
.ah-avatar img[data-v-a7f8b0d4] {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.dark .ah-avatar[data-v-a7f8b0d4] {
  border-color: rgba(148, 163, 184, 0.2);
  box-shadow: 0 0 0 1px rgba(148, 163, 184, 0.15), 0 4px 12px rgba(0, 0, 0, 0.3);
}
.ah-meta[data-v-a7f8b0d4] {
  flex: 1;
  min-width: 0;
}
.ah-name[data-v-a7f8b0d4] {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.ah-name .name[data-v-a7f8b0d4] {
  font-size: 15px;
  font-weight: 600;
  color: var(--vp-c-text-1);
}
.ah-name .badge[data-v-a7f8b0d4] {
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 4px;
  /* Brand olive chip — matches the "作者" badge in ArticleFooter so
     the same author signal reads identically on top-of-chapter and
     bottom-of-chapter. Previous blue was pre-brand residue. */
  background: rgba(107, 158, 44, 0.14);
  color: #5a8426;
  font-weight: 500;
}
.dark {
  background: rgba(196, 248, 87, 0.16);
  color: #c4f857;
}
.ah-name .badge-paid[data-v-a7f8b0d4] {
  background: linear-gradient(135deg, rgba(245, 158, 11, 0.12), rgba(249, 115, 22, 0.12));
  color: #d97706;
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
.dark .ah-name .badge-paid[data-v-a7f8b0d4] {
  color: #fbbf24;
  background: linear-gradient(135deg, rgba(245, 158, 11, 0.15), rgba(249, 115, 22, 0.15));
}
.ah-stats[data-v-a7f8b0d4] {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--vp-c-text-3);
  flex-wrap: wrap;
}
.ah-stats .dot[data-v-a7f8b0d4] {
  opacity: 0.5;
}
.ah-date[data-v-a7f8b0d4] {
  cursor: help;
}
.ah-date-rel[data-v-a7f8b0d4] {
  color: var(--vp-c-text-2);
  font-weight: 500;
}
.ah-my-visits[data-v-a7f8b0d4] {
  /* "你第 N 次阅读" personal stat — was indigo, so it contrasted
     with the meta-row text but in an off-brand way. Use brand
     olive; the weight + cursor:help tooltip still mark it as
     interactive without needing a contrasting hue. */
  color: var(--vp-c-brand-1);
  font-weight: 600;
  cursor: help;
}
.dark {
  color: #c4f857;
}
.ah-sync[data-v-a7f8b0d4] {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 7px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 11.5px;
  cursor: help;
}
.ah-sync.is-cloud[data-v-a7f8b0d4] {
  background: rgba(16, 185, 129, 0.1);
  color: #059669;
}
.ah-sync.is-local[data-v-a7f8b0d4] {
  background: rgba(148, 163, 184, 0.12);
  color: #64748b;
}
.ah-sync svg[data-v-a7f8b0d4] {
  flex-shrink: 0;
  opacity: 0.85;
}
.dark .ah-sync.is-cloud[data-v-a7f8b0d4] {
  background: rgba(16, 185, 129, 0.18);
  color: #34d399;
}
.dark .ah-sync.is-local[data-v-a7f8b0d4] {
  background: rgba(148, 163, 184, 0.18);
  color: #94a3b8;
}
@media (max-width: 640px) {
.article-header[data-v-a7f8b0d4] {
    padding: 12px 0 16px;
    margin-bottom: 16px;
}
.ah-avatar[data-v-a7f8b0d4] {
    width: 38px;
    height: 38px;
    font-size: 15px;
}
.ah-name .name[data-v-a7f8b0d4] {
    font-size: 14px;
}
.ah-stats[data-v-a7f8b0d4] {
    font-size: 12px;
}
}

.book-header[data-v-33f5f092] {
  display: flex;
  flex-direction: column;
  padding: 0 0 20px;
  margin: 0 0 20px;
  border-bottom: 1px solid var(--vp-c-divider);
}

/* Hero strip — same geometric art vocabulary as the landing
   book cards, but now carrying the primary title + one-line
   description so the hero is the page's real opening. The
   markdown H1 below is still there as a heading anchor, just
   visually redundant with the hero — readers scan the hero
   first and skip the H1. */
.bh-hero[data-v-33f5f092] {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 6;
  max-height: 260px;
  min-height: 180px;
  border-radius: 14px;
  overflow: hidden;
  margin: 0 0 22px;
  /* tier-1 hairline elevation — this is a hero image, not a
     card, so we keep the resting shadow minimal. */
  box-shadow: var(--shadow-1);
}
.bh-hero[data-v-33f5f092]::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 80% at 20% 0%, rgba(255, 255, 255, 0.15), transparent 50%),
    linear-gradient(180deg, transparent 40%, rgba(0, 0, 0, 0.34));
  pointer-events: none;
}
.bh-hero-ink[data-v-33f5f092] {
  position: absolute;
  left: 28px;
  right: 28px;
  bottom: 22px;
  z-index: 1;
  color: #fff;
  max-width: 620px;
}
.bh-hero-eyebrow[data-v-33f5f092] {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.82;
  margin: 0 0 10px;
}
.bh-hero-slug[data-v-33f5f092] {
  font-weight: 600;
}
.bh-hero-sep[data-v-33f5f092] {
  opacity: 0.6;
}
.bh-hero-title[data-v-33f5f092] {
  font-family: 'Newsreader', 'Noto Serif SC', Georgia, serif;
  font-size: clamp(22px, 3.2vw, 32px);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.15;
  margin: 0 0 8px;
  /* Soft drop shadow so the title stays readable over the
     radial glow patch in the top-left of some compositions. */
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.18);
}
.bh-hero-desc[data-v-33f5f092] {
  font-size: 14px;
  line-height: 1.55;
  opacity: 0.92;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
@media (max-width: 640px) {
.bh-hero[data-v-33f5f092] {
    aspect-ratio: 4 / 3;
    max-height: 240px;
    border-radius: 10px;
}
.bh-hero-ink[data-v-33f5f092] {
    left: 16px;
    right: 16px;
    bottom: 14px;
}
.bh-hero-eyebrow[data-v-33f5f092] {
    font-size: 10.5px;
    letter-spacing: 0.16em;
}
.bh-hero-desc[data-v-33f5f092] {
    font-size: 13px;
    -webkit-line-clamp: 3;
}
}
.bh-author[data-v-33f5f092] {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 4px 0 0;
}
.bh-avatar[data-v-33f5f092] {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  flex-shrink: 0;
  overflow: hidden;
  background: #f1f5f9;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.06), 0 4px 12px rgba(15, 23, 42, 0.08);
}
.bh-avatar img[data-v-33f5f092] {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.dark .bh-avatar[data-v-33f5f092] {
  border-color: rgba(148, 163, 184, 0.2);
  box-shadow: 0 0 0 1px rgba(148, 163, 184, 0.15), 0 4px 12px rgba(0, 0, 0, 0.3);
}
.bh-meta[data-v-33f5f092] {
  flex: 1;
  min-width: 0;
}
.bh-name[data-v-33f5f092] {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.bh-name .name[data-v-33f5f092] {
  font-size: 16px;
  font-weight: 600;
  color: var(--vp-c-text-1);
}
.bh-name .badge[data-v-33f5f092] {
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 4px;
  /* Matches the "作者" badge on ArticleHeader + ArticleFooter.
     Was pre-brand blue — now olive 14% alpha on light, lemon 16%
     on dark, so the same author signal reads identically across
     book index, top-of-chapter and bottom-of-chapter. */
  background: rgba(107, 158, 44, 0.14);
  color: #5a8426;
  font-weight: 500;
}
.dark {
  background: rgba(196, 248, 87, 0.16);
  color: #c4f857;
}
.bh-stats[data-v-33f5f092] {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--vp-c-text-3);
  flex-wrap: wrap;
}
.bh-stats .dot[data-v-33f5f092] {
  opacity: 0.5;
}
.bh-unlock[data-v-33f5f092] {
  margin-top: 16px;
  padding-top: 14px;
  /* Solid hairline, not dashed — same reasoning as the
     .book-latest divider fix on the landing: dashed reads
     "provisional" and fights the editorial feel. */
  border-top: 1px solid rgba(15, 23, 42, 0.08);
}
.dark .bh-unlock[data-v-33f5f092] {
  border-top-color: rgba(148, 163, 184, 0.12);
}
.bh-unlock-bar[data-v-33f5f092] {
  height: 6px;
  background: rgba(15, 23, 42, 0.06);
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 8px;
}
.dark .bh-unlock-bar[data-v-33f5f092] {
  background: rgba(148, 163, 184, 0.1);
}
.bh-unlock-fill[data-v-33f5f092] {
  height: 100%;
  /* Book index "unlock progress" bar — blue→purple was a
     pre-brand holdover. Olive → accent-lemon so "how much of
     this book have I read" reads on-brand, with a warmer end-
     stop that tracks the chapter-progress bar on the sidebar. */
  background: linear-gradient(90deg, var(--vp-c-brand-1), #a5e043);
  border-radius: 3px;
  transition: width 0.5s cubic-bezier(0.2, 0, 0, 1);
}
.dark {
  background: linear-gradient(90deg, #c4f857, #a5e043);
}
.bh-unlock-label[data-v-33f5f092] {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: var(--vp-c-text-3);
  flex-wrap: wrap;
  gap: 8px;
}
.bh-unlock-num[data-v-33f5f092] {
  font-weight: 600;
  color: var(--vp-c-text-1);
}
.bh-unlock-cta[data-v-33f5f092] {
  color: var(--vp-c-brand-1);
  font-weight: 500;
  text-decoration: none;
  transition: color 0.15s var(--ease-out);
}
.bh-unlock-cta[data-v-33f5f092]:hover {
  color: var(--vp-c-brand-2);
}
.bh-unlock-cta-btn[data-v-33f5f092] {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
}
.bh-unlock-cta-btn[data-v-33f5f092]:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.bh-unlock-done[data-v-33f5f092] {
  color: #10b981;
  font-weight: 500;
}
@media (max-width: 640px) {
.book-header[data-v-33f5f092] {
    padding: 12px 0 16px;
    margin-bottom: 16px;
}
.bh-avatar[data-v-33f5f092] {
    width: 42px;
    height: 42px;
}
.bh-name .name[data-v-33f5f092] {
    font-size: 15px;
}
.bh-stats[data-v-33f5f092] {
    font-size: 12px;
}
}

/* V3 Docs Modern: subtle context strip + two nav cards.
   Placed BEFORE the doc content (via 'doc-before' slot) so the reader
   sees "book › chapter · progress" then hits the article body. */
.ctn-wrap[data-v-44835ba5] {
  margin: 0 0 28px;
}
.ctn-context[data-v-44835ba5] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 16px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-radius: 10px;
  font-size: 12.5px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.ctn-crumbs[data-v-44835ba5] { display: inline-flex; align-items: center; gap: 8px; min-width: 0; flex: 1;
}
.crumb-book[data-v-44835ba5] { color: var(--vp-c-text-2); font-weight: 500; white-space: nowrap; transition: color .15s;
}
.crumb-book[data-v-44835ba5]:hover { color: var(--vp-c-brand-1);
}
.crumb-sep[data-v-44835ba5] { color: var(--vp-c-text-3); flex-shrink: 0;
}
.crumb-chapter[data-v-44835ba5] {
  color: var(--vp-c-text-1); font-weight: 500; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ctn-progress[data-v-44835ba5] { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0;
}
.ctn-progress-text[data-v-44835ba5] {
  font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  font-size: 11px; color: var(--vp-c-text-3); font-weight: 600;
}
.ctn-progress-track[data-v-44835ba5] {
  width: 80px; height: 3px;
  background: var(--vp-c-default-2); border-radius: 2px; overflow: hidden;
}
.ctn-progress-fill[data-v-44835ba5] {
  height: 100%; background: var(--vp-c-brand-1);
  border-radius: 2px; transition: width 0.4s var(--ease-out);
}
.ctn-progress-pct[data-v-44835ba5] {
  font-size: 11px; font-weight: 700; color: var(--vp-c-brand-1);
  min-width: 32px; text-align: right;
  font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
}
.ctn-read-badge[data-v-44835ba5] {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 700; color: var(--vp-c-brand-1);
  background: var(--vp-c-brand-soft); padding: 2px 8px; border-radius: 999px;
  letter-spacing: 0.05em; margin-right: 4px;
}

/* Prev / home / next */
.chapter-top-nav[data-v-44835ba5] {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 12px;
  align-items: stretch;
}
.ctn-card[data-v-44835ba5] {
  display: block; padding: 14px 16px;
  border: 1px solid var(--vp-c-divider); border-radius: 10px;
  background: var(--vp-c-bg);
  transition: border-color .15s, box-shadow .15s;
  min-width: 0;
}
.ctn-card[data-v-44835ba5]:hover {
  border-color: var(--vp-c-text-3);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06);
}
.ctn-card .d[data-v-44835ba5] {
  font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  font-size: 11px; color: var(--vp-c-text-3);
  letter-spacing: .04em; text-transform: uppercase; margin-bottom: 4px;
}
.ctn-card .t[data-v-44835ba5] {
  font-size: 14px; font-weight: 600; color: var(--vp-c-text-1);
  letter-spacing: -.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ctn-next[data-v-44835ba5] { text-align: right;
}
.ctn-next .t[data-v-44835ba5]::after { content: " →"; color: var(--vp-c-brand-1);
}
.ctn-prev .t[data-v-44835ba5]::before { content: "← "; color: var(--vp-c-brand-1);
}
.ctn-home[data-v-44835ba5] {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0 14px;
  border: 1px solid var(--vp-c-divider); border-radius: 10px;
  background: var(--vp-c-bg); color: var(--vp-c-text-2);
  font-size: 12px; font-weight: 500;
  transition: border-color .15s, color .15s;
  white-space: nowrap; align-self: stretch;
}
.ctn-home[data-v-44835ba5]:hover { border-color: var(--vp-c-brand-1); color: var(--vp-c-brand-1);
}
.ctn-home svg[data-v-44835ba5] { flex-shrink: 0;
}
.ctn-placeholder[data-v-44835ba5] { min-width: 1px;
}
@media (max-width: 640px) {
.chapter-top-nav[data-v-44835ba5] { gap: 8px;
}
.ctn-context[data-v-44835ba5] { padding: 10px 12px; flex-direction: column; align-items: flex-start; gap: 8px;
}
.ctn-progress[data-v-44835ba5] { width: 100%;
}
.ctn-progress-track[data-v-44835ba5] { flex: 1;
}
.ctn-home span[data-v-44835ba5] { display: none;
}
.ctn-home[data-v-44835ba5] { padding: 0 10px;
}
}

.nav-breadcrumb {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: 18px;
  padding-left: 18px;
  border-left: 1px solid var(--vp-c-divider);
  font-size: 13.5px;
  color: var(--vp-c-text-2);
  white-space: nowrap;
  min-width: 0;
  max-width: 60vw;
}
.nav-breadcrumb .nbc-book {
  color: var(--vp-c-text-2);
  font-weight: 500;
  transition: color 0.15s var(--ease-out);
}
.nav-breadcrumb .nbc-book:hover {
  color: var(--vp-c-text-1);
}
.nav-breadcrumb .nbc-sep {
  color: var(--vp-c-text-3);
  opacity: 0.5;
  flex-shrink: 0;
}
.nav-breadcrumb .nbc-section {
  color: var(--vp-c-text-2);
  flex-shrink: 0;
}
.nav-breadcrumb .nbc-current {
  color: var(--vp-c-text-1);
  font-weight: 600;
  flex-shrink: 0;
}
html.dark .nav-breadcrumb .nbc-current {
  color: #ecedf0;
}
@media (max-width: 959px) {
.nav-breadcrumb { display: none;
}
}

.cr[data-v-afce0927] {
  margin: 36px 0 28px;
  padding: 20px 22px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-radius: 14px;
}
.cr-head[data-v-afce0927] {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 14px;
}
.cr-title[data-v-afce0927] { font-size: 14px; color: var(--vp-c-text-2); font-weight: 500;
}
.cr-total[data-v-afce0927] { font-size: 12px; color: var(--vp-c-text-3); font-variant-numeric: tabular-nums;
}
.cr-row[data-v-afce0927] { display: flex; gap: 10px; flex-wrap: wrap;
}
.cr-btn[data-v-afce0927] {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 999px;
  background: var(--vp-c-bg);
  color: var(--vp-c-text-2);
  font-size: 13px;
  cursor: pointer;
  transition:
    border-color 0.15s,
    color        0.15s,
    background   0.15s,
    transform    0.1s;
}
.cr-btn[data-v-afce0927]:hover:not(:disabled) { border-color: var(--cr-tint); color: var(--vp-c-text-1);
}
.cr-btn[data-v-afce0927]:active:not(:disabled) { transform: scale(0.97);
}
.cr-btn.on[data-v-afce0927] {
  border-color: var(--cr-tint);
  background: color-mix(in oklab, var(--cr-tint) 18%, transparent);
  color: var(--vp-c-text-1);
}
.cr-btn[data-v-afce0927]:disabled { opacity: 0.6; cursor: wait;
}
.cr-icon[data-v-afce0927] { font-size: 16px; line-height: 1;
}
.cr-label[data-v-afce0927] { font-weight: 500;
}
.cr-count[data-v-afce0927] { color: var(--vp-c-text-3); font-variant-numeric: tabular-nums;
}
.cr-btn.on .cr-count[data-v-afce0927] { color: var(--vp-c-text-1);
}
@media (max-width: 600px) {
.cr[data-v-afce0927] { padding: 16px 16px;
}
.cr-btn[data-v-afce0927] { padding: 7px 12px; font-size: 12.5px;
}
}

.rw[data-v-ef486cb6] {
  margin: 28px 0;
  padding: 18px 22px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-radius: 14px;
}
.rw-head[data-v-ef486cb6] {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 12px;
}
.rw-title[data-v-ef486cb6] { font-size: 14px; color: var(--vp-c-text-2); font-weight: 500;
}
.rw-count[data-v-ef486cb6] { font-size: 12px; color: var(--vp-c-text-3); font-variant-numeric: tabular-nums;
}
.rw-list[data-v-ef486cb6] { display: flex; flex-wrap: wrap; gap: 8px;
}
.rw-ava[data-v-ef486cb6] {
  position: relative;
  width: 36px; height: 36px; border-radius: 50%;
  background: linear-gradient(135deg, #6b9e2c, #568620);
  color: #fff; font-size: 14px; font-weight: 600;
  display: flex; align-items: center; justify-content: center;
  text-decoration: none; overflow: hidden;
  transition: transform 0.15s;
}
.rw-ava[data-v-ef486cb6]:hover { transform: scale(1.1); z-index: 1;
}
.rw-letter[data-v-ef486cb6] { line-height: 1; user-select: none;
}
.rw-img[data-v-ef486cb6] { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
@media (max-width: 600px) {
.rw[data-v-ef486cb6] { padding: 14px 16px;
}
.rw-ava[data-v-ef486cb6] { width: 32px; height: 32px; font-size: 13px;
}
}

.article-footer[data-v-6a5bc068] {
  margin: 48px 0 24px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* Footer quick-nav — four small chips at the top of the footer
   so a returning reader can jump to their notes / the
   bibliography / recommendations / author card without scrolling
   past the rest. Low-key by design: 12px text, bg-soft pill,
   hover flips indigo. */
.af-quicknav[data-v-6a5bc068] {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 4px;
}
.af-quicknav a[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  color: var(--vp-c-text-2);
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  transition:
    transform    0.15s var(--ease-out),
    color        0.15s var(--ease-out),
    border-color 0.15s var(--ease-out),
    background   0.15s var(--ease-out);
}
.af-quicknav a[data-v-6a5bc068]:hover {
  transform: translateY(-1px);
  color: var(--vp-c-brand-1);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 38%, transparent);
  background: var(--vp-c-bg);
}

/* Offset anchor targets so smooth-scroll lands below the nav,
   not underneath it. */
.article-footer [id$="-anchor"][data-v-6a5bc068] {
  scroll-margin-top: 80px;
}

/* Visual learning trail — a row of small dots representing every
   chapter in the book. Past dots are emerald-filled, the current
   one is brand-color and enlarged with its number, future dots
   are hollow. Gives the reader a "where am I in the journey"
   sense at chapter end without scrolling to the sidebar. */
.af-trail[data-v-6a5bc068] {
  padding: 16px 20px 14px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-radius: 14px;
}
.af-trail-meta[data-v-6a5bc068] {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.af-trail-label[data-v-6a5bc068] {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vp-c-text-2);
}
.af-trail-progress[data-v-6a5bc068] {
  font-size: 12px;
  color: var(--vp-c-text-3);
}
.af-trail-dwell[data-v-6a5bc068] {
  margin-left: 4px;
  color: #f59e0b;
  font-weight: 600;
}

/* Book-level time meter — slim track between the meta line and
   the chapter dots. Reads at-a-glance: "you've put in 3 of the
   estimated 12 hours". Indigo→amber gradient fill so progress
   feels warm regardless of completion percentage. */
.af-trail-meter[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 10px 0 14px;
  font-size: 11.5px;
  color: var(--vp-c-text-3);
  flex-wrap: wrap;
}
.af-trail-meter-track[data-v-6a5bc068] {
  flex: 1;
  min-width: 120px;
  height: 5px;
  background: var(--vp-c-divider);
  border-radius: 3px;
  overflow: hidden;
  position: relative;
}
.af-trail-meter-fill[data-v-6a5bc068] {
  height: 100%;
  /* Brand-olive → amber journey gradient — "where you are" in
     the brand, "where you're going" in the warmer milestone hue.
     Previous value opened in indigo which clashed with the
     surrounding book chrome. */
  background: linear-gradient(90deg, var(--vp-c-brand-1), #f59e0b);
  border-radius: 3px;
  transition: width 0.4s cubic-bezier(0.2, 0, 0, 1);
  box-shadow: 0 0 8px color-mix(in oklab, var(--vp-c-brand-1) 32%, transparent);
}
.af-trail-meter-text[data-v-6a5bc068] {
  flex-shrink: 0;
  white-space: nowrap;
}
.af-trail-meter-sep[data-v-6a5bc068] {
  opacity: 0.5;
  margin: 0 3px;
}
.af-trail-meter-pct[data-v-6a5bc068] {
  margin-left: 4px;
  color: var(--vp-c-text-2);
  font-weight: 600;
}

/* Collectible badges row — 5 milestones per book, drawn from
   localStorage. Earned badges glow with a gradient + soft halo;
   locked ones stay gray with a 🔒 placeholder so the reader can
   see what's still ahead (that's the whole point of a collection). */
.af-badges[data-v-6a5bc068] {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 14px 0 4px;
}
.af-badge[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px 5px 7px;
  border-radius: 999px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  color: var(--vp-c-text-3);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: help;
  transition: transform 0.18s var(--ease-out);
}
.af-badge.is-earned[data-v-6a5bc068] {
  /* Amber → olive gradient — the amber (milestone / gold) is the
     dominant "achievement" hue; olive is the brand tint that
     glues the badge back into the site. Old indigo tail was
     pre-brand residue. */
  background: linear-gradient(135deg,
    rgba(245, 158, 11, 0.14),
    color-mix(in oklab, var(--vp-c-brand-1) 12%, transparent));
  border-color: rgba(245, 158, 11, 0.35);
  color: var(--vp-c-text-1);
  box-shadow: 0 2px 10px rgba(245, 158, 11, 0.18);
}
.af-badge.is-earned[data-v-6a5bc068]:hover {
  transform: translateY(-2px);
}
.af-badge-emoji[data-v-6a5bc068] {
  font-size: 13px;
  line-height: 1;
  filter: grayscale(0.6);
  opacity: 0.6;
}
.af-badge.is-earned .af-badge-emoji[data-v-6a5bc068] {
  filter: none;
  opacity: 1;
}
.dark .af-badge.is-earned[data-v-6a5bc068] {
  background: linear-gradient(135deg,
    rgba(245, 158, 11, 0.20),
    rgba(196, 248, 87, 0.16));
}
.af-trail-dots[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.af-trail-dot[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: transparent;
  border: 1.5px solid var(--vp-c-divider);
  color: transparent;
  font-size: 10px;
  font-weight: 700;
  text-decoration: none;
  transition:
    transform    0.18s var(--ease-out),
    background   0.18s var(--ease-out),
    border-color 0.18s var(--ease-out),
    color        0.18s var(--ease-out),
    box-shadow   0.18s var(--ease-out);
}
.af-trail-dot[data-v-6a5bc068]:hover {
  transform: scale(1.2);
  border-color: var(--vp-c-brand-1);
  color: var(--vp-c-brand-1);
}
.af-trail-dot.is-read[data-v-6a5bc068] {
  background: linear-gradient(135deg, #10b981, #059669);
  border-color: transparent;
  color: #fff;
}
.af-trail-dot.is-read[data-v-6a5bc068]:hover {
  color: #fff;
  border-color: transparent;
  box-shadow: 0 4px 10px rgba(16, 185, 129, 0.35);
}
.af-trail-dot.is-current[data-v-6a5bc068] {
  width: 30px;
  height: 30px;
  /* The "you are here" dot on the chapter trail — was indigo→blue
     gradient. Shift to olive→deeper-olive so the current-position
     marker sits inside the brand and the ring below can pick up
     the same accent alpha automatically. */
  background: linear-gradient(135deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  border-color: transparent;
  color: #fff;
  font-size: 12px;
  box-shadow: 0 4px 14px color-mix(in oklab, var(--vp-c-brand-1) 38%, transparent);
  position: relative;
}
.af-trail-dot.is-current[data-v-6a5bc068]::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 1.5px solid color-mix(in oklab, var(--vp-c-brand-1) 32%, transparent);
}
.af-trail-dot.is-current .af-trail-num[data-v-6a5bc068] {
  display: inline;
}
.af-trail-dot.is-locked[data-v-6a5bc068] {
  border-style: dashed;
  opacity: 0.55;
}
/* Numbers only show in the current dot — small read/unread dots
   stay clean. The hover scale + tooltip carry the chapter ref. */
.af-trail-num[data-v-6a5bc068] {
  display: none;
}
.af-trail-dot.is-current .af-trail-num[data-v-6a5bc068] {
  display: inline;
}

/* Per-chapter dwell line — quiet stat above the checkin button.
   Reads as a self-pacing signal, not a metric to hit. */
.af-dwell[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-size: 12.5px;
  color: var(--vp-c-text-3);
  align-self: flex-start;
}
.af-dwell svg[data-v-6a5bc068] {
  flex-shrink: 0;
  color: var(--vp-c-text-3);
  opacity: 0.85;
}
.af-dwell strong[data-v-6a5bc068] {
  color: var(--vp-c-text-1);
  font-weight: 600;
}
.af-dwell-sep[data-v-6a5bc068] {
  opacity: 0.5;
  margin: 0 4px;
}
.af-dwell-pace[data-v-6a5bc068] {
  color: #f59e0b;
  font-weight: 600;
}

/* Read-checkpoint banner — switches between "encourage" and
   "celebrate" states based on whether the chapter has been
   marked. Sits above the author card so it's the first thing a
   reader sees as they reach the chapter end. */
.af-checkin[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 22px;
  border-radius: 14px;
  /* Brand-tinted "still to do" card — the is-done variant below
     switches to emerald (semantic success). Values derive from
     var(--vp-c-brand-1) so colour shifts track the accent system. */
  background: linear-gradient(135deg,
    color-mix(in oklab, var(--vp-c-brand-1) 6%, transparent),
    color-mix(in oklab, var(--vp-c-brand-1) 4%, transparent));
  border: 1px solid color-mix(in oklab, var(--vp-c-brand-1) 22%, transparent);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition:
    transform    0.22s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1);
  width: 100%;
}
.af-checkin[data-v-6a5bc068]:hover {
  transform: translateY(-1px);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 45%, transparent);
  box-shadow: 0 8px 24px color-mix(in oklab, var(--vp-c-brand-1) 14%, transparent);
}
.af-checkin.is-done[data-v-6a5bc068] {
  background: linear-gradient(135deg, rgba(16, 185, 129, 0.08), rgba(5, 150, 105, 0.04));
  border-color: rgba(16, 185, 129, 0.32);
}
.af-checkin.is-done[data-v-6a5bc068]:hover {
  border-color: rgba(16, 185, 129, 0.5);
  box-shadow: 0 8px 24px rgba(16, 185, 129, 0.14);
}
.af-checkin-icon[data-v-6a5bc068] {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  flex-shrink: 0;
  /* Olive → deeper-olive gradient so the pre-click icon sits inside
     the brand family; the done state below still gets emerald. */
  background: linear-gradient(135deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  box-shadow: 0 4px 14px color-mix(in oklab, var(--vp-c-brand-1) 32%, transparent);
  transition:
    background 0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow 0.22s cubic-bezier(0.2, 0, 0, 1);
}
.af-checkin.is-done .af-checkin-icon[data-v-6a5bc068] {
  background: linear-gradient(135deg, #10b981, #059669);
  box-shadow: 0 4px 14px rgba(16, 185, 129, 0.3);
}
.af-checkin-text[data-v-6a5bc068] {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.af-checkin-title[data-v-6a5bc068] {
  font-size: 15px;
  font-weight: 700;
  color: var(--vp-c-text-1);
  letter-spacing: -0.01em;
}
.af-checkin-sub[data-v-6a5bc068] {
  font-size: 12.5px;
  color: var(--vp-c-text-3);
  line-height: 1.5;
}

/* Author card — tuned to match the brand olive/lemon palette
   used on the landing page and login CTA; the old blue/violet
   wash here clashed with the greens everywhere else. */
.af-author-card[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px 24px;
  border-radius: 14px;
  background: linear-gradient(135deg, rgba(107, 158, 44, 0.05), rgba(196, 248, 87, 0.06));
  border: 1px solid rgba(107, 158, 44, 0.12);
}
.af-avatar[data-v-6a5bc068] {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  flex-shrink: 0;
  overflow: hidden;
  background: #f1f5f9;
  border: 3px solid #fff;
  box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.06), 0 6px 20px rgba(107, 158, 44, 0.14);
}
.af-avatar img[data-v-6a5bc068] {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.dark {
  border-color: rgba(148, 163, 184, 0.2);
  box-shadow: 0 0 0 1px rgba(148, 163, 184, 0.15), 0 6px 20px rgba(0, 0, 0, 0.3);
}
.af-author-info[data-v-6a5bc068] {
  flex: 1;
  min-width: 0;
}
.af-name[data-v-6a5bc068] {
  font-size: 16px;
  font-weight: 600;
  color: var(--vp-c-text-1);
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.af-badge[data-v-6a5bc068] {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(107, 158, 44, 0.14);
  color: #5a8426;
  font-weight: 500;
}
.dark {
  background: rgba(196, 248, 87, 0.16);
  color: #c4f857;
}
.af-bio[data-v-6a5bc068] {
  font-size: 13px;
  color: var(--vp-c-text-2);
  line-height: 1.5;
}
.af-subscribe-btn[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 9px 18px;
  border-radius: 8px;
  border: none;
  background: #6b9e2c;
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition:
    background 0.18s cubic-bezier(0.2, 0, 0, 1),
    transform  0.18s cubic-bezier(0.2, 0, 0, 1),
    box-shadow 0.22s cubic-bezier(0.2, 0, 0, 1);
  flex-shrink: 0;
  box-shadow: 0 1px 3px rgba(107, 158, 44, 0.16);
}
.af-subscribe-btn[data-v-6a5bc068]:hover {
  background: #5a8426;
  transform: translateY(-1px);
  box-shadow:
    0 6px 16px rgba(107, 158, 44, 0.32),
    0 2px 4px rgba(107, 158, 44, 0.18);
}
.af-subscribe-btn[data-v-6a5bc068]:active {
  transform: translateY(0);
  transition-duration: 0.08s;
}
.dark {
  background: #c4f857;
  color: #0a0b0f;
}
.dark {
  background: #d5ff7a;
}

/* Prev/Next nav */
.af-nav[data-v-6a5bc068] {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.af-nav-card[data-v-6a5bc068] {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px 18px;
  border-radius: 12px;
  border: 1px solid var(--vp-c-divider);
  background: var(--vp-c-bg);
  text-decoration: none;
  color: var(--vp-c-text-1);
  /* Transition list replaces `all` so paint-only props animate,
     layout-affecting ones don't — prevents subpixel reflow jitter
     on hover across long chapter lists. */
  transition:
    border-color 0.22s cubic-bezier(0.2, 0, 0, 1),
    background   0.22s cubic-bezier(0.2, 0, 0, 1),
    transform    0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1);
  min-width: 0;
}
.af-nav-card[data-v-6a5bc068]:hover {
  /* Prev/next chapter cards — olive-tinted hover to match the
     rest of the reading footer. Previous blue edges broke the
     handshake with the (now olive) check-in card + meter fill. */
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 38%, transparent);
  background: color-mix(in oklab, var(--vp-c-brand-1) 3%, transparent);
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
  transition:
    border-color 0.22s cubic-bezier(0.2, 0, 0, 1),
    background   0.22s cubic-bezier(0.2, 0, 0, 1),
    transform    0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1);
}
.af-nav-prev[data-v-6a5bc068] { text-align: left;
}
.af-nav-next[data-v-6a5bc068] { text-align: right; grid-column: 2;
}
.af-nav-card[data-v-6a5bc068]:only-child {
  grid-column: 1 / -1;
}
.af-nav-label[data-v-6a5bc068] {
  font-size: 12px;
  color: var(--vp-c-text-3);
  display: flex;
  align-items: center;
  gap: 4px;
  font-weight: 500;
}
.af-nav-next .af-nav-label[data-v-6a5bc068] {
  justify-content: flex-end;
}
.af-nav-title[data-v-6a5bc068] {
  font-size: 14px;
  font-weight: 600;
  color: var(--vp-c-text-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Related chapters */
.af-related[data-v-6a5bc068] {
  padding-top: 8px;
}
.af-related-title[data-v-6a5bc068] {
  font-size: 13px;
  font-weight: 600;
  color: var(--vp-c-text-2);
  margin: 0 0 12px;
  letter-spacing: 0.02em;
  border: none;
  padding: 0;
}
.af-related-grid[data-v-6a5bc068] {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 8px;
}
.af-related-item[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 8px;
  background: rgba(15, 23, 42, 0.02);
  border: 1px solid transparent;
  text-decoration: none;
  color: var(--vp-c-text-2);
  font-size: 13px;
  transition:
    background   0.18s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    color        0.18s cubic-bezier(0.2, 0, 0, 1);
  min-width: 0;
}
.af-related-item[data-v-6a5bc068]:hover {
  background: color-mix(in oklab, var(--vp-c-brand-1) 5%, transparent);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 22%, transparent);
  color: var(--vp-c-text-1);
}
.af-related-num[data-v-6a5bc068] {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--vp-c-text-3);
  font-weight: 600;
  flex-shrink: 0;
}
.af-related-text[data-v-6a5bc068] {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}
.af-related-lock[data-v-6a5bc068] {
  flex-shrink: 0;
  color: var(--vp-c-text-3);
  opacity: 0.7;
  margin-left: 4px;
}
.af-related-item.is-locked .af-related-lock[data-v-6a5bc068] {
  color: #f59e0b;
  opacity: 0.9;
}
.af-related-item.is-locked[data-v-6a5bc068]:hover {
  background: rgba(245, 158, 11, 0.04);
  border-color: rgba(245, 158, 11, 0.2);
}

/* Highlights list — the reader's saved excerpts for this chapter,
   pulled from the same localStorage map useReadingEnhancers writes
   to. Renders each as a small blockquote with a × button; the ×
   fires a CustomEvent so the enhancer unwraps the inline <mark>
   in sync with removing the list entry. */
.af-hls[data-v-6a5bc068] {
  padding: 16px 20px 14px;
  background: linear-gradient(135deg, rgba(250, 204, 21, 0.08), rgba(245, 158, 11, 0.04));
  border: 1px solid rgba(250, 204, 21, 0.3);
  border-radius: 12px;
}
.af-hls-header[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #b45309;
}
.af-hls-header svg[data-v-6a5bc068] {
  flex-shrink: 0;
  opacity: 0.85;
}
.af-hls-hint[data-v-6a5bc068] {
  margin-left: auto;
  font-size: 11px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.01em;
  color: var(--vp-c-text-3);
}
.af-hls-list[data-v-6a5bc068] {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.af-hls-list li[data-v-6a5bc068] {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.af-hl-quote[data-v-6a5bc068] {
  flex: 1;
  margin: 0 !important;
  padding: 8px 12px !important;
  background: rgba(250, 204, 21, 0.14) !important;
  border-left: 3px solid #eab308 !important;
  border-radius: 6px !important;
  font-size: 13.5px;
  line-height: 1.7;
  color: var(--vp-c-text-1);
  white-space: pre-wrap;
  word-break: break-word;
}
.af-hl-del[data-v-6a5bc068] {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  border: none;
  background: transparent;
  color: var(--vp-c-text-3);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
  margin-top: 4px;
  transition: background 0.15s, color 0.15s;
}
.af-hl-del[data-v-6a5bc068]:hover {
  background: rgba(239, 68, 68, 0.14);
  color: #ef4444;
}
.dark .af-hls[data-v-6a5bc068] {
  background: linear-gradient(135deg, rgba(250, 204, 21, 0.14), rgba(245, 158, 11, 0.08));
  border-color: rgba(250, 204, 21, 0.35);
}
.dark .af-hls-header[data-v-6a5bc068] {
  color: #fbbf24;
}

/* Per-chapter local notes. Treats the chapter as a working
   document: a tiny textarea + list so the reader can jot
   impressions, cross-references, reminders without reaching
   for a separate app. All data lives in localStorage. */
.af-notes[data-v-6a5bc068] {
  padding: 16px 20px 14px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-radius: 12px;
}
.af-notes-header[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vp-c-text-2);
  margin-bottom: 10px;
}
.af-notes-header svg[data-v-6a5bc068] {
  flex-shrink: 0;
  opacity: 0.65;
}
.af-notes-hint[data-v-6a5bc068] {
  margin-left: auto;
  font-size: 11px;
  letter-spacing: 0.01em;
  font-weight: 500;
  text-transform: none;
  color: var(--vp-c-text-3);
}
.af-notes-export[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--vp-c-divider);
  background: var(--vp-c-bg);
  color: var(--vp-c-text-2);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: none;
  cursor: pointer;
  font-family: inherit;
  transition:
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    color        0.18s cubic-bezier(0.2, 0, 0, 1),
    background   0.18s cubic-bezier(0.2, 0, 0, 1);
}
.af-notes-export[data-v-6a5bc068]:hover {
  color: #5a8426;
  border-color: rgba(107, 158, 44, 0.4);
  background: var(--vp-c-bg-soft);
}
.af-notes-export svg[data-v-6a5bc068] {
  flex-shrink: 0;
}
.af-notes-input-row[data-v-6a5bc068] {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.af-notes-input[data-v-6a5bc068] {
  flex: 1;
  resize: vertical;
  min-height: 52px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--vp-c-divider);
  background: var(--vp-c-bg);
  color: var(--vp-c-text-1);
  font-family: inherit;
  font-size: 13.5px;
  line-height: 1.6;
  transition: border-color 0.15s var(--ease-out);
}
.af-notes-input[data-v-6a5bc068]:focus {
  outline: none;
  border-color: rgba(107, 158, 44, 0.45);
}
.af-notes-save[data-v-6a5bc068] {
  padding: 8px 16px;
  border-radius: 8px;
  border: none;
  background: linear-gradient(135deg, #6b9e2c, #5a8426);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
  transition:
    transform  0.15s var(--ease-out),
    box-shadow 0.15s var(--ease-out),
    opacity    0.15s var(--ease-out);
}
.dark {
  background: linear-gradient(135deg, #c4f857, #a9dc46);
  color: #0a0b0f;
}
.af-notes-save[data-v-6a5bc068]:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.af-notes-save[data-v-6a5bc068]:not(:disabled):hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(107, 158, 44, 0.32);
}
.af-notes-list[data-v-6a5bc068] {
  list-style: none;
  padding: 0;
  margin: 12px 0 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.af-notes-list li[data-v-6a5bc068] {
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.af-note-body[data-v-6a5bc068] {
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--vp-c-text-1);
  white-space: pre-wrap;
  word-break: break-word;
}
.af-note-meta[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: var(--vp-c-text-3);
}
.af-note-del[data-v-6a5bc068] {
  margin-left: auto;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  border: none;
  background: transparent;
  color: var(--vp-c-text-3);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  font-family: inherit;
}
.af-note-del[data-v-6a5bc068]:hover {
  background: rgba(239, 68, 68, 0.14);
  color: #ef4444;
}

/* Chapter glossary — auto-extracted from inline <code> frequency
   in the chapter. Chips are compact, mono font (they're code
   tokens), with a frequency badge to signal weight. Click
   scrolls to the first occurrence in the prose and flashes it. */
.af-glossary[data-v-6a5bc068] {
  padding: 14px 18px 12px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-radius: 12px;
}
.af-glossary-title[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vp-c-text-2);
  margin-bottom: 10px;
}
.af-glossary-title svg[data-v-6a5bc068] {
  flex-shrink: 0;
  opacity: 0.6;
}
.af-glossary-list[data-v-6a5bc068] {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.af-glossary-chip[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  background: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
  transition: transform 0.15s var(--ease-out), border-color 0.15s var(--ease-out);
}
.af-glossary-chip[data-v-6a5bc068]:hover {
  transform: translateY(-1px);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 45%, transparent);
}
.af-glossary-chip code[data-v-6a5bc068] {
  background: transparent !important;
  color: var(--vp-c-brand-1) !important;
  padding: 0 !important;
  font-size: 12px !important;
  font-weight: 600;
}
.af-glossary-count[data-v-6a5bc068] {
  font-size: 10.5px;
  font-weight: 700;
  color: var(--vp-c-text-3);
  background: rgba(148, 163, 184, 0.14);
  padding: 1px 5px;
  border-radius: 999px;
  min-width: 18px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  /* The chip's hover handoff changes both color + background on
     this count pill — scope transitions so they ease in/out
     instead of snapping, matching the parent's motion. */
  transition:
    background 0.18s var(--ease-out),
    color      0.18s var(--ease-out);
}
.af-glossary-chip:hover .af-glossary-count[data-v-6a5bc068] {
  background: color-mix(in oklab, var(--vp-c-brand-1) 14%, transparent);
  color: var(--vp-c-brand-1);
}

/* Auto-extracted reference list. Reads as a tidy bibliography
   beneath the chapter rather than another visually competing
   card; numbered list with host + truncated link text. */
.af-refs[data-v-6a5bc068] {
  padding: 16px 20px 14px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-radius: 12px;
}
.af-cite[data-v-6a5bc068] {
  margin-top: 18px;
  padding: 16px 20px 14px;
  background: linear-gradient(135deg,
              color-mix(in srgb, var(--vp-c-brand-1) 5%, var(--vp-c-bg-soft)),
              var(--vp-c-bg-soft));
  border: 1px solid var(--vp-c-divider);
  border-radius: 12px;
}
.af-cite-header[data-v-6a5bc068] {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 10px;
}
.af-cite-title[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--vp-c-text-1);
}
.af-cite-title svg[data-v-6a5bc068] {
  opacity: 0.7;
  color: var(--vp-c-brand-1);
}
.af-cite-sub[data-v-6a5bc068] {
  font-size: 11.5px;
  color: var(--vp-c-text-3);
}
.af-cite-tabs[data-v-6a5bc068] {
  display: flex;
  gap: 2px;
  padding: 2px;
  margin-bottom: 10px;
  background: var(--vp-c-bg);
  border-radius: 7px;
  border: 1px solid var(--vp-c-divider);
  width: fit-content;
}
.af-cite-tab[data-v-6a5bc068] {
  padding: 4px 12px;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: var(--vp-c-text-3);
  font-size: 12px;
  cursor: pointer;
  transition:
    color      0.18s cubic-bezier(0.2, 0, 0, 1),
    background 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.af-cite-tab[data-v-6a5bc068]:hover {
  color: var(--vp-c-text-1);
}
.af-cite-tab.is-active[data-v-6a5bc068] {
  background: var(--vp-c-bg-soft);
  color: var(--vp-c-brand-1);
  font-weight: 600;
  /* tier-1 hairline — "active" segment lifts a hair above its
     inactive siblings, matches the reader-prefs segment style. */
  box-shadow: var(--shadow-1);
}
.af-cite-body[data-v-6a5bc068] {
  position: relative;
}
.af-cite-text[data-v-6a5bc068] {
  margin: 0;
  padding: 12px 60px 12px 14px;
  background: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  border-radius: 8px;
  font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
  font-size: 12px;
  line-height: 1.65;
  color: var(--vp-c-text-1);
  white-space: pre-wrap;
  word-break: break-word;
  overflow-x: auto;
}
.af-cite-copy[data-v-6a5bc068] {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 6px;
  background: var(--vp-c-bg-soft);
  color: var(--vp-c-text-2);
  font-size: 11.5px;
  cursor: pointer;
  transition:
    color        0.18s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    background   0.18s cubic-bezier(0.2, 0, 0, 1);
}
.af-cite-copy[data-v-6a5bc068]:hover {
  color: var(--vp-c-brand-1);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 45%, transparent);
  background: var(--vp-c-bg);
}
.af-cite-copy.is-copied[data-v-6a5bc068] {
  color: #059669;
  border-color: rgba(16, 185, 129, 0.45);
  background: rgba(16, 185, 129, 0.08);
}
@media (max-width: 640px) {
.af-cite[data-v-6a5bc068] {
    padding: 14px 16px 12px;
}
.af-cite-text[data-v-6a5bc068] {
    padding: 10px 56px 10px 12px;
    font-size: 11.5px;
}
}
.af-refs-title[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vp-c-text-2);
  margin-bottom: 10px;
}
.af-refs-title svg[data-v-6a5bc068] {
  flex-shrink: 0;
  opacity: 0.6;
}
.af-refs-list[data-v-6a5bc068] {
  list-style: decimal;
  padding-left: 20px;
  margin: 0;
  font-size: 13px;
  line-height: 1.7;
  /* Tabular-nums on the list itself so the ::marker numerals
     (1, 2, … 10, 11) right-align in the gutter. Inherited by
     children. */
  font-variant-numeric: tabular-nums;
}
.af-refs-list li[data-v-6a5bc068] {
  color: var(--vp-c-text-3);
  margin: 0;
}
.af-refs-list li[data-v-6a5bc068]::marker {
  color: var(--vp-c-text-3);
  font-weight: 600;
  /* Keep the marker slightly quieter than the link text; a
     0.02em tracking bump separates adjacent digits visually. */
  font-feature-settings: 'tnum' 1;
}
.af-refs-list a[data-v-6a5bc068] {
  color: var(--vp-c-text-1);
  text-decoration: none;
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  transition: color 0.15s var(--ease-out);
}
.af-refs-list a[data-v-6a5bc068]:hover {
  color: var(--vp-c-brand-1);
}
.af-ref-host[data-v-6a5bc068] {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px;
  font-weight: 600;
  /* External-reference host chip (e.g. "github.com") — brand olive
     in prose context so it reads as "external but on-brand" rather
     than "random indigo pill". */
  color: var(--vp-c-brand-2);
  background: color-mix(in oklab, var(--vp-c-brand-1) 10%, transparent);
  padding: 1px 6px;
  border-radius: 4px;
}
.af-ref-text[data-v-6a5bc068] {
  word-break: break-all;
}

/* Hero "继续阅读" CTA — full-width gradient banner that explicitly
   pulls the reader into the next chapter. Stronger visual call
   than the balanced prev/next pair above; designed as the single
   most obvious "what now?" affordance at chapter end. */
/* Tinted-neutral CTA, not a saturated banner. Readers reach this
   after ~15min of prose; a full-bleed indigo gradient jolts the
   eye. A soft brand-tinted surface + primary text keeps the
   "continue" affordance obvious without screaming. */
.af-continue[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 22px;
  border-radius: 12px;
  background: var(--vp-c-brand-soft);
  border: 1px solid var(--vp-c-divider);
  color: var(--vp-c-text-1);
  text-decoration: none;
  transition: background 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
  position: relative;
}
.af-continue[data-v-6a5bc068]:hover {
  background: color-mix(in srgb, var(--vp-c-brand-1) 10%, var(--vp-c-bg));
  border-color: color-mix(in srgb, var(--vp-c-brand-1) 35%, var(--vp-c-divider));
}
.af-continue:hover .af-continue-arrow[data-v-6a5bc068] {
  transform: translateX(3px);
}
.af-continue:hover .af-continue-arrow[data-v-6a5bc068] {
  transform: translateX(4px);
}
.af-continue-content[data-v-6a5bc068] {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  position: relative;
  z-index: 1;
}
.af-continue-label[data-v-6a5bc068] {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.85;
}
.af-continue-title[data-v-6a5bc068] {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.af-continue-arrow[data-v-6a5bc068] {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  transition: transform 0.22s var(--ease-out), background 0.22s var(--ease-out);
  position: relative;
  z-index: 1;
}

/* Milestone banner — surfaces only when the reader has marked
   the entire book read AND is on its last chapter. Treats whole-
   book completion as a moment, not a footnote. Soft amber/red
   gradient (warmer than the indigo "继续阅读" hero) so the two
   never share the same chapter. */
.af-finish[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 22px 26px;
  border-radius: 16px;
  background: linear-gradient(135deg, #f59e0b, #ef4444);
  color: #fff;
  position: relative;
  overflow: hidden;
  box-shadow: 0 12px 32px rgba(245, 158, 11, 0.28);
}
.af-finish[data-v-6a5bc068]::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 90% 18%, rgba(255,255,255,0.22), transparent 55%),
    radial-gradient(circle at 5% 85%, rgba(255,255,255,0.14), transparent 60%);
  pointer-events: none;
}
.af-finish-medal[data-v-6a5bc068] {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
  color: #fff;
}
.af-finish-content[data-v-6a5bc068] {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  position: relative;
  z-index: 1;
}
.af-finish-title[data-v-6a5bc068] {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.af-finish-stats[data-v-6a5bc068] {
  font-size: 13px;
  opacity: 0.92;
}
.af-finish-actions[data-v-6a5bc068] {
  margin-top: 6px;
}
.af-finish-cta[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.92);
  color: #b45309;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  transition: transform 0.18s var(--ease-out), background 0.18s var(--ease-out);
}
.af-finish-cta[data-v-6a5bc068]:hover {
  transform: translateX(2px);
  background: #fff;
}
@media (max-width: 640px) {
.af-finish[data-v-6a5bc068] {
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
}
}

/* Share row — quiet icon buttons in a single horizontal line.
   Reads as a tool-tray, not a CTA. Hover lifts each chip; copy
   button briefly turns emerald on success. */
.af-share[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 4px;
  flex-wrap: wrap;
}
.af-share-label[data-v-6a5bc068] {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vp-c-text-3);
}
.af-share-buttons[data-v-6a5bc068] {
  display: inline-flex;
  gap: 8px;
  flex-wrap: wrap;
}
.af-share-btn[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  color: var(--vp-c-text-2);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  font-family: inherit;
  transition:
    transform    0.18s var(--ease-out),
    color        0.18s var(--ease-out),
    border-color 0.18s var(--ease-out),
    background   0.18s var(--ease-out),
    box-shadow   0.22s var(--ease-out);
}
.af-share-btn[data-v-6a5bc068]:hover {
  transform: translateY(-2px);
  color: var(--vp-c-text-1);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 38%, transparent);
  /* tier-2 lift so the -2px translation has shadow weight to
     match; shares the hover elevation convention with .book
     and .pill cards. */
  box-shadow: var(--shadow-2);
}
.af-share-btn[data-v-6a5bc068]:active {
  transform: translateY(0);
  transition-duration: 0.08s;
}
.af-share-btn svg[data-v-6a5bc068] {
  flex-shrink: 0;
}
.af-share-btn.is-copied[data-v-6a5bc068] {
  background: linear-gradient(135deg, #10b981, #059669);
  border-color: transparent;
  color: #fff;
}

/* Lightweight chapter feedback — single-tap thumbs up/down with
   immediate visual confirmation. Two equally-weighted buttons so
   neither verdict is biased; once voted, both lock and the active
   one inverts colors as a "got it" signal. */
.af-feedback[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 18px 22px;
  border-radius: 14px;
  /* Was indigo→blue 4%/3% — swap to olive-derived tint so this
     "这一章对你有帮助吗" prompt sits in the brand family. The
     is-voted variant still flips to emerald (success) below. */
  background: linear-gradient(135deg,
    color-mix(in oklab, var(--vp-c-brand-1) 4%, transparent),
    color-mix(in oklab, var(--vp-c-brand-1) 3%, transparent));
  border: 1px dashed var(--vp-c-divider);
  flex-wrap: wrap;
}
.af-feedback.is-voted[data-v-6a5bc068] {
  background: linear-gradient(135deg, rgba(16, 185, 129, 0.05), rgba(5, 150, 105, 0.03));
  border-color: rgba(16, 185, 129, 0.25);
  border-style: solid;
}
.af-feedback-prompt[data-v-6a5bc068] {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.af-feedback-q[data-v-6a5bc068] {
  font-size: 15px;
  font-weight: 700;
  color: var(--vp-c-text-1);
  letter-spacing: -0.01em;
}
.af-feedback.is-voted .af-feedback-q[data-v-6a5bc068]::after {
  content: ' · 已收到，谢谢你的反馈';
  color: #059669;
  font-weight: 600;
  font-size: 13.5px;
}
.af-feedback-sub[data-v-6a5bc068] {
  font-size: 12px;
  color: var(--vp-c-text-3);
}
.af-feedback-buttons[data-v-6a5bc068] {
  display: inline-flex;
  gap: 10px;
  flex-shrink: 0;
}
.af-fb-btn[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 16px;
  border-radius: 10px;
  background: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  color: var(--vp-c-text-2);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition:
    transform    0.18s var(--ease-out),
    border-color 0.18s var(--ease-out),
    background   0.18s var(--ease-out),
    color        0.18s var(--ease-out),
    box-shadow   0.18s var(--ease-out);
}
.af-fb-btn[data-v-6a5bc068]:not(:disabled):hover {
  transform: translateY(-2px);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 42%, transparent);
  color: var(--vp-c-text-1);
  box-shadow: var(--shadow-2);
}
.af-fb-btn[data-v-6a5bc068]:disabled {
  cursor: default;
  opacity: 0.55;
}
.af-fb-btn.is-active[data-v-6a5bc068] {
  opacity: 1;
}
.af-fb-yes.is-active[data-v-6a5bc068] {
  background: linear-gradient(135deg, #10b981, #059669);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 4px 14px rgba(16, 185, 129, 0.32);
}
.af-fb-no.is-active[data-v-6a5bc068] {
  background: var(--vp-c-bg-soft);
  color: var(--vp-c-text-2);
  border-color: var(--vp-c-divider);
}
.af-fb-btn svg[data-v-6a5bc068] {
  flex-shrink: 0;
}
@media (max-width: 640px) {
.af-feedback[data-v-6a5bc068] {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
}
.af-feedback-buttons[data-v-6a5bc068] {
    width: 100%;
}
.af-fb-btn[data-v-6a5bc068] {
    flex: 1;
    justify-content: center;
}
}

/* Cross-book recommendation cards. Each card mirrors the homepage's
   book card style at a smaller scale: gradient cover slab on the
   left, title + one-line desc on the right. Designed to invite the
   reader sideways into another book in the same vertical without
   competing visually with the same-book chapter list above. */
.af-cross[data-v-6a5bc068] {
  margin-top: 8px;
}
.af-cross-title[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 700;
  color: var(--vp-c-text-2);
  letter-spacing: 0.02em;
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--vp-c-divider);
}
.af-cross-icon[data-v-6a5bc068] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  background: color-mix(in oklab, var(--vp-c-brand-1) 14%, transparent);
  color: var(--vp-c-brand-2);
}
.dark {
  color: #c4f857;
}
.af-cross-grid[data-v-6a5bc068] {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.af-cross-card[data-v-6a5bc068] {
  display: grid;
  grid-template-columns: 76px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 10px 12px 10px 0;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  transition:
    transform    0.2s var(--ease-out),
    border-color 0.2s var(--ease-out),
    box-shadow   0.2s var(--ease-out);
}
.af-cross-card[data-v-6a5bc068]:hover {
  transform: translateY(-2px);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 42%, transparent);
  box-shadow: var(--shadow-3);
}
.af-cross-card:hover .af-cross-arrow[data-v-6a5bc068] {
  transform: translateX(3px);
  opacity: 1;
}
.af-cross-cover[data-v-6a5bc068] {
  height: 100%;
  min-height: 56px;
  display: flex;
  align-items: flex-end;
  padding: 8px 10px;
  color: #fff;
}
.af-cross-slug[data-v-6a5bc068] {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  font-weight: 600;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
  word-break: break-all;
  line-height: 1.2;
}
.af-cross-content[data-v-6a5bc068] {
  min-width: 0;
}
.af-cross-name[data-v-6a5bc068] {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--vp-c-text-1);
  letter-spacing: -0.01em;
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.af-cross-desc[data-v-6a5bc068] {
  font-size: 11.5px;
  color: var(--vp-c-text-3);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.af-cross-arrow[data-v-6a5bc068] {
  color: var(--vp-c-text-3);
  flex-shrink: 0;
  opacity: 0.6;
  transition: transform 0.2s var(--ease-out), opacity 0.2s var(--ease-out);
}
@media (max-width: 768px) {
.af-cross-grid[data-v-6a5bc068] {
    grid-template-columns: 1fr;
}
}

/* Subscribe modal */
.subscribe-overlay[data-v-6a5bc068] {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  padding: 20px;
}
.subscribe-modal[data-v-6a5bc068] {
  background: var(--vp-c-bg);
  border-radius: 16px;
  padding: 28px;
  max-width: 440px;
  width: 100%;
  position: relative;
  box-shadow: 0 32px 80px rgba(0, 0, 0, 0.2);
}
.subscribe-modal h3[data-v-6a5bc068] {
  margin: 0 0 4px;
  font-size: 18px;
  font-weight: 600;
  color: var(--vp-c-text-1);
}
.subscribe-desc[data-v-6a5bc068] {
  margin: 0 0 20px;
  font-size: 13px;
  color: var(--vp-c-text-3);
}
.subscribe-close[data-v-6a5bc068] {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: rgba(15, 23, 42, 0.04);
  font-size: 20px;
  cursor: pointer;
  color: var(--vp-c-text-3);
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
.subscribe-close[data-v-6a5bc068]:hover {
  background: rgba(15, 23, 42, 0.08);
  color: var(--vp-c-text-1);
}
.subscribe-grid[data-v-6a5bc068] {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 12px;
}
.sub-card[data-v-6a5bc068] {
  padding: 14px 12px 12px;
  border-radius: 12px;
  border: 1px solid var(--vp-c-divider);
  background: var(--vp-c-bg);
  text-align: center;
  /* Scope the transition to the four properties actually changing
     on hover — `transition: all` animates everything including
     layout-triggering props, which can cause subtle jitters when
     the browser decides to re-flow. */
  transition:
    border-color 0.22s cubic-bezier(0.2, 0, 0, 1),
    background   0.22s cubic-bezier(0.2, 0, 0, 1),
    transform    0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1);
}
.sub-card[data-v-6a5bc068]:hover {
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 32%, transparent);
  background: color-mix(in oklab, var(--vp-c-brand-1) 3%, transparent);
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}
.sub-card-qr[data-v-6a5bc068] {
  width: 100%;
  aspect-ratio: 1;
  background: #fff;
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 10px;
  border: 1px solid var(--vp-c-divider);
  display: flex;
  align-items: center;
  justify-content: center;
}
.sub-card-qr img[data-v-6a5bc068] {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.sub-card-title[data-v-6a5bc068] {
  font-size: 14px;
  font-weight: 600;
  color: var(--vp-c-text-1);
  margin-bottom: 4px;
}
.sub-card-desc[data-v-6a5bc068] {
  font-size: 12px;
  color: var(--vp-c-text-3);
  line-height: 1.5;
}
.sub-rss[data-v-6a5bc068] {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--vp-c-divider);
  background: var(--vp-c-bg);
  text-decoration: none;
  color: inherit;
  transition:
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    background   0.18s cubic-bezier(0.2, 0, 0, 1);
}
.sub-rss[data-v-6a5bc068]:hover {
  border-color: rgba(249, 115, 22, 0.3);
  background: rgba(249, 115, 22, 0.04);
}
.sub-rss-icon[data-v-6a5bc068] {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: #f97316;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.sub-rss-info[data-v-6a5bc068] {
  flex: 1;
  min-width: 0;
}
.sub-rss-title[data-v-6a5bc068] {
  font-size: 13px;
  font-weight: 600;
  color: var(--vp-c-text-1);
  margin-bottom: 2px;
}
.sub-rss-url[data-v-6a5bc068] {
  font-size: 11px;
  color: var(--vp-c-text-3);
  font-family: 'JetBrains Mono', monospace;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sub-rss-copy[data-v-6a5bc068] {
  border: 1px solid var(--vp-c-divider);
  background: transparent;
  border-radius: 6px;
  padding: 5px 12px;
  font-size: 12px;
  color: var(--vp-c-text-2);
  cursor: pointer;
  font-family: inherit;
  flex-shrink: 0;
  transition:
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    color        0.18s cubic-bezier(0.2, 0, 0, 1),
    background   0.18s cubic-bezier(0.2, 0, 0, 1);
}
.sub-rss-copy[data-v-6a5bc068]:hover {
  border-color: #f97316;
  color: #f97316;
}
.modal-enter-active[data-v-6a5bc068] { transition: opacity 0.2s var(--ease-out);
}
.modal-leave-active[data-v-6a5bc068] { transition: opacity 0.15s var(--ease-in);
}
.modal-enter-from[data-v-6a5bc068], .modal-leave-to[data-v-6a5bc068] { opacity: 0;
}
@media (max-width: 640px) {
.af-author-card[data-v-6a5bc068] {
    flex-direction: column;
    text-align: center;
    align-items: center;
    padding: 18px;
}
.af-nav[data-v-6a5bc068] {
    grid-template-columns: 1fr;
}
.af-nav-next[data-v-6a5bc068] { grid-column: 1;
}
.af-related-grid[data-v-6a5bc068] {
    grid-template-columns: 1fr;
}
  /* Reduce related-chapters list from 6 to 4 on small screens to avoid
     an overwhelming footer — the full list is still accessible via the
     sidebar / book index page. */
.af-related-item[data-v-6a5bc068]:nth-child(n+5) {
    display: none;
}

  /* Mobile polish for the chapter-end card stack — the cards
     designed at desktop sizes get cramped on narrow screens.
     Trail dots shrink, continue/finish CTAs lose vertical
     padding, cross-book grid stacks. */
.af-trail[data-v-6a5bc068] {
    padding: 12px 14px 10px;
}
.af-trail-dots[data-v-6a5bc068] {
    gap: 4px;
}
.af-trail-dot[data-v-6a5bc068] {
    width: 18px;
    height: 18px;
    border-width: 1px;
}
.af-trail-dot.is-current[data-v-6a5bc068] {
    width: 26px;
    height: 26px;
    font-size: 11px;
}
.af-trail-progress[data-v-6a5bc068] {
    font-size: 11px;
}
.af-checkin[data-v-6a5bc068] {
    padding: 14px 16px;
    gap: 12px;
}
.af-checkin-icon[data-v-6a5bc068] {
    width: 36px;
    height: 36px;
}
.af-checkin-title[data-v-6a5bc068] {
    font-size: 14px;
}
.af-continue[data-v-6a5bc068] {
    padding: 14px 18px;
    gap: 12px;
}
.af-continue-title[data-v-6a5bc068] {
    font-size: 15px;
}
.af-continue-arrow[data-v-6a5bc068] {
    width: 36px;
    height: 36px;
}
.af-finish[data-v-6a5bc068] {
    padding: 18px 18px;
    gap: 14px;
}
.af-finish-medal[data-v-6a5bc068] {
    width: 44px;
    height: 44px;
}
.af-finish-title[data-v-6a5bc068] {
    font-size: 16px;
}
.af-cross-card[data-v-6a5bc068] {
    grid-template-columns: 64px 1fr auto;
}
.af-cross-name[data-v-6a5bc068] {
    font-size: 13px;
}
}

/* ===========================================================
   Dark-mode contrast pass — the light-mode 4-6% brand-color
   tints visually disappear against a dark page background;
   bumping to 12-14% keeps every card readable as a distinct
   surface in dark mode without being noisy in light mode.
   =========================================================== */
.dark .af-checkin[data-v-6a5bc068] {
  /* Dark-mode bumps from 6%/4% to 14%/8% brand tint so the card
     still reads as a distinct surface on a near-black page. */
  background: linear-gradient(135deg,
    rgba(196, 248, 87, 0.12),
    rgba(107, 158, 44, 0.08));
  border-color: rgba(196, 248, 87, 0.24);
}
.dark .af-checkin.is-done[data-v-6a5bc068] {
  background: linear-gradient(135deg, rgba(16, 185, 129, 0.14), rgba(5, 150, 105, 0.07));
  border-color: rgba(16, 185, 129, 0.34);
}
.dark .af-feedback[data-v-6a5bc068] {
  background: linear-gradient(135deg,
    rgba(196, 248, 87, 0.10),
    rgba(107, 158, 44, 0.07));
}
.dark .af-feedback.is-voted[data-v-6a5bc068] {
  background: linear-gradient(135deg, rgba(16, 185, 129, 0.13), rgba(5, 150, 105, 0.07));
  border-color: rgba(16, 185, 129, 0.32);
}
.dark .af-trail-dot[data-v-6a5bc068] {
  border-color: rgba(255, 255, 255, 0.18);
}
.dark .af-trail-dot[data-v-6a5bc068]:hover {
  border-color: var(--vp-c-brand-1);
}
.dark .af-cross-card[data-v-6a5bc068]:hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.dark .af-cross-icon[data-v-6a5bc068] {
  background: rgba(196, 248, 87, 0.14);
}
.dark .af-finish[data-v-6a5bc068] {
  /* Slightly dimmer in dark mode so the bright amber doesn't blast
     the reader on a black background. */
  box-shadow: 0 12px 32px rgba(245, 158, 11, 0.18);
}
.dark .af-continue[data-v-6a5bc068] {
  box-shadow: 0 8px 28px rgba(196, 248, 87, 0.16);
}

.ama[data-v-05c5cc6b] {
  max-width: 768px;
  margin: 48px auto;
  padding: 0 24px;
}
.ama-head[data-v-05c5cc6b] {
  display: flex; align-items: baseline; gap: 10px;
  margin-bottom: 16px;
}
.ama-badge[data-v-05c5cc6b] {
  font-size: 12px; font-weight: 600; letter-spacing: 0.06em;
  padding: 3px 10px; border-radius: 999px;
  background: rgba(107, 158, 44, 0.12);
  color: #6b9e2c;
  border: 1px solid rgba(107, 158, 44, 0.3);
}
.ama-sub[data-v-05c5cc6b] { font-size: 12.5px; color: var(--vp-c-text-3);
}
.ama-post[data-v-05c5cc6b] {
  padding: 20px 22px;
  border-left: 3px solid #6b9e2c;
  background: var(--vp-c-bg-soft);
  border-radius: 0 12px 12px 0;
  margin-bottom: 14px;
}
.ama-body[data-v-05c5cc6b] { color: var(--vp-c-text-1); font-size: 15px; line-height: 1.75;
}
.ama-body[data-v-05c5cc6b] pre {
  background: var(--vp-code-block-bg); color: var(--vp-c-text-1);
  padding: 12px 14px; border-radius: 8px; font-size: 13px; overflow-x: auto;
  margin: 10px 0;
}
.ama-body[data-v-05c5cc6b] code { font-family: var(--vp-font-family-mono);
}
.ama-meta[data-v-05c5cc6b] { margin-top: 10px; font-size: 12.5px; color: var(--vp-c-text-3); font-style: italic;
}

/* Editorial paywall: no card, no border, no shadow, no rainbow.
   The truncated prose above dissolves via `mask-image` applied to
   the content-container (see custom.css .paywalled block), so the
   paywall itself doesn't need a top gradient — the transition is
   already continuous in the content above. */
.paywall-overlay[data-v-7c1771f5] {
  position: relative;
  margin: 0;
  padding: 32px 0 48px;
  text-align: center;
}
.paywall-card[data-v-7c1771f5] {
  max-width: 540px;
  margin: 0 auto;
  padding: 0;
  background: transparent;
  border: none;
  box-shadow: none;
  border-radius: 0;
}
.paywall-icon[data-v-7c1771f5] {
  width: 36px;
  height: 36px;
  margin: 0 auto 18px;
  color: var(--vp-c-text-3);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.7;
}
.paywall-title[data-v-7c1771f5] {
  font-size: 22px;
  font-weight: 700;
  color: var(--vp-c-text-1);
  margin: 0 0 10px;
  letter-spacing: -0.01em;
}
.paywall-desc[data-v-7c1771f5] {
  font-size: 14.5px;
  color: var(--vp-c-text-2);
  line-height: 1.7;
  margin: 0 0 22px;
}
.paywall-desc strong[data-v-7c1771f5] {
  color: var(--vp-c-text-1);
  font-weight: 600;
}
.paywall-progress[data-v-7c1771f5] {
  margin: 4px auto 24px;
  max-width: 420px;
}
.progress-track[data-v-7c1771f5] {
  height: 4px;
  border-radius: 999px;
  background: var(--vp-c-divider);
  overflow: hidden;
  margin-bottom: 10px;
}
.progress-fill[data-v-7c1771f5] {
  height: 100%;
  border-radius: 999px;
  background: var(--vp-c-text-2);
  transition: width 0.6s var(--ease-out);
}
.progress-text[data-v-7c1771f5] {
  font-size: 12.5px;
  color: var(--vp-c-text-3);
  line-height: 1.5;
}
.progress-text strong[data-v-7c1771f5] {
  color: var(--vp-c-text-1);
  font-weight: 600;
  font-size: 13px;
}
.progress-detail[data-v-7c1771f5] {
  display: inline-block;
  color: var(--vp-c-text-3);
  font-size: 12px;
  margin-left: 2px;
}

/* Perks row: inline, no box. Reads as a lede line instead of
   a marketing panel. */
.paywall-perks[data-v-7c1771f5] {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 6px 18px;
  justify-content: center;
  margin-bottom: 24px;
  padding: 0;
  border: none;
  background: transparent;
}
.perk[data-v-7c1771f5] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--vp-c-text-2);
  text-align: left;
}
.perk svg[data-v-7c1771f5] {
  width: 13px;
  height: 13px;
  color: var(--vp-c-text-3);
  flex-shrink: 0;
}
.paywall-actions[data-v-7c1771f5] {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}

/* CTA: tinted brand surface (matches the "下一章·继续阅读" style),
   no gradient, no glow. A tinted button is still obvious; we don't
   need the chrome. */
.paywall-cta[data-v-7c1771f5] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 11px 26px;
  background: var(--vp-c-brand-soft);
  color: var(--vp-c-brand-1);
  font-size: 14px;
  font-weight: 600;
  border: 1px solid color-mix(in srgb, var(--vp-c-brand-1) 25%, var(--vp-c-divider));
  border-radius: 10px;
  text-decoration: none;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.18s var(--ease-out), border-color 0.18s var(--ease-out);
}
.paywall-cta[data-v-7c1771f5]:hover {
  background: color-mix(in srgb, var(--vp-c-brand-1) 14%, var(--vp-c-bg));
  border-color: color-mix(in srgb, var(--vp-c-brand-1) 45%, var(--vp-c-divider));
}
.paywall-secondary[data-v-7c1771f5] {
  display: inline-flex;
  align-items: center;
  padding: 11px 22px;
  background: transparent;
  color: var(--vp-c-text-1);
  font-size: 14px;
  font-weight: 500;
  border: 1px solid var(--vp-c-divider);
  border-radius: 10px;
  text-decoration: none;
  cursor: pointer;
  font-family: inherit;
  transition:
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    color        0.18s cubic-bezier(0.2, 0, 0, 1);
}
.paywall-secondary[data-v-7c1771f5]:hover {
  border-color: var(--vp-c-brand-1);
  color: var(--vp-c-brand-1);
}
.paywall-footnote[data-v-7c1771f5] {
  margin-top: 18px;
  font-size: 12px;
  color: var(--vp-c-text-3);
}

/* Dark mode handled by VitePress CSS variables (--vp-c-bg, --vp-c-bg-soft, --vp-c-divider) */
@media (max-width: 640px) {
.paywall-card[data-v-7c1771f5] {
    padding: 28px 22px 22px;
    border-radius: 16px;
}
.paywall-title[data-v-7c1771f5] { font-size: 19px;
}
.paywall-actions[data-v-7c1771f5] { flex-direction: column;
}
.paywall-cta[data-v-7c1771f5], .paywall-secondary[data-v-7c1771f5] { justify-content: center; width: 100%;
}
}

.nf-page[data-v-a62f70c8] {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 80px 24px 40px;
  position: relative;
  overflow: hidden;
  background: var(--vp-c-bg);
}
.nf-bg[data-v-a62f70c8] {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}
.nf-orb[data-v-a62f70c8] {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  opacity: 0.18;
}
.nf-orb-1[data-v-a62f70c8] {
  width: 480px;
  height: 480px;
  /* Ambient orb — was blue. Olive so the 404 page's atmosphere
     belongs to the site instead of feeling like a different
     product's error screen. */
  background: #6b9e2c;
  top: -120px;
  left: -120px;
  animation: nf-float-a-a62f70c8 20s ease-in-out infinite;
}
.nf-orb-2[data-v-a62f70c8] {
  width: 420px;
  height: 420px;
  /* Accent-lemon companion orb — pairs with the olive-1 above
     for a two-tone brand wash, replacing the purple #8b5cf6
     that appeared nowhere else on this page. */
  background: #c4f857;
  bottom: -100px;
  right: -100px;
  animation: nf-float-b-a62f70c8 24s ease-in-out infinite;
}
@keyframes nf-float-a-a62f70c8 {
0%, 100% { transform: translate(0, 0);
}
50% { transform: translate(40px, 30px);
}
}
@keyframes nf-float-b-a62f70c8 {
0%, 100% { transform: translate(0, 0);
}
50% { transform: translate(-30px, -40px);
}
}
.nf-container[data-v-a62f70c8] {
  position: relative;
  z-index: 1;
  max-width: 760px;
  width: 100%;
  text-align: center;
}
.nf-code[data-v-a62f70c8] {
  font-family: 'Newsreader', 'Noto Serif SC', Georgia, serif;
  font-size: clamp(96px, 18vw, 200px);
  font-weight: 700;
  line-height: 1;
  /* "404" hero numerals — olive → accent-lemon → deeper-olive
     text gradient. The hero of this whole page is a 3-character
     display, so if its colour is off-brand the whole page feels
     off-brand. Previous 3-stop blue → purple → pink rainbow was
     the loudest residue on the 404. */
  background: linear-gradient(135deg,
    var(--vp-c-brand-1),
    #a5e043,
    var(--vp-c-brand-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  margin-bottom: 16px;
  letter-spacing: -0.02em;
}
.nf-title[data-v-a62f70c8] {
  font-size: clamp(22px, 4vw, 32px);
  font-weight: 700;
  color: var(--vp-c-text-1);
  margin: 0 0 12px;
  letter-spacing: -0.01em;
}
.nf-desc[data-v-a62f70c8] {
  font-size: 15px;
  color: var(--vp-c-text-2);
  line-height: 1.7;
  margin: 0 0 32px;
}
.nf-actions[data-v-a62f70c8] {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin-bottom: 56px;
  flex-wrap: wrap;
}
.nf-btn[data-v-a62f70c8] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 11px 22px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition:
    background   0.22s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.22s cubic-bezier(0.2, 0, 0, 1),
    color        0.22s cubic-bezier(0.2, 0, 0, 1),
    transform    0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1);
  font-family: inherit;
  border: 1px solid transparent;
}
.nf-btn-primary[data-v-a62f70c8] {
  background: linear-gradient(135deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  color: #fff;
  box-shadow: 0 4px 14px color-mix(in oklab, var(--vp-c-brand-1) 32%, transparent);
  transition:
    transform  0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow 0.22s cubic-bezier(0.2, 0, 0, 1);
}
.nf-btn-primary[data-v-a62f70c8]:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 24px color-mix(in oklab, var(--vp-c-brand-1) 42%, transparent);
}
.nf-btn-secondary[data-v-a62f70c8] {
  background: transparent;
  color: var(--vp-c-text-1);
  border-color: var(--vp-c-divider);
}
.nf-btn-secondary[data-v-a62f70c8]:hover {
  border-color: var(--vp-c-text-2);
  background: rgba(15, 23, 42, 0.02);
}
.dark {
  background: rgba(148, 163, 184, 0.06);
}
.nf-suggest[data-v-a62f70c8] {
  text-align: left;
}
.nf-suggest-title[data-v-a62f70c8] {
  font-size: 13px;
  font-weight: 600;
  color: var(--vp-c-text-3);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin-bottom: 14px;
  text-align: center;
}
.nf-books[data-v-a62f70c8] {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
}
.nf-book-card[data-v-a62f70c8] {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  text-decoration: none;
  color: inherit;
  transition:
    border-color 0.22s cubic-bezier(0.2, 0, 0, 1),
    transform    0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1);
}
.nf-book-card[data-v-a62f70c8]:hover {
  transform: translateY(-2px);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 32%, transparent);
  box-shadow: var(--shadow-3);
}
.nf-book-icon[data-v-a62f70c8] {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  flex-shrink: 0;
}
.nf-book-info[data-v-a62f70c8] { min-width: 0;
}
.nf-book-title[data-v-a62f70c8] { font-size: 13px; font-weight: 600; color: var(--vp-c-text-1); margin-bottom: 2px;
}
.nf-book-desc[data-v-a62f70c8] { font-size: 11px; color: var(--vp-c-text-3);
}
@media (max-width: 640px) {
.nf-page[data-v-a62f70c8] { padding: 60px 16px 40px;
}
.nf-actions[data-v-a62f70c8] { flex-direction: column; align-items: stretch;
}
.nf-btn[data-v-a62f70c8] { justify-content: center;
}
.nf-books[data-v-a62f70c8] { grid-template-columns: 1fr;
}
}


/* Premium serif font stack — must precede all other statements */
/* ===== Design System — Terminal Codex (dark-first) + Docs Modern (light) =====
   Palette redesigned against the two new mockups:
   • Home (dark) — near-black surface + lemon-green accent (#c4f857)
   • Reader (V3 "Docs Modern") — crisp light doc surface + ink black accent
   Both themes share the same token names; VitePress toggles .dark on html. */
:root {
  /* Brand — lemon-green primary fill in both themes. --vp-c-brand-1 stays
   * a darker AA-compliant green so VitePress's link/emphasis text still
   * meets contrast on white; bright lemon is parked on --accent-fill. */
  --vp-c-brand-1: #3b7e00;
  --vp-c-brand-2: #2e6700;
  --vp-c-brand-3: #224f00;
  --vp-c-brand-soft: rgba(196, 248, 87, 0.22);
  --accent-fill: #c4f857;
  --accent-fill-hover: #d5ff7a;
  --accent-ink: #0a0b0f;

  /* Landing surfaces (light mode = V3 Docs Modern paper-white) */
  --home-bg: #fafafa;
  --home-bg-alt: #f4f4f4;
  --home-card-bg: #ffffff;
  --home-card-border: #ebebeb;
  --home-card-shadow: 0 1px 2px rgba(10, 10, 10, 0.04);
  --home-card-shadow-hover: 0 8px 24px rgba(10, 10, 10, 0.08);

  /* ---- Shadow scale (light) ----
     Five intentional elevation levels for the whole site. Pick the
     smallest that still communicates the needed elevation. Use the
     dark-mode overrides further down when .dark is on.
       --shadow-1  hairline "paper on paper"   — input chips, inline cards
       --shadow-2  resting card                — grid tiles, list items
       --shadow-3  hovered card                — card :hover default
       --shadow-4  sticky / popover            — dropdowns, floating ui
       --shadow-5  modal                       — login, payment, cropper
     Each value is slate-tinted (rgba(15,23,42,…)) rather than pure
     #000 so shadows on a near-white surface read as "paper cast"
     instead of surgical silhouettes. */
  --shadow-1: 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-2: 0 2px 6px rgba(15, 23, 42, 0.05), 0 1px 2px rgba(15, 23, 42, 0.03);
  --shadow-3: 0 8px 24px rgba(15, 23, 42, 0.08), 0 2px 6px rgba(15, 23, 42, 0.04);
  --shadow-4: 0 12px 32px rgba(15, 23, 42, 0.12), 0 4px 10px rgba(15, 23, 42, 0.06);
  --shadow-5: 0 24px 60px rgba(15, 23, 42, 0.20), 0 8px 24px rgba(15, 23, 42, 0.10);

  /* ---- Motion easing tokens ----
     The site's motion vocabulary is three curves; naming them so
     components don't have to hand-copy the bezier coordinates:
       --ease-out   — primary curve for enter / hover / state changes.
                      Fast-start, slow-settle (Material's "emphasized").
       --ease-in    — for leaves / retractions. Slow-start, fast-exit.
       --ease-io    — symmetric; only for infinite pulse / heartbeat. */
  --ease-out: cubic-bezier(0.2, 0, 0, 1);
  --ease-in:  cubic-bezier(0.4, 0, 1, 1);
  --ease-io:  cubic-bezier(0.4, 0, 0.2, 1);

  --home-text-1: #0a0a0a;
  --home-text-2: #525252;
  --home-text-3: #8b8b8b;

  --hero-bg: #fafafa;
  --hero-grid-line: rgba(10, 10, 10, 0.035);
  --hero-orb-1: rgba(196, 248, 87, 0.14);
  --hero-orb-2: rgba(139, 92, 246, 0.08);
  --hero-orb-3: rgba(59, 130, 246, 0.06);
  --hero-badge-color: #525252;
  --hero-badge-border: #ebebeb;
  --hero-badge-bg: #ffffff;
  --hero-pulse: #3b7e00;
  --hero-pulse-shadow: rgba(196, 248, 87, 0.5);
  --hero-title-main-from: #0a0a0a;
  --hero-title-main-to: #262626;
  --hero-title-accent-from: #3b7e00;
  --hero-title-accent-mid: #62a827;
  --hero-title-accent-to: #87c44a;
  --hero-desc: #525252;
  --hero-stat-num: #0a0a0a;
  --hero-stat-label: #8b8b8b;
  --hero-stat-sep: #ebebeb;
  --hero-ghost-color: #262626;
  --hero-ghost-border: #ebebeb;
  --hero-ghost-bg: #ffffff;
  --hero-ghost-hover-border: #0a0a0a;
  --hero-ghost-hover-bg: #ffffff;
  --hero-nav-brand: #0a0a0a;
  --hero-nav-link: #525252;
  --hero-nav-link-hover: #0a0a0a;
  --hero-nav-icon: #525252;

  --home-tag-bg: #f0ebff;
  --home-tag-color: #6f42c1;
  --home-tag-border: #e9e3ff;

  --home-feature-icon-bg: rgba(196, 248, 87, 0.12);
  --home-divider: #ebebeb;

  /* Reader-specific tokens (used in chapter pages for eyebrow, code-bar, tip) */
  --reader-surface: #ffffff;
  --reader-surface-alt: #fafafa;
  --reader-border: #ebebeb;
  --reader-border-strong: #d4d4d4;
  --reader-ink: #0a0a0a;
  --reader-muted: #525252;
  --reader-muted-2: #8b8b8b;
  /* Reader accent now tracks the brand green (was #6f42c1 purple,
     which read as a fourth color alongside brand-green, logo-blue,
     and beak-orange — four hue families fighting in one view).
     Consolidated here so inline code + blockquote bar stay on-brand. */
  --reader-accent: #3b7e00;
  --reader-accent-soft: rgba(59, 126, 0, 0.08);
  --reader-tip-bg: #f8f6ff;
  --reader-tip-border: #e9e3ff;
  --reader-prog-bar: linear-gradient(90deg, #0a0a0a, #6b6b6b);
  --reader-sans: 'Inter', 'PingFang SC', 'HarmonyOS Sans', system-ui, sans-serif;
  --reader-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;

  /* Transition */
  --ease-out: cubic-bezier(0.4, 0, 0.2, 1);
}
.dark {
  /* Lemon-green accent on near-black: the home mockup's signature */
  --vp-c-brand-1: #c4f857;
  --vp-c-brand-2: #b4ef45;
  --vp-c-brand-3: #9ad43e;
  --vp-c-brand-soft: rgba(196, 248, 87, 0.16);
  --accent-fill: #c4f857;
  --accent-fill-hover: #d5ff7a;
  --accent-ink: #0a0b0f;

  --home-bg: #0a0b0f;
  --home-bg-alt: #0e1016;
  --home-card-bg: #0e1016;
  --home-card-border: #1f2430;
  --home-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
  --home-card-shadow-hover: 0 24px 60px rgba(0, 0, 0, 0.55);

  /* Dark-mode shadow scale — near-black surfaces need deeper alphas
     to feel elevated; stronger blacks read as "real depth" rather
     than a flat overlay. Pure #000 is OK here since we're casting
     onto a near-black page. */
  --shadow-1: 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.45), 0 1px 3px rgba(0, 0, 0, 0.3);
  --shadow-3: 0 10px 28px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);
  --shadow-4: 0 16px 40px rgba(0, 0, 0, 0.55), 0 4px 10px rgba(0, 0, 0, 0.35);
  --shadow-5: 0 28px 72px rgba(0, 0, 0, 0.65), 0 10px 28px rgba(0, 0, 0, 0.45);

  --home-text-1: #ecedf0;
  --home-text-2: #a4a9b7;
  --home-text-3: #5d6478;

  --hero-bg: #0a0b0f;
  --hero-grid-line: rgba(255, 255, 255, 0.04);
  --hero-orb-1: rgba(196, 248, 87, 0.08);
  --hero-orb-2: rgba(139, 92, 246, 0.08);
  --hero-orb-3: rgba(59, 130, 246, 0.06);
  --hero-badge-color: #a4a9b7;
  --hero-badge-border: #2a3044;
  --hero-badge-bg: #0e1016;
  --hero-pulse: #c4f857;
  --hero-pulse-shadow: rgba(196, 248, 87, 0.55);
  --hero-title-main-from: #ecedf0;
  --hero-title-main-to: #ecedf0;
  --hero-title-accent-from: #c4f857;
  --hero-title-accent-mid: #8de3a3;
  --hero-title-accent-to: #61dafb;
  --hero-desc: #a4a9b7;
  --hero-stat-num: #ecedf0;
  --hero-stat-label: #a4a9b7;
  --hero-stat-sep: #1f2430;
  --hero-ghost-color: #ecedf0;
  --hero-ghost-border: #2a3044;
  --hero-ghost-bg: transparent;
  --hero-ghost-hover-border: #c4f857;
  --hero-ghost-hover-bg: rgba(196, 248, 87, 0.05);
  --hero-nav-brand: #ecedf0;
  --hero-nav-link: #a4a9b7;
  --hero-nav-link-hover: #ecedf0;
  --hero-nav-icon: #a4a9b7;

  --home-tag-bg: rgba(196, 248, 87, 0.08);
  --home-tag-color: #c4f857;
  --home-tag-border: rgba(196, 248, 87, 0.22);

  --home-feature-icon-bg: rgba(196, 248, 87, 0.08);
  --home-divider: #1f2430;

  /* Reader tokens, dark */
  --reader-surface: #0e1016;
  --reader-surface-alt: #141722;
  --reader-border: #1f2430;
  --reader-border-strong: #2a3044;
  --reader-ink: #ecedf0;
  --reader-muted: #a4a9b7;
  --reader-muted-2: #5d6478;
  --reader-accent: #c4f857;
  --reader-accent-soft: rgba(196, 248, 87, 0.1);
  --reader-tip-bg: rgba(196, 248, 87, 0.06);
  --reader-tip-border: rgba(196, 248, 87, 0.22);
  --reader-prog-bar: linear-gradient(90deg, #c4f857, #9ad43e);
}
/* ===== Global Smooth Scroll ===== */
html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Newsreader / Noto Serif SC ship an `opsz` variable axis. Letting
     the browser pick the optical-size instance per rendered pixel
     size nudges captions to feel slightly tighter and titles to feel
     slightly wider — the kind of detail you don't see until you
     compare side-by-side, but is table-stakes for a publication. */
  font-optical-sizing: auto;
}
/* ===== Selection Highlight ===== */
::selection {
  background: rgba(196, 248, 87, 0.45);
  color: #0a0b0f;
}
.dark ::selection {
  background: #c4f857;
  color: #0a0b0f;
}
/* ===== Global Scrollbar — thin, subtle, theme-aware =====
   The OS default scrollbar is 17px and steel-gray on both macOS
   and Windows — it dominates the right edge of the page and
   clashes with the dark hero canvas and the light reader.
   Replace with a 10px rail that fades to 35%/45% of the ink
   colour on hover. Inner scrollables (.VPSidebar, code blocks,
   tables) keep their own more-subtle styling. */
html {
  scrollbar-width: thin;                     /* Firefox */
  scrollbar-color: rgba(15, 23, 42, 0.22) transparent;
}
html.dark {
  scrollbar-color: rgba(196, 248, 87, 0.18) transparent;
}
html::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
html::-webkit-scrollbar-track {
  background: transparent;
}
html::-webkit-scrollbar-thumb {
  background: rgba(15, 23, 42, 0.18);
  border: 2px solid transparent;
  background-clip: content-box;
  border-radius: 999px;
  transition: background-color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
html::-webkit-scrollbar-thumb:hover {
  background: rgba(15, 23, 42, 0.32);
  background-clip: content-box;
}
html.dark::-webkit-scrollbar-thumb {
  background: rgba(196, 248, 87, 0.16);
  background-clip: content-box;
}
html.dark::-webkit-scrollbar-thumb:hover {
  background: rgba(196, 248, 87, 0.32);
  background-clip: content-box;
}
html::-webkit-scrollbar-corner {
  background: transparent;
}
/* ===== Placeholders — consistent muted baseline =====
   Default browser placeholder is too opaque (60-70% alpha-black)
   and reads as "almost real input text". Drop to 48% alpha of
   --vp-c-text-3 so the placeholder clearly differentiates from
   entered text but stays legible. Applied globally; components
   with existing placeholder styles (LoginModal) keep theirs via
   specificity. */
input::placeholder,
textarea::placeholder {
  color: var(--vp-c-text-3);
  opacity: 0.65;
  font-weight: 400;
}
input:focus::placeholder,
textarea:focus::placeholder {
  /* On focus the placeholder fades a hair further — signals
     "ready for input" without actually hiding the hint before
     the user types. */
  opacity: 0.45;
}
/* Expose dark-palette tokens to VitePress's own variable system so the
   default theme (sidebar, outline, search modal, code blocks) inherits
   the new near-black surfaces without per-component overrides. */
.dark {
  --vp-c-bg: #0a0b0f;
  --vp-c-bg-alt: #0e1016;
  --vp-c-bg-elv: #141722;
  --vp-c-bg-soft: #141722;
  --vp-c-divider: #1f2430;
  --vp-c-gutter: #0a0b0f;
  --vp-c-text-1: #ecedf0;
  --vp-c-text-2: #a4a9b7;
  --vp-c-text-3: #5d6478;
  --vp-c-default-1: #1f2430;
  --vp-c-default-2: #141722;
  --vp-c-default-3: #0e1016;
  --vp-c-default-soft: rgba(42, 48, 68, 0.28);
}
/* ===== Top Navigation — Premium & Clean ===== */
/* Nav bar: glass morphism background */
/* Nav bar: unified background — override ALL layers */
.VPNav .VPNavBar,
.VPNav .VPNavBar .wrapper,
.VPNav .VPNavBar .container,
.VPNav .VPNavBar .container > .title,
.VPNav .VPNavBar .container > .content,
.VPNav .VPNavBar .container > .content > .content-body,
.VPNavBarTitle,
.VPNavBarTitle.has-sidebar {
  background: transparent !important;
}
.VPNav .VPNavBar {
  background: rgba(255, 255, 255, 0.92) !important;
  backdrop-filter: saturate(180%) blur(16px) !important;
  -webkit-backdrop-filter: saturate(180%) blur(16px) !important;
}
.dark .VPNav .VPNavBar {
  background: rgba(12, 15, 26, 0.92) !important;
}
/* Kill sidebar curtain in nav */
.VPNavBar .curtain,
.VPNavBar.has-sidebar .curtain {
  background: transparent !important;
}
.VPNav .VPNavBar .divider {
  border-bottom: 1px solid rgba(15, 23, 42, 0.08) !important;
}
.dark .VPNav .VPNavBar .divider {
  border-bottom-color: rgba(148, 163, 184, 0.1) !important;
}
/* Reorder: menu items left, search right */
@media (min-width: 768px) {
  .VPNavBar .VPNavBarMenu {
    order: -1 !important;
    flex-grow: 0 !important;
    padding-left: 20px !important;
  }

  .VPNavBar .VPNavBarSearch {
    flex-grow: 1 !important;
    display: flex !important;
    justify-content: flex-end !important;
    order: 0 !important;
    padding-right: 12px !important;
  }
}
/* Nav links: refined typography + hover underline */
.VPNavBarMenuLink {
  font-weight: 500 !important;
  font-size: 14px !important;
  color: var(--vp-c-text-2) !important;
  position: relative !important;
  transition: color 0.2s !important;
}
.VPNavBarMenuLink::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 50%;
  width: 0;
  height: 2px;
  background: var(--vp-c-brand-1);
  border-radius: 1px;
  transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1), left 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.VPNavBarMenuLink:hover {
  color: var(--vp-c-text-1) !important;
}
.VPNavBarMenuLink:hover::after,
.VPNavBarMenuLink.active::after {
  width: 100%;
  left: 0;
}
.VPNavBarMenuLink.active {
  color: var(--vp-c-brand-1) !important;
  font-weight: 600 !important;
}
/* Search button: refined pill shape (desktop) */
@media (min-width: 768px) {
  .VPNavBar .DocSearch-Button,
  .VPNavBar .VPNavBarSearch button {
    min-width: 200px !important;
  }
}
.VPNavBar .DocSearch-Button,
.VPNavBar .VPNavBarSearch button {
  border-radius: 10px !important;
  border: 1px solid rgba(15, 23, 42, 0.08) !important;
  background: rgba(15, 23, 42, 0.03) !important;
  transition:
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    background   0.18s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1) !important;
}
/* Mobile: compact icon-only search + tighter right spacing */
@media (max-width: 767px) {
  .VPNavBar .VPNavBarSearch {
    flex-grow: 0 !important;
    flex-shrink: 0 !important;
    padding: 0 !important;
    margin-left: auto !important;
  }

  .VPNavBar .DocSearch-Button,
  .VPNavBar .VPNavBarSearch button {
    width: 38px !important;
    min-width: 38px !important;
    height: 38px !important;
    padding: 0 !important;
    border-radius: 10px !important;
    justify-content: center !important;
  }

  /* Hide search placeholder text + keyboard hint on mobile, keep icon */
  .VPNavBar .DocSearch-Button .DocSearch-Button-Placeholder,
  .VPNavBar .DocSearch-Button .DocSearch-Button-Keys,
  .VPNavBar .VPNavBarSearch button .DocSearch-Button-Placeholder,
  .VPNavBar .VPNavBarSearch button .DocSearch-Button-Keys {
    display: none !important;
  }

  .VPNavBar .DocSearch-Button-Container {
    margin: 0 !important;
  }

  /* Tighten user avatar gap on mobile */
  .VPNavBar .user-nav {
    margin-left: 8px !important;
  }

  /* Trim hamburger padding so right edge matches left */
  .VPNavBar .VPNavBarHamburger {
    padding-right: 4px !important;
  }
}
.VPNavBar .DocSearch-Button:hover,
.VPNavBar .VPNavBarSearch button:hover {
  border-color: rgba(15, 23, 42, 0.15) !important;
  background: rgba(15, 23, 42, 0.05) !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04) !important;
}
.dark .VPNavBar .DocSearch-Button,
.dark .VPNavBar .VPNavBarSearch button {
  border-color: rgba(148, 163, 184, 0.1) !important;
  background: rgba(148, 163, 184, 0.04) !important;
}
.dark .VPNavBar .DocSearch-Button:hover,
.dark .VPNavBar .VPNavBarSearch button:hover {
  border-color: rgba(148, 163, 184, 0.2) !important;
  background: rgba(148, 163, 184, 0.08) !important;
}
/* Remove all divider lines */
.VPNavBarAppearance::before,
.VPNavBarAppearance::after,
.VPNavBarExtra::before,
.VPNavBar .divider-line {
  display: none !important;
}
/* Theme toggle: clean, proper dark mode */
.VPNavBarAppearance .VPSwitch {
  border-color: transparent !important;
  background: rgba(15, 23, 42, 0.06) !important;
}
.dark .VPNavBarAppearance .VPSwitch {
  background: rgba(148, 163, 184, 0.1) !important;
}
.VPNavBarAppearance .VPSwitch:hover {
  background: rgba(15, 23, 42, 0.1) !important;
}
.dark .VPNavBarAppearance .VPSwitch:hover {
  background: rgba(148, 163, 184, 0.18) !important;
}
/* Brand wordmark now lives inside /logo_horizontal_{light,dark}.svg
   (config.ts sets siteTitle: false). The old .VPNavBarTitle .title
   typography + ::after hairline rules here were dead code once the
   title text element stopped rendering — removed to avoid confusing
   future readers. */
/* Horizontal lockup is 1100×280 (~3.93:1). VitePress's default logo
   slot is a 24px square — that squashes the wordmark to ~94px wide,
   which reads as a tiny smudge in the nav. Force height + auto width
   so the mark renders at its natural aspect. */
.VPNavBarTitle .VPImage.logo,
.VPNavBarTitle.has-sidebar .VPImage.logo {
  height: 36px !important;
  width: auto !important;
  max-width: none !important;
}
/* Mobile: shrink the wordmark a touch and keep the slot from being
   squeezed when the right-side nav is crowded. */
@media (max-width: 600px) {
  .VPNavBarTitle,
  .VPNavBarTitle.has-sidebar {
    flex-shrink: 0 !important;
  }
  .VPNavBarTitle .VPImage.logo,
  .VPNavBarTitle.has-sidebar .VPImage.logo {
    height: 28px !important;
  }
}
/* NavBreadcrumb is rendered in nav-bar-content-before so it lives in the
   .content-body flex row alongside menu/search. Push it to the leftmost
   position (menu has order:-1, search order:0). Drop the inline-flex
   width clamp from the legacy in-title rules. */
.book-page .VPNavBar .nav-breadcrumb {
  order: -2 !important;
  margin-left: 0 !important;
  padding-left: 0 !important;
  border-left: none !important;
  flex-shrink: 1 !important;
  min-width: 0 !important;
}
/* Section + current can ellipsize when the viewport is too narrow,
   instead of forcing the whole row to overflow. Book stays full. */
.book-page .VPNavBar .nav-breadcrumb .nbc-section,
.book-page .VPNavBar .nav-breadcrumb .nbc-current {
  flex-shrink: 1 !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  min-width: 0 !important;
}
.book-page .VPNavBar .nav-breadcrumb .nbc-book {
  flex-shrink: 0 !important;
}
/* ===== Hide default VitePress home content ===== */
.VPHome .VPHero,
.VPHome .VPFeatures {
  display: none !important;
}
.VPDoc .VPDocFooter,
.VPPage .VPFooter,
.VPContent + .VPFooter,
.Layout > .VPFooter {
  display: none !important;
}
/* ===== Reading Progress Bar ===== */
.reading-progress {
  position: fixed;
  top: var(--vp-nav-height);
  left: 0;
  height: 3px;
  /* Pure-brand gradient — olive → deeper-olive. Previous middle
     stop was #8b5cf6 purple, a colour that appeared nowhere else
     on the reading surface. The shadow was blue 40%; swapped to
     a brand-mixed glow so the whole bar sits inside the palette. */
  background: linear-gradient(90deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  z-index: 21;
  transition: width 0.1s linear;
  pointer-events: none;
  box-shadow: 0 0 8px color-mix(in oklab, var(--vp-c-brand-1) 40%, transparent);
}
/* ===== Sidebar — World-class Book Navigation ===== */
@media (min-width: 960px) {
  .VPSidebar {
    top: var(--vp-nav-height) !important;
    padding-top: 12px !important;
    padding-bottom: 24px !important;
    background: #fafbfd !important;
    border-right: none !important;
    box-shadow: 1px 0 0 rgba(15, 23, 42, 0.04);
  }

  .dark .VPSidebar {
    background: rgba(12, 15, 26, 0.5) !important;
    box-shadow: 1px 0 0 rgba(148, 163, 184, 0.06);
  }

  .VPSidebar .curtain {
    display: none !important;
  }

  .VPNavBar.has-sidebar .divider {
    padding-left: 0 !important;
  }

  .VPNavBarTitle.has-sidebar .title {
    border-bottom-color: transparent !important;
  }
}
/* Sidebar scrollbar: invisible until hover, ultra-thin */
.VPSidebar::-webkit-scrollbar { width: 3px; }
.VPSidebar::-webkit-scrollbar-thumb { background: transparent; border-radius: 3px; }
.VPSidebar:hover::-webkit-scrollbar-thumb { background: rgba(15, 23, 42, 0.1); }
.dark .VPSidebar:hover::-webkit-scrollbar-thumb { background: rgba(148, 163, 184, 0.12); }
.VPSidebar::-webkit-scrollbar-track { background: transparent; }
/* Section group headers — muted label style */
.VPSidebar .VPSidebarItem.level-0 > .item > .text {
  font-size: 11.5px !important;
  font-weight: 600 !important;
  letter-spacing: 0.03em;
  color: var(--vp-c-text-3) !important;
  padding: 8px 0 4px;
}
/* Chapter items */
.VPSidebar .VPSidebarItem .text {
  font-size: 13px;
  line-height: 1.5;
  color: var(--vp-c-text-2);
  transition: color 0.15s;
}
/* Nav items: rounded hover zones */
.VPSidebar .VPSidebarItem.level-1 > .item {
  border-radius: 6px;
  margin: 1px 6px 1px 4px;
  padding: 4px 8px !important;
  transition: background 0.15s;
}
.VPSidebar .VPSidebarItem.level-1 > .item:hover {
  background: var(--vp-c-bg-soft);
}
.VPSidebar .VPSidebarItem.level-1 > .item:hover .text {
  color: var(--vp-c-text-1);
}
.dark .VPSidebar .VPSidebarItem.level-1 > .item:hover {
  background: rgba(148, 163, 184, 0.06);
}
/* Active item: left accent bar + tinted background + brand glow.
   Strengthened so the reader can find their place in a 25-chapter
   sidebar at a glance without hunting for a single bold line.
   Historical note: the accent bar used to be indigo→blue from the
   pre-brand palette; reworked to derive from var(--vp-c-brand-1)
   so it always matches the current accent family. The dark-mode
   variant is owned by the §4724 block further down. */
.VPSidebar .VPSidebarItem.is-active.level-1 > .item {
  background: linear-gradient(90deg, var(--vp-c-brand-soft), transparent 80%);
  position: relative;
  border-radius: 0 6px 6px 0;
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--vp-c-brand-1) 18%, transparent);
}
.VPSidebar .VPSidebarItem.is-active.level-1 > .item::before {
  content: '';
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 3px;
  background: linear-gradient(180deg,
    var(--vp-c-brand-1),
    color-mix(in oklab, var(--vp-c-brand-1) 70%, transparent));
  border-radius: 0 2px 2px 0;
  box-shadow: 0 0 8px color-mix(in oklab, var(--vp-c-brand-1) 45%, transparent);
}
.VPSidebar .VPSidebarItem.is-active > .item .text {
  font-weight: 600 !important;
  color: var(--vp-c-brand-1) !important;
}
/* Group dividers */
.VPSidebar .group + .group {
  border-top: 1px solid var(--vp-c-divider);
  margin-top: 12px;
  padding-top: 12px;
}
/* Collapse/expand caret: refined */
.VPSidebar .VPSidebarItem .caret {
  transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1) !important;
}
/* ===== Doc Typography — Book pages (World-class reading) ===== */
/* Content area max width for optimal line length (~70-80 chars) */
.book-page .vp-doc {
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1;
  /* Chinese typography — hanging punctuation pushes leading/trailing
     「」『』.,!? out into the margin so paragraphs keep a clean left
     edge. Safari 17.4+ honours this; other browsers ignore it (no
     regression). Worth the line for how much it polishes blockquotes
     and quoted dialogue. */
  hanging-punctuation: first last;
}
/* Balance wraps on headings so the last line doesn't orphan a single
   word. text-wrap: balance is supported in all evergreen browsers
   (Chrome 114+, Safari 17.4+, Firefox 121+); no-op elsewhere. */
.book-page .vp-doc h1,
.book-page .vp-doc h2,
.book-page .vp-doc h3,
.book-page .vp-doc h4 {
  text-wrap: balance;
}
/* Pretty wraps on body prose — moves the widow threshold from "any
   last-line fragment" to "no single dangling word". Costs a few ms
   of layout time per paragraph on the first paint; unnoticeable. */
.book-page .vp-doc p,
.book-page .vp-doc li {
  text-wrap: pretty;
}
.book-page .vp-doc h1 {
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.02em;
  padding-bottom: 20px;
  border-bottom: none;
  margin-bottom: 28px;
  margin-top: 4px;
  line-height: 1.4;
  color: var(--vp-c-text-1);
}
/* Textbook-style chapter cover label injected client-side above
   the h1 by useReadingEnhancers#enhanceChapterCover. Reads as
   the running header of a printed book ("CHAPTER 05") rather
   than competing with the chapter title for prominence. */
.book-page .vp-doc .chapter-cover-label {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 8px;
  padding: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: transparent;
  /* Chapter-cover label ("CHAPTER 04 / ARCHITECTURE OVERVIEW") —
     brand olive gradient replaces the pre-brand indigo→blue. The
     whole label is clip-masked text so the gradient becomes the
     visible character fill. */
  background: linear-gradient(90deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  -webkit-background-clip: text;
  background-clip: text;
  text-transform: uppercase;
}
.book-page .vp-doc .chapter-cover-label .ccl-en {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.book-page .vp-doc .chapter-cover-label .ccl-sep {
  opacity: 0.5;
  font-weight: 400;
  letter-spacing: normal;
}
.book-page .vp-doc .chapter-cover-label .ccl-zh {
  font-family: var(--vp-font-family-base);
  letter-spacing: 0.05em;
  font-size: 11.5px;
}
/* ===========================================================
   Global dark-mode polish — small bumps to the bits that read
   right in light mode but go too quiet on a dark background.
   =========================================================== */
.dark.book-page .vp-doc tbody tr:nth-child(even) td {
  background: rgba(255, 255, 255, 0.04);
}
.dark.book-page .vp-doc ul > li::before,
.dark.book-page .vp-doc ol > li::before {
  background: linear-gradient(180deg, #818cf8, #60a5fa);
}
.dark.book-page .vp-doc h2::after {
  background: linear-gradient(to right, #818cf8, rgba(129, 140, 248, 0.55) 35%, rgba(255, 255, 255, 0.12) 75%, transparent);
}
.dark.book-page .vp-doc h3::before {
  background: linear-gradient(180deg, #818cf8, #60a5fa);
}
.dark .kbd-help-overlay {
  background: rgba(0, 0, 0, 0.6);
}
.dark .kbd-help-card {
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
}
/* ===========================================================
   Sticky current-section header — sits below the nav once the
   chapter title scrolls out, showing the current H2's text.
   Click to scroll back to that section's heading. Long prose
   chapters (15+ scroll-screens between H2 markers) finally
   give the reader a "you're reading section X" anchor that
   doesn't require glancing at the right-side outline.
   =========================================================== */
.sticky-section {
  position: fixed;
  top: var(--vp-nav-height, 60px);
  left: 50%;
  transform: translateX(-50%) translateY(-8px);
  z-index: 19;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 16px 7px 14px;
  border-radius: 999px;
  background: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  /* Sticky section pill — popover tier: floats above scrolling
     content like a dropdown would. */
  box-shadow: var(--shadow-4);
  font-size: 13px;
  font-weight: 600;
  color: var(--vp-c-text-1);
  letter-spacing: -0.01em;
  cursor: pointer;
  max-width: min(720px, calc(100vw - 32px));
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s var(--ease-out), transform 0.2s var(--ease-out);
  margin-top: 8px;
}
.sticky-section.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
.sticky-section:hover {
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 42%, transparent);
  color: var(--vp-c-brand-1);
}
.sticky-section .ss-icon {
  color: var(--vp-c-text-3);
  font-size: 16px;
  line-height: 1;
  flex-shrink: 0;
}
.sticky-section .ss-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.sticky-section .ss-num {
  flex-shrink: 0;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--vp-c-bg-soft);
  color: var(--vp-c-text-3);
  font-size: 10.5px;
  font-weight: 600;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.06em;
}
.sticky-section .ss-num:empty { display: none; }
.sticky-section .ss-remain {
  flex-shrink: 0;
  margin-left: 4px;
  padding-left: 10px;
  border-left: 1px solid var(--vp-c-divider);
  color: var(--vp-c-text-3);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.sticky-section .ss-remain:empty {
  display: none;
  border-left: none;
  padding-left: 0;
  margin-left: 0;
}
html.dark.book-page .sticky-section {
  background: rgba(14, 16, 22, 0.96) !important;
  border-color: #1f2430 !important;
}
html.dark.book-page .sticky-section:hover {
  border-color: rgba(196, 248, 87, 0.45) !important;
  color: var(--jt-accent) !important;
}
html.dark.book-page .sticky-section .ss-num {
  background: rgba(196, 248, 87, 0.12);
  color: var(--jt-accent);
}
html.dark.book-page .sticky-section .ss-icon {
  color: var(--jt-accent);
}
.dark .sticky-section {
  background: rgba(20, 22, 35, 0.95);
  backdrop-filter: blur(8px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
}
@media (max-width: 640px) {
  .sticky-section {
    font-size: 12px;
    padding: 6px 12px;
    max-width: calc(100vw - 24px);
  }
}
@media print {
  .sticky-section { display: none !important; }
}
/* ===========================================================
   Focus mode — a fixed right-side button hides the global
   chrome when toggled on: nav bar, sidebar, right outline,
   ArticleHeader / ArticleFooter, sticky section, resume pill,
   mobile TOC FAB. Only the chapter prose (with its chapter-top
   nav still present for navigation) remains. Persists across
   visits via localStorage.
   =========================================================== */
/* Focus-mode toggle. Sits in the right-edge FAB column, above
   the chapter-listen and back-to-top buttons. See also
   .chapter-listen-btn + .back-to-top-fab for the stack layout. */
.focus-mode-btn {
  position: fixed;
  right: 22px;
  bottom: 118px;
  z-index: 24;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--vp-c-divider);
  background: var(--vp-c-bg);
  color: var(--vp-c-text-3);
  cursor: pointer;
  box-shadow: var(--shadow-3);
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    color        0.18s var(--ease-out),
    border-color 0.18s var(--ease-out),
    background   0.18s var(--ease-out),
    transform    0.18s var(--ease-out);
}
.focus-mode-btn:hover {
  transform: scale(1.05);
  color: var(--vp-c-brand-1);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 45%, transparent);
}
.focus-mode-btn.is-on {
  /* Brand olive → deeper-olive for the "on" state. Previously
     indigo→blue, which didn't belong to the site's accent family.
     Dark mode swaps to lemon via the existing .dark override
     block at the bottom of this file. */
  background: linear-gradient(135deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  color: #fff;
  border-color: transparent;
  box-shadow: 0 6px 18px color-mix(in oklab, var(--vp-c-brand-1) 40%, transparent);
}
@media (max-width: 640px) {
  .focus-mode-btn { display: none; }
}
/* ===========================================================
   Full-chapter TTS button — stacks 48px below the focus-mode
   button on the right edge. Toggle between "play" (outline
   speaker) and "stop" (solid square) based on speaking state.
   =========================================================== */
/* Chapter TTS. Middle slot of the right-edge FAB stack. */
.chapter-listen-btn {
  position: fixed;
  right: 22px;
  bottom: 70px;
  z-index: 24;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--vp-c-divider);
  background: var(--vp-c-bg);
  color: var(--vp-c-text-3);
  cursor: pointer;
  box-shadow: var(--shadow-3);
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    color        0.18s var(--ease-out),
    border-color 0.18s var(--ease-out),
    background   0.18s var(--ease-out),
    transform    0.18s var(--ease-out);
}
.chapter-listen-btn:hover {
  transform: scale(1.05);
  color: var(--vp-c-brand-1);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 45%, transparent);
}
.chapter-listen-btn .clb-stop { display: none; }
.chapter-listen-btn.is-speaking {
  background: linear-gradient(135deg, #f59e0b, #ef4444);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 6px 18px rgba(245, 158, 11, 0.4);
  animation: listen-pulse 1.4s ease-in-out infinite;
}
.chapter-listen-btn.is-speaking .clb-play { display: none; }
.chapter-listen-btn.is-speaking .clb-stop { display: block; }
@keyframes listen-pulse {
  0%, 100% { box-shadow: 0 6px 18px rgba(245, 158, 11, 0.4); }
  50%      { box-shadow: 0 6px 24px rgba(245, 158, 11, 0.65); }
}
@media (max-width: 640px) {
  .chapter-listen-btn { display: none; }
}
/* Voice / TTS playback hidden platform-wide for now — Web Speech
   API voices on most browsers sound too robotic to match the
   "professional learning platform" feel we want. Code paths stay
   wired so we can flip this back on once we have a better voice
   pipeline (Azure Neural TTS, ElevenLabs, etc.). */
.chapter-listen-btn,
.tts-player,
.tts-play-btn { display: none !important; }
/* TTS currently-speaking element highlight. A 3px amber gradient
   rail grows in from the left of whichever paragraph / heading /
   list item is being read, plus a faint amber wash across the
   element. Reader sees the reading position travel through the
   chapter rather than guessing. */
.book-page .vp-doc .tts-now {
  position: relative;
  background: linear-gradient(90deg, rgba(245, 158, 11, 0.08), transparent 40%);
  border-radius: 4px;
  transition: background 0.2s var(--ease-out);
}
.book-page .vp-doc .tts-now::before {
  content: '';
  position: absolute;
  left: -14px;
  top: 4px;
  bottom: 4px;
  width: 3px;
  border-radius: 2px;
  background: linear-gradient(180deg, #f59e0b, #ef4444);
  box-shadow: 0 0 8px rgba(245, 158, 11, 0.6);
  animation: tts-rail-pulse 1.2s ease-in-out infinite;
}
@keyframes tts-rail-pulse {
  0%, 100% { opacity: 0.85; }
  50%      { opacity: 1; }
}
.dark .book-page .vp-doc .tts-now {
  background: linear-gradient(90deg, rgba(245, 158, 11, 0.16), transparent 40%);
}
/* TTS mini-player — bottom-center floater that appears while
   the chapter is being read aloud. Prev / play-pause / next +
   progress + speed + close. Paused state swaps the icon. */
.tts-player {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%) translateY(16px);
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 8px;
  border-radius: 999px;
  background: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  /* Floating TTS player pill — popover tier. */
  box-shadow: var(--shadow-4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s var(--ease-out), transform 0.22s var(--ease-out);
}
.tts-player.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
.tts-player button {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--vp-c-text-2);
  cursor: pointer;
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s var(--ease-out), color 0.15s var(--ease-out);
}
.tts-player button:hover {
  background: var(--vp-c-bg-soft);
  color: var(--vp-c-text-1);
}
.tts-player .tp-rate {
  width: auto;
  padding: 0 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--vp-c-brand-1);
}
.tts-player .tp-stop {
  color: var(--vp-c-text-3);
  font-size: 16px;
}
.tts-player .tp-stop:hover {
  color: #ef4444;
  background: rgba(239, 68, 68, 0.08);
}
.tts-player .tp-idx {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--vp-c-text-3);
  padding: 0 6px;
  font-variant-numeric: tabular-nums;
  min-width: 54px;
  text-align: center;
}
/* Pause/play icon swap */
.tts-player button[data-act="pause"] .tp-pause { display: none; }
.tts-player button[data-act="pause"] .tp-play { display: none; }
.tts-player:not(.is-paused) button[data-act="pause"] .tp-pause { display: block; }
.tts-player.is-paused button[data-act="pause"] .tp-play { display: block; }
/* play-pause button is the visual focal point */
.tts-player button[data-act="pause"] {
  background: linear-gradient(135deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  color: #fff;
}
.tts-player button[data-act="pause"]:hover {
  background: linear-gradient(135deg, #4f46e5, #2563eb);
  color: #fff;
}
@media (max-width: 640px) {
  .tts-player {
    bottom: 14px;
    padding: 4px 6px;
  }
  .tts-player .tp-idx {
    display: none;
  }
}
/* ===========================================================
   Back-to-top progress ring — fixed bottom-right FAB. The SVG
   ring fills proportionally to the reader's scroll through the
   chapter; an up-arrow sits at the center. Faded out by default;
   slides in only after the reader has scrolled past ~120vh so it
   never clutters the above-the-fold.
   =========================================================== */
/* Back-to-top. Bottom slot of the right-edge FAB stack. See also
   .focus-mode-btn (top slot, bottom 118px) + .chapter-listen-btn
   (middle slot, bottom 70px). */
.back-to-top-fab {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 24;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--vp-c-divider);
  background: var(--vp-c-bg);
  color: var(--vp-c-text-2);
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Back-to-top floating FAB — popover tier. */
  box-shadow: var(--shadow-4);
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition:
    opacity      0.2s var(--ease-out),
    transform    0.2s var(--ease-out),
    color        0.2s var(--ease-out),
    border-color 0.2s var(--ease-out);
}
.back-to-top-fab.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.back-to-top-fab:hover {
  color: var(--vp-c-brand-1);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 45%, transparent);
}
.back-to-top-fab .btt-ring {
  position: absolute;
  inset: 2px;
}
.back-to-top-fab .btt-track {
  stroke: var(--vp-c-divider);
}
.back-to-top-fab .btt-fill {
  stroke: var(--vp-c-brand-1);
  transition: stroke-dashoffset 0.15s var(--ease-out);
}
.back-to-top-fab:hover .btt-fill {
  stroke: var(--vp-c-brand-2);
}
.back-to-top-fab .btt-arrow {
  position: relative;
  z-index: 1;
}
/* Stack cleanly with mobile-toc-fab (20px/20px right/bottom) when
   both would collide: back-to-top sits above it. */
@media (max-width: 768px) {
  .back-to-top-fab {
    right: 20px;
    bottom: 78px;
  }
}
@media (max-width: 640px) {
  .back-to-top-fab { display: none; }
}
/* When focus mode is on, hide everything that isn't the chapter
   content column. Chapter content (.vp-doc with its enhancer
   injections) is left alone. */
html.reading-focus .VPNav,
html.reading-focus .VPLocalNav,
html.reading-focus .VPSidebar,
html.reading-focus .VPDocAside,
html.reading-focus .VPDocFooter,
html.reading-focus .article-header,
html.reading-focus .article-footer,
html.reading-focus .sticky-section,
html.reading-focus .mobile-toc-fab,
html.reading-focus .VPFooter {
  display: none !important;
}
html.reading-focus .VPContent,
html.reading-focus .VPDoc,
html.reading-focus .VPDoc .container,
html.reading-focus .VPDoc .content,
html.reading-focus .VPDoc .content-container {
  padding-top: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  max-width: 880px !important;
  margin: 0 auto !important;
}
html.reading-focus body {
  padding-top: 24px;
}
/* ===========================================================
   Mobile in-chapter outline — FAB + bottom sheet. Desktop has
   the right-side .VPDocAsideOutline; mobile users had nothing
   between the sidebar (full-screen drawer) and scrolling by hand.
   FAB hidden ≥769px since the sticky outline already does the job.
   =========================================================== */
.mobile-toc-fab {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 25;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  background: linear-gradient(135deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  color: #fff;
  cursor: pointer;
  display: none;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 24px color-mix(in oklab, var(--vp-c-brand-1) 40%, transparent);
  transition: transform 0.18s var(--ease-out);
}
.mobile-toc-fab:hover,
.mobile-toc-fab:focus-visible {
  transform: translateY(-2px);
}
@media (max-width: 768px) {
  .mobile-toc-fab {
    display: flex;
  }
}
/* Bottom-sheet container: backdrop + card slide-up. */
.mobile-toc-sheet {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  pointer-events: none;
}
.mobile-toc-sheet .mts-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.5);
  opacity: 0;
  transition: opacity 0.24s var(--ease-out);
  pointer-events: auto;
}
.mobile-toc-sheet.is-open .mts-backdrop {
  opacity: 1;
}
.mobile-toc-sheet .mts-card {
  position: relative;
  width: 100%;
  max-height: 70vh;
  background: var(--vp-c-bg);
  border-radius: 14px 14px 0 0;
  box-shadow: 0 -16px 40px rgba(15, 23, 42, 0.2);
  transform: translateY(100%);
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: auto;
  display: flex;
  flex-direction: column;
}
.mobile-toc-sheet.is-open .mts-card {
  transform: translateY(0);
}
.mobile-toc-sheet .mts-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--vp-c-divider);
  font-size: 14px;
  font-weight: 700;
  color: var(--vp-c-text-1);
  letter-spacing: -0.01em;
}
.mobile-toc-sheet .mts-close {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: none;
  background: transparent;
  color: var(--vp-c-text-3);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
}
.mobile-toc-sheet .mts-close:hover {
  background: var(--vp-c-bg-soft);
  color: var(--vp-c-text-1);
}
.mobile-toc-sheet .mts-list {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 6px 4px 14px;
}
.mobile-toc-sheet .mts-item {
  display: block;
  padding: 10px 18px;
  border-radius: 8px;
  margin: 1px 8px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--vp-c-text-1);
  text-decoration: none;
  border-left: 2px solid transparent;
  transition: background 0.15s var(--ease-out), border-color 0.15s var(--ease-out);
  cursor: pointer;
}
.mobile-toc-sheet .mts-item:hover,
.mobile-toc-sheet .mts-item:active {
  background: var(--vp-c-bg-soft);
  border-left-color: var(--vp-c-brand-1);
}
.mobile-toc-sheet .mts-h3 {
  font-size: 13px;
  color: var(--vp-c-text-2);
  padding-left: 32px;
}
/* ===========================================================
   KaTeX math polish — align inline math with prose baseline
   and give display math a little breathing room. KaTeX's
   default CSS ships the core styling; we tune the chapter
   integration.
   =========================================================== */
.book-page .vp-doc .katex {
  font-size: 1.02em;
  line-height: 1.4;
}
.book-page .vp-doc .katex-display {
  margin: 20px 0;
  padding: 10px 14px;
  overflow-x: auto;
  overflow-y: hidden;
  background: var(--vp-c-bg-soft);
  border-radius: 8px;
  /* Brand-olive accent rail on the left of every LaTeX display block
     (∬ ∫ ∇ etc.). Previous 35% indigo read as "info callout" by
     mistake; olive keeps the rail decorative rather than semantic. */
  border-left: 3px solid color-mix(in oklab, var(--vp-c-brand-1) 38%, transparent);
}
.book-page .vp-doc .katex-display > .katex {
  font-size: 1.1em;
}
.dark .book-page .vp-doc .katex-display {
  background: rgba(255, 255, 255, 0.03);
  border-left-color: rgba(129, 140, 248, 0.45);
}
/* KaTeX parse error renders as a red inline code — keep it
   readable but clearly flagged. */
.book-page .vp-doc .katex-error {
  background: rgba(239, 68, 68, 0.1);
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 0.9em;
}
/* ===========================================================
   Mobile polish — tighten the new components on narrow screens
   (overrides land last so they win over earlier media blocks).
   =========================================================== */
@media (max-width: 640px) {
  .book-page .vp-doc .chapter-cover-label {
    font-size: 11px;
    letter-spacing: 0.14em;
    gap: 8px;
    margin-bottom: 6px;
  }
  .book-page .vp-doc .chapter-cover-label .ccl-zh {
    font-size: 10.5px;
  }
  .book-page .vp-doc h2 {
    margin-top: 44px;
  }
  .book-page .vp-doc h3 {
    margin-top: 32px;
  }
  .kbd-help-card {
    padding: 16px 18px 18px;
  }
  .kbd-help-grid .kbd-row {
    font-size: 12.5px;
  }
  /* Long-listing collapse fade is full-width by default; on
     narrow screens the inner pill ends up off-center for very
     long file names — recenter explicitly. */
  .book-page .vp-doc .code-expand-toggle .cet-label {
    font-size: 11px;
    padding: 5px 12px;
  }
  /* File-path label can wrap on narrow widths — keep ellipsis. */
  .book-page .vp-doc .code-file-label {
    padding: 7px 12px;
    font-size: 11.5px;
  }
}
/* ===========================================================
   Print stylesheet — Cmd+P from any chapter produces a clean
   PDF: just the chapter content, in light mode, with all
   navigation / floaters / interaction widgets stripped. The
   target use case is offline study + saving chapters as PDF
   for personal annotation, so we treat the chapter as a
   printable document, not a screen UI.
   =========================================================== */
@media print {
  /* Force light treatment regardless of current scheme — printing
     a dark-mode page wastes ink and produces poor contrast. */
  :root,
  .dark {
    --vp-c-bg: #fff !important;
    --vp-c-bg-soft: #fafafa !important;
    --vp-c-bg-alt: #fff !important;
    --vp-c-text-1: #000 !important;
    --vp-c-text-2: #333 !important;
    --vp-c-text-3: #555 !important;
  }
  body {
    background: #fff !important;
    color: #000 !important;
  }
  /* Strip everything that isn't the chapter content. */
  .VPNav,
  .VPLocalNav,
  .VPSidebar,
  .VPDocAside,
  .VPDocFooter,
  .VPFooter,
  .VPNavBar,
  .reading-progress,
  .kbd-help-overlay,
  .img-lightbox-overlay,
  .selection-toolbar,
  .article-header .ah-stats > *:not(:first-child),
  .article-footer,
  .ctn-wrap,
  .vp-doc .header-anchor,
  .vp-doc .para-anchor,
  .vp-doc .code-expand-toggle,
  .vp-doc div[class*='language-'] button.copy {
    display: none !important;
  }
  /* Reset main column to use the full page width (no fixed sidebar
     gutter, no SPA chrome). */
  .VPContent,
  .VPDoc,
  .VPDoc .container,
  .VPDoc .content,
  .VPDoc .content-container {
    margin: 0 !important;
    padding: 0 !important;
    max-width: 100% !important;
  }
  .vp-doc {
    max-width: 100% !important;
  }
  /* Long code blocks that were collapsed on screen must be expanded
     in print — otherwise PDF readers see a 25-line cliff with no
     way to view the rest. */
  .book-page .vp-doc div[class*='language-'].code-collapsible.is-collapsed pre {
    max-height: none !important;
  }
  .book-page .vp-doc div[class*='language-'] {
    box-shadow: none !important;
    border: 1px solid #ddd !important;
    background: #fafafa !important;
    page-break-inside: avoid;
  }
  .book-page .vp-doc div[class*='language-'] pre,
  .book-page .vp-doc div[class*='language-'] code {
    color: #111 !important;
    background: #fafafa !important;
  }
  .book-page .vp-doc .line-numbers-wrapper {
    background: #f0f0f0 !important;
    color: #888 !important;
    border-right: 1px solid #ddd !important;
  }
  /* Show URL after external links so the printed PDF doesn't lose
     the reference. */
  .book-page .vp-doc a[href^="http"]:not([href*="yangyitao.com"])::after {
    content: " (" attr(href) ")" !important;
    font-size: 0.85em;
    color: #666 !important;
    opacity: 1 !important;
  }
  /* Avoid awkward page breaks. */
  .book-page .vp-doc h1,
  .book-page .vp-doc h2,
  .book-page .vp-doc h3,
  .book-page .vp-doc h4 {
    page-break-after: avoid;
  }
  .book-page .vp-doc figure,
  .book-page .vp-doc .mermaid,
  .book-page .vp-doc table {
    page-break-inside: avoid;
  }
  /* Image caption already in flow; lighten gray for ink. */
  .book-page .vp-doc .img-caption,
  .book-page .vp-doc .mermaid-caption {
    color: #555 !important;
  }
  /* Page metadata at the very top — readers want a printable
     "Chapter X of <book>" header in the saved PDF. */
  .book-page .vp-doc h1::before {
    content: '杨艺韬讲堂';
    display: block;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    color: #888;
    text-transform: uppercase;
    margin-bottom: 8px;
  }
}
.book-page .vp-doc h2 {
  position: relative;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.015em;
  margin-top: 56px;
  padding-bottom: 12px;
  border-bottom: none;
  line-height: 1.35;
}
/* Replace the flat divider underline with a brand-tinted gradient.
   Reads more like a chapter section break and less like a generic
   horizontal rule. */
.book-page .vp-doc h2::after {
  content: '';
  position: absolute;
  left: 0;
  right: 25%;
  bottom: 0;
  height: 2px;
  border-radius: 1px;
  /* Pure-brand → divider fade. The old middle stop was a 50%
     indigo literal that broke the gradient's colour continuity
     with the rest of the site — now it's a brand-mixed mid-tone
     so the rule reads as "accent → neutral" on-brand. */
  background: linear-gradient(to right,
    var(--vp-c-brand-1),
    color-mix(in oklab, var(--vp-c-brand-1) 50%, transparent) 35%,
    var(--vp-c-divider) 75%,
    transparent);
}
.book-page .vp-doc h3 {
  position: relative;
  font-size: 19px;
  font-weight: 600;
  margin-top: 40px;
  padding-left: 16px;
  line-height: 1.4;
  letter-spacing: -0.01em;
}
/* Small vertical brand bar so h3 sub-sections have a clearer
   "this is a fresh subsection" signal without competing with h2's
   weight. Sized to match the cap height of the h3 type. */
.book-page .vp-doc h3::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.18em;
  width: 4px;
  height: 0.95em;
  border-radius: 2px;
  /* Olive → deeper-olive vertical accent. Was blue→indigo — the
     single most-frequent colour mistake on the entire reading
     surface since every h3 in every chapter painted this bar. */
  background: linear-gradient(180deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
}
.book-page .vp-doc h4 {
  font-size: 16px;
  font-weight: 600;
  margin-top: 32px;
  color: var(--vp-c-text-2);
  line-height: 1.45;
}
/* Paragraph — optimized for long-form reading */
.book-page .vp-doc p {
  line-height: 1.88;
  margin: 20px 0;
  /* letter-spacing / word-spacing removed: they hurt Chinese
     glyph rhythm (no inter-glyph spaces to widen) and spread
     Latin-in-Chinese runs apart awkwardly. */
}
/* Lists */
.book-page .vp-doc ul,
.book-page .vp-doc ol {
  padding-left: 1.5em;
}
.book-page .vp-doc li {
  line-height: 1.85;
}
.book-page .vp-doc li + li {
  margin-top: 8px;
}
.book-page .vp-doc li::marker {
  color: var(--vp-c-brand-1);
}
/* Ordered list: prominent numbers */
.book-page .vp-doc ol > li::marker {
  font-weight: 700;
  color: var(--vp-c-brand-1);
  font-size: 15px;
}
/* Nested lists spacing */
.book-page .vp-doc li > ul,
.book-page .vp-doc li > ol {
  margin-top: 6px;
}
/* ===== Blockquote — quiet callout, emoji-led ===== */
/* The prose convention is that the author prefixes the quote with
   their own emoji (⚠️ 💡 📺 📝 etc.) to signal kind — so we drop the
   auto-injected "i" icon and the heavy brand-gradient background.
   A slim left bar + soft bg is enough to separate the quote visually
   without competing with the author's semantic marker. */
.book-page .vp-doc blockquote {
  position: relative;
  background: var(--vp-c-bg-soft);
  border-left: 3px solid var(--vp-c-divider);
  border-radius: 0 8px 8px 0;
  padding: 14px 20px;
  margin: 24px 0;
  color: var(--vp-c-text-1);
  font-size: 15.5px;
}
.book-page .vp-doc blockquote p {
  margin: 6px 0;
  line-height: 1.8;
}
.book-page .vp-doc blockquote p:first-child {
  margin-top: 0;
}
.book-page .vp-doc blockquote p:last-child {
  margin-bottom: 0;
}
/* ===== Code Blocks — Premium IDE feel ===== */
/* Shadow intentionally dropped: stacked on top of the page-level
   surface it added visual weight that competed with prose; the
   dark bg + 1px border is enough edge definition against the
   light reader surface. */
.vp-doc div[class*='language-'] {
  border-radius: 10px;
  margin: 24px 0;
  background-color: #1e1e2e !important;
  border: 1px solid rgba(255, 255, 255, 0.06);
}
.vp-doc div[class*='language-'] span.lang {
  color: rgba(255, 255, 255, 0.3);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.dark .vp-doc div[class*='language-'] {
  border-color: rgba(255, 255, 255, 0.04);
}
/* Code block line numbers area */
.vp-doc div[class*='language-'] pre {
  padding: 20px 24px;
}
.vp-doc div[class*='language-'] code {
  font-size: 13.5px;
  line-height: 1.7;
  font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, Monaco, Consolas, monospace;
  font-feature-settings: 'liga' 1, 'calt' 1;
}
/* Inline code */
.book-page .vp-doc :not(pre) > code {
  padding: 2px 7px;
  border-radius: 5px;
  font-size: 0.88em;
  font-weight: 500;
  background: var(--vp-c-brand-soft);
  color: var(--vp-c-brand-1);
  font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace;
  transition: background 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out);
}
/* IDE-style "find similar": when the reader hovers an inline
   code token, every other inline code in the chapter with the
   same text gets a soft amber wash. Lets them visually trace
   where an API name reappears across long prose. */
.book-page .vp-doc :not(pre) > code.token-similar {
  background: rgba(245, 158, 11, 0.18);
  color: #b45309;
  box-shadow: 0 0 0 1px rgba(245, 158, 11, 0.3);
}
.dark .book-page .vp-doc :not(pre) > code.token-similar {
  background: rgba(245, 158, 11, 0.25);
  color: #fbbf24;
}
/* Auto-linked "第 N 章" references — generated client-side by
   enhanceChapterRefs so prose chapter pointers become clickable.
   Visually subtle: underline only, not a full blue link, since
   they appear frequently in dense prose. Amber hover for "jump
   to chapter" affordance. */
.book-page .vp-doc .chapter-ref-auto {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: color-mix(in oklab, var(--vp-c-brand-1) 42%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-style: dotted;
  cursor: pointer;
  transition: color 0.15s var(--ease-out), text-decoration-color 0.15s var(--ease-out);
}
.book-page .vp-doc .chapter-ref-auto:hover {
  color: #d97706;
  text-decoration-color: #f59e0b;
  text-decoration-style: solid;
}
/* Double-click any inline code → text copied → emerald flash
   for ~700ms so the reader sees the click registered. */
.book-page .vp-doc :not(pre) > code.code-dblclick-copied {
  background: rgba(16, 185, 129, 0.25) !important;
  color: #059669 !important;
  box-shadow: 0 0 0 1px rgba(16, 185, 129, 0.4);
  animation: code-dblclick-flash 0.7s cubic-bezier(0.2, 0, 0, 1) forwards;
}
@keyframes code-dblclick-flash {
  0% {
    background: rgba(16, 185, 129, 0.35);
    color: #059669;
  }
  100% {
    background: rgba(16, 185, 129, 0.25);
  }
}
.dark .book-page .vp-doc :not(pre) > code.code-dblclick-copied {
  background: rgba(16, 185, 129, 0.3) !important;
  color: #34d399 !important;
}
/* ===== Tables — Clean & Modern ===== */
.book-page .vp-doc table {
  border-collapse: separate;
  border-spacing: 0;
  border-radius: 10px;
  border: 1px solid var(--vp-c-divider);
  margin: 0;
  width: max-content;
  min-width: 100%;
  font-size: 14px;
}
/* JS-injected wrapper div around each <table> — this div scrolls
   horizontally on narrow screens while the table keeps its natural
   width. Injected by useReadingEnhancers::enhanceTables(). */
.book-page .vp-doc .table-scroll-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 24px 0;
  border-radius: 10px;
}
.book-page .vp-doc .table-scroll-wrap::-webkit-scrollbar {
  height: 4px;
}
.book-page .vp-doc .table-scroll-wrap::-webkit-scrollbar-thumb {
  background: var(--vp-c-divider);
  border-radius: 4px;
}
.book-page .vp-doc th {
  background: var(--vp-c-brand-soft);
  font-weight: 600;
  font-size: 13px;
  padding: 12px 18px;
  text-align: left;
  letter-spacing: 0.02em;
}
.book-page .vp-doc td {
  padding: 11px 18px;
  font-size: 14px;
  border-top: 1px solid var(--vp-c-divider);
  line-height: 1.6;
}
/* Zebra striping — alternate rows get a faint olive tint so the
   eye can track across wide comparison tables without losing its
   place. (Prior value was indigo/violet residue from the pre-
   brand palette — off-key against olive surrounding.) Counts
   from tbody so the thead row never picks up the stripe. */
.book-page .vp-doc tbody tr:nth-child(even) td {
  background: color-mix(in oklab, var(--vp-c-brand-1) 3%, transparent);
}
.dark .book-page .vp-doc tbody tr:nth-child(even) td {
  background: rgba(255, 255, 255, 0.025);
}
/* First-column emphasis — table-leading cells often carry the
   row's "key" (option name, API method, etc.); bumping weight
   makes wide tables far easier to scan top-to-bottom. */
.book-page .vp-doc td:first-child {
  font-weight: 600;
  color: var(--vp-c-text-1);
}
.book-page .vp-doc tr:hover td {
  /* Warm the hover row with a brand-tinted wash instead of the
     cold neutral bg-soft; the subtle olive lift signals "live"
     without pulling attention off the content. */
  background: color-mix(in oklab, var(--vp-c-brand-1) 6%, transparent);
  transition: background 0.18s var(--ease-out);
}
/* ===== Images — Polished =====
   Chapter figures get tier-2 elevation at rest and a smooth
   lift to tier-3 on hover, so they feel like mounted prints
   rather than inline raster paste-ins. Tokens handle dark mode
   automatically via the .dark override block at the top. */
.book-page .vp-doc img {
  border-radius: 10px;
  box-shadow: var(--shadow-2);
  margin: 24px 0;
  transition: box-shadow 0.28s cubic-bezier(0.2, 0, 0, 1);
}
.book-page .vp-doc img:hover {
  box-shadow: var(--shadow-3);
}
/* ===== Horizontal Rule — Elegant ===== */
.book-page .vp-doc hr {
  margin: 48px 0;
  border: none;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--vp-c-divider) 20%,
    var(--vp-c-divider) 80%,
    transparent 100%
  );
}
/* ===== Links — Editorial underline =====
   Replace the legacy blue border-bottom (stale hue from the pre-brand
   -refactor palette) with a real text-decoration underline so it:
   (a) skips descenders via text-decoration-skip-ink
   (b) sits 3px below the baseline instead of welding to it
   (c) is 1.5px precise regardless of font-weight
   Colour fades from 35%→80% alpha on hover — subtle signal, strong
   affordance. */
.book-page .vp-doc a {
  color: var(--vp-c-brand-1);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: color-mix(in oklab, var(--vp-c-brand-1) 35%, transparent);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  text-decoration-skip-ink: auto;
  transition: text-decoration-color 0.18s var(--ease-out), color 0.18s var(--ease-out);
  border-bottom: none;
}
.book-page .vp-doc a:hover {
  text-decoration-color: color-mix(in oklab, var(--vp-c-brand-1) 80%, transparent);
}
/* ===== Strong / Em — Subtle emphasis ===== */
.book-page .vp-doc strong {
  font-weight: 700;
  color: var(--vp-c-text-1);
}
.book-page .vp-doc em {
  font-style: italic;
  color: var(--vp-c-text-2);
}
/* ===== Homepage Layout Override ===== */
.Layout.is-home .VPContent {
  padding: 0 !important;
}
.Layout.is-home .VPContent .VPHome {
  max-width: 100% !important;
  padding: 0 !important;
}
/* Home page uses its own sticky .ly-nav — hide VitePress's default
   .VPNav entirely so there's no thin dark strip above the custom
   nav on mobile. Reset body margin just in case browser UA adds
   the default 8px. */
.Layout.is-home .VPNav {
  display: none !important;
}
.Layout.is-home .VPLocalNav {
  display: none !important;
}
body {
  margin: 0;
}
/* Global horizontal overflow guard — on mobile the hero book-stack
   translates children ±200px past their container, and the ambient
   grid background can render a hair past the edge on some Android
   browsers. Use `clip` not `hidden`: `hidden` on html/body creates
   a containing block for `position: sticky` descendants (like
   .ly-nav on the landing page), which breaks scroll-follow. `clip`
   has the same visual effect without the containing-block side
   effect. Supported in all browsers we care about. */
html, body {
  overflow-x: clip;
  max-width: 100vw;
}
/* ===== Mermaid diagrams: center, breathe, soft surface ===== */
.book-page .vp-doc .mermaid {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px 16px 16px;
  margin: 28px 0;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-radius: 10px;
}
.dark.book-page .vp-doc .mermaid {
  background: rgba(30, 35, 50, 0.35);
  border-color: rgba(148, 163, 184, 0.1);
}
/* Dark-mode mermaid retint.
   vitepress-plugin-mermaid applies the theme once at init, so we
   can't swap themeVariables per color scheme. Instead, override
   the SVG inline fills/strokes in dark mode via CSS. The brand
   border green stays (same identity in both modes); surfaces
   flip from warm off-white to a dark ink-tinted panel, and text
   flips to light.  Uses !important because mermaid sets these
   as inline style attrs. */
.dark.book-page .vp-doc .mermaid svg .node rect,
.dark.book-page .vp-doc .mermaid svg .node circle,
.dark.book-page .vp-doc .mermaid svg .node ellipse,
.dark.book-page .vp-doc .mermaid svg .node polygon,
.dark.book-page .vp-doc .mermaid svg .node path {
  fill: rgba(30, 35, 50, 0.7) !important;
  stroke: #6b9e2c !important;
}
.dark.book-page .vp-doc .mermaid svg .cluster rect {
  fill: rgba(20, 24, 35, 0.5) !important;
  stroke: rgba(148, 163, 184, 0.25) !important;
}
.dark.book-page .vp-doc .mermaid svg .label,
.dark.book-page .vp-doc .mermaid svg .nodeLabel,
.dark.book-page .vp-doc .mermaid svg .nodeLabel *,
.dark.book-page .vp-doc .mermaid svg text {
  color: #e2e8f0 !important;
  fill: #e2e8f0 !important;
}
.dark.book-page .vp-doc .mermaid svg .edgeLabel {
  background: rgba(30, 35, 50, 0.85) !important;
}
.dark.book-page .vp-doc .mermaid svg .edgeLabel .labelBkg,
.dark.book-page .vp-doc .mermaid svg .edgeLabel rect {
  fill: rgba(30, 35, 50, 0.85) !important;
}
/* Edges / lines / arrows */
.dark.book-page .vp-doc .mermaid svg .flowchart-link,
.dark.book-page .vp-doc .mermaid svg .messageLine0,
.dark.book-page .vp-doc .mermaid svg .messageLine1,
.dark.book-page .vp-doc .mermaid svg path.transition,
.dark.book-page .vp-doc .mermaid svg path.relation {
  stroke: #94a3b8 !important;
}
.dark.book-page .vp-doc .mermaid svg .arrowheadPath,
.dark.book-page .vp-doc .mermaid svg .marker {
  fill: #94a3b8 !important;
  stroke: #94a3b8 !important;
}
/* Sequence diagrams: actors, activations, notes */
.dark.book-page .vp-doc .mermaid svg .actor,
.dark.book-page .vp-doc .mermaid svg .activation0,
.dark.book-page .vp-doc .mermaid svg .activation1,
.dark.book-page .vp-doc .mermaid svg .activation2 {
  fill: rgba(30, 35, 50, 0.7) !important;
  stroke: #6b9e2c !important;
}
.dark.book-page .vp-doc .mermaid svg .note {
  fill: rgba(244, 132, 95, 0.12) !important;
  stroke: #F4845F !important;
}
/* State diagrams: alt background + composite states */
.dark.book-page .vp-doc .mermaid svg .statediagram-state rect,
.dark.book-page .vp-doc .mermaid svg .statediagram-cluster rect {
  fill: rgba(30, 35, 50, 0.7) !important;
  stroke: #6b9e2c !important;
}
.dark.book-page .vp-doc .mermaid svg .statediagram-cluster .inner,
.dark.book-page .vp-doc .mermaid svg .statediagram-cluster .background {
  fill: rgba(20, 24, 35, 0.4) !important;
}
.mermaid,
[id^="mermaid"] {
  cursor: zoom-in;
  transition: opacity 0.2s;
}
.mermaid:hover {
  opacity: 0.92;
}
.mermaid svg,
.mermaid svg * {
  pointer-events: auto !important;
}
.mermaid-zoom-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: rgba(0, 0, 0, 0.85);
  backdrop-filter: blur(12px);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  animation: mermaid-fade-in 0.22s cubic-bezier(0.2, 0, 0, 1);
}
.mermaid-zoom-container {
  overflow: visible;
  background: #fff;
  border-radius: 16px;
  padding: 36px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
  cursor: grab;
  transform-origin: center center;
  transition: transform 0.15s var(--ease-out);
}
.mermaid-zoom-container:active {
  cursor: grabbing;
}
.dark .mermaid-zoom-container {
  background: #1e1e2e;
}
.mermaid-zoom-container svg {
  display: block;
  min-width: 60vw;
  height: auto;
}
.mermaid-zoom-container,
.mermaid-zoom-container * {
  cursor: grab !important;
}
.mermaid-zoom-container:active,
.mermaid-zoom-container:active * {
  cursor: grabbing !important;
}
.mermaid-zoom-controls {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 6px;
  z-index: 10000;
  background: rgba(30, 30, 46, 0.92);
  padding: 6px 10px;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.1);
}
.mz-btn {
  width: 36px;
  height: 36px;
  border: none;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.12);
  color: #e2e8f0;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.15s cubic-bezier(0.2, 0, 0, 1),
    color      0.15s cubic-bezier(0.2, 0, 0, 1);
}
.mz-btn:hover {
  background: rgba(255, 255, 255, 0.25);
  color: #fff;
}
.mz-close {
  background: rgba(239, 68, 68, 0.3);
}
.mz-close:hover {
  background: rgba(239, 68, 68, 0.6);
}
@keyframes mermaid-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
/* ================================================================
   WORLD-CLASS READING EXPERIENCE — Scholarly Serenity
   ================================================================ */
/* Newsreader font is imported at the top of this file */
.book-page .vp-doc {
  font-family: 'Newsreader', 'Noto Serif SC', 'Source Han Serif SC', 'STSong', Georgia, serif;
  font-size: 17.5px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* — Heading decorations — subtle brand flourishes — */
.book-page .vp-doc h1 {
  font-family: 'Newsreader', 'Noto Serif SC', Georgia, serif;
  position: relative;
}
/* h1: clean bottom border, no decorative bar */
.book-page .vp-doc h1::after {
  display: none;
}
.book-page .vp-doc h2 {
  font-family: 'Newsreader', 'Noto Serif SC', Georgia, serif;
  position: relative;
  padding-left: 14px;
  border-bottom: none;
  border-left: 2px solid var(--vp-c-brand-1);
}
.book-page .vp-doc h3 {
  font-family: 'Newsreader', 'Noto Serif SC', Georgia, serif;
  color: var(--vp-c-text-1);
}
/* — Drop cap removed: not ideal for Chinese tech docs — */
/* — Smooth scroll anchor highlight — */
.book-page .vp-doc h1:target,
.book-page .vp-doc h2:target,
.book-page .vp-doc h3:target,
.book-page .vp-doc h4:target {
  /* Jump-to-anchor highlight — a 2s fade from brand-soft to
     transparent. ease-out feels right here: the highlight
     "arrives" immediately (reader just clicked the link) and
     settles slowly, which is what draws the eye to the correct
     heading without the flashy bounce a spring would imply. */
  animation: anchor-highlight 2s cubic-bezier(0.2, 0, 0, 1);
}
@keyframes anchor-highlight {
  0% { background: var(--vp-c-brand-soft); border-radius: 4px; }
  100% { background: transparent; }
}
/* (blockquote auto-injected "i" icon removed — author's own emoji
    in the first line carries the semantic; the base blockquote
    padding above is now sufficient) */
/* — Content area: breathing room — */
@media (min-width: 960px) {
  .book-page .VPDoc .content-container {
    padding-left: 16px;
  }
}
/* — Image: zoom hint + refined shadow — */
.book-page .vp-doc img {
  cursor: zoom-in;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s ease;
}
.book-page .vp-doc img:hover {
  transform: scale(1.01);
}
/* — Code block refinement: glass morphism border — */
.book-page .vp-doc div[class*='language-'] {
  position: relative;
}
.book-page .vp-doc div[class*='language-']::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 12px;
  padding: 1px;
  background: linear-gradient(135deg, rgba(255,255,255,0.08), rgba(255,255,255,0.02));
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}
/* — Code block horizontal scrollbar — */
.vp-doc div[class*='language-'] pre::-webkit-scrollbar {
  height: 4px;
}
.vp-doc div[class*='language-'] pre::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.12);
  border-radius: 4px;
}
.vp-doc div[class*='language-'] pre::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.25);
}
.vp-doc div[class*='language-'] pre::-webkit-scrollbar-track {
  background: transparent;
}
/* — Copy button: tiny, invisible until hover — */
.vp-doc div[class*='language-'] button.copy {
  width: 28px !important;
  height: 28px !important;
  border-radius: 6px !important;
  background: transparent !important;
  border: none !important;
  transition:
    opacity    0.18s cubic-bezier(0.2, 0, 0, 1),
    background 0.18s cubic-bezier(0.2, 0, 0, 1) !important;
  opacity: 0 !important;
  top: 10px !important;
  right: 10px !important;
}
.vp-doc div[class*='language-']:hover button.copy {
  /* 0.4 was too ghostly — you had to guess the button was there.
     0.55 lets the glyph read at a glance without competing with
     the code. */
  opacity: 0.55 !important;
}
.vp-doc div[class*='language-'] button.copy:hover {
  opacity: 1 !important;
  /* Theme-aware hover wash: the old rgba(255,255,255,0.1) was
     invisible on light surfaces. 12% ink gives a soft button
     shape in both modes. */
  background: rgba(15, 23, 42, 0.08) !important;
}
.dark .vp-doc div[class*='language-'] button.copy:hover {
  background: rgba(255, 255, 255, 0.1) !important;
}
.vp-doc div[class*='language-'] button.copy.copied {
  opacity: 1 !important;
  /* Brand-tinted success flash on the button itself (not the pill) —
     derives from --vp-c-brand-1 so light gets olive, dark gets
     lemon via the same token. 18% alpha is enough to register as
     "something happened" without flooding the corner of the block. */
  background: color-mix(in oklab, var(--vp-c-brand-1) 18%, transparent) !important;
}
/* Subtle "已复制" pill that pops above the button so the reader
   gets clear acknowledgement instead of just a state change.
   Brand olive on light, lemon on dark. Easing is the same fast-
   out-slow-in curve we use for the header-anchor copied pill, so
   both acknowledgement moments feel like they come from the same
   motion system. */
.vp-doc div[class*='language-'] button.copy.copied::after {
  content: '已复制';
  position: absolute;
  right: 0;
  top: -28px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--vp-c-brand-1);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  box-shadow: 0 4px 14px color-mix(in oklab, var(--vp-c-brand-1) 36%, transparent);
  pointer-events: none;
  animation: copy-pill-pop 1.6s cubic-bezier(0.2, 0, 0, 1) forwards;
}
.dark .vp-doc div[class*='language-'] button.copy.copied::after {
  background: #c4f857;
  color: #0a0b0f;
  box-shadow: 0 4px 14px rgba(196, 248, 87, 0.28);
}
@keyframes copy-pill-pop {
  0%   { opacity: 0; transform: translateY(4px); }
  15%  { opacity: 1; transform: translateY(0); }
  80%  { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-4px); }
}
/* — Prev/Next page navigation enhancement — */
.book-page .pager-link {
  border-radius: 12px !important;
  border: 1px solid var(--vp-c-divider) !important;
  padding: 16px 20px !important;
  transition:
    border-color 0.22s cubic-bezier(0.2, 0, 0, 1),
    transform    0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1) !important;
}
.book-page .pager-link:hover {
  border-color: var(--vp-c-brand-1) !important;
  box-shadow: 0 4px 16px color-mix(in oklab, var(--vp-c-brand-1) 12%, transparent) !important;
  transform: translateY(-2px);
}
.book-page .pager-link .title {
  font-family: 'Newsreader', 'Noto Serif SC', serif !important;
  font-weight: 600 !important;
}
/* — Paragraph spacing rhythm — every other p gets extra top — */
.book-page .vp-doc p + p {
  margin-top: 22px;
}
/* — Section breaks: elegant double-line for hr — */
.book-page .vp-doc hr {
  position: relative;
  margin: 56px 0;
  background: none;
  height: auto;
}
.book-page .vp-doc hr::before {
  content: '• • •';
  display: block;
  text-align: center;
  font-size: 14px;
  color: var(--vp-c-text-3);
  letter-spacing: 0.5em;
}
/* — Strong text: just bold, no decoration — */
.book-page .vp-doc strong {
  font-weight: 700;
  color: var(--vp-c-text-1);
}
/* — Smooth page transitions — */
.book-page .VPDoc {
  animation: page-enter 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes page-enter {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
/* — List items: refined markers — */
.book-page .vp-doc ul > li {
  position: relative;
}
.book-page .vp-doc ol > li::marker {
  font-family: 'Newsreader', Georgia, serif;
  font-weight: 600;
  color: var(--vp-c-brand-1);
}
/* — Right-side outline — mockup V3 "在本章" refinement —
   Matches .v3-toc in the design spec: h4-style title ("在本章"),
   no card background, ample vertical rhythm between links, clean
   left-stripe for active, gentle indent for nested items. Flat +
   quiet, so the stats / notes cards can be the accented layer. */
.book-page .VPDocAsideOutline {
  padding: 4px 0 !important;
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  margin-top: 16px;
}
.book-page .VPDocAsideOutline .content {
  position: relative;
}
.book-page .VPDocAsideOutline .outline-title {
  font-size: 0 !important;
  font-weight: 700 !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  color: transparent !important;
  position: relative;
  margin: 0 0 10px 0 !important;
  padding: 0 0 10px 0 !important;
  border-bottom: 1px solid var(--vp-c-divider);
}
.book-page .VPDocAsideOutline .outline-title::before {
  content: '在本章';
  display: block;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--vp-c-text-1);
  line-height: 1;
}
.book-page .VPDocAsideOutline .outline-link {
  /* The scroll-spy handover between "inactive" and "active"
     benefits from an explicit curve — scroll fires small,
     frequent class flips, and cubic-bezier(0.2, 0, 0, 1) lands
     each transition softly instead of the abrupt step-feel of
     the browser default `ease`. */
  transition:
    color        0.18s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    font-weight  0.18s cubic-bezier(0.2, 0, 0, 1) !important;
  font-size: 13px !important;
  line-height: 1.5 !important;
  color: var(--vp-c-text-2) !important;
  position: relative;
  padding: 6px 0 6px 12px !important;
  border-left: 2px solid transparent !important;
  border-radius: 0 !important;
  margin: 0 !important;
  background: transparent !important;
  display: block;
}
.book-page .VPDocAsideOutline .outline-link:hover {
  color: var(--vp-c-text-1) !important;
  background: transparent !important;
  border-left-color: var(--vp-c-divider) !important;
}
/* Active section — mockup V3 .cur: bold black text + solid left bar */
.book-page .VPDocAsideOutline .outline-link.active {
  color: var(--vp-c-text-1) !important;
  font-weight: 700 !important;
  background: transparent !important;
  border-left: 2px solid var(--vp-c-text-1) !important;
}
html.dark.book-page .VPDocAsideOutline .outline-link.active {
  color: #ecedf0 !important;
  border-left-color: var(--jt-accent) !important;
}
.book-page .VPDocAsideOutline .outline-marker {
  display: none !important;
}
/* Nested H3 — mockup V3 .sub: 16px extra indent, 12px font, lighter */
.book-page .VPDocAsideOutline .outline-link.nested {
  padding-left: 28px !important;
  font-size: 12px !important;
  color: var(--vp-c-text-3) !important;
  padding-top: 5px !important;
  padding-bottom: 5px !important;
}
.book-page .VPDocAsideOutline .outline-link.nested:hover {
  color: var(--vp-c-text-2) !important;
}
.book-page .VPDocAsideOutline .outline-link.nested.active {
  font-weight: 600 !important;
  color: var(--vp-c-text-1) !important;
}
/* — Refined table hover — */
.book-page .vp-doc tr:hover td {
  background: linear-gradient(90deg, var(--vp-c-brand-soft), transparent) !important;
}
/* — Content area max width tuning for serifs — */
@media (min-width: 960px) {
  .book-page .VPDoc:not(.has-aside) .content-container {
    max-width: 760px !important;
  }
}
/* — Inline code in serif context — */
.book-page .vp-doc :not(pre) > code {
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  font-size: 0.85em;
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: 400;
  background: var(--vp-c-brand-soft);
  color: var(--vp-c-brand-2);
}
.dark .book-page .vp-doc :not(pre) > code {
  color: var(--vp-c-brand-1);
}
/* — Selection color —
   Scoped-override of the global ::selection for .vp-doc. Was
   blue 15% / dark 20% — the rest of the site's ::selection
   (line 174) is olive/lemon; harmonise here so book-page selection
   feels like the global one, not a sandbox. */
.book-page .vp-doc ::selection {
  background: color-mix(in oklab, var(--vp-c-brand-1) 22%, transparent);
  color: inherit;
}
.dark .book-page .vp-doc ::selection {
  background: rgba(196, 248, 87, 0.28);
}
/* — Footnote-style small text — */
.book-page .vp-doc small {
  font-size: 13px;
  color: var(--vp-c-text-3);
  font-style: italic;
}
/* — Smooth heading anchors — */
.book-page .vp-doc .header-anchor {
  opacity: 0;
  transition: opacity 0.2s, color 0.2s !important;
}
.book-page .vp-doc h1:hover .header-anchor,
.book-page .vp-doc h2:hover .header-anchor,
.book-page .vp-doc h3:hover .header-anchor,
.book-page .vp-doc h4:hover .header-anchor {
  opacity: 1;
}
/* — Reading progress shimmer —
   Brand-only shimmer gradient. Previous value had purple #8b5cf6
   and pink #ec4899 middle stops — colours the site uses nowhere
   else, so the shimmer read as "generic rainbow progress bar"
   instead of a branded motion accent. Now olive → deeper-olive
   → olive loop so the animation feels like a ripple within
   the brand rather than a drive-by across random hues. */
.reading-progress {
  background: linear-gradient(90deg,
    var(--vp-c-brand-1),
    var(--vp-c-brand-2),
    var(--vp-c-brand-1)) !important;
  background-size: 200% 100% !important;
  /* linear for a seamless shimmer loop — `ease` on an infinite
     animation stutters at each iteration boundary because the
     curve's start/end velocities don't match. */
  animation: progress-shimmer 3s linear infinite !important;
  height: 2px !important;
  box-shadow: 0 0 12px color-mix(in oklab, var(--vp-c-brand-1) 32%, transparent) !important;
}
@keyframes progress-shimmer {
  0% { background-position: 0% 0%; }
  50% { background-position: 100% 0%; }
  100% { background-position: 0% 0%; }
}
/* ===== Code block language badge ===== */
.book-page .vp-doc div[class*="language-"] {
  position: relative;
}
.book-page .vp-doc .code-lang-badge {
  position: absolute;
  top: 8px;
  right: 50px;
  font-size: 11px;
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  font-weight: 500;
  color: rgba(148, 163, 184, 0.6);
  text-transform: lowercase;
  letter-spacing: 0.04em;
  pointer-events: none;
  user-select: none;
  z-index: 1;
  opacity: 0;
  transition: opacity 0.2s var(--ease-out);
}
.book-page .vp-doc div[class*="language-"]:hover .code-lang-badge {
  opacity: 1;
}
/* ===== Image lightbox ===== */
.book-page .vp-doc .zoomable-img {
  cursor: zoom-in;
  border-radius: 6px;
  transition: opacity 0.2s var(--ease-out);
}
.book-page .vp-doc .zoomable-img:hover {
  opacity: 0.92;
}
.img-lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  animation: img-lightbox-in 0.2s cubic-bezier(0.2, 0, 0, 1);
  cursor: zoom-out;
}
@keyframes img-lightbox-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
/* Stage wraps the zoomed image + caption so they layout as one
   centered column. Image still gets its own max constraints; the
   caption tracks below it without breaking the centering. */
.img-lightbox-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  max-width: 92vw;
  max-height: 92vh;
}
.img-lightbox-img {
  max-width: 92vw;
  max-height: 78vh;
  border-radius: 4px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.4);
  cursor: default;
}
.img-lightbox-caption {
  max-width: 80ch;
  font-size: 14px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.82);
  text-align: center;
  font-style: italic;
  letter-spacing: 0.01em;
  padding: 0 16px;
}
.img-lightbox-close {
  position: fixed;
  top: 20px;
  right: 24px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 24px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  transition: background 0.18s var(--ease-out);
}
.img-lightbox-close:hover {
  background: rgba(255, 255, 255, 0.22);
}
.img-lightbox-nav {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.18s var(--ease-out), transform 0.18s var(--ease-out);
  z-index: 10;
}
.img-lightbox-nav[hidden] { display: none; }
.img-lightbox-nav.prev { left: 24px; }
.img-lightbox-nav.next { right: 24px; }
.img-lightbox-nav:hover {
  background: rgba(255, 255, 255, 0.22);
  transform: translateY(-50%) scale(1.06);
}
.img-lightbox-counter {
  position: fixed;
  top: 24px;
  left: 28px;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  z-index: 10;
}
@media (max-width: 640px) {
  .img-lightbox-nav {
    width: 40px;
    height: 40px;
  }
  .img-lightbox-nav.prev { left: 10px; }
  .img-lightbox-nav.next { right: 10px; }
  .img-lightbox-counter {
    top: 18px;
    left: 16px;
    font-size: 11px;
    padding: 5px 10px;
  }
}
/* ===== Selection toolbar ===== */
.selection-toolbar {
  display: flex;
  gap: 2px;
  padding: 4px;
  background: rgba(15, 23, 42, 0.95);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-radius: 8px;
  /* Dark toolbar on a light page — keep the pure-black shadow
     (not --shadow-4 which is slate-tinted on light). Add a
     6%-alpha inner highlight so the dark disc has a crisp edge
     against the light surface behind it. */
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.18),
    0 2px 8px rgba(0, 0, 0, 0.12),
    0 0 0 1px rgba(255, 255, 255, 0.06) inset;
  z-index: 9000;
  animation: selection-toolbar-in 0.15s var(--ease-out);
}
@keyframes selection-toolbar-in {
  from { opacity: 0; transform: translateX(-50%) translateY(4px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}
.selection-toolbar button {
  background: transparent;
  border: none;
  color: #fff;
  font-size: 12px;
  padding: 6px 12px;
  border-radius: 5px;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s var(--ease-out);
}
.selection-toolbar button:hover {
  background: rgba(255, 255, 255, 0.12);
}
.selection-toolbar button:active {
  /* Snap press — picked text already waits for a click, so the
     press confirmation should feel immediate not cushioned. */
  background: rgba(255, 255, 255, 0.22);
  transition-duration: 0.06s;
}
.selection-toolbar::after {
  content: '';
  position: absolute;
  bottom: -5px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid rgba(15, 23, 42, 0.95);
}
/* Mobile: bottom fixed action bar instead of floating */
@media (max-width: 768px) {
  .selection-toolbar {
    display: none; /* mobile uses native context menu */
  }
  .img-lightbox-close {
    top: 12px;
    right: 12px;
    width: 38px;
    height: 38px;
  }
}
/* ===== User-adjustable reading settings ===== */
:root {
  --reading-font-size: 16px;
  --reading-line-height: 1.85;
}
.book-page .vp-doc {
  font-size: var(--reading-font-size);
  line-height: var(--reading-line-height);
}
.book-page .vp-doc p,
.book-page .vp-doc li {
  font-size: var(--reading-font-size);
  line-height: var(--reading-line-height);
}
/* Sans (黑体) reading font option — overrides serif default */
html[data-reading-font="sans"].book-page .vp-doc,
html[data-reading-font="sans"].book-page .vp-doc p,
html[data-reading-font="sans"].book-page .vp-doc li,
html[data-reading-font="sans"].book-page .vp-doc h1,
html[data-reading-font="sans"].book-page .vp-doc h2,
html[data-reading-font="sans"].book-page .vp-doc h3,
html[data-reading-font="sans"].book-page .vp-doc h4 {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', sans-serif !important;
}
/* Width adjustments */
@media (min-width: 1280px) {
  html[data-reading-width="narrow"].book-page .VPDoc .container {
    max-width: 920px !important;
  }
  html[data-reading-width="narrow"].book-page .vp-doc .content-container {
    max-width: 680px !important;
  }
  html[data-reading-width="wide"].book-page .VPDoc .container {
    max-width: 1320px !important;
  }
  html[data-reading-width="wide"].book-page .vp-doc .content-container {
    max-width: 880px !important;
  }
}
/* ===== Broken image / mermaid fallback ===== */
.book-page .vp-doc .broken-img-placeholder {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 20px;
  margin: 24px 0;
  border: 1px dashed rgba(15, 23, 42, 0.15);
  border-radius: 12px;
  background: rgba(15, 23, 42, 0.02);
  color: var(--vp-c-text-3);
  font-family: var(--vp-font-family-base);
  font-size: 14px;
}
.book-page .vp-doc .broken-img-placeholder svg {
  flex-shrink: 0;
  opacity: 0.5;
}
.book-page .vp-doc .broken-img-info {
  flex: 1;
  min-width: 0;
}
.book-page .vp-doc .broken-img-alt {
  font-weight: 600;
  color: var(--vp-c-text-2);
  margin-bottom: 2px;
}
.book-page .vp-doc .broken-img-src {
  font-size: 12px;
  color: var(--vp-c-brand-1);
  text-decoration: none;
}
.book-page .vp-doc .broken-img-src:hover {
  text-decoration: underline;
}
.dark .book-page .vp-doc .broken-img-placeholder {
  border-color: rgba(148, 163, 184, 0.18);
  background: rgba(148, 163, 184, 0.04);
}
.book-page .vp-doc .mermaid-fallback {
  margin: 24px 0;
  border: 1px solid rgba(245, 158, 11, 0.25);
  background: rgba(254, 252, 232, 0.6);
  border-radius: 12px;
  overflow: hidden;
  font-family: var(--vp-font-family-base);
  font-size: 14px;
}
.dark .book-page .vp-doc .mermaid-fallback {
  border-color: rgba(245, 158, 11, 0.3);
  background: rgba(120, 53, 15, 0.18);
}
.book-page .vp-doc .mermaid-fallback-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  color: #b45309;
  font-weight: 500;
}
.dark .book-page .vp-doc .mermaid-fallback-header {
  color: #fbbf24;
}
.book-page .vp-doc .mermaid-fallback-toggle {
  margin-left: auto;
  padding: 4px 12px;
  border: 1px solid rgba(245, 158, 11, 0.4);
  border-radius: 6px;
  background: transparent;
  color: inherit;
  font-size: 12px;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s cubic-bezier(0.2, 0, 0, 1);
}
.book-page .vp-doc .mermaid-fallback-toggle:hover {
  background: rgba(245, 158, 11, 0.12);
}
.book-page .vp-doc .mermaid-fallback-src {
  margin: 0;
  padding: 14px 18px;
  border-top: 1px solid rgba(245, 158, 11, 0.2);
  background: rgba(255, 255, 255, 0.6);
  color: var(--vp-c-text-2);
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  font-size: 12px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 320px;
  overflow: auto;
}
.dark .book-page .vp-doc .mermaid-fallback-src {
  background: rgba(0, 0, 0, 0.25);
  border-top-color: rgba(245, 158, 11, 0.18);
}
/* ===== Nav book dropdown badges ===== */
.nav-book-badge {
  font-size: 10px;
  font-weight: 500;
  margin-left: 6px;
  opacity: 0.45;
  letter-spacing: 0.02em;
}
.nav-book-badge-free {
  color: var(--vp-c-text-2);
}
.nav-book-badge-paid {
  color: var(--vp-c-text-3);
}
/* ===== Login gate — CSS-only content hiding ===== */
/* Full content is in the DOM. For non-logged-in users,
   PaywallOverlay adds .paywalled to <html>. We clip the preview
   height and use mask-image to fade the last ~360px of content
   to transparent. Using a mask (not an overlay gradient) makes
   the text itself dissolve instead of being covered by a hazy
   white rectangle — the eye sees a continuous transition from
   prose → nothing → login card. */
html.paywalled .vp-doc .content-container,
html.paywalled .vp-doc > div[v-pre],
html.paywalled .vp-doc > div:first-child {
  max-height: 900px;
  overflow: hidden;
  position: relative;
  /* Multi-stop mask for an ease-out fade — linear masks finish
     too suddenly, the multi-stop curve keeps the middle of the
     fade already translucent so the eye has time to "release"
     the content instead of losing it all in the last 50px. */
  -webkit-mask-image: linear-gradient(
    to bottom,
    #000 0%,
    #000 calc(100% - 360px),
    rgba(0, 0, 0, 0.85) calc(100% - 280px),
    rgba(0, 0, 0, 0.55) calc(100% - 180px),
    rgba(0, 0, 0, 0.22) calc(100% - 80px),
    transparent 100%
  );
          mask-image: linear-gradient(
    to bottom,
    #000 0%,
    #000 calc(100% - 360px),
    rgba(0, 0, 0, 0.85) calc(100% - 280px),
    rgba(0, 0, 0, 0.55) calc(100% - 180px),
    rgba(0, 0, 0, 0.22) calc(100% - 80px),
    transparent 100%
  );
}
/* Hide the article footer's prev/next + related grid for gated chapters */
html.paywalled .article-footer .af-nav,
html.paywalled .article-footer .af-related {
  display: none;
}
/* Hide the comments section for non-logged-in visitors */
html.paywalled .custom-comment {
  display: none;
}
/* ===== Dynamically loaded chapter content ===== */
/* The chapter-full-content div is injected by useChapterContent for
   subscribers who visit a paid chapter. It contains rendered markdown
   that replaces the truncated build-time preview. */
.book-page .vp-doc .chapter-full-content {
  /* Inherit all the same typography / spacing as the rest of .vp-doc */
}
.book-page .vp-doc .chapter-full-content h1,
.book-page .vp-doc .chapter-full-content h2,
.book-page .vp-doc .chapter-full-content h3,
.book-page .vp-doc .chapter-full-content h4 {
  margin-top: 32px;
}
.book-page .vp-doc .chapter-full-content pre {
  padding: 16px;
  border-radius: 8px;
  overflow-x: auto;
  background: var(--vp-code-block-bg);
  font-size: 14px;
  line-height: 1.7;
}
.book-page .vp-doc .chapter-full-content code {
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
}
.book-page .vp-doc .chapter-full-content table {
  border-collapse: collapse;
  width: 100%;
  margin: 16px 0;
}
.book-page .vp-doc .chapter-full-content th,
.book-page .vp-doc .chapter-full-content td {
  border: 1px solid var(--vp-c-divider);
  padding: 8px 12px;
  text-align: left;
}
.book-page .vp-doc .chapter-full-content blockquote {
  border-left: 4px solid var(--vp-c-brand-1);
  padding: 8px 16px;
  margin: 16px 0;
  color: var(--vp-c-text-2);
}
/* Heading anchor: use # symbol on hover */
.book-page .vp-doc .header-anchor::before {
  content: '#';
  font-weight: 600;
  color: var(--vp-c-brand-1);
}
/* ========================================================== */
/* Polish batch — reading affordances, a11y, motion refinement */
/* ========================================================== */
/* 1. Scroll-margin for heading anchors so in-page links land BELOW
      the sticky nav rather than under it. 60px nav + 24px breathing. */
.book-page .vp-doc h1,
.book-page .vp-doc h2,
.book-page .vp-doc h3,
.book-page .vp-doc h4 {
  scroll-margin-top: 84px;
}
/* Same for the root html to cover hash navigations to named elements
   outside .vp-doc (e.g. book index sections). */
html {
  scroll-padding-top: 84px;
}
/* 2. Unified focus ring — lemon-green glow on interactive elements
      for keyboard users, applied SITE-WIDE (not just .book-page) so
      landing / admin / user center share the same keyboard affordance.
      Default browser outline jumps between styles per element; this
      standardizes. The outline follows the element's border-radius
      on modern browsers, so we don't force a square radius. */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--vp-c-brand-1);
  outline-offset: 2px;
}
/* Don't show focus ring on mouse clicks — :focus-visible should
   already scope to keyboard / programmatic focus, but some older
   chromium releases leak through, so force-remove on plain :focus. */
a:focus:not(:focus-visible),
button:focus:not(:focus-visible),
[role="button"]:focus:not(:focus-visible),
[tabindex]:focus:not(:focus-visible) {
  outline: none;
}
/* Inputs keep their existing border-color focus state as the
   primary indicator, but add a faint outline glow to match the
   site's keyboard affordance so a screen-reader / keyboard user
   still sees the same lemon signal. */
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid color-mix(in oklab, var(--vp-c-brand-1) 40%, transparent);
  outline-offset: 1px;
}
/* Anchor # on reading-page headings fades in on keyboard focus too */
.book-page .vp-doc .header-anchor:focus-visible {
  opacity: 1;
}
/* 3. Smoother heading hover — the anchor # symbol fades in slightly
      rather than popping. Subtle enough to be invisible to most
      readers but makes the page feel polished. */
.book-page .vp-doc .header-anchor {
  opacity: 0;
  transition: opacity 0.18s var(--ease-out);
  margin-left: 4px;
}
.book-page .vp-doc h1:hover .header-anchor,
.book-page .vp-doc h2:hover .header-anchor,
.book-page .vp-doc h3:hover .header-anchor,
.book-page .vp-doc h4:hover .header-anchor,
.book-page .vp-doc .header-anchor:focus-visible {
  opacity: 1;
}
/* 4. Inline code: olive-tinted chip with a 1px hairline so it lifts
      off the body copy by a half-step instead of flooding a big
      color field. Previous values here carried over the pre-brand
      blue palette and clashed with the surrounding green text. */
.book-page .vp-doc :not(pre) > code {
  background: color-mix(in oklab, var(--vp-c-brand-1) 10%, transparent);
  color: var(--vp-c-brand-2);
  padding: 1.5px 6px;
  border-radius: 5px;
  font-size: 0.88em;
  font-weight: 500;
  font-family: 'JetBrains Mono', 'SF Mono', 'Menlo', Consolas, monospace;
  border: 1px solid color-mix(in oklab, var(--vp-c-brand-1) 16%, transparent);
  /* Subpixel baseline nudge — monospace x-heights tend to sit
     slightly higher than the serif prose they live inside, so
     drop the chip a hair to align optically. */
  vertical-align: 0.02em;
  transition: background 0.18s var(--ease-out), border-color 0.18s var(--ease-out);
}
/* Dark-mode tuning lives in the §4693 block — keep this rule
   light-mode-only so we don't fight the lime-tinted dark variant. */
/* 5. Reduced motion: honor prefers-reduced-motion so vestibular users
      don't get seasick from our scroll-reveal / hover lifts. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
/* 6. Selection color on book pages: brand-tinted highlight so it
      reads as "intentional accent" rather than the stark default
      blue. (Comment claimed brand-soft; the values were still
      literal blue residue.) */
.book-page ::selection {
  background: color-mix(in oklab, var(--vp-c-brand-1) 22%, transparent);
  color: var(--vp-c-text-1);
}
.dark.book-page ::selection,
.dark .book-page ::selection {
  background: rgba(196, 248, 87, 0.30);
}
/* 7. Code block line hover for easier reading — tint every
      line on hover so the reader can track where they are in
      a long source listing. */
.book-page .vp-doc [class*='language-'] pre code .line:hover {
  background: rgba(255, 255, 255, 0.04);
}
/* ===========================================================
   Callouts (VitePress :::info / :::tip / :::warning / :::danger
   / :::details). Rebuilt to look like the colored "highlight"
   blocks that learning platforms (Stripe docs, Geek Time, etc.)
   use to make in-line warnings actually noticeable in a long
   prose chapter, while still feeling at home with the rest of
   the page typography.

   Visual recipe per type:
   - 4px tinted left bar (the strongest signal, scannable from
     a fast scroll)
   - Tinted background at ~6% opacity
   - Inline title row with a colored dot + uppercase label
   - Body padding tuned to match the chapter's paragraph rhythm
   =========================================================== */
.book-page .vp-doc .custom-block {
  position: relative;
  margin: 24px 0;
  padding: 14px 18px 14px 22px;
  border-radius: 10px;
  border: 1px solid transparent;
  border-left-width: 4px;
  font-size: 14px;
  line-height: 1.75;
}
.book-page .vp-doc .custom-block .custom-block-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 8px;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
}
/* Circular letter badge — matches mockup V3's `i` / `!` / `✓`
   icons on callouts. Letter comes from the ::before content
   per type; the base sets geometry. Colors inherit from the
   callout type via currentColor on background. */
.book-page .vp-doc .custom-block .custom-block-title::before {
  content: '';
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: currentColor;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: 'Georgia', 'Times New Roman', serif;
  font-style: italic;
  font-weight: 700;
  font-size: 12.5px;
  line-height: 1;
  flex-shrink: 0;
}
.book-page .vp-doc .custom-block.info .custom-block-title::before {
  content: 'i';
  background: #3b82f6;
}
.book-page .vp-doc .custom-block.tip .custom-block-title::before {
  content: '✓';
  background: #10b981;
  font-style: normal;
  font-family: var(--vp-font-family-base);
}
.book-page .vp-doc .custom-block.warning .custom-block-title::before {
  content: '!';
  background: #f59e0b;
  font-style: normal;
  font-family: var(--vp-font-family-base);
}
.book-page .vp-doc .custom-block.danger .custom-block-title::before,
.book-page .vp-doc .custom-block.caution .custom-block-title::before {
  content: '!';
  background: #ef4444;
  font-style: normal;
  font-family: var(--vp-font-family-base);
}
.book-page .vp-doc .custom-block.details .custom-block-title::before {
  content: '+';
  background: #8b5cf6;
  font-style: normal;
  font-family: var(--vp-font-family-base);
  font-size: 16px;
}
.book-page .vp-doc .custom-block p {
  margin: 0;
  line-height: 1.75;
  font-size: 14px;
}
.book-page .vp-doc .custom-block p + p {
  margin-top: 8px;
}
.book-page .vp-doc .custom-block code {
  font-size: 0.86em;
  padding: 1px 6px;
}
.book-page .vp-doc .custom-block a {
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
/* INFO — blue */
.book-page .vp-doc .custom-block.info {
  background: rgba(59, 130, 246, 0.06);
  border-color: rgba(59, 130, 246, 0.2);
  border-left-color: #3b82f6;
  color: var(--vp-c-text-1);
}
.book-page .vp-doc .custom-block.info .custom-block-title {
  color: #2563eb;
}
/* TIP — emerald */
.book-page .vp-doc .custom-block.tip {
  background: rgba(16, 185, 129, 0.06);
  border-color: rgba(16, 185, 129, 0.22);
  border-left-color: #10b981;
  color: var(--vp-c-text-1);
}
.book-page .vp-doc .custom-block.tip .custom-block-title {
  color: #059669;
}
/* WARNING — amber */
.book-page .vp-doc .custom-block.warning {
  background: rgba(245, 158, 11, 0.07);
  border-color: rgba(245, 158, 11, 0.25);
  border-left-color: #f59e0b;
  color: var(--vp-c-text-1);
}
.book-page .vp-doc .custom-block.warning .custom-block-title {
  color: #b45309;
}
/* DANGER / CAUTION — red */
.book-page .vp-doc .custom-block.danger,
.book-page .vp-doc .custom-block.caution {
  background: rgba(239, 68, 68, 0.06);
  border-color: rgba(239, 68, 68, 0.22);
  border-left-color: #ef4444;
  color: var(--vp-c-text-1);
}
.book-page .vp-doc .custom-block.danger .custom-block-title,
.book-page .vp-doc .custom-block.caution .custom-block-title {
  color: #dc2626;
}
/* DETAILS — collapsible, neutral violet */
.book-page .vp-doc .custom-block.details {
  background: rgba(139, 92, 246, 0.05);
  border-color: rgba(139, 92, 246, 0.2);
  border-left-color: #8b5cf6;
  padding: 0;
}
.book-page .vp-doc .custom-block.details summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 18px 12px 18px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: #7c3aed;
  letter-spacing: 0.02em;
  list-style: none;
  user-select: none;
}
.book-page .vp-doc .custom-block.details summary::-webkit-details-marker {
  display: none;
}
.book-page .vp-doc .custom-block.details summary::before {
  content: '';
  width: 0;
  height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform 0.2s var(--ease-out);
  flex-shrink: 0;
}
.book-page .vp-doc .custom-block.details[open] summary::before {
  transform: rotate(90deg);
}
.book-page .vp-doc .custom-block.details > *:not(summary) {
  padding: 0 18px 14px 18px;
}
/* Dark-mode tweaks: the 6% tints get washed out on a dark page bg,
   so bump them up a notch and brighten the title color so it stays
   legible against the deeper background. */
.dark .book-page .vp-doc .custom-block.info {
  background: rgba(59, 130, 246, 0.10);
}
.dark .book-page .vp-doc .custom-block.info .custom-block-title { color: #60a5fa; }
.dark .book-page .vp-doc .custom-block.tip {
  background: rgba(16, 185, 129, 0.10);
}
.dark .book-page .vp-doc .custom-block.tip .custom-block-title { color: #34d399; }
.dark .book-page .vp-doc .custom-block.warning {
  background: rgba(245, 158, 11, 0.12);
}
.dark .book-page .vp-doc .custom-block.warning .custom-block-title { color: #fbbf24; }
.dark .book-page .vp-doc .custom-block.danger,
.dark .book-page .vp-doc .custom-block.caution {
  background: rgba(239, 68, 68, 0.10);
}
.dark .book-page .vp-doc .custom-block.danger .custom-block-title,
.dark .book-page .vp-doc .custom-block.caution .custom-block-title { color: #f87171; }
.dark .book-page .vp-doc .custom-block.details {
  background: rgba(139, 92, 246, 0.10);
}
.dark .book-page .vp-doc .custom-block.details summary { color: #a78bfa; }
/* Sidebar "已读" tick — appended client-side by the read-tracker
   (useReadingEnhancers#enhanceSidebarReadMarks). Sits after the
   chapter title and signals at-a-glance which chapters the
   visitor has already finished. */
.VPSidebarItem .text .sb-read-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: rgba(16, 185, 129, 0.14);
  color: #059669;
  margin-left: 6px;
  vertical-align: middle;
}
.dark .VPSidebarItem .text .sb-read-mark {
  background: rgba(16, 185, 129, 0.20);
  color: #34d399;
}
/* Partial-progress strip under in-flight chapters in the sidebar.
   A 2px rail with a gradient fill indicating % scrolled. Reader
   scans the sidebar and instantly spots the chapter they were
   halfway through — the single biggest quality-of-life win for
   readers who dip in and out across multiple chapters. */
.VPSidebarItem .sb-progress {
  position: relative;
  height: 2px;
  margin: 2px 14px 4px;
  background: var(--vp-c-divider);
  border-radius: 2px;
  overflow: hidden;
  cursor: help;
}
.VPSidebarItem .sb-progress-fill {
  height: 100%;
  /* Brand-olive progress across the per-chapter sidebar bar —
     was blue → indigo. Dark mode gets lemon (via the §4754
     override block) so we only paint the light gradient here. */
  background: linear-gradient(90deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  border-radius: 2px;
  transition: width 0.3s cubic-bezier(0.2, 0, 0, 1);
}
.dark .VPSidebarItem .sb-progress {
  background: rgba(148, 163, 184, 0.18);
}
.dark .VPSidebarItem .sb-progress-fill {
  background: linear-gradient(90deg, #c4f857, #a5e043);
}
.VPSidebarItem.is-active .sb-progress-fill {
  /* Active chapter progress: slightly warmer end-stop so the
     reader can tell their current chapter's bar apart from the
     surrounding read-but-not-open bars. Olive → accent-lemon. */
  background: linear-gradient(90deg, var(--vp-c-brand-1), #a5e043);
}
/* ===========================================================
   File-path label on top of a code block. Set client-side by
   useReadingEnhancers when the block's first comment line
   names a file. Reads as a "this snippet is from <file>"
   header strip — makes source-commentary chapters far easier
   to navigate when the same module gets quoted across
   sub-sections.
   =========================================================== */
.book-page .vp-doc div[class*='language-'].has-file-label {
  padding-top: 0;
}
.book-page .vp-doc .code-file-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  margin: 0 0 0 0;
  background: rgba(255, 255, 255, 0.04);
  color: rgba(255, 255, 255, 0.62);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 12px 12px 0 0;
  /* Sits above the code area; the code block keeps its 24px top
     padding, so the label visually stitches into the editor chrome
     instead of floating disconnected. */
}
.book-page .vp-doc .code-file-label svg {
  flex-shrink: 0;
  opacity: 0.75;
}
.book-page .vp-doc .has-file-label .cfl-path {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
/* When a label exists the lang-badge would clip with it — push the
   badge a few px lower so they don't touch. */
.book-page .vp-doc .has-file-label .code-lang-badge {
  top: 38px;
}
/* Line / character meta on every code block, bottom-right. Low
   opacity, monospace, compact — reads as "block stats" at the
   corner of the editor, like an IDE status bar. */
.book-page .vp-doc div[class*='language-'] .code-meta {
  position: absolute;
  bottom: 6px;
  right: 12px;
  padding: 1px 8px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.4);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s;
  z-index: 1;
}
.book-page .vp-doc div[class*='language-']:hover .code-meta {
  opacity: 1;
}
/* ===========================================================
   Long code-block collapse — applied client-side by
   useReadingEnhancers when a block exceeds ~25 lines. Lets
   prose breathe around long source listings without hiding
   them entirely; one click expands.
   =========================================================== */
.book-page .vp-doc div[class*='language-'].code-collapsible {
  position: relative;
}
.book-page .vp-doc div[class*='language-'].code-collapsible.is-collapsed pre {
  /* ~25 lines × 1.7 line-height × 13.5px ≈ 575px, +40px padding */
  max-height: 615px;
  overflow: hidden;
  overflow-y: hidden !important;
}
/* VitePress puts the scroll on the inner <code> on some themes.
   Kill the vertical scrollbar on the collapsed container too —
   the fade + "展开剩余 N 行" button already communicates there's
   more, a scrollbar on top of it reads as clutter. */
.book-page .vp-doc div[class*='language-'].code-collapsible.is-collapsed pre,
.book-page .vp-doc div[class*='language-'].code-collapsible.is-collapsed pre code {
  scrollbar-width: none;
}
.book-page .vp-doc div[class*='language-'].code-collapsible.is-collapsed pre::-webkit-scrollbar,
.book-page .vp-doc div[class*='language-'].code-collapsible.is-collapsed pre code::-webkit-scrollbar {
  display: none;
}
/* The expand toggle is the same element in both states; its visual
   chrome differs by container class. */
.book-page .vp-doc .code-expand-toggle {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 56px;
  background: transparent;
  border: none;
  cursor: pointer;
  font: inherit;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: rgba(255, 255, 255, 0.85);
  z-index: 2;
  padding: 0;
}
.book-page .vp-doc .code-expand-toggle .cet-fade {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, transparent, #1e1e2e 70%);
  pointer-events: none;
  transition: opacity 0.2s var(--ease-out);
}
.book-page .vp-doc div[class*='language-']:not(.is-collapsed) .code-expand-toggle {
  position: static;
  height: 36px;
  margin-top: -8px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.03);
}
.book-page .vp-doc div[class*='language-']:not(.is-collapsed) .code-expand-toggle .cet-fade {
  display: none;
}
.book-page .vp-doc .code-expand-toggle .cet-label {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(4px);
  transition: background 0.2s var(--ease-out);
}
.book-page .vp-doc .code-expand-toggle:hover .cet-label {
  background: rgba(255, 255, 255, 0.14);
}
/* Fullscreen toggle on every code block — sits next to the copy
   button in the top-right. Visible on hover (matching the copy
   button's discoverability). */
.book-page .vp-doc div[class*='language-'] .code-fullscreen-btn {
  position: absolute;
  top: 10px;
  right: 44px;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.6);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s, background 0.15s, color 0.15s;
  z-index: 2;
}
.book-page .vp-doc div[class*='language-']:hover .code-fullscreen-btn {
  opacity: 0.5;
}
.book-page .vp-doc div[class*='language-'] .code-fullscreen-btn:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}
.book-page .vp-doc div[class*='language-'].has-file-label .code-fullscreen-btn {
  top: 38px;  /* match the badge offset rule */
}
/* Fullscreen overlay — translucent backdrop + dark card containing
   a clean clone of the code block (collapse/copy/etc stripped). */
.code-fullscreen-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(15, 23, 42, 0.7);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  opacity: 0;
  transition: opacity 0.2s var(--ease-out);
}
.code-fullscreen-overlay.is-open {
  opacity: 1;
}
.code-fullscreen-overlay .cf-card {
  width: min(1100px, 100%);
  max-height: 90vh;
  background: #1e1e2e;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.code-fullscreen-overlay .cf-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: rgba(255, 255, 255, 0.04);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.code-fullscreen-overlay .cf-title {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.78);
  letter-spacing: 0.02em;
}
.code-fullscreen-overlay .cf-close {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: none;
  background: transparent;
  color: rgba(255, 255, 255, 0.55);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s, color 0.15s;
}
.code-fullscreen-overlay .cf-close:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}
.code-fullscreen-overlay .cf-body {
  overflow: auto;
  padding: 0;
  background: #1e1e2e;
}
.code-fullscreen-overlay .cf-body div[class*='language-'] {
  margin: 0 !important;
  border-radius: 0 !important;
  border: none !important;
  box-shadow: none !important;
  max-height: none !important;
}
.code-fullscreen-overlay .cf-body div[class*='language-'] pre {
  max-height: none !important;
}
/* ===========================================================
   Inline image caption — sits right below an inline image,
   showing the alt text as a small italic line. Only added
   when the alt looks like a real human description (not a
   filename or "image-3.png"). Gives chapters with diagrams
   a textbook-grade "Figure X" feel without anyone having to
   author <figure> markup explicitly.
   =========================================================== */
.book-page .vp-doc .img-caption {
  display: block;
  margin: 6px auto 4px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--vp-c-text-3);
  font-style: italic;
  text-align: center;
  letter-spacing: 0.01em;
  max-width: 80ch;
}
.book-page .vp-doc p:has(> img) {
  text-align: center;
}
.book-page .vp-doc p > img + .img-caption {
  margin-top: 6px;
}
/* Mermaid diagram caption — appended client-side when an italic
   paragraph immediately follows a mermaid block. Same visual
   weight as image captions so the two read as a unified "figure"
   convention across chapters. */
.book-page .vp-doc .mermaid-caption {
  display: block;
  margin: 12px auto 0;
  padding: 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--vp-c-text-3);
  font-style: italic;
  text-align: center;
  max-width: 80ch;
}
/* ===========================================================
   Heading anchor "copied!" feedback — when the reader clicks
   the # next to an h2/h3/h4, useReadingEnhancers copies the
   permalink and flips data-copied="1" briefly. Render an
   inline floating pill that confirms, then fades.
   =========================================================== */
.book-page .vp-doc .header-anchor {
  position: relative;
}
.book-page .vp-doc .header-anchor[data-copied]::after {
  content: '链接已复制';
  position: absolute;
  left: 50%;
  top: -28px;
  transform: translateX(-50%);
  white-space: nowrap;
  padding: 3px 10px;
  border-radius: 999px;
  /* On-brand: olive fill with light-ink text (light mode) switches
     to lemon fill with dark-ink text in dark mode below. The prior
     emerald #10b981 was an off-palette green that visually "popped"
     in a way that broke the reader's focus. */
  background: var(--vp-c-brand-1);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  box-shadow: 0 4px 14px color-mix(in oklab, var(--vp-c-brand-1) 36%, transparent);
  pointer-events: none;
  animation: anchor-copied-pop 1.4s cubic-bezier(0.2, 0, 0, 1) forwards;
}
.dark .book-page .vp-doc .header-anchor[data-copied]::after {
  background: #c4f857;
  color: #0a0b0f;
  box-shadow: 0 4px 14px rgba(196, 248, 87, 0.28);
}
.book-page .vp-doc .header-anchor[data-copied="fail"]::after {
  content: '复制失败';
  background: #ef4444;
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.35);
}
@keyframes anchor-copied-pop {
  0%   { opacity: 0; transform: translateX(-50%) translateY(4px); }
  15%  { opacity: 1; transform: translateX(-50%) translateY(0); }
  80%  { opacity: 1; transform: translateX(-50%) translateY(0); }
  100% { opacity: 0; transform: translateX(-50%) translateY(-4px); }
}
/* ===========================================================
   Polish pass — small typographic touches that separately are
   trivial but together push the chapter from "blog post" to
   "course textbook".
   =========================================================== */
/* Lead paragraph: the first <p> right after h1 reads as the
   章节导言 — slightly larger, dimmer, with a thin left rule.
   Catches the reader's eye before they commit to the chapter. */
.book-page .vp-doc > h1 + p,
.book-page .vp-doc .content-container > h1 + p {
  font-size: 16px;
  line-height: 1.85;
  color: var(--vp-c-text-2);
  padding: 4px 0 4px 14px;
  /* Lead-paragraph accent rail — brand olive at 38% alpha so it
     reads as "this is the chapter's thesis" without competing
     with the h1 above or the body that follows. */
  border-left: 3px solid color-mix(in oklab, var(--vp-c-brand-1) 38%, transparent);
  margin: 4px 0 28px;
  letter-spacing: 0.005em;
}
/* <kbd> — keyboard-key style. Authors who use `<kbd>Ctrl</kbd>`
   in chapters about IDE / editor / shell internals now get a
   real key-cap look instead of inheriting the inline-code style. */
.book-page .vp-doc kbd {
  display: inline-block;
  padding: 1px 7px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.82em;
  font-weight: 600;
  line-height: 1.5;
  color: var(--vp-c-text-1);
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-bottom-width: 2px;
  border-radius: 5px;
  box-shadow: 0 1px 0 rgba(15, 23, 42, 0.04);
  vertical-align: 1px;
  white-space: nowrap;
}
/* <mark> — yellow-highlight callout for the rare "this is the
   one sentence that matters in this paragraph" emphasis. */
.book-page .vp-doc mark {
  background: linear-gradient(180deg, transparent 55%, rgba(245, 158, 11, 0.35) 55%);
  color: inherit;
  padding: 0 2px;
  border-radius: 1px;
}
.dark .book-page .vp-doc mark {
  background: linear-gradient(180deg, transparent 55%, rgba(245, 158, 11, 0.55) 55%);
}
/* User-saved highlights (jt-hl). Distinct warmer tint + cursor
   hint that double-click un-highlights. */
.book-page .vp-doc mark.jt-hl {
  background: linear-gradient(180deg, transparent 55%, rgba(250, 204, 21, 0.55) 55%);
  cursor: help;
  transition: background 0.15s var(--ease-out);
}
.book-page .vp-doc mark.jt-hl:hover {
  background: linear-gradient(180deg, transparent 50%, rgba(250, 204, 21, 0.7) 50%);
}
.dark .book-page .vp-doc mark.jt-hl {
  background: linear-gradient(180deg, transparent 55%, rgba(250, 204, 21, 0.5) 55%);
}
/* External links: differentiate from in-doc anchor links so the
   reader knows they're leaving the page. Tiny ↗ glyph + the
   underline becomes amber on hover. */
.book-page .vp-doc a[href^="http"]:not([href*="yangyitao.com"])::after {
  content: '↗';
  display: inline-block;
  font-size: 0.78em;
  margin-left: 2px;
  opacity: 0.55;
  vertical-align: 1px;
}
.book-page .vp-doc a[href^="http"]:not([href*="yangyitao.com"]):hover::after {
  opacity: 1;
}
/* ===========================================================
   Line numbers — enabled in config.markdown.lineNumbers.
   VitePress's default line-number rail is muddy; this turns it
   into a quiet left gutter that fades into the dark editor
   chrome but still gives "ref: line 47" readers an anchor to
   count from.
   =========================================================== */
.book-page .vp-doc .line-numbers-wrapper {
  background: rgba(0, 0, 0, 0.16) !important;
  border-right: 1px solid rgba(255, 255, 255, 0.05) !important;
  color: rgba(255, 255, 255, 0.32) !important;
  padding-top: 20px !important;
  padding-bottom: 20px !important;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace !important;
  font-size: 12px !important;
  text-align: right !important;
  user-select: none;
  width: 42px !important;
  transition: color 0.2s, background 0.2s;
}
.book-page .vp-doc div[class*='language-']:hover .line-numbers-wrapper {
  color: rgba(255, 255, 255, 0.52) !important;
}
/* Pre needs to push past the gutter so code text doesn't sit
   underneath the rail. */
.book-page .vp-doc div[class*='language-'].line-numbers-mode pre {
  padding-left: 60px !important;
}
/* Highlighted line still shines through on top of the gutter. */
.book-page .vp-doc .line-numbers-wrapper .highlighted {
  background: linear-gradient(to right,
    color-mix(in oklab, var(--vp-c-brand-1) 20%, transparent),
    transparent);
  color: rgba(255, 255, 255, 0.85) !important;
}
/* ===========================================================
   Line-level diff / highlight annotations — drives VitePress's
   {1,3-5} / {1+} / {1-} fence-info syntax into a readable
   GitHub-style presentation: green add, red remove, indigo
   "pay attention", each with a ~14-18% tinted background that
   runs edge-to-edge and a 3px left rail in the accent color.
   =========================================================== */
.book-page .vp-doc div[class*='language-'] pre code .highlighted {
  /* Neutral "pay attention" line highlight. Was indigo so it
     contrasted with the green-add / red-remove diff lanes;
     keep the semantic distinction but shift the neutral to
     brand olive so it belongs to the site's accent family. */
  background: color-mix(in oklab, var(--vp-c-brand-1) 18%, transparent);
  box-shadow: inset 3px 0 0 var(--vp-c-brand-1);
  display: block;
  margin: 0 -24px;
  padding: 0 24px;
  width: calc(100% + 48px);
}
.book-page .vp-doc div[class*='language-'] pre code .diff.add {
  background: rgba(16, 185, 129, 0.16);
  box-shadow: inset 3px 0 0 #10b981;
  display: block;
  margin: 0 -24px;
  padding: 0 24px;
  width: calc(100% + 48px);
}
.book-page .vp-doc div[class*='language-'] pre code .diff.add::before {
  content: '+';
  position: absolute;
  left: 4px;
  color: #10b981;
  font-weight: 700;
  opacity: 0.8;
}
.book-page .vp-doc div[class*='language-'] pre code .diff.remove {
  background: rgba(239, 68, 68, 0.16);
  box-shadow: inset 3px 0 0 #ef4444;
  display: block;
  margin: 0 -24px;
  padding: 0 24px;
  width: calc(100% + 48px);
  opacity: 0.75;
  text-decoration: line-through;
  text-decoration-color: rgba(239, 68, 68, 0.4);
}
.book-page .vp-doc div[class*='language-'] pre code .diff.remove::before {
  content: '−';
  position: absolute;
  left: 4px;
  color: #ef4444;
  font-weight: 700;
  opacity: 0.8;
}
.book-page .vp-doc div[class*='language-'] pre code .line {
  position: relative;
}
/* Mirror the diff-row strip into the line-number gutter so the
   number stays aligned with its row, not the surrounding code. */
.book-page .vp-doc .line-numbers-wrapper .diff.add {
  background: rgba(16, 185, 129, 0.14);
  color: rgba(16, 185, 129, 0.85) !important;
}
.book-page .vp-doc .line-numbers-wrapper .diff.remove {
  background: rgba(239, 68, 68, 0.14);
  color: rgba(239, 68, 68, 0.8) !important;
}
/* Click-to-copy on the line-number gutter — wrapper picks up
   pointer cursor + a subtle hover tint to advertise the action. */
.book-page .vp-doc .lnw-copyable {
  cursor: pointer !important;
}
.book-page .vp-doc .lnw-copyable:hover {
  background: color-mix(in oklab, var(--vp-c-brand-1) 18%, transparent) !important;
  color: rgba(255, 255, 255, 0.78) !important;
}
/* The flash applied to the just-copied line — 1s green wash
   that fades out, so the reader sees the exact line that
   landed on their clipboard. */
.book-page .vp-doc .line-just-copied {
  background: rgba(16, 185, 129, 0.22) !important;
  box-shadow: inset 3px 0 0 #10b981;
  animation: line-copy-flash 1.1s cubic-bezier(0.2, 0, 0, 1) forwards;
}
@keyframes line-copy-flash {
  0%   { background: rgba(16, 185, 129, 0.32); }
  60%  { background: rgba(16, 185, 129, 0.22); }
  100% { background: transparent; box-shadow: none; }
}
/* ===========================================================
   List item hover — kept extremely subtle: a 3px accent slides
   in from the left, no background flash, no color shift on the
   text itself. Reads as "the eye knows where it is" rather
   than a click affordance (these aren't links). Works for the
   long bullet lists that appear in design-philosophy chapters.
   =========================================================== */
.book-page .vp-doc ul > li,
.book-page .vp-doc ol > li {
  position: relative;
  padding-left: 2px;
  transition: padding-left 0.18s var(--ease-out);
}
.book-page .vp-doc ul > li::before,
.book-page .vp-doc ol > li::before {
  content: '';
  position: absolute;
  left: -10px;
  top: 0.45em;
  bottom: 0.45em;
  width: 2px;
  border-radius: 1px;
  /* Olive → deeper-olive. Indigo→blue was pre-brand residue —
     every bullet in every long chapter list animated this bar
     on hover. */
  background: linear-gradient(180deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  opacity: 0;
  transform: scaleY(0.4);
  transform-origin: center;
  transition:
    opacity   0.18s cubic-bezier(0.2, 0, 0, 1),
    transform 0.18s cubic-bezier(0.2, 0, 0, 1);
  pointer-events: none;
}
.book-page .vp-doc ul > li:hover::before,
.book-page .vp-doc ol > li:hover::before {
  opacity: 0.7;
  transform: scaleY(1);
}
.book-page .vp-doc ul > li:hover,
.book-page .vp-doc ol > li:hover {
  padding-left: 6px;
}
/* ===========================================================
   Paragraph deep-link button — appended client-side to each
   prose <p>. Sits at the right margin, only visible on hover,
   click copies a Text Fragment URL the recipient's browser
   will scroll-and-highlight on open. Quiet by default, no
   visual cost when not interacting.
   =========================================================== */
.book-page .vp-doc .para-anchor {
  position: absolute;
  top: 4px;
  right: -28px;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--vp-c-text-3);
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition:
    opacity      0.18s var(--ease-out),
    background   0.18s var(--ease-out),
    color        0.18s var(--ease-out),
    border-color 0.18s var(--ease-out);
  user-select: none;
}
.book-page .vp-doc p:hover > .para-anchor {
  opacity: 0.55;
}
.book-page .vp-doc .para-anchor:hover {
  opacity: 1 !important;
  color: var(--vp-c-brand-1);
  background: var(--vp-c-bg-soft);
  border-color: var(--vp-c-divider);
}
.book-page .vp-doc .para-anchor[data-copied] {
  opacity: 1 !important;
  color: #fff;
  background: #10b981;
  border-color: transparent;
}
.book-page .vp-doc .para-anchor[data-copied="fail"] {
  background: #ef4444;
}
.book-page .vp-doc .para-anchor[data-copied]::after {
  content: '段落链接已复制';
  position: absolute;
  right: 32px;
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
  padding: 3px 9px;
  border-radius: 999px;
  background: #10b981;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  font-family: var(--vp-font-family-base);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.35);
  pointer-events: none;
  animation: copy-pill-pop 1.6s cubic-bezier(0.2, 0, 0, 1) forwards;
}
.book-page .vp-doc .para-anchor[data-copied="fail"]::after {
  content: '复制失败';
  background: #ef4444;
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.35);
}
/* On narrow viewports the right margin disappears, so anchor
   tucks inline at the end of the paragraph instead. */
@media (max-width: 900px) {
  .book-page .vp-doc .para-anchor {
    position: relative;
    right: auto;
    top: auto;
    margin-left: 6px;
    display: inline-flex;
    vertical-align: middle;
  }
}
/* ===========================================================
   Keyboard-shortcut help overlay — opens on "?" press, closes
   on "Esc" or backdrop / × click. Pure CSS card on a backdrop;
   no Vue, no portal, lightweight.
   =========================================================== */
.kbd-help-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(15, 23, 42, 0.42);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: kbd-fade-in 0.2s cubic-bezier(0.2, 0, 0, 1);
}
.kbd-help-card {
  background: var(--vp-c-bg);
  color: var(--vp-c-text-1);
  border: 1px solid var(--vp-c-divider);
  border-radius: 14px;
  padding: 20px 24px 22px;
  width: min(440px, 100%);
  /* Keyboard-shortcut help card — full modal tier. */
  box-shadow: var(--shadow-5);
  animation: kbd-pop-in 0.22s cubic-bezier(0.2, 0, 0, 1);
}
.kbd-help-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--vp-c-divider);
}
.kbd-help-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.kbd-help-close {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  border: none;
  background: transparent;
  color: var(--vp-c-text-3);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.18s var(--ease-out), color 0.18s var(--ease-out);
}
.kbd-help-close:hover {
  background: var(--vp-c-bg-soft);
  color: var(--vp-c-text-1);
}
.kbd-help-grid {
  display: grid;
  gap: 10px;
}
.kbd-help-grid .kbd-row {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: center;
  gap: 6px;
  font-size: 13.5px;
  color: var(--vp-c-text-2);
}
.kbd-help-grid .kbd-row span {
  margin-left: 8px;
}
.kbd-help-grid kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  padding: 2px 7px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  font-weight: 700;
  color: var(--vp-c-text-1);
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
  border-bottom-width: 2px;
  border-radius: 5px;
  line-height: 1.4;
}
@keyframes kbd-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes kbd-pop-in {
  from { opacity: 0; transform: translateY(8px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* ===========================================================
   Chapter intro box — sits right after the chapter <h1> and
   lists every H2 as a numbered jump link, with section count
   and estimated read time in the header. Collapsible;
   preference persists across chapters.
   =========================================================== */
.book-page .vp-doc .chapter-intro-box {
  margin: 18px 0 28px;
  background: linear-gradient(135deg,
              color-mix(in srgb, var(--vp-c-brand-1) 4%, var(--vp-c-bg-soft)),
              var(--vp-c-bg-soft));
  border: 1px solid var(--vp-c-divider);
  border-radius: 12px;
  overflow: hidden;
}
.book-page .vp-doc .chapter-intro-box .cib-header {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 12px 16px;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--vp-c-text-1);
  font: inherit;
  transition: background 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.book-page .vp-doc .chapter-intro-box .cib-header:hover {
  background: color-mix(in oklab, var(--vp-c-brand-1) 7%, transparent);
}
.book-page .vp-doc .chapter-intro-box .cib-title {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--vp-c-text-1);
}
.book-page .vp-doc .chapter-intro-box .cib-title svg {
  color: var(--vp-c-brand-1);
  opacity: 0.85;
}
.book-page .vp-doc .chapter-intro-box .cib-meta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: auto;
  margin-right: 8px;
  font-size: 12px;
  color: var(--vp-c-text-3);
  font-weight: 500;
}
.book-page .vp-doc .chapter-intro-box .cib-meta .cib-sep {
  opacity: 0.5;
}
.book-page .vp-doc .chapter-intro-box .cib-chevron {
  display: inline-flex;
  align-items: center;
  color: var(--vp-c-text-3);
  transition: transform 0.25s cubic-bezier(0.2, 0, 0, 1);
}
.book-page .vp-doc .chapter-intro-box.is-collapsed .cib-chevron {
  transform: rotate(-90deg);
}
.book-page .vp-doc .chapter-intro-box .cib-list {
  list-style: none;
  padding: 4px 12px 12px;
  margin: 0;
  max-height: 900px;
  /* Scoped easing + asymmetric timing: max-height leads the
     animation, padding and opacity follow on slightly shorter
     curves so collapse feels "settled" rather than uniform. */
  transition:
    max-height 0.3s cubic-bezier(0.2, 0, 0, 1),
    opacity    0.2s cubic-bezier(0.2, 0, 0, 1),
    padding    0.25s cubic-bezier(0.2, 0, 0, 1);
  overflow: hidden;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 2px 12px;
}
.book-page .vp-doc .chapter-intro-box.is-collapsed .cib-list {
  max-height: 0;
  opacity: 0;
  padding-top: 0;
  padding-bottom: 0;
}
.book-page .vp-doc .chapter-intro-box .cib-list li {
  margin: 0;
  padding: 0;
}
.book-page .vp-doc .chapter-intro-box .cib-list li::marker { content: none; }
.book-page .vp-doc .chapter-intro-box .cib-list a {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 5px 8px;
  border-radius: 6px;
  text-decoration: none;
  color: var(--vp-c-text-2);
  font-size: 13.5px;
  line-height: 1.5;
  transition: background 0.15s var(--ease-out), color 0.15s var(--ease-out);
}
.book-page .vp-doc .chapter-intro-box .cib-list a:hover {
  background: var(--vp-c-bg);
  color: var(--vp-c-brand-1);
}
.book-page .vp-doc .chapter-intro-box .cib-list .cib-num {
  flex-shrink: 0;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  font-weight: 500;
  color: var(--vp-c-brand-1);
  opacity: 0.65;
  letter-spacing: 0.04em;
}
.book-page .vp-doc .chapter-intro-box .cib-list .cib-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (max-width: 640px) {
  .book-page .vp-doc .chapter-intro-box .cib-list {
    grid-template-columns: 1fr;
  }
  .book-page .vp-doc .chapter-intro-box .cib-header {
    padding: 10px 14px;
    gap: 10px;
    flex-wrap: wrap;
  }
  .book-page .vp-doc .chapter-intro-box .cib-meta {
    font-size: 11.5px;
  }
}
html.reading-focus .chapter-intro-box {
  display: none !important;
}
/* Book-index pages (/books/<slug>/) now show the book title and
   one-line description in BookHeader's hero banner. The markdown
   source still opens with an <h1>书名</h1> + intro paragraph, which
   duplicates what's in the hero. Hide the H1 when BookHeader's
   hero is present so the book's opening reads as one clean block.
   The :has() match keeps this conditional — if for some reason the
   hero doesn't render (unknown slug, missing gradient), the H1
   stays visible as a graceful fallback. */
.book-header:has(.bh-hero) + .vp-doc > h1:first-of-type {
  display: none;
}
/* ===========================================================
   Sidebar collapse / expand — a small chevron at the top-right
   of .VPSidebar toggles html.jt-sidebar-collapsed; when set, we
   zero-out the sidebar width and widen the content column, and
   a floating chevron at the left edge offers re-expand. Mobile
   is untouched because the sidebar is a drawer there already.
   =========================================================== */
.jt-sb-toggle {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid var(--vp-c-divider);
  border-radius: 6px;
  background: var(--vp-c-bg);
  color: var(--vp-c-text-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition:
    opacity      0.15s cubic-bezier(0.2, 0, 0, 1),
    color        0.15s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.15s cubic-bezier(0.2, 0, 0, 1);
  opacity: 0;
}
.VPSidebar:hover .jt-sb-toggle,
.jt-sb-toggle:focus-visible {
  opacity: 1;
}
.jt-sb-toggle:hover {
  color: var(--vp-c-brand-1);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 45%, transparent);
}
.jt-sb-reopen {
  position: fixed;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 22;
  width: 30px;
  min-height: 96px;
  padding: 10px 4px;
  border: 1px solid var(--vp-c-divider);
  border-left: none;
  border-radius: 0 12px 12px 0;
  background: linear-gradient(90deg, var(--vp-c-bg) 0%, var(--vp-c-bg-soft) 100%);
  color: var(--vp-c-text-2);
  /* Sidebar reopen tab — popover tier, floats above page edge. */
  box-shadow: var(--shadow-4);
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  /* Width + color + border + shadow animate on hover — keep the
     fixed 50%-translated transform out of the transition list so
     it stays pinned to the viewport centre mid-hover instead of
     micro-jittering. */
  transition:
    width        0.2s cubic-bezier(0.2, 0, 0, 1),
    color        0.2s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.2s cubic-bezier(0.2, 0, 0, 1),
    box-shadow   0.22s cubic-bezier(0.2, 0, 0, 1),
    opacity      0.2s cubic-bezier(0.2, 0, 0, 1);
  opacity: 0;
  pointer-events: none;
}
.jt-sb-reopen.is-visible {
  opacity: 1;
  pointer-events: auto;
}
.jt-sb-reopen .sbr-label {
  writing-mode: vertical-rl;
  text-orientation: upright;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--vp-c-text-2);
}
.jt-sb-reopen:hover {
  width: 36px;
  color: var(--vp-c-brand-1);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 45%, transparent);
  box-shadow: 0 8px 24px color-mix(in oklab, var(--vp-c-brand-1) 28%, transparent);
  background: linear-gradient(90deg,
              color-mix(in srgb, var(--vp-c-brand-1) 6%, var(--vp-c-bg)),
              var(--vp-c-bg-soft));
}
.jt-sb-reopen:hover .sbr-label {
  color: var(--vp-c-brand-1);
}
html.dark .jt-sb-reopen {
  background: linear-gradient(90deg, rgba(30, 35, 50, 0.95), rgba(20, 24, 36, 0.95));
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
}
@media (min-width: 960px) {
  /* Sidebar collapse is visual-only: fade and slide the sidebar
     out of view but keep VitePress's has-sidebar layout intact.
     The right edge of the content column stays anchored — we
     only shrink the left sidebar gutter and grow the content
     column leftward into the freed space. */
  html.jt-sidebar-collapsed .VPSidebar {
    transform: translateX(calc(-1 * var(--vp-sidebar-width, 272px)));
    opacity: 0;
    pointer-events: none;
    transition: transform 0.25s var(--ease-out), opacity 0.2s var(--ease-out);
  }
}
/* Shrink the left sidebar gutter to 60% and grow the content
   column by the freed 40% (272 × 0.4 ≈ 109px), so the content's
   right edge stays put while its left edge extends into the
   space the sidebar vacated. */
@media (min-width: 1280px) {
  html.jt-sidebar-collapsed .VPContent.has-sidebar {
    padding-left: calc(var(--vp-sidebar-width, 272px) * 0.6) !important;
  }
  html.jt-sidebar-collapsed .book-page .VPDoc.has-aside .content-container {
    max-width: 1069px !important;  /* 960 + 109 */
  }
  html.jt-sidebar-collapsed .book-page .VPDoc:not(.has-aside) .content-container {
    max-width: 1009px !important;  /* 900 + 109 */
  }
}
@media (min-width: 1440px) {
  html.jt-sidebar-collapsed .book-page .VPDoc.has-aside .content-container {
    max-width: 1189px !important;  /* 1080 + 109 */
  }
}
@media (max-width: 959px) {
  .jt-sb-toggle,
  .jt-sb-reopen { display: none !important; }
}
html.reading-focus .jt-sb-toggle,
html.reading-focus .jt-sb-reopen { display: none !important; }
/* ===========================================================
   Top reading-progress bar — a 2px horizontal line fixed at
   the top of the viewport, filling left-to-right as the reader
   scrolls the chapter. The fill is a gradient so the bar
   doesn't look sterile; we use scaleX on a transform-only path
   so scroll ticks don't trigger layout. */
.jt-top-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 40;
  background: transparent;
  pointer-events: none;
}
.jt-top-progress-fill {
  height: 100%;
  transform-origin: left center;
  transform: scaleX(0);
  /* Olive → accent-lemon → deeper-olive loop. Previous 3-stop
     gradient was blue → indigo → purple, none of which match the
     brand — the bar literally advertised "other site" colours
     every time it filled. */
  background: linear-gradient(90deg,
    var(--vp-c-brand-1),
    #a5e043 55%,
    var(--vp-c-brand-2));
  box-shadow: 0 0 8px color-mix(in oklab, var(--vp-c-brand-1) 50%, transparent);
  will-change: transform;
  transition: transform 0.08s linear;
}
html.dark .jt-top-progress-fill {
  background: linear-gradient(90deg, #c4f857, #a5e043 55%, #6b9e2c);
  box-shadow: 0 0 10px rgba(196, 248, 87, 0.55);
}
html.reading-focus .jt-top-progress { display: none; }
/* ===========================================================
   Reader preferences — a FAB (top of the right-edge stack,
   above focus-mode) opens a compact panel for font-size, line-
   height, and content-width controls. The chosen values are
   applied as CSS custom properties on <html>, so they cascade
   into chapter prose without us having to re-render anything.
   =========================================================== */
.reader-prefs-btn {
  position: fixed;
  right: 22px;
  bottom: 166px;
  z-index: 24;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--vp-c-divider);
  background: var(--vp-c-bg);
  color: var(--vp-c-text-3);
  cursor: pointer;
  box-shadow: var(--shadow-3);
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    color        0.18s var(--ease-out),
    border-color 0.18s var(--ease-out),
    background   0.18s var(--ease-out),
    transform    0.18s var(--ease-out);
}
.reader-prefs-btn:hover {
  transform: scale(1.05);
  color: var(--vp-c-brand-1);
  border-color: color-mix(in oklab, var(--vp-c-brand-1) 45%, transparent);
}
.reader-prefs-btn .rp-aa {
  font-family: 'Georgia', 'Times New Roman', serif;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.02em;
  line-height: 1;
}
.reader-prefs-btn .rp-aa::first-letter {
  font-size: 18px;
}
.reader-prefs-btn.is-open {
  background: linear-gradient(135deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  color: #fff;
  border-color: transparent;
  box-shadow: 0 6px 18px color-mix(in oklab, var(--vp-c-brand-1) 40%, transparent);
}
.reader-prefs-panel {
  position: fixed;
  right: 72px;
  bottom: 148px;
  z-index: 25;
  width: 240px;
  padding: 14px;
  background: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  border-radius: 12px;
  /* Reader-preferences popover panel — tier 4. */
  box-shadow: var(--shadow-4);
  opacity: 0;
  transform: translateY(6px) scale(0.98);
  pointer-events: none;
  transition: opacity 0.18s var(--ease-out), transform 0.18s var(--ease-out);
}
html.dark .reader-prefs-panel {
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5),
              0 0 0 1px rgba(148, 163, 184, 0.08);
}
.reader-prefs-panel.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
.reader-prefs-panel .rp-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.reader-prefs-panel .rp-label {
  flex-shrink: 0;
  width: 32px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--vp-c-text-2);
  letter-spacing: 0.02em;
}
.reader-prefs-panel .rp-seg {
  flex: 1;
  display: flex;
  gap: 2px;
  padding: 2px;
  background: var(--vp-c-bg-soft);
  border-radius: 7px;
}
.reader-prefs-panel .rp-seg button {
  flex: 1;
  padding: 5px 2px;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: var(--vp-c-text-2);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s var(--ease-out), color 0.15s var(--ease-out);
}
.reader-prefs-panel .rp-seg button:hover {
  color: var(--vp-c-text-1);
}
.reader-prefs-panel .rp-seg button.on {
  background: var(--vp-c-bg);
  color: var(--vp-c-brand-1);
  /* tier-1 hairline — the selected segment lifts a hair above
     its unselected siblings to read as "picked". */
  box-shadow: var(--shadow-1);
  font-weight: 600;
}
.reader-prefs-panel .rp-reset {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 6px 8px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 6px;
  background: transparent;
  color: var(--vp-c-text-3);
  font-size: 12px;
  cursor: pointer;
  transition:
    color        0.15s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.15s cubic-bezier(0.2, 0, 0, 1);
}
.reader-prefs-panel .rp-reset:hover {
  color: var(--vp-c-text-1);
  border-color: var(--vp-c-text-3);
}
/* Apply the preferences to the chapter prose. Font-scale and
   line-height are pushed through CSS vars; wide mode widens
   the content container on large screens. */
.book-page .vp-doc p,
.book-page .vp-doc li {
  font-size: calc(16px * var(--jt-reader-font-scale, 1));
  line-height: var(--jt-reader-line-h, 1.85);
}
.book-page .vp-doc h2 {
  font-size: calc(1.65em * var(--jt-reader-font-scale, 1));
}
.book-page .vp-doc h3 {
  font-size: calc(1.35em * var(--jt-reader-font-scale, 1));
}
@media (min-width: 1200px) {
  html.jt-reader-wide .VPDoc .content-container {
    max-width: 960px !important;
  }
  html.jt-reader-wide .VPDoc.has-aside .content-container {
    max-width: 900px !important;
  }
}
@media (max-width: 640px) {
  .reader-prefs-btn { display: none; }
  .reader-prefs-panel { display: none; }
}
html.reading-focus .reader-prefs-btn,
html.reading-focus .reader-prefs-panel { display: none; }
/* Hide the two floating right-edge FABs (eye = focus mode,
   Aa = reader prefs panel). The in-nav + top-of-chapter controls
   already cover these without the extra visual noise. */
.focus-mode-btn,
.reader-prefs-btn,
.reader-prefs-panel {
  display: none !important;
}
/* ============================================================
   Dark-mode chapter-page skin. Deep black + acid-lime accent
   (#c4f857). Applies whenever the reader toggles dark mode on
   a chapter page — no variant-switcher involved.
   ============================================================ */
:root {
  --jt-accent: #c4f857;
  --jt-accent-soft: rgba(196, 248, 87, 0.14);
  --jt-accent-soft-hover: rgba(196, 248, 87, 0.22);
  --jt-accent-dim: rgba(196, 248, 87, 0.55);
}
html.dark.book-page {
  --vp-c-bg: #0a0b0f;
  --vp-c-bg-alt: #0c0d13;
  --vp-c-bg-soft: #141722;
  --vp-c-bg-elv: #0e1016;
  --vp-c-divider: #1f2430;
  --vp-c-border: #1f2430;
  --vp-c-gutter: #1f2430;
  --vp-c-text-1: #ecedf0;
  --vp-c-text-2: #a4a9b7;
  --vp-c-text-3: #6b7080;
}
/* Lime-accent inline code — softened. Full-saturation lime text
   on every inline `code` span was overpowering; switch to
   near-white text with a subtle lime border + very faint lime
   tint so the color still reads as the signature accent but
   doesn't fight the prose for attention. */
html.dark.book-page .book-page .vp-doc :not(pre) > code,
html.dark .book-page .vp-doc :not(pre) > code {
  background: rgba(196, 248, 87, 0.06);
  color: #e0f5b3;
  border: 1px solid rgba(196, 248, 87, 0.15);
}
/* Sidebar chapters rendered as pill-cards on a deeper surface.
   Active item gets the translucent acid-lime fill + 1px lime
   border that the mockup calls out. */
html.dark.book-page .VPSidebar {
  background: var(--vp-c-bg-alt) !important;
  border-right-color: var(--vp-c-divider);
}
html.dark.book-page .VPSidebarItem .link {
  border-radius: 6px;
  padding: 7px 10px !important;
  margin: 2px 8px 2px 8px;
  transition: background 0.15s var(--ease-out), color 0.15s var(--ease-out);
}
html.dark.book-page .VPSidebarItem .link:hover {
  background: var(--vp-c-bg-soft);
}
/* Active chapter — tone down: darker card surface + a thin lime
   left-stripe and lime text, instead of a full acid-lime fill.
   The big fluorescent block was the #1 complaint. */
html.dark.book-page .VPSidebarItem.is-active > .item .link,
html.dark.book-page .VPSidebarItem.is-active > .link {
  background: rgba(196, 248, 87, 0.05) !important;
  color: var(--jt-accent) !important;
  box-shadow: inset 2px 0 0 var(--jt-accent);
}
html.dark.book-page .VPSidebarItem.is-active > .item .link .text,
html.dark.book-page .VPSidebarItem.is-active > .link .text {
  color: var(--jt-accent) !important;
  font-weight: 600;
}
html.dark.book-page .VPSidebarItem.level-0 > .item > h2,
html.dark.book-page .VPSidebarItem.level-0 > .item > .section-header {
  color: var(--vp-c-text-3) !important;
  font-size: 10.5px !important;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
html.dark.book-page .VPSidebarItem .sb-progress-fill {
  background: linear-gradient(90deg, var(--jt-accent), #a5e043) !important;
}
/* Hero-class chapter title. The mockup puts the h1 at 52px /
   800-weight so the top of a chapter reads like a book spread.
   We cap the line-height tight and the letter-spacing negative
   for the modern editorial feel. */
html.dark.book-page .book-page .vp-doc h1 {
  font-size: clamp(32px, 4.2vw, 52px);
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.08;
  color: var(--vp-c-text-1);
  margin: 0.3em 0 0.5em;
}
html.dark.book-page .book-page .vp-doc h2 {
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--vp-c-text-1);
}
/* Chapter cover label re-skinned to the lime accent. */
html.dark.book-page .chapter-cover-label {
  color: var(--jt-accent) !important;
}
html.dark.book-page .chapter-cover-label .ccl-en {
  color: var(--jt-accent) !important;
  font-weight: 600;
}
html.dark.book-page .chapter-cover-label .ccl-zh {
  color: var(--vp-c-text-2) !important;
}
/* Code block "window chrome" — three traffic-light circles in
   the top-left of each block header, matching the mockup's
   IDE-window affordance. Pure pseudo-elements so it costs zero
   DOM. Non-negotiable: the dots sit *inside* the language badge
   area, don't overlap the copy button or the fullscreen button. */
html.dark.book-page .book-page .vp-doc div[class*='language-'] {
  background: var(--vp-c-bg-alt) !important;
  border: 1px solid var(--vp-c-divider);
  border-radius: 10px;
}
html.dark.book-page .book-page .vp-doc div[class*='language-']::after {
  content: '';
  position: absolute;
  top: 12px;
  left: 14px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #5d6478;
  box-shadow:
    18px 0 0 #5d6478,
    36px 0 0 #5d6478;
  opacity: 0.55;
  pointer-events: none;
  z-index: 2;
}
html.dark.book-page .book-page .vp-doc div[class*='language-'] pre {
  padding-top: 36px !important;
  background: transparent !important;
}
html.dark.book-page .book-page .vp-doc div[class*='language-'].has-file-label::after {
  top: 50px;
}
html.dark.book-page .book-page .vp-doc .code-lang-badge {
  right: 14px !important;
  color: var(--vp-c-text-3);
  background: transparent;
  border: 1px solid var(--vp-c-divider);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 10.5px;
  letter-spacing: 0.08em;
}
html.dark.book-page .book-page .vp-doc .code-file-label {
  background: var(--vp-c-bg-elv);
  border-bottom: 1px solid var(--vp-c-divider);
  color: var(--vp-c-text-2);
  padding-left: 70px;
  padding-right: 14px;
}
/* :::tip callout becomes the accent callout — the mockup's
   "highlighted paragraph with lime strip" is literally the
   native tip container, just re-colored. */
html.dark.book-page .book-page .vp-doc .custom-block.tip {
  background: var(--jt-accent-soft) !important;
  border-color: rgba(196, 248, 87, 0.25) !important;
  border-left-color: var(--jt-accent) !important;
  color: var(--vp-c-text-1) !important;
}
html.dark.book-page .book-page .vp-doc .custom-block.tip .custom-block-title {
  color: var(--jt-accent) !important;
}
html.dark.book-page .book-page .vp-doc .custom-block.tip a {
  color: var(--jt-accent) !important;
  text-decoration-color: rgba(196, 248, 87, 0.4);
}
/* Right outline — bolder current-section indicator, numbered
   feel from the mockup. The past-dot / current-dot machinery
   already lives in useReadingEnhancers; we just re-skin the
   active highlight to the lime accent. */
html.dark.book-page .book-page .VPDocAsideOutline {
  background: transparent !important;
  border-color: var(--vp-c-divider) !important;
}
/* Dark-mode active outline: acid-lime left bar; text stays
   off-white (handled by the base rule). The progress-dot
   selectors (data-jt-past / data-jt-current) are no-ops now
   that the dots are removed — leaving the rules would just
   hang on stale attributes nothing paints. */
/* Top progress bar switches to the lime gradient. */
html.dark.book-page .jt-top-progress-fill {
  background: linear-gradient(90deg, var(--jt-accent), #a5e043 55%, #87b82e) !important;
  box-shadow: 0 0 10px rgba(196, 248, 87, 0.55) !important;
}
/* "本章导读" intro box takes the accent left-stripe. */
html.dark.book-page .book-page .vp-doc .chapter-intro-box {
  background: linear-gradient(135deg,
              rgba(196, 248, 87, 0.04),
              var(--vp-c-bg-alt)) !important;
  border-color: var(--vp-c-divider) !important;
  border-left: 2px solid var(--jt-accent) !important;
}
html.dark.book-page .book-page .vp-doc .chapter-intro-box .cib-title svg,
html.dark.book-page .book-page .vp-doc .chapter-intro-box .cib-list .cib-num {
  color: var(--jt-accent) !important;
}
html.dark.book-page .book-page .vp-doc .chapter-intro-box .cib-list a:hover {
  color: var(--jt-accent) !important;
  background: var(--vp-c-bg-soft) !important;
}
/* Body link color — the brand-blue default is jarring next to
   the lime. Swap both hover and focus states to the accent. */
html.dark.book-page .book-page .vp-doc a:not(.VPButton):hover {
  color: var(--jt-accent);
  text-decoration-color: var(--jt-accent);
}
/* ArticleHeader stats row — the sync pill + my-visits pill
   re-colored to match the new palette. */
html.dark.book-page .ah-sync.is-cloud {
  background: var(--jt-accent-soft) !important;
  color: var(--jt-accent) !important;
}
html.dark.book-page .ah-my-visits {
  color: var(--jt-accent) !important;
}
/* Back-to-top FAB progress ring in acid lime. */
html.dark.book-page .back-to-top-fab .btt-fill {
  stroke: var(--jt-accent) !important;
}
/* Selection color on prose. Small detail but it's the one
   constant visual touch readers produce themselves, and a
   lime-tinted selection makes the whole page feel intentional. */
html.dark.book-page .book-page .vp-doc ::selection {
  background: rgba(196, 248, 87, 0.28);
  color: #ecedf0;
}
/* V1 "Terminal Codex" sidebar: chapter serial numbers as a
   mono-face prefix before every chapter title, matching the
   mockup's ordinal-first layout. Shows up in both themes;
   styled restraint in light, slightly bolder in dark. */
.VPSidebarItem .text .sb-num {
  display: inline-block;
  min-width: 26px;
  margin-right: 6px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--vp-c-text-3);
  vertical-align: baseline;
}
html.dark.book-page .VPSidebarItem .text .sb-num {
  color: #5d6478;
}
html.dark.book-page .VPSidebarItem.is-active > .item .link .text .sb-num,
html.dark.book-page .VPSidebarItem.is-active > .link .text .sb-num {
  color: var(--jt-accent);
}
/* Done chapters (sb-read-mark present) — strike the number too
   so the "completed" pattern reads at a glance across the
   whole sidebar. */
/* Done chapters: keep the serial number normal-colored — no
   strike-through. Striking just the number while leaving the
   chapter title untouched looks inconsistent. The green dot
   marker (.sb-read-mark) by itself is enough signal. */
.VPSidebarItem .text:has(.sb-read-mark) .sb-num {
  color: var(--vp-c-text-3);
}
/* Book header card at the top of the sidebar. Shows the current
   book + aggregated completion progress. Replaces the need for
   the reader to mentally aggregate "which book, how far in" —
   the card does it for them every chapter open. */
.jt-sb-bookcard {
  padding: 14px 18px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--vp-c-divider);
}
.jt-sb-bookcard .sbbc-meta {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--vp-c-text-3);
  margin-bottom: 6px;
  /* Fixed-width digits so "第 1 章" → "第 12 章" on chapter nav
     doesn't nudge the surrounding layout. Also sharpens the
     dashboard feel. */
  font-variant-numeric: tabular-nums;
}
.jt-sb-bookcard .sbbc-title {
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--vp-c-text-1);
  margin-bottom: 10px;
  line-height: 1.35;
}
.jt-sb-bookcard .sbbc-prog {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10.5px;
  color: var(--vp-c-text-2);
  font-variant-numeric: tabular-nums;
}
.jt-sb-bookcard .sbbc-bar {
  flex: 1;
  height: 4px;
  background: var(--vp-c-divider);
  border-radius: 2px;
  overflow: hidden;
}
.jt-sb-bookcard .sbbc-bar i {
  display: block;
  height: 100%;
  /* Sidebar book-card progress bar (the small 4px bar showing
     reader completion across the whole book). Olive →
     deeper-olive so this and the per-chapter bars tell one
     consistent visual story. */
  background: linear-gradient(90deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
  transition: width 0.3s cubic-bezier(0.2, 0, 0, 1);
}
html.dark.book-page .jt-sb-bookcard {
  background: transparent;
  border-bottom-color: #1f2430;
}
html.dark.book-page .jt-sb-bookcard .sbbc-meta {
  color: #5d6478;
}
html.dark.book-page .jt-sb-bookcard .sbbc-bar {
  background: #1a1e2c;
}
html.dark.book-page .jt-sb-bookcard .sbbc-bar i {
  background: linear-gradient(90deg, var(--jt-accent), #9ad43e);
}
@media (max-width: 959px) {
  .jt-sb-bookcard {
    display: none;
  }
}
/* FloatingActions (heart / star / comment / share) — force the
   dark-mode surface globally. The component's own scoped styles
   keep losing specificity rounds against the near-white default
   .fa-btn { background: rgba(255,255,255,0.95); } rule, so we
   bolt it down here where nothing can outrank. */
html.dark .floating-actions .fa-btn,
html[data-theme='dark'] .floating-actions .fa-btn {
  background: rgba(18, 22, 32, 0.92) !important;
  border: 1px solid rgba(148, 163, 184, 0.12) !important;
  color: rgba(203, 213, 225, 0.8) !important;
  box-shadow:
    0 2px 10px rgba(0, 0, 0, 0.35),
    0 8px 28px rgba(0, 0, 0, 0.25) !important;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html.dark .floating-actions .fa-btn .fa-count,
html[data-theme='dark'] .floating-actions .fa-btn .fa-count {
  color: rgba(148, 163, 184, 0.8) !important;
}
html.dark .floating-actions .fa-btn:hover,
html[data-theme='dark'] .floating-actions .fa-btn:hover {
  background: rgba(28, 32, 44, 0.95) !important;
  border-color: rgba(148, 163, 184, 0.24) !important;
  color: #e2e8f0 !important;
  transform: translateY(-1px);
}
html.dark .floating-actions .fa-btn.active,
html[data-theme='dark'] .floating-actions .fa-btn.active {
  background: rgba(36, 40, 56, 0.95) !important;
  border-color: rgba(148, 163, 184, 0.28) !important;
  color: #f1f5f9 !important;
}
html.dark .floating-actions .fa-divider,
html[data-theme='dark'] .floating-actions .fa-divider {
  background: rgba(148, 163, 184, 0.1) !important;
}
/* ============================================================
   Chapter-page structural upgrade — mockup-inspired. One
   layout, applied directly to every chapter page (not gated by
   a variant). Highlights:
     - Content container widens to use available viewport
     - Right-rail stats + notes cards (see below)
     - Sidebar book card + chapter serial numbers (see earlier
       enhancer code)
   ============================================================ */
/* Widen chapter prose. Previous 760px cap made every chapter
   feel like a pamphlet floating inside a huge empty page; the
   mockup lets content + rail together consume the viewport. */
@media (min-width: 960px) {
  .book-page .VPDoc .content-container {
    max-width: 100% !important;
  }
  .book-page .VPDoc:not(.has-aside) .content-container {
    max-width: 900px !important;
  }
  .book-page .VPDoc.has-aside .content-container {
    max-width: 880px !important;
  }
}
@media (min-width: 1280px) {
  .book-page .VPDoc.has-aside .content-container {
    max-width: 960px !important;
  }
}
@media (min-width: 1440px) {
  .book-page .VPDoc.has-aside .content-container {
    max-width: 1080px !important;
  }
}
/* V3-only: 2×2 stats card injected above the right outline.
   Mockup puts this block at the top of the reading rail —
   at-a-glance "how far into the chapter am I, how long have I
   been reading, how many notes/code blocks are in play".
   Injected by useReadingEnhancers::ensureV3StatsCard. */
/* Chrome-light: no border, no bg. Rail cards compete with prose
   when framed; typography + whitespace carries the separation. */
.book-page .jt-v3-stats {
  display: block;
  margin: 0 0 20px;
  padding: 0 2px;
}
.book-page .jt-v3-stats .v3s-head {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--vp-c-text-1);
  margin: 0 0 10px;
}
.book-page .jt-v3-stats .v3s-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 14px;
}
.book-page .jt-v3-stats .v3s-cell {
  min-width: 0;
}
.book-page .jt-v3-stats .v3s-num {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--vp-c-text-1);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.book-page .jt-v3-stats .v3s-lbl {
  font-size: 11px;
  color: var(--vp-c-text-3);
  margin-top: 3px;
  letter-spacing: 0;
}
html.dark.book-page .jt-v3-stats .v3s-num {
  color: #e2e8f0;
}
/* Hide on narrow screens — VitePress stacks the right aside
   below the content on <960px and the card would just duplicate
   information the reader already sees in the sticky bar. */
@media (max-width: 959px) {
  .book-page .jt-v3-stats { display: none !important; }
}
/* Focus mode hides the rail anyway, but be explicit. */
html.reading-focus .jt-v3-stats { display: none !important; }
/* V3-only: notes preview card under the outline. Mirrors the
   mockup's "你的笔记" rail block — 3 most recent notes clipped
   to 2 lines, click an item or the "+ 新建笔记" footer to jump
   to the ArticleFooter composer. */
/* Chrome-light (same treatment as jt-v3-stats above): drop the
   card frame so the rail reads as a continuous sidebar column. */
.book-page .jt-v3-notes {
  display: block;
  margin: 20px 0 0;
  padding: 14px 2px 0;
  border-top: 1px solid var(--vp-c-divider);
}
.book-page .jt-v3-notes .v3n-head {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--vp-c-text-1);
  margin: 0 0 10px;
}
.book-page .jt-v3-notes .v3n-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.book-page .jt-v3-notes .v3n-item {
  padding: 9px 11px;
  border-radius: 8px;
  background: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  cursor: pointer;
  transition: border-color 0.15s var(--ease-out), transform 0.1s var(--ease-out);
}
.book-page .jt-v3-notes .v3n-item:hover {
  border-color: var(--vp-c-brand-1, #3b7e00);
  transform: translateY(-1px);
}
.book-page .jt-v3-notes .v3n-text {
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--vp-c-text-1);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-word;
}
.book-page .jt-v3-notes .v3n-meta {
  font-size: 10.5px;
  color: var(--vp-c-text-3);
  margin-top: 4px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.03em;
}
.book-page .jt-v3-notes .v3n-empty {
  font-size: 12px;
  color: var(--vp-c-text-3);
  line-height: 1.6;
  padding: 4px 2px;
}
.book-page .jt-v3-notes .v3n-add {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 8px 10px;
  border: 1px dashed var(--vp-c-divider);
  border-radius: 8px;
  background: transparent;
  color: var(--vp-c-text-2);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition:
    color        0.15s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.15s cubic-bezier(0.2, 0, 0, 1),
    border-style 0.15s cubic-bezier(0.2, 0, 0, 1);
}
.book-page .jt-v3-notes .v3n-add:hover {
  color: var(--vp-c-brand-1, #3b7e00);
  border-color: var(--vp-c-brand-1, #3b7e00);
  border-style: solid;
}
html.dark.book-page .jt-v3-notes {
  border-top-color: rgba(148, 163, 184, 0.15);
}
html.dark.book-page .jt-v3-notes .v3n-item {
  background: rgba(14, 16, 22, 0.6);
  border-color: rgba(148, 163, 184, 0.12);
}
html.dark.book-page .jt-v3-notes .v3n-text { color: #e2e8f0; }
@media (max-width: 959px) {
  .book-page .jt-v3-notes { display: none !important; }
}
html.reading-focus .jt-v3-notes { display: none !important; }
/* ============================================================
   Sidebar + rail comfort polish (mockup V3 match)

   Mockup shows more generous sizing + clearer hierarchy than
   VitePress default:
     · Book card: 紫色 "· 阅读中" pill (was mono "// currently
       reading") + bigger bold book name + bold progress number
     · Chapter items: larger font (14.5px), more padding, done
       chapters get a small green dot at right (not the ✓ tick)
     · Current chapter: a rounded pill with a soft bg-soft fill
       + bold black text, not just a lime stripe
     · Right-rail stats: 2×2 bigger numbers, more padding
     · Right-rail notes: sticky-note style with warm cream bg
   ============================================================ */
/* --- Book card — matches mockup V3 v3-book-card ---
   Structure (from mockup HTML):
     span .sbbc-badge  "· 阅读中"          -- purple pill
     div .sbbc-title   "MCP 协议设计与实现"
     div .sbbc-meta    "21 章 · 第 4 章"  <b>21%</b>
     div .sbbc-bar     inner i (fill)
*/
.book-page .jt-sb-bookcard {
  padding: 16px 18px 18px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 14px;
  background: var(--vp-c-bg);
  margin: 16px 12px 16px;
}
.book-page .jt-sb-bookcard .sbbc-badge {
  display: inline-block;
  padding: 3px 10px;
  margin-bottom: 10px;
  border-radius: 999px;
  /* Neutral ink-on-bg-soft. The purple pill jumped out of the
     calm reading palette; a muted text-on-soft treatment reads
     as "state indicator" not "marketing pill". */
  background: var(--vp-c-bg-soft);
  color: var(--vp-c-text-2);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: none;
}
.book-page .jt-sb-bookcard .sbbc-title {
  font-size: 16px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--vp-c-text-1);
  margin-bottom: 14px;
}
.book-page .jt-sb-bookcard .sbbc-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: 11.5px;
  color: var(--vp-c-text-3);
  margin-bottom: 8px;
}
.book-page .jt-sb-bookcard .sbbc-meta b {
  color: var(--vp-c-text-1);
  font-size: 14px;
  font-weight: 700;
}
.book-page .jt-sb-bookcard .sbbc-bar {
  height: 3px;
  background: var(--vp-c-divider);
  border-radius: 2px;
  overflow: hidden;
}
.book-page .jt-sb-bookcard .sbbc-bar i {
  display: block;
  height: 100%;
  background: #0a0b0f;
  transition: width 0.3s var(--ease-out);
}
html.dark .book-page .jt-sb-bookcard {
  background: rgba(30, 35, 50, 0.45);
}
html.dark .book-page .jt-sb-bookcard .sbbc-badge {
  background: rgba(139, 92, 246, 0.22);
  color: #c4b5fd;
}
html.dark .book-page .jt-sb-bookcard .sbbc-bar i {
  background: var(--jt-accent);
}
/* --- Chapter items in sidebar ---
   Slightly bigger font + more padding so chapters feel like
   tap targets, not dense lines. */
.book-page .VPSidebarItem .link {
  font-size: 14px;
  padding: 8px 12px !important;
}
.book-page .VPSidebarItem .text .sb-num {
  font-size: 11.5px;
  min-width: 22px;
  margin-right: 6px;
  color: var(--vp-c-text-3);
}
/* Current chapter — bold text, no pill. The right-side status
   dot (.sb-st) in filled black is enough "you are here" signal.
   Override VitePress's default brand-blue hover color. */
.book-page .VPSidebarItem.is-active > .item .link,
.book-page .VPSidebarItem.is-active > .link {
  background: transparent !important;
  color: var(--vp-c-text-1) !important;
  font-weight: 600 !important;
}
.book-page .VPSidebarItem.is-active > .item .link .text,
.book-page .VPSidebarItem.is-active > .link .text {
  color: var(--vp-c-text-1) !important;
}
/* Status dot on every chapter item — three states matching
   mockup's .v3-item.done / .v3-item.active / .v3-item (unread):
     default  : 6px outline-only gray circle (unread)
     done     : 6px filled green
     active   : 7px filled black (bigger for self-location)
*/
.book-page .VPSidebarItem .text .sb-st {
  display: inline-block;
  margin-left: auto;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 1.5px solid var(--vp-c-text-3);
  opacity: 0.45;
  flex-shrink: 0;
  transition:
    background   0.18s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    opacity      0.18s cubic-bezier(0.2, 0, 0, 1),
    width        0.18s cubic-bezier(0.2, 0, 0, 1),
    height       0.18s cubic-bezier(0.2, 0, 0, 1);
}
/* Done — filled green. Presence of .sb-read-mark sibling is the
   marker we use to detect "read" state. */
.book-page .VPSidebarItem .text:has(.sb-read-mark) .sb-st {
  background: #10b981;
  border-color: #10b981;
  opacity: 1;
}
.book-page .VPSidebarItem.is-active .text .sb-st {
  width: 7px;
  height: 7px;
  background: var(--vp-c-text-1);
  border-color: var(--vp-c-text-1);
  opacity: 1;
}
html.dark.book-page .VPSidebarItem.is-active .text .sb-st {
  background: var(--jt-accent);
  border-color: var(--jt-accent);
}
html.dark.book-page .VPSidebarItem .text:has(.sb-read-mark) .sb-st {
  background: #34d399;
  border-color: #34d399;
}
/* Since we now render .sb-st on every chapter, hide the older
   .sb-read-mark marker to avoid double dots. The class is still
   used as a "is-read" detector for the :has selector above. */
.book-page .VPSidebarItem .text .sb-read-mark {
  display: none !important;
}
/* The .text container needs to be flex so .sb-st's margin-left:
   auto actually pushes it to the right. It's a <p> in VitePress's
   markup and inherits the default 16px top/bottom margin which
   inflates every chapter item to ~55px tall — strip that. */
.book-page .VPSidebarItem .text {
  display: flex;
  align-items: center;
  min-width: 0;
  width: 100%;
  flex: 1 1 auto;
  margin: 0 !important;
  padding: 0 !important;
  line-height: 1.3 !important;
}
/* Title segment between .sb-num and .sb-st. Without this wrapping
   element the title is a raw text node that can't be ellipsized,
   so a long chapter name (e.g., "为什么在 2026 年重新理解 React")
   breaks the active item into 3 lines. .sb-title is injected by
   enhanceSidebarChapterNumbers and shrinks to fit with ellipsis. */
.book-page .VPSidebarItem .text .sb-title {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.3;
}
.book-page .VPSidebarItem .text .sb-st {
  margin-left: auto !important;
}
/* `.jt-sb-book-dup` kept as a legacy safety net — the sidebar config
   no longer names the first group after the book title (it's now a
   generic "入门" category), so this class should never be tagged. But
   if someone re-introduces a duplicate wrapper group, we still hide it. */
.book-page .VPSidebar .VPSidebarItem.level-0.jt-sb-book-dup > .item {
  display: none !important;
}
.book-page .VPSidebar .VPSidebarItem.level-0.jt-sb-book-dup {
  margin-top: 0 !important;
  padding-top: 0 !important;
}
/* Group header caret: hide VitePress's chunky SVG chevron and draw a
   delicate unicode ▾ via ::before so it reads like the mockup's
   small triangle that flips to ▸ when collapsed. */
.book-page .VPSidebar .VPSidebarItem.level-0 > .item {
  display: flex;
  align-items: center;
  cursor: pointer;
  position: relative;
}
.book-page .VPSidebar .VPSidebarItem.level-0 > .item .caret {
  order: -1;
  margin-right: 7px;
  padding: 0;
  width: 18px;
  height: 18px;
  background: transparent;
  flex-shrink: 0;
  position: relative;
}
.book-page .VPSidebar .VPSidebarItem.level-0 > .item .caret-icon {
  display: none !important;
}
/* Single ▸ glyph that rotates 90° when the group is expanded — same
   trick the mockup uses (.v3-grp-h.open .car { transform: rotate(90deg) }).
   Smooth rotation instead of swapping glyphs. */
.book-page .VPSidebar .VPSidebarItem.level-0 > .item .caret::before {
  content: '▸';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  line-height: 1;
  color: #a3a3a3;
  transform: rotate(90deg);
  transition:
    transform 0.2s cubic-bezier(0.2, 0, 0, 1),
    color     0.18s cubic-bezier(0.2, 0, 0, 1);
}
.book-page .VPSidebar .VPSidebarItem.level-0.collapsed > .item .caret::before {
  transform: rotate(0deg);
}
.book-page .VPSidebar .VPSidebarItem.level-0 > .item:hover .caret::before {
  color: var(--vp-c-text-1);
}
html.dark.book-page .VPSidebar .VPSidebarItem.level-0 > .item .caret::before {
  color: #737373;
}
.book-page .VPSidebarItem.is-active > .item .link .text .sb-num,
.book-page .VPSidebarItem.is-active > .link .text .sb-num {
  color: var(--vp-c-text-1) !important;
  font-weight: 600;
}
html.dark.book-page .VPSidebarItem.is-active > .item .link,
html.dark.book-page .VPSidebarItem.is-active > .link {
  background: transparent !important;
  box-shadow: none !important;
}
/* ============================================================
   V3 mockup rhythm — tighten vertical spacing + switch active
   item from gradient-stripe outline to a soft filled pill.
   The screenshot showed ~50px between rows; mockup wants ~36px.
   ============================================================ */
/* Sidebar: tight horizontal padding so items span the whole width
   (mockup shows active pill reaching edge-to-edge of the side panel). */
.book-page .VPSidebar {
  padding-left: 10px !important;
  padding-right: 10px !important;
}
.book-page .VPSidebarGroup,
.book-page .VPSidebar .group {
  padding-left: 0 !important;
  padding-right: 0 !important;
}
/* Items: zero level-1 padding, keep one rounded hit-area */
.book-page .VPSidebar .VPSidebarItem.level-1 {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}
.book-page .VPSidebar .VPSidebarItem.level-1 > .item {
  margin: 1px 0 !important;
  padding: 0 !important;
  border-radius: 10px;
  background: transparent !important;
  box-shadow: none !important;
}
.book-page .VPSidebar .VPSidebarItem.level-1 > .item::before {
  display: none !important;
}
.book-page .VPSidebar .VPSidebarItem.level-1 > .item .link {
  padding: 4px 10px !important;
  border-radius: 10px;
  line-height: 1.3 !important;
  min-height: 0 !important;
  height: auto !important;
  width: 100%;
  display: flex;
  align-items: center;
  font-size: 13.5px !important;
}
.book-page .VPSidebar .VPSidebarItem.level-1 > .item:hover {
  background: var(--vp-c-bg-soft) !important;
}
/* Active item: soft filled pill, no outline/stripe */
.book-page .VPSidebar .VPSidebarItem.is-active.level-1 > .item {
  background: var(--vp-c-bg-soft) !important;
  box-shadow: none !important;
  border-radius: 10px !important;
}
.book-page .VPSidebar .VPSidebarItem.is-active.level-1 > .item::before {
  display: none !important;
}
html.dark.book-page .VPSidebar .VPSidebarItem.is-active.level-1 > .item {
  background: rgba(196, 248, 87, 0.08) !important;
  box-shadow: none !important;
}
/* Group header rhythm: tighter top margin, tighter padding */
.book-page .VPSidebar .VPSidebarItem.level-0:not(.jt-sb-book-dup) {
  margin-top: 14px !important;
  padding-bottom: 2px !important;
}
.book-page .VPSidebar .VPSidebarItem.level-0:not(.jt-sb-book-dup) > .item {
  padding: 4px 14px !important;
}
.book-page .VPSidebar .VPSidebarItem.level-0:not(.jt-sb-book-dup) > .item .text,
.book-page .VPSidebar .VPSidebarItem.level-0:not(.jt-sb-book-dup) > .item .title {
  font-size: 12px !important;
  font-weight: 600 !important;
  color: var(--vp-c-text-2) !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
}
/* Group child container: no extra top padding */
.book-page .VPSidebar .VPSidebarItem.level-0 > .items {
  padding-top: 2px !important;
}
/* Group spacing without dividers — the caret + group-header font
   weight is enough to separate sections visually, matching the
   mockup which has no divider lines between categories. */
.book-page .VPSidebar .group + .group {
  border-top: none !important;
  margin-top: 8px !important;
  padding-top: 0 !important;
}
.book-page .VPSidebar .group + .group::before {
  display: none !important;
}
/* Done-chapter marker — small green dot instead of a ✓ tick.
   Cleaner, matches mockup's pattern of tiny right-side dots. */
.book-page .VPSidebarItem .text .sb-read-mark {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #10b981;
  color: transparent;
  margin-left: auto;
  padding: 0;
  flex-shrink: 0;
}
.book-page .VPSidebarItem .text .sb-read-mark svg {
  display: none;
}
html.dark.book-page .VPSidebarItem .text .sb-read-mark {
  background: #34d399;
}
/* --- Right-rail stats card: more comfortable sizing ---
   Numbers were 22px, bump to 26px; add extra padding + gap. */
.book-page .jt-v3-stats {
  padding: 14px 2px 0;
}
.book-page .jt-v3-stats .v3s-head {
  margin-bottom: 10px;
  font-size: 11px;
  text-transform: none;
  letter-spacing: 0.02em;
  font-weight: 600;
  color: var(--vp-c-text-2);
}
/* 4 metrics on one row, compact typography. Was 2×2 with
   26px numbers — in the narrower, chrome-less rail that felt
   oversized and "dashboardy". */
.book-page .jt-v3-stats .v3s-grid {
  grid-template-columns: repeat(4, 1fr);
  gap: 0 10px;
}
.book-page .jt-v3-stats .v3s-num {
  font-size: 15px;
  letter-spacing: -0.01em;
}
.book-page .jt-v3-stats .v3s-lbl {
  margin-top: 2px;
  font-size: 10.5px;
}
/* --- Right-rail notes: sticky-note warm cream style ---
   Mockup makes each note item a warm cream rectangle with the
   content in serif-neutral gray, reading like an actual sticky
   note more than a line of UI text. */
.book-page .jt-v3-notes .v3n-item {
  background: #fffbeb !important;
  border-color: rgba(245, 201, 93, 0.35) !important;
  padding: 12px 14px;
  border-radius: 10px;
}
.book-page .jt-v3-notes .v3n-item:hover {
  border-color: rgba(245, 158, 11, 0.6) !important;
  background: #fef6d8 !important;
}
.book-page .jt-v3-notes .v3n-text {
  font-size: 13.5px;
  line-height: 1.65;
  color: #3a2d10;
  -webkit-line-clamp: 4;
}
.book-page .jt-v3-notes .v3n-meta {
  font-size: 11px;
  color: #8b6914;
  margin-top: 6px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
html.dark.book-page .jt-v3-notes .v3n-item {
  background: rgba(120, 100, 40, 0.2) !important;
  border-color: rgba(245, 201, 93, 0.25) !important;
}
html.dark.book-page .jt-v3-notes .v3n-text {
  color: #e8dba6;
}
html.dark.book-page .jt-v3-notes .v3n-meta {
  color: rgba(245, 201, 93, 0.75);
}
/* ============================================================
   Edge-to-edge chapter layout — carefully.

   Goal from mockup screenshots:
     1. Top nav stretches full viewport width (no 1440px cap)
     2. Sidebar flush to browser left edge (no centered-column
        offset on wide screens)

   Previous attempt (accde89) also tried to push content to
   start right after sidebar — that caused overlap. This time:
   leave .VPContent.has-sidebar's padding logic untouched;
   VitePress's own calc already positions content correctly
   relative to the sidebar in every breakpoint. Only touch the
   two specific things the user called out.
   ============================================================ */
/* 1. Top nav: strip the 1440px max-width cap on the inner
      container. Title keeps its left padding; content body
      keeps its normal right padding. Safe because we don't
      touch any width/position of the content area below. */
@media (min-width: 1440px) {
  .book-page .VPNavBar .container {
    max-width: 100% !important;
  }
  .book-page .VPNavBar.has-sidebar .content {
    padding-right: 32px !important;
    padding-left: var(--vp-sidebar-width, 272px) !important;
  }
  .book-page .VPNavBar .title {
    padding-left: 22px !important;
    width: var(--vp-sidebar-width, 272px) !important;
  }
}
/* 2. Sidebar flush to viewport left on wide screens.
      VitePress's upstream rule adds big padding-left on the
      sidebar (max(32px, (100% - 1376) / 2)) to align its
      visible content with the centered column. We zero that
      out and cap the sidebar's width to the actual 272px, so
      the sidebar sits at x=0..272 with a normal inner 22px
      gutter. Content below still uses VitePress's native
      has-sidebar padding logic, which accounts for this. */
@media (min-width: 1440px) {
  .book-page .VPSidebar {
    padding-left: 22px !important;
    width: var(--vp-sidebar-width, 272px) !important;
  }
}
/* 3. Right outline / aside flush to viewport right on wide
      screens. Upstream .aside-container has position:fixed but
      no left/right offsets, so it sits wherever the centered
      1440-column flex layout puts it — on a 2560 viewport that
      leaves ~600px of empty gutter to its right. Pin it to the
      right edge with a 32px gutter instead. */
@media (min-width: 1440px) {
  .book-page .VPDoc .aside-container {
    right: 32px !important;
    left: auto !important;
  }
}
/* ============================================================
   V3 "Docs Modern" reader polish — appended last so these rules
   win over the legacy brand-blue palette above. The tokens
   (--reader-*) come from the top-of-file dual-theme block and
   flip with .dark automatically.
   ============================================================ */
/* ---- Reading progress bar ---- */
.reading-progress {
  top: 0 !important;
  height: 2px !important;
  background: var(--reader-prog-bar) !important;
  box-shadow: none !important;
  z-index: 30 !important;
}
/* ---- Book-page surfaces ---- */
.book-page {
  background: var(--reader-surface-alt);
  color: var(--reader-ink);
}
.book-page .VPContent { background: var(--reader-surface-alt); }
/* ---- Sidebar: V3 book-card + grouped chapters ---- */
@media (min-width: 960px) {
  .book-page .VPSidebar {
    background: var(--reader-surface-alt) !important;
    border-right: 1px solid var(--reader-border) !important;
    box-shadow: none !important;
    padding-top: 20px !important;
  }
}
.book-page .VPSidebar .group {
  padding: 0 4px;
  margin-bottom: 6px;
}
.book-page .VPSidebar .VPSidebarItem.level-0 > .item {
  padding: 8px 10px !important;
}
.book-page .VPSidebar .VPSidebarItem.level-0 > .item > .text {
  font-family: var(--reader-sans);
  font-size: 12.5px !important;
  font-weight: 600 !important;
  color: var(--reader-muted) !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  padding: 0 !important;
}
.book-page .VPSidebar .VPSidebarItem.level-0 > .item .caret {
  color: var(--reader-muted-2) !important;
}
.book-page .VPSidebar .VPSidebarItem.level-1 > .item {
  margin: 1px 4px !important;
  padding: 6px 10px 6px 22px !important;
  border-radius: 6px;
}
.book-page .VPSidebar .VPSidebarItem.level-1 > .item .text {
  font-size: 13px !important;
  color: var(--reader-muted) !important;
  font-weight: 400 !important;
}
.book-page .VPSidebar .VPSidebarItem.level-1 > .item:hover {
  background: var(--reader-surface) !important;
}
.book-page .VPSidebar .VPSidebarItem.level-1 > .item:hover .text {
  color: var(--reader-ink) !important;
}
.book-page .VPSidebar .VPSidebarItem.is-active.level-1 > .item {
  background: var(--reader-surface) !important;
  box-shadow: inset 0 0 0 1px var(--reader-border), 0 1px 2px rgba(0, 0, 0, 0.04) !important;
}
.book-page .VPSidebar .VPSidebarItem.is-active.level-1 > .item::before {
  display: none !important;
}
.book-page .VPSidebar .VPSidebarItem.is-active.level-1 > .item .text {
  color: var(--reader-ink) !important;
  font-weight: 500 !important;
}
/* ---- Right rail outline (VPDocAsideOutline) ---- */
.book-page .VPDocAside .outline-title,
.book-page .VPDocAside .VPDocAsideOutline .outline-title {
  font-family: var(--reader-sans) !important;
  font-size: 11.5px !important;
  font-weight: 600 !important;
  color: var(--reader-muted-2) !important;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 12px;
}
.book-page .VPDocAsideOutline .outline-link {
  font-size: 12.5px !important;
  line-height: 1.5 !important;
  color: var(--reader-muted) !important;
  padding: 4px 0 4px 12px !important;
  border-left: 2px solid var(--reader-border);
  transition: color .15s, border-color .15s;
}
.book-page .VPDocAsideOutline .outline-link.active {
  color: var(--reader-ink) !important;
  font-weight: 500 !important;
  border-left-color: var(--reader-ink);
}
.book-page .VPDocAsideOutline .outline-link:hover { color: var(--reader-ink) !important; }
.book-page .VPDocAsideOutline .outline-marker {
  display: none !important;
}
/* ---- Article content: V3 H1/h2/h3 spec ---- */
.book-page .vp-doc h1 {
  font-size: 40px !important;
  line-height: 1.15 !important;
  letter-spacing: -0.03em !important;
  font-weight: 700 !important;
  color: var(--reader-ink) !important;
  margin: 0 0 14px !important;
}
.book-page .vp-doc h2 {
  font-size: 26px !important;
  font-weight: 700 !important;
  letter-spacing: -0.02em !important;
  margin: 56px 0 16px !important;
  color: var(--reader-ink) !important;
  padding-top: 0 !important;
}
.book-page .vp-doc h2::before,
.book-page .vp-doc h2::after { display: none !important; }
.book-page .vp-doc h3 {
  font-size: 18.5px !important;
  font-weight: 600 !important;
  margin: 36px 0 12px !important;
  letter-spacing: -0.01em !important;
  color: var(--reader-ink) !important;
}
.book-page .vp-doc h3::before { display: none !important; }
.book-page .vp-doc p {
  font-size: 15.5px !important;
  line-height: 1.75 !important;
  color: var(--reader-ink) !important;
  opacity: .95;
  margin: 0 0 20px !important;
}
.book-page .vp-doc p strong {
  color: var(--reader-ink) !important;
  font-weight: 600 !important;
}
.book-page .vp-doc ul,
.book-page .vp-doc ol {
  padding-left: 22px !important;
  margin: 0 0 22px !important;
}
.book-page .vp-doc li {
  font-size: 15.5px !important;
  line-height: 1.7 !important;
  color: var(--reader-ink) !important;
  opacity: .95;
  margin-bottom: 6px !important;
}
/* ---- Inline code: V3 purple ---- */
.book-page .vp-doc :not(pre) > code {
  font-family: var(--reader-mono) !important;
  font-size: .86em !important;
  background: var(--reader-accent-soft) !important;
  color: var(--reader-accent) !important;
  border: 1px solid var(--reader-tip-border) !important;
  padding: 1.5px 6px !important;
  border-radius: 4px !important;
  font-weight: 500 !important;
}
/* ---- Code block chrome (VP's <div class="language-xyz">) ---- */
.book-page .vp-doc div[class*='language-'] {
  border: 1px solid var(--reader-border) !important;
  border-radius: 10px !important;
  background: var(--reader-surface) !important;
  margin: 24px 0 28px !important;
  overflow: hidden !important;
}
.book-page .vp-doc div[class*='language-'] pre {
  background: var(--reader-surface-alt) !important;
  padding: 14px 0 !important;
  font-family: var(--reader-mono) !important;
  font-size: 12.5px !important;
  line-height: 1.65 !important;
}
.book-page .vp-doc div[class*='language-']::before {
  content: attr(data-language);
  position: absolute; top: 10px; right: 14px;
  font-family: var(--reader-mono);
  font-size: 10.5px !important;
  color: var(--reader-muted) !important;
  padding: 3px 8px;
  background: var(--reader-surface) !important;
  border: 1px solid var(--reader-border);
  border-radius: 4px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
/* ---- Blockquote → V3 quiet callout ---- */
/* No auto-injected icon: authors lead each quote with their own
   emoji (⚠️ 💡 📺 📝 …) which already carries semantic. A soft
   surface + thin left bar is enough separation from prose. */
.book-page .vp-doc blockquote {
  display: block;
  padding: 14px 18px !important;
  background: var(--reader-tip-bg) !important;
  border: 1px solid var(--reader-tip-border) !important;
  border-left: 3px solid var(--reader-accent) !important;
  border-radius: 0 8px 8px 0 !important;
  margin: 24px 0 !important;
  color: var(--reader-ink) !important;
  position: relative;
}
.book-page .vp-doc blockquote p {
  font-size: 15.5px !important;
  line-height: 1.75 !important;
  margin: 6px 0 !important;
  color: var(--reader-ink) !important;
}
.book-page .vp-doc blockquote p:first-child { margin-top: 0 !important; }
.book-page .vp-doc blockquote p:last-child  { margin-bottom: 0 !important; }
.book-page .vp-doc blockquote p strong {
  color: var(--reader-ink) !important;
}
/* ---- Prev/Next footer links (VPDocFooter) ---- */
.book-page .VPDocFooterLastUpdated { color: var(--reader-muted-2) !important; font-size: 12.5px !important; }
.book-page .pager-link {
  padding: 16px 18px !important;
  border: 1px solid var(--reader-border) !important;
  border-radius: 10px !important;
  background: var(--reader-surface) !important;
  transition: border-color .15s, box-shadow .15s;
}
.book-page .pager-link:hover {
  border-color: var(--reader-border-strong) !important;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.05);
}
.book-page .pager-link .desc {
  font-size: 11.5px !important;
  color: var(--reader-muted-2) !important;
  margin-bottom: 5px !important;
}
.book-page .pager-link .title {
  font-size: 14px !important;
  font-weight: 600 !important;
  color: var(--reader-ink) !important;
  letter-spacing: -0.005em;
}
/* ---- Top nav: subtle frosted glass — visible enough to separate
        navbar from content, light enough to avoid the "logo sits in
        a box" look the prior 88% mix produced. ---- */
.book-page .VPNav .VPNavBar {
  background: color-mix(in oklab, var(--reader-surface-alt) 45%, transparent) !important;
  border-bottom: 1px solid var(--reader-border) !important;
  backdrop-filter: saturate(180%) blur(14px) !important;
}
.book-page .VPNav .VPNavBar .divider { border-bottom-color: transparent !important; }
/* ---- Paywall overlay doesn't clash with new palette ---- */
.book-page .vp-doc { color: var(--reader-ink); }
/* ---- Mobile: drop sidebar V3 polish when it collapses into VP drawer ---- */
@media (max-width: 959px) {
  .book-page .VPSidebar {
    background: var(--reader-surface) !important;
  }
}
/* ============================================================
   V1 "Terminal Codex" reader — dark-only overrides.
   Light mode keeps the V3 Docs Modern block above; dark mode
   becomes IDE-flavored: near-black surfaces, lemon-green
   accent, JetBrains Mono labels, § H2 prefix, NOTE callout,
   green TOC border. Selector is html.dark.book-page so it
   outweighs both the legacy blue palette and the V3 block.
   ============================================================ */
html.dark.book-page {
  background: #0a0b0f;
}
html.dark.book-page .VPContent { background: #0a0b0f !important; }
/* ---- Sidebar: file-tree feel, green active bar ---- */
@media (min-width: 960px) {
  html.dark.book-page .VPSidebar {
    background: #0c0d13 !important;
    border-right: 1px solid #1f2430 !important;
    box-shadow: none !important;
  }
}
html.dark.book-page .VPSidebar .VPSidebarItem.level-0 > .item > .text {
  font-family: 'JetBrains Mono', ui-monospace, monospace !important;
  font-size: 10.5px !important;
  font-weight: 600 !important;
  color: #5d6478 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
}
html.dark.book-page .VPSidebar .VPSidebarItem.level-0 > .item .caret {
  color: #2a3044 !important;
}
html.dark.book-page .VPSidebar .VPSidebarItem.level-1 > .item .text {
  color: #a4a9b7 !important;
  font-size: 13px !important;
  font-weight: 400 !important;
}
html.dark.book-page .VPSidebar .VPSidebarItem.level-1 > .item:hover {
  background: #141722 !important;
  box-shadow: none !important;
}
html.dark.book-page .VPSidebar .VPSidebarItem.level-1 > .item:hover .text {
  color: #ecedf0 !important;
}
html.dark.book-page .VPSidebar .VPSidebarItem.is-active.level-1 > .item {
  background: linear-gradient(90deg, rgba(196, 248, 87, 0.08), transparent 80%) !important;
  box-shadow: none !important;
  position: relative;
}
html.dark.book-page .VPSidebar .VPSidebarItem.is-active.level-1 > .item::before {
  content: '' !important;
  display: block !important;
  position: absolute !important;
  left: 0 !important;
  top: 6px !important;
  bottom: 6px !important;
  width: 2px !important;
  background: #c4f857 !important;
  border-radius: 0 2px 2px 0 !important;
  box-shadow: 0 0 8px rgba(196, 248, 87, 0.5) !important;
}
html.dark.book-page .VPSidebar .VPSidebarItem.is-active.level-1 > .item .text {
  color: #c4f857 !important;
  font-weight: 500 !important;
}
html.dark.book-page .VPSidebar::-webkit-scrollbar-thumb {
  background: #1f2430 !important;
}
/* ---- Reading progress bar (top of viewport) ---- */
html.dark.book-page .reading-progress {
  background: linear-gradient(90deg, #c4f857, #9ad43e) !important;
  box-shadow: 0 0 6px rgba(196, 248, 87, 0.4) !important;
}
/* ---- Right outline / "On this page" ---- */
html.dark.book-page .VPDocAside .outline-title,
html.dark.book-page .VPDocAside .VPDocAsideOutline .outline-title {
  font-family: 'JetBrains Mono', ui-monospace, monospace !important;
  font-size: 10.5px !important;
  color: #5d6478 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
}
html.dark.book-page .VPDocAsideOutline .outline-link {
  color: #6b7080 !important;
  border-left-color: #1f2430 !important;
  font-size: 12.5px !important;
}
html.dark.book-page .VPDocAsideOutline .outline-link:hover {
  color: #ecedf0 !important;
}
html.dark.book-page .VPDocAsideOutline .outline-link.active {
  color: #c4f857 !important;
  border-left-color: #c4f857 !important;
  font-weight: 500 !important;
}
/* ---- Article body typography ---- */
html.dark.book-page .vp-doc h1 {
  color: #ecedf0 !important;
  font-weight: 800 !important;
  letter-spacing: -0.025em !important;
}
html.dark.book-page .vp-doc h2 {
  color: #ecedf0 !important;
  font-weight: 700 !important;
  letter-spacing: -0.015em !important;
  border-left: none !important;
  padding-left: 0 !important;
  display: flex !important;
  align-items: baseline !important;
  gap: 14px !important;
}
/* § prefix in green — V1 signature heading mark */
html.dark.book-page .vp-doc h2::before {
  content: '§' !important;
  display: inline-block !important;
  color: #c4f857 !important;
  font-family: 'JetBrains Mono', ui-monospace, monospace !important;
  font-weight: 500 !important;
  font-size: 0.85em !important;
  flex-shrink: 0 !important;
}
html.dark.book-page .vp-doc h2::after { display: none !important; }
html.dark.book-page .vp-doc h3 {
  color: #ecedf0 !important;
  font-weight: 600 !important;
  border-left: none !important;
  padding-left: 0 !important;
}
html.dark.book-page .vp-doc h3::before { display: none !important; }
html.dark.book-page .vp-doc h4 {
  color: #c8ccd4 !important;
}
html.dark.book-page .vp-doc p {
  color: #c8ccd4 !important;
  opacity: 1 !important;
  line-height: 1.78 !important;
}
html.dark.book-page .vp-doc p strong,
html.dark.book-page .vp-doc li strong {
  color: #ecedf0 !important;
  font-weight: 600 !important;
}
html.dark.book-page .vp-doc li {
  color: #c8ccd4 !important;
  opacity: 1 !important;
}
html.dark.book-page .vp-doc li::marker {
  color: #c4f857 !important;
}
html.dark.book-page .vp-doc ol > li::marker {
  color: #c4f857 !important;
  font-weight: 700 !important;
}
/* ---- Inline code: green on near-black, monospace ---- */
html.dark.book-page .vp-doc :not(pre) > code {
  background: #141722 !important;
  color: #c4f857 !important;
  border: 1px solid #1f2430 !important;
  font-family: 'JetBrains Mono', ui-monospace, monospace !important;
}
html.dark.book-page .vp-doc a :not(pre) > code,
html.dark.book-page .vp-doc :not(pre) > a > code {
  color: #c4f857 !important;
}
/* ---- Code block chrome: dark IDE feel ---- */
html.dark.book-page .vp-doc div[class*='language-'] {
  background: #0c0d13 !important;
  border: 1px solid #1f2430 !important;
  border-radius: 10px !important;
}
html.dark.book-page .vp-doc div[class*='language-'] pre {
  background: #0c0d13 !important;
  font-family: 'JetBrains Mono', ui-monospace, monospace !important;
}
html.dark.book-page .vp-doc div[class*='language-']::before {
  background: #141722 !important;
  border-color: #1f2430 !important;
  color: #5d6478 !important;
  font-family: 'JetBrains Mono', ui-monospace, monospace !important;
}
/* glass-morphism overlay from the legacy block clashes with the
   solid V1 surface — disable it in dark mode */
html.dark.book-page .vp-doc div[class*='language-']::after {
  display: none !important;
}
html.dark.book-page .vp-doc div[class*='language-'] span.lang {
  color: #5d6478 !important;
}
/* ---- Blockquote → V1 callout: green left bar + NOTE label ---- */
html.dark.book-page .vp-doc blockquote {
  background: linear-gradient(90deg, rgba(196, 248, 87, 0.05), transparent) !important;
  border: none !important;
  border-left: 2px solid #c4f857 !important;
  border-radius: 0 10px 10px 0 !important;
  padding: 16px 18px 16px 60px !important;
  color: #c8ccd4 !important;
}
/* override the V3 purple "i" / "!" circle with a NOTE mono label */
html.dark.book-page .vp-doc blockquote::before {
  content: 'NOTE' !important;
  position: absolute !important;
  top: 17px !important;
  left: 14px !important;
  width: auto !important;
  height: auto !important;
  background: none !important;
  background-image: none !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', ui-monospace, monospace !important;
  font-size: 11px !important;
  font-weight: 700 !important;
  letter-spacing: 0.06em !important;
  color: #c4f857 !important;
  display: block !important;
  opacity: 1 !important;
}
html.dark.book-page .vp-doc blockquote p {
  color: #c8ccd4 !important;
  font-size: 14.5px !important;
  line-height: 1.65 !important;
}
html.dark.book-page .vp-doc blockquote p strong {
  color: #ecedf0 !important;
}
html.dark.book-page .vp-doc blockquote :not(pre) > code {
  background: rgba(196, 248, 87, 0.08) !important;
}
/* ---- Tables: align with V1 dark surfaces ---- */
html.dark.book-page .vp-doc table {
  border-color: #1f2430 !important;
}
html.dark.book-page .vp-doc th {
  background: rgba(196, 248, 87, 0.06) !important;
  color: #ecedf0 !important;
  border-color: #1f2430 !important;
}
html.dark.book-page .vp-doc td {
  border-top-color: #1f2430 !important;
  color: #c8ccd4 !important;
}
html.dark.book-page .vp-doc td:first-child {
  color: #ecedf0 !important;
}
html.dark.book-page .vp-doc tbody tr:nth-child(even) td {
  background: rgba(196, 248, 87, 0.025) !important;
}
html.dark.book-page .vp-doc tr:hover td {
  background: #141722 !important;
}
/* ---- Links — dark mode: lemon with a faded underline ---- */
html.dark.book-page .vp-doc a {
  color: #c4f857 !important;
  text-decoration-color: rgba(196, 248, 87, 0.35) !important;
}
html.dark.book-page .vp-doc a:hover {
  text-decoration-color: rgba(196, 248, 87, 0.85) !important;
}
/* ---- Prev/Next pager footer ---- */
html.dark.book-page .pager-link {
  background: #0e1016 !important;
  border-color: #1f2430 !important;
}
html.dark.book-page .pager-link:hover {
  border-color: #c4f857 !important;
  background: rgba(196, 248, 87, 0.04) !important;
  box-shadow: none !important;
}
html.dark.book-page .pager-link .desc {
  color: #5d6478 !important;
}
html.dark.book-page .pager-link .title {
  color: #ecedf0 !important;
}
/* ---- Chapter cover label (CHAPTER N · 章节) injected client-side ---- */
html.dark.book-page .vp-doc .chapter-cover-label {
  background: linear-gradient(90deg, #c4f857, #9ad43e) !important;
  -webkit-background-clip: text !important;
  background-clip: text !important;
  color: transparent !important;
}
/* ---- Anchor highlight on hash navigation ---- */
html.dark.book-page .vp-doc h1:target,
html.dark.book-page .vp-doc h2:target,
html.dark.book-page .vp-doc h3:target,
html.dark.book-page .vp-doc h4:target {
  animation: anchor-highlight-v1 2s ease;
}
@keyframes anchor-highlight-v1 {
  0% { background: rgba(196, 248, 87, 0.12); border-radius: 4px; }
  100% { background: transparent; }
}
/* ---- Top nav: undo V3 light surface in dark; restore Terminal Codex glass ---- */
html.dark.book-page .VPNav .VPNavBar {
  background: rgba(10, 11, 15, 0.82) !important;
  border-bottom: 1px solid #1f2430 !important;
}
/* ---- Auto-linked "第 N 章" refs: green dotted, not blue ---- */
html.dark.book-page .vp-doc .chapter-ref-auto {
  text-decoration-color: rgba(196, 248, 87, 0.4) !important;
}
html.dark.book-page .vp-doc .chapter-ref-auto:hover {
  color: #c4f857 !important;
  text-decoration-color: #c4f857 !important;
}
/* ---- Sticky current-section pill: already green-aware above; ensure it stays ---- */
html.dark.book-page .sticky-section .ss-num {
  background: rgba(196, 248, 87, 0.12) !important;
  color: #c4f857 !important;
  font-family: 'JetBrains Mono', ui-monospace, monospace !important;
}
html.dark.book-page .sticky-section .ss-icon {
  color: #c4f857 !important;
}
/* ---- Mobile sidebar drawer: keep Terminal Codex bg ---- */
@media (max-width: 959px) {
  html.dark.book-page .VPSidebar {
    background: #0c0d13 !important;
  }
}
/* ---- Aliyun Captcha 2.0 popup — dark-mode tint ----------------
   The SDK injects its popup as a sibling of <body>, outside our
   Vue scope; scoped CSS can't reach it. `filter: invert hue-rotate`
   is deliberately coarse: it covers whatever inner DOM the SDK
   uses now or in a future version without hard-coding their class
   names. 0.92 (not 1.0) keeps pure black from going gray, and
   hue-rotate(180deg) restores the original hues of any colored
   elements after the inversion. */
html.dark #aliyunCaptcha-window-popup,
html.dark .sm-pop-container,
html.dark [id^="aliyunCaptcha"] {
  filter: invert(0.92) hue-rotate(180deg);
}
/* Images / icons inside the popup would get double-inverted and
   look wrong — un-invert them back. */
html.dark #aliyunCaptcha-window-popup img,
html.dark [id^="aliyunCaptcha"] img {
  filter: invert(0.92) hue-rotate(180deg);
}
@font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(/assets/KaTeX_AMS-Regular.BQhdFMY1.woff2) format("woff2"),url(/assets/KaTeX_AMS-Regular.DMm9YOAa.woff) format("woff"),url(/assets/KaTeX_AMS-Regular.DRggAlZN.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Caligraphic-Bold.Dq_IR9rO.woff2) format("woff2"),url(/assets/KaTeX_Caligraphic-Bold.BEiXGLvX.woff) format("woff"),url(/assets/KaTeX_Caligraphic-Bold.ATXxdsX0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Caligraphic-Regular.Di6jR-x-.woff2) format("woff2"),url(/assets/KaTeX_Caligraphic-Regular.CTRA-rTL.woff) format("woff"),url(/assets/KaTeX_Caligraphic-Regular.wX97UBjC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Fraktur-Bold.CL6g_b3V.woff2) format("woff2"),url(/assets/KaTeX_Fraktur-Bold.BsDP51OF.woff) format("woff"),url(/assets/KaTeX_Fraktur-Bold.BdnERNNW.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Fraktur-Regular.CTYiF6lA.woff2) format("woff2"),url(/assets/KaTeX_Fraktur-Regular.Dxdc4cR9.woff) format("woff"),url(/assets/KaTeX_Fraktur-Regular.CB_wures.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Main-Bold.Cx986IdX.woff2) format("woff2"),url(/assets/KaTeX_Main-Bold.Jm3AIy58.woff) format("woff"),url(/assets/KaTeX_Main-Bold.waoOVXN0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(/assets/KaTeX_Main-BoldItalic.DxDJ3AOS.woff2) format("woff2"),url(/assets/KaTeX_Main-BoldItalic.SpSLRI95.woff) format("woff"),url(/assets/KaTeX_Main-BoldItalic.DzxPMmG6.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(/assets/KaTeX_Main-Italic.NWA7e6Wa.woff2) format("woff2"),url(/assets/KaTeX_Main-Italic.BMLOBm91.woff) format("woff"),url(/assets/KaTeX_Main-Italic.3WenGoN9.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Main-Regular.B22Nviop.woff2) format("woff2"),url(/assets/KaTeX_Main-Regular.Dr94JaBh.woff) format("woff"),url(/assets/KaTeX_Main-Regular.ypZvNtVU.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(/assets/KaTeX_Math-BoldItalic.CZnvNsCZ.woff2) format("woff2"),url(/assets/KaTeX_Math-BoldItalic.iY-2wyZ7.woff) format("woff"),url(/assets/KaTeX_Math-BoldItalic.B3XSjfu4.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(/assets/KaTeX_Math-Italic.t53AETM-.woff2) format("woff2"),url(/assets/KaTeX_Math-Italic.DA0__PXp.woff) format("woff"),url(/assets/KaTeX_Math-Italic.flOr_0UB.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(/assets/KaTeX_SansSerif-Bold.D1sUS0GD.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Bold.DbIhKOiC.woff) format("woff"),url(/assets/KaTeX_SansSerif-Bold.CFMepnvq.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(/assets/KaTeX_SansSerif-Italic.C3H0VqGB.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Italic.DN2j7dab.woff) format("woff"),url(/assets/KaTeX_SansSerif-Italic.YYjJ1zSn.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(/assets/KaTeX_SansSerif-Regular.DDBCnlJ7.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Regular.CS6fqUqJ.woff) format("woff"),url(/assets/KaTeX_SansSerif-Regular.BNo7hRIc.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Script-Regular.D3wIWfF6.woff2) format("woff2"),url(/assets/KaTeX_Script-Regular.D5yQViql.woff) format("woff"),url(/assets/KaTeX_Script-Regular.C5JkGWo-.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size1-Regular.mCD8mA8B.woff2) format("woff2"),url(/assets/KaTeX_Size1-Regular.C195tn64.woff) format("woff"),url(/assets/KaTeX_Size1-Regular.Dbsnue_I.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size2-Regular.Dy4dx90m.woff2) format("woff2"),url(/assets/KaTeX_Size2-Regular.oD1tc_U0.woff) format("woff"),url(/assets/KaTeX_Size2-Regular.B7gKUWhC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(data:font/woff2;base64,d09GMgABAAAAAA4oAA4AAAAAHbQAAA3TAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAAgRQIDgmcDBEICo1oijYBNgIkA14LMgAEIAWJAAeBHAyBHBvbGiMRdnO0IkRRkiYDgr9KsJ1NUAf2kILNxgUmgqIgq1P89vcbIcmsQbRps3vCcXdYOKSWEPEKgZgQkprQQsxIXUgq0DqpGKmIvrgkeVGtEQD9DzAO29fM9jYhxZEsL2FeURH2JN4MIcTdO049NCVdxQ/w9NrSYFEBKTDKpLKfNkCGDc1RwjZLQcm3vqJ2UW9Xfa3tgAHz6ivp6vgC2yD4/6352ndnN0X0TL7seypkjZlMsjmZnf0Mm5Q+JykRWQBKCVCVPbARPXWyQtb5VgLB6Biq7/Uixcj2WGqdI8tGSgkuRG+t910GKP2D7AQH0DB9FMDW/obJZ8giFI3Wg8Cvevz0M+5m0rTh7XDBlvo9Y4vm13EXmfttwI4mBo1EG15fxJhUiCLbiiyCf/ZA6MFAhg3pGIZGdGIVjtPn6UcMk9A/UUr9PhoNsCENw1APAq0gpH73e+M+0ueyHbabc3vkbcdtzcf/fiy+NxQEjf9ud/ELBHAXJ0nk4z+MXH2Ev/kWyV4k7SkvpPc9Qr38F6RPWnM9cN6DJ0AdD1BhtgABtmoRoFCvPsBAumNm6soZG2Gk5GyVTo2sJncSyp0jQTYoR6WDvTwaaEcHsxHfvuWhHA3a6bN7twRKtcGok6NsCi7jYRrM2jExsUFMxMQYuJbMhuWNOumEJy9hi29Dmg5zMp/A5+hhPG19j1vBrq8JTLr8ki5VLPmG/PynJHVul440bxg5xuymHUFPBshC+nA9I1FmwbRBTNHAcik3Oae0cxKoI3MOriM42UrPe51nsaGxJ+WfXubAsP84aabUlQSJ1IiE0iPETLUU4CATgfXSCSpuRFRmCGbO+wSpAnzaeaCYW1VNEysRtuXCEL1kUFUbbtMv3Tilt/1c11jt3Q5bbMa84cpWipp8Elw3MZhOHsOlwwVUQM3lAR35JiFQbaYCRnMF2lxAWoOg2gyoIV4PouX8HytNIfLhqpJtXB4vjiViUI8IJ7bkC4ikkQvKksnOTKICwnqWSZ9YS5f0WCxmpgjbIq7EJcM4aI2nmhLNY2JIUgOjXZFWBHb+x5oh6cwb0Tv1ackHdKi0I9OO2wE9aogIOn540CCCziyhN+IaejtgAONKznHlHyutPrHGwCx9S6B8kfS4Mfi4Eyv7OU730bT1SCBjt834cXsf43zVjPUqqJjgrjeGnBxSG4aYAKFuVbeCfkDIjAqMb6yLNIbCuvXhMH2/+k2vkNpkORhR59N1CkzoOENvneIosjYmuTxlhUzaGEJQ/iWqx4dmwpmKjrwTiTGTCVozNAYqk/zXOndWxuWSmJkQpJw3pK5KX6QrLt5LATMqpmPAQhkhK6PUjzHUn7E0gHE0kPE0iKkolgkUx9SZmVAdDgpffdyJKg3k7VmzYGCwVXGz/tXmkOIp+vcWs+EMuhhvN0h9uhfzWJziBQmCREGSIFmQIkgVpAnSBRmC//6hkLZwaVhwxlrJSOdqlFtOYxlau9F2QN5Y98xmIAsiM1HVp2VFX+DHHGg6Ecjh3vmqtidX3qHI2qycTk/iwxSt5UzTmEP92ZBnEWTk4Mx8Mpl78ZDokxg/KWb+Q0QkvdKVmq3TMW+RXEgrsziSAfNXFMhDc60N5N9jQzjfO0kBKpUZl0ZmwJ41j/B9Hz6wmRaJB84niNmQrzp9eSlQCDDzazGDdVi3P36VZQ+Jy4f9UBNp+3zTjqI4abaFAm+GShVaXlsGdF3FYzZcDI6cori4kMxUECl9IjJZpzkvitAoxKue+90pDMvcKRxLl53TmOKCmV/xRolNKSqqUxc6LStOETmFOiLZZptlZepcKiAzteG8PEdpnQpbOMNcMsR4RR2Bs0cKFEvSmIjAFcnarqwUL4lDhHmnVkwu1IwshbiCcgvOheZuYyOteufZZwlcTlLgnZ3o/WcYdzZHW/WGaqaVfmTZ1aWCceJjkbZqsfbkOtcFlUZM/jy+hXHDbaUobWqqXaeWobbLO99yG5N3U4wxco0rQGGcOLASFMXeJoham8M+/x6O2WywK2l4HGbq1CoUyC/IZikQhdq3SiuNrvAEj0AVu9x2x3lp/xWzahaxidezFVtdcb5uEnzyl0ZmYiuKI0exvCd4Xc9CV1KB0db00z92wDPde0kukbvZIWN6jUWFTmPIC/Y4UPCm8UfDTFZpZNon1qLFTkBhxzB+FjQRA2Q/YRJT8pQigslMaUpFyAG8TMlXigiqmAZX4xgijKjRlGpLE0GdplRfCaJo0JQaSxNBk6ZmMzcya0FmrcisDdn0Q3HI2sWSppYigmlM1XT/kLQZSNpMJG0WkjYbSZuDpM1F0uYhFc1HxU4m1QJjDK6iL0S5uSj5rgXc3RejEigtcRBtqYPQsiTskmO5vosV+q4VGIKbOkDg0jtRrq+Em1YloaTFar3EGr1EUC8R0kus1Uus00usL97ABr2BjXoDm/QGNhuWtMVBKOwg/i78lT7hBsAvDmwHc/ao3vmUbBmhjeYySZNWvGkfZAgISDSaDo1SVpzGDsAEkF8B+gEapViUoZgUWXcRIGFZNm6gWbAKk0bp0k1MHG9fLYtV4iS2SmLEQFARzRcnf9PUS0LVn05/J9MiRRBU3v2IrvW974v4N00L7ZMk0wXP1409CHo/an8zTRHD3eSJ6m8D4YMkZNl3M79sqeuAsr/m3f+8/yl7A50aiAEJgeBeMWzu7ui9UfUBCe2TIqZIoOd/3/udRBOQidQZUERzb2/VwZN1H/Sju82ew2H2Wfr6qvfVf3hqwDvAIpkQVFy4B9Pe9e4/XvPeceu7h3dvO56iJPf0+A6cqA2ip18ER+iFgggiuOkvj24bby0N9j2UHIkgqIt+sVgfodC4YghLSMjSZbH0VR/6dMDrYJeKHilKTemt6v6kvzvn3/RrdWtr0GoN/xL+Sex/cPYLUpepx9cz/D46UPU5KXgAQa+NDps1v6J3xP1i2HtaDB0M9aX2deA7SYff//+gUCovMmIK/qfsFcOk+4Y5ZN97XlG6zebqtMbKgeRFi51vnxTQYBUik2rS/Cn6PC8ADR8FGxsRPB82dzfND90gIcshOcYUkfjherBz53odpm6TP8txlwOZ71xmfHHOvq053qFF/MRlS3jP0ELudrf2OeN8DHvp6ZceLe8qKYvWz/7yp0u4dKPfli3CYq0O13Ih71mylJ80tOi10On8wi+F4+LWgDPeJ30msSQt9/vkmHq9/Lvo2b461mP801v3W4xTcs6CbvF9UDdrSt+A8OUbpSh55qAUFXWznBBfdeJ8a4d7ugT5tvxUza3h9m4H7ptTqiG4z0g5dc0X29OcGlhpGFMpQo9ytTS+NViZpNdvU4kWx+LKxNY10kQ1yqGXrhe4/1nvP7E+nd5A92TtaRplbHSqoIdOqtRWti+fkB5/n1+/VvCmz12pG1kpQWsfi1ftlBobm0bpngs16CHkbIwdLnParxtTV3QYRlfJ0KFskH7pdN/YDn+yRuSd7sNH3aO0DYPggk6uWuXrfOc+fa3VTxFVvKaNxHsiHmsXyCLIE5yuOeN3/Jdf8HBL/5M6shjyhxHx9BjB1O0+4NLOnjLLSxwO7ukN4jMbOIcD879KLSi6Pk61Oqm2377n8079PXEEQ7cy7OKEC9nbpet118fxweTafpt69x/Bt8UqGzNQt7aelpc44dn5cqhwf71+qKp/Zf/+a0zcizOUWpl/iBcSXip0pplkatCchoH5c5aUM8I7/dWxAej8WicPL1URFZ9BDJelUwEwTkGqUhgSlydVes95YdXvhh9Gfz/aeFWvgVb4tuLbcv4+wLdutVZv/cUonwBD/6eDlE0aSiKK/uoH3+J1wDE/jMVqY2ysGufN84oIXB0sPzy8ollX/LegY74DgJXJR57sn+VGza0x3DnuIgABFM15LmajjjsNlYj+JEZGbuRYcAMOWxFkPN2w6Wd46xo4gVWQR/X4lyI/R6K/YK0110GzudPRW7Y+UOBGTfNNzHeYT0fiH0taunBpq9HEW8OKSaBGj21L0MqenEmNRWBAWDWAk4CpNoEZJ2tTaPFgbQYj8HxtFilErs3BTRwT8uO1NXQaWfIotchmPkAF5mMBAliEmZiOGVgCG9LgRzpscMAOOwowlT3JhusdazXGSC/hxR3UlmWVwWHpOIKheqONvjyhSiTHIkVUco5bnji8m//zL7PKaT1Vl5I6UE609f+gkr6MZKVyKc7zJRmCahLsdlyA5fdQkRSan9LgnnLEyGSkaKJCJog0wAgvepWBt80+1yKln1bMVtCljfNWDueKLsWwaEbBSfSPTEmVRsUcYYMnEjcjeyCZzBXK9E9BYBXLKjOSpUDR+nEV3TFSUdQaz+ot98QxgXwx0GQ+EEUAKB2qZPkQQ0GqFD8UPFMqyaCHM24BZmSGic9EYMagKizOw9Hz50DMrDLrqqLkTAhplMictiCAx5S3BIUQdeJeLnBy2CNtMfz6cV4u8XKoFZQesbf9YZiIERiHjaNodDW6LgcirX/mPnJIkBGDUpTBhSa0EIr38D5hCIszhCM8URGBqImoWjpvpt1ebu/v3Gl3qJfMnNM+9V+kiRFyROTPHQWOcs1dNW94/ukKMPZBvDi55i5CttdeJz84DLngLqjcdwEZ87bFFR8CIG35OAkDVN6VRDZ7aq67NteYqZ2lpT8oYB2CytoBd6VuAx4WgiAsnuj3WohG+LugzXiQRDeM3XYXlULv4dp5VFYC) format("woff2"),url(/assets/KaTeX_Size3-Regular.CTq5MqoE.woff) format("woff"),url(/assets/KaTeX_Size3-Regular.DgpXs0kz.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size4-Regular.Dl5lxZxV.woff2) format("woff2"),url(/assets/KaTeX_Size4-Regular.BF-4gkZK.woff) format("woff"),url(/assets/KaTeX_Size4-Regular.DWFBv043.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Typewriter-Regular.CO6r4hn1.woff2) format("woff2"),url(/assets/KaTeX_Typewriter-Regular.C0xS9mPB.woff) format("woff"),url(/assets/KaTeX_Typewriter-Regular.D3Ib7_Hf.ttf) format("truetype")}.katex{font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;position:relative;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.45"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .mathsfit,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .smash{display:inline;line-height:0}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex svg{fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo}

.msg-login[data-v-9f8b2dc2] { max-width: 480px; margin: 80px auto; text-align: center; color: var(--vp-c-text-2);
}
.msg[data-v-9f8b2dc2] {
  display: grid; grid-template-columns: 320px 1fr;
  max-width: 1100px; margin: 32px auto;
  height: calc(100vh - 140px);
  border: 1px solid var(--vp-c-divider); border-radius: 14px;
  overflow: hidden; background: var(--vp-c-bg);
}
@media (max-width: 720px) {
.msg[data-v-9f8b2dc2] { grid-template-columns: 1fr; height: calc(100vh - 80px);
}
.msg-main[data-v-9f8b2dc2] { display: none;
}
.msg:has(.msg-main-head) .msg-side[data-v-9f8b2dc2] { display: none;
}
.msg:has(.msg-main-head) .msg-main[data-v-9f8b2dc2] { display: flex;
}
}
.msg-side[data-v-9f8b2dc2] {
  display: flex; flex-direction: column;
  border-right: 1px solid var(--vp-c-divider);
  background: var(--vp-c-bg-soft);
}
.msg-side-head[data-v-9f8b2dc2] {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--vp-c-divider);
}
.msg-side-head strong[data-v-9f8b2dc2] { font-size: 14px; color: var(--vp-c-text-1);
}
.msg-support-btn[data-v-9f8b2dc2] {
  font-size: 12.5px; padding: 5px 12px; border-radius: 999px;
  background: #6b9e2c; color: #fff; border: none; cursor: pointer;
}
.msg-support-btn[data-v-9f8b2dc2]:hover:not(:disabled) { background: #568620;
}
.msg-support-btn[data-v-9f8b2dc2]:disabled { opacity: 0.5; cursor: wait;
}
.msg-threads[data-v-9f8b2dc2] { list-style: none; margin: 0; padding: 4px; overflow-y: auto; flex: 1;
}
.msg-thread[data-v-9f8b2dc2] {
  display: flex; gap: 10px; padding: 10px; border-radius: 10px; cursor: pointer;
  transition: background 0.12s;
}
.msg-thread[data-v-9f8b2dc2]:hover { background: var(--vp-c-bg);
}
.msg-thread.active[data-v-9f8b2dc2] { background: var(--vp-c-bg); box-shadow: inset 0 0 0 1px rgba(107, 158, 44, 0.4);
}
.msg-thread.support .msg-ava[data-v-9f8b2dc2] { background: linear-gradient(135deg, #0ea5e9, #6366f1);
}
.msg-ava[data-v-9f8b2dc2] {
  position: relative; width: 40px; height: 40px; border-radius: 50%;
  background: linear-gradient(135deg, #6b9e2c, #568620);
  color: #fff; font-size: 15px; font-weight: 600;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; flex-shrink: 0;
}
.msg-img[data-v-9f8b2dc2] { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.msg-meta[data-v-9f8b2dc2] { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center;
}
.msg-name[data-v-9f8b2dc2] { font-size: 13.5px; font-weight: 600; color: var(--vp-c-text-1);
}
.msg-preview[data-v-9f8b2dc2] {
  font-size: 12px; color: var(--vp-c-text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  margin-top: 2px;
}
.msg-side-right[data-v-9f8b2dc2] { display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
}
.msg-when[data-v-9f8b2dc2] { font-size: 11px; color: var(--vp-c-text-3); white-space: nowrap;
}
.msg-unread[data-v-9f8b2dc2] {
  min-width: 18px; height: 18px; padding: 0 5px;
  background: #ef4444; color: #fff; border-radius: 999px;
  font-size: 11px; line-height: 18px; text-align: center; font-weight: 600;
}
.msg-main[data-v-9f8b2dc2] { display: flex; flex-direction: column; min-width: 0;
}
.msg-main-head[data-v-9f8b2dc2] {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 18px; border-bottom: 1px solid var(--vp-c-divider);
}
.msg-main-title[data-v-9f8b2dc2] { font-size: 15px; font-weight: 600; color: var(--vp-c-text-1);
}
.msg-main-actions[data-v-9f8b2dc2] { display: inline-flex; gap: 10px;
}
.msg-inline-btn[data-v-9f8b2dc2] {
  font-size: 12px; padding: 4px 10px; border-radius: 6px;
  border: 1px solid var(--vp-c-divider); background: var(--vp-c-bg);
  color: var(--vp-c-text-2); cursor: pointer; text-decoration: none;
}
.msg-inline-btn[data-v-9f8b2dc2]:hover { border-color: var(--vp-c-text-3); color: var(--vp-c-text-1);
}
.msg-banner[data-v-9f8b2dc2] {
  padding: 10px 18px; background: rgba(239, 68, 68, 0.08); color: #ef4444;
  font-size: 12.5px; border-bottom: 1px solid rgba(239, 68, 68, 0.18);
}
.msg-list[data-v-9f8b2dc2] {
  flex: 1; overflow-y: auto; padding: 20px;
  background: var(--vp-c-bg-soft);
}
.msg-empty[data-v-9f8b2dc2] { color: var(--vp-c-text-3); font-size: 13px; padding: 20px; text-align: center;
}
.msg-empty-center[data-v-9f8b2dc2] { margin: auto;
}
.msg-bubble-row[data-v-9f8b2dc2] {
  display: flex; flex-direction: column; align-items: flex-start;
  margin-bottom: 14px;
}
.msg-bubble-row.mine[data-v-9f8b2dc2] { align-items: flex-end;
}
.msg-bubble-row.admin[data-v-9f8b2dc2] { align-items: flex-start;
}
.msg-bubble[data-v-9f8b2dc2] {
  max-width: 76%;
  padding: 10px 14px;
  border-radius: 14px;
  background: var(--vp-c-bg);
  color: var(--vp-c-text-1);
  font-size: 14px; line-height: 1.55;
  white-space: pre-wrap; word-break: break-word;
  border: 1px solid var(--vp-c-divider);
}
.msg-bubble-row.mine .msg-bubble[data-v-9f8b2dc2] {
  background: #6b9e2c; color: #fff; border-color: transparent;
}
.msg-bubble-row.admin .msg-bubble[data-v-9f8b2dc2] {
  background: linear-gradient(135deg, rgba(14, 165, 233, 0.1), rgba(99, 102, 241, 0.1));
  border-color: rgba(99, 102, 241, 0.25);
}
.msg-bubble-row.redacted .msg-bubble[data-v-9f8b2dc2] {
  background: var(--vp-c-bg-soft); color: var(--vp-c-text-3);
  font-style: italic;
}
.msg-time[data-v-9f8b2dc2] { font-size: 11px; color: var(--vp-c-text-3); margin-top: 4px; padding: 0 6px; display: inline-flex; align-items: center; gap: 8px;
}
.msg-report-btn[data-v-9f8b2dc2] {
  border: none; background: transparent; color: var(--vp-c-text-3);
  font-size: 11px; cursor: pointer; padding: 0; text-decoration: underline;
}
.msg-report-btn[data-v-9f8b2dc2]:hover { color: #ef4444;
}
.msg-compose[data-v-9f8b2dc2] {
  display: flex; gap: 8px; padding: 12px;
  border-top: 1px solid var(--vp-c-divider); background: var(--vp-c-bg);
}
.msg-compose textarea[data-v-9f8b2dc2] {
  flex: 1; resize: none; border: 1px solid var(--vp-c-divider);
  border-radius: 10px; padding: 10px 12px;
  background: var(--vp-c-bg); color: var(--vp-c-text-1);
  font-size: 14px; font-family: inherit; line-height: 1.5;
  outline: none;
}
.msg-compose textarea[data-v-9f8b2dc2]:focus { border-color: #6b9e2c;
}
.msg-send[data-v-9f8b2dc2] {
  padding: 0 20px; border-radius: 10px; border: none;
  background: #6b9e2c; color: #fff; font-size: 14px; font-weight: 600; cursor: pointer;
}
.msg-send[data-v-9f8b2dc2]:hover:not(:disabled) { background: #568620;
}
.msg-send[data-v-9f8b2dc2]:disabled { opacity: 0.5; cursor: not-allowed;
}

.badges[data-v-acb9ee65] {
  display: flex; flex-wrap: wrap; gap: 10px;
}
.badge[data-v-acb9ee65] {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  border-radius: 999px;
  background: linear-gradient(135deg, rgba(107, 158, 44, 0.12), rgba(196, 248, 87, 0.16));
  border: 1px solid rgba(107, 158, 44, 0.3);
  color: var(--vp-c-text-1);
  font-size: 13px;
  font-weight: 500;
  cursor: default;
}
.dark {
  background: linear-gradient(135deg, rgba(107, 158, 44, 0.18), rgba(196, 248, 87, 0.12));
  border-color: rgba(196, 248, 87, 0.3);
}
.emoji[data-v-acb9ee65] { font-size: 16px; line-height: 1;
}
.empty[data-v-acb9ee65] { color: var(--vp-c-text-3); font-size: 13px;
}

.heatmap[data-v-5189315d] { font-size: 12px; color: var(--vp-c-text-3);
}
.meta[data-v-5189315d] { margin-bottom: 10px; color: var(--vp-c-text-2);
}
.sep[data-v-5189315d] { margin: 0 6px; color: var(--vp-c-text-3);
}
.grid[data-v-5189315d] {
  display: flex; gap: 3px;
  overflow-x: auto; padding-bottom: 4px;
  scrollbar-width: thin;
}
.col[data-v-5189315d] { display: grid; grid-template-rows: repeat(7, 1fr); gap: 3px;
}
.cell[data-v-5189315d] {
  width: 11px; height: 11px; border-radius: 2px;
  background: var(--vp-c-bg-soft);
  border: 1px solid var(--vp-c-divider);
}
.cell.empty[data-v-5189315d] { background: transparent; border-color: transparent;
}
.cell.lvl-0[data-v-5189315d] { background: var(--vp-c-bg-soft);
}
.cell.lvl-1[data-v-5189315d] { background: rgba(107, 158, 44, 0.25); border-color: rgba(107, 158, 44, 0.35);
}
.cell.lvl-2[data-v-5189315d] { background: rgba(107, 158, 44, 0.45); border-color: rgba(107, 158, 44, 0.55);
}
.cell.lvl-3[data-v-5189315d] { background: rgba(107, 158, 44, 0.7);  border-color: rgba(107, 158, 44, 0.8);
}
.cell.lvl-4[data-v-5189315d] { background: #6b9e2c; border-color: #568620;
}
.legend[data-v-5189315d] {
  display: inline-flex; align-items: center; gap: 4px;
  margin-top: 10px;
}
.legend .cell[data-v-5189315d] { width: 11px; height: 11px;
}

.bl[data-v-6b105903] { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px;
}
.bl-card[data-v-6b105903] {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 12px;
  background: var(--vp-c-bg-soft);
  text-decoration: none; color: inherit;
  transition: border-color 0.15s, transform 0.15s;
}
.bl-card[data-v-6b105903]:hover { border-color: #6b9e2c; transform: translateY(-1px);
}
.bl-ava[data-v-6b105903] {
  position: relative; width: 40px; height: 40px; border-radius: 50%;
  background: linear-gradient(135deg, #6b9e2c, #568620);
  color: #fff; font-size: 15px; font-weight: 600;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; overflow: hidden;
}
.bl-img[data-v-6b105903] { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.bl-info[data-v-6b105903] { min-width: 0;
}
.bl-name[data-v-6b105903] { font-size: 14px; color: var(--vp-c-text-1); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bl-meta[data-v-6b105903] { font-size: 12px; color: var(--vp-c-text-3); margin-top: 2px;
}
.empty[data-v-6b105903] { color: var(--vp-c-text-3); font-size: 13px;
}

.reader-profile[data-v-3bc7b957] { max-width: 880px; margin: 40px auto; padding: 0 24px;
}
.state[data-v-3bc7b957] { padding: 80px 20px; text-align: center; color: var(--vp-c-text-2);
}
.state h2[data-v-3bc7b957] { color: var(--vp-c-text-1); margin-bottom: 8px;
}
.back-link[data-v-3bc7b957] {
  display: inline-block; margin-top: 16px; padding: 8px 18px;
  border-radius: 8px; background: #6b9e2c; color: #fff; text-decoration: none; font-size: 14px;
}
.hero[data-v-3bc7b957] {
  display: flex; gap: 20px; align-items: center;
  padding: 28px 24px; background: var(--vp-c-bg-soft); border-radius: 16px; margin-bottom: 24px;
}
.avatar[data-v-3bc7b957] {
  position: relative; width: 84px; height: 84px; border-radius: 50%; overflow: hidden;
  background: linear-gradient(135deg, #6b9e2c, #568620);
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 32px; font-weight: 700; flex-shrink: 0;
}
.avatar-img[data-v-3bc7b957] { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.meta[data-v-3bc7b957] { flex: 1; min-width: 0;
}
.name[data-v-3bc7b957] { font-size: 24px; font-weight: 700; color: var(--vp-c-text-1); margin: 0 0 6px;
}
.bio[data-v-3bc7b957] { color: var(--vp-c-text-2); font-size: 14px; line-height: 1.5; margin: 0 0 6px;
}
.joined[data-v-3bc7b957] { color: var(--vp-c-text-3); font-size: 12.5px; margin: 0;
}
.msg-btn[data-v-3bc7b957] {
  margin-top: 12px;
  padding: 6px 14px;
  border-radius: 8px; border: none;
  background: #6b9e2c; color: #fff;
  font-size: 13px; font-weight: 600; cursor: pointer;
}
.msg-btn[data-v-3bc7b957]:hover { background: #568620;
}
.private-card[data-v-3bc7b957] {
  padding: 20px 24px; background: var(--vp-c-bg-soft);
  border: 1px dashed var(--vp-c-divider); border-radius: 12px;
  color: var(--vp-c-text-2); font-size: 14px;
}
.panel[data-v-3bc7b957] { margin-bottom: 28px;
}
.panel h2[data-v-3bc7b957] {
  font-size: 16px; font-weight: 600; color: var(--vp-c-text-1);
  margin: 0 0 12px; padding-bottom: 10px; border-bottom: 1px solid var(--vp-c-divider);
}
@media (max-width: 600px) {
.hero[data-v-3bc7b957] { flex-direction: column; text-align: center; gap: 12px;
}
.meta[data-v-3bc7b957] { text-align: center;
}
}

.site-footer[data-v-c647cca0] {
  padding: 48px 24px 36px;
  border-top: 1px solid var(--home-card-border, rgba(15,23,42,0.08));
  background: var(--home-bg-alt, #f5f7fa);
  margin-top: 60px;
}
.footer-inner[data-v-c647cca0] {
  max-width: 1080px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  gap: 48px;
  align-items: start;
}
.footer-left[data-v-c647cca0] {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.footer-brand[data-v-c647cca0] {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: 14px;
  color: var(--home-text-2, #475569);
}
.footer-logo[data-v-c647cca0] { width: 24px; height: 24px; object-fit: contain;
}
.footer-copy[data-v-c647cca0] {
  font-size: 13px;
  color: var(--home-text-3, #94a3b8);
}
.footer-heading[data-v-c647cca0] {
  display: block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--home-text-3, #94a3b8);
  margin-bottom: 14px;
  text-transform: uppercase;
}
.footer-col[data-v-c647cca0] {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.footer-link[data-v-c647cca0] {
  font-size: 14px;
  color: var(--home-text-2, #475569);
  text-decoration: none;
  transition: color 0.2s;
}
.footer-link[data-v-c647cca0]:hover { color: var(--vp-c-brand-1, #3b7e00);
}
.footer-filing[data-v-c647cca0] {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}
.filing-link[data-v-c647cca0] {
  font-size: 12px;
  color: var(--home-text-3, #94a3b8);
  text-decoration: none;
  transition: color 0.2s;
}
.filing-link[data-v-c647cca0]:hover { color: var(--home-text-2, #475569);
}
.footer-qr-col[data-v-c647cca0] {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.footer-qr[data-v-c647cca0] {
  width: 90px;
  height: 90px;
  border-radius: 8px;
  border: 1px solid var(--home-card-border, rgba(15,23,42,0.08));
}
@media (max-width: 768px) {
.footer-inner[data-v-c647cca0] {
    grid-template-columns: 1fr;
    gap: 32px;
    text-align: center;
}
.footer-left[data-v-c647cca0] { align-items: center;
}
.footer-col[data-v-c647cca0] { align-items: center;
}
}

.pay-overlay[data-v-992636b0] {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.6);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}
.pay-modal[data-v-992636b0] {
  background: var(--vp-c-bg, #fff);
  border-radius: 20px;
  padding: 36px;
  width: 380px;
  max-width: 90vw;
  position: relative;
  /* Modal elevation — payment, login, cropper share tier 5. */
  box-shadow: var(--shadow-5);
  text-align: center;
}
.pay-close[data-v-992636b0] {
  position: absolute;
  top: 12px;
  right: 16px;
  background: none;
  border: none;
  font-size: 24px;
  color: var(--vp-c-text-3, #94a3b8);
  cursor: pointer;
}
.pay-body h3[data-v-992636b0] {
  font-size: 20px;
  font-weight: 700;
  color: var(--vp-c-text-1, #0f172a);
  margin: 0 0 8px;
}
.pay-amount[data-v-992636b0] {
  font-size: 32px;
  font-weight: 800;
  color: #ef4444;
  margin: 0 0 20px;
}
.qr-wrap[data-v-992636b0] {
  display: inline-block;
  padding: 12px;
  background: #fff;
  border-radius: 12px;
  border: 1px solid #f1f5f9;
  margin-bottom: 16px;
}
.qr-wrap canvas[data-v-992636b0] {
  display: block;
  border-radius: 4px;
}
.pay-hint[data-v-992636b0] {
  font-size: 14px;
  color: var(--vp-c-text-2, #64748b);
  margin: 0 0 6px;
}
.pay-order[data-v-992636b0] {
  font-size: 12px;
  color: var(--vp-c-text-3, #94a3b8);
  font-family: monospace;
  margin: 0 0 16px;
}
.pay-polling[data-v-992636b0] {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 13px;
  color: var(--vp-c-text-3, #94a3b8);
}
.polling-dot[data-v-992636b0] {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--vp-c-brand-1);
  animation: pulse-992636b0 1.5s ease infinite;
}
@keyframes pulse-992636b0 {
0%, 100% { opacity: 0.3; transform: scale(0.8);
}
50% { opacity: 1; transform: scale(1.2);
}
}
.pay-success .success-icon[data-v-992636b0] {
  margin-bottom: 16px;
}
.pay-btn[data-v-992636b0] {
  margin-top: 20px;
  padding: 10px 32px;
  background: var(--vp-c-brand-1);
  color: #fff;
  border: none;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.pay-btn[data-v-992636b0]:hover { background: var(--vp-c-brand-2);
}
.modal-enter-active[data-v-992636b0] { transition: opacity 0.25s var(--ease-out);
}
.modal-enter-active .pay-modal[data-v-992636b0] { transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.modal-leave-active[data-v-992636b0] { transition: opacity 0.15s var(--ease-in);
}
.modal-enter-from[data-v-992636b0] { opacity: 0;
}
.modal-enter-from .pay-modal[data-v-992636b0] { transform: scale(0.92);
}
.modal-leave-to[data-v-992636b0] { opacity: 0;
}

.ac-backdrop[data-v-360ec615] {
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(0, 0, 0, 0.55);
  display: flex; align-items: center; justify-content: center;
  backdrop-filter: blur(4px);
}
.ac-dialog[data-v-360ec615] {
  background: var(--vp-c-bg, #fff);
  color: var(--vp-c-text-1, #0f172a);
  border-radius: 16px;
  padding: 20px 22px 16px;
  width: min(380px, calc(100vw - 32px));
  /* Modal elevation token — keeps the cropper and login modal
     visually peered at the same depth. */
  box-shadow: var(--shadow-5);
  border: 1px solid var(--vp-c-divider, #e2e8f0);
}
.ac-title[data-v-360ec615] { font-size: 15px; font-weight: 600; margin-bottom: 12px;
}
.ac-stage[data-v-360ec615] {
  position: relative; width: 320px; height: 320px; margin: 0 auto;
  background: #0f172a;
  border-radius: 8px; overflow: hidden;
  touch-action: none;
  cursor: grab;
}
.ac-stage[data-v-360ec615]:active { cursor: grabbing;
}
.ac-stage canvas[data-v-360ec615] { display: block;
}
.ac-mask[data-v-360ec615] {
  position: absolute; inset: 0;
  pointer-events: none;
}
.ac-zoom[data-v-360ec615] {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 0 6px;
}
.ac-zoom-label[data-v-360ec615] { font-size: 12px; color: var(--vp-c-text-2, #64748b);
}
.ac-zoom input[type=range][data-v-360ec615] { flex: 1; accent-color: #6b9e2c;
}
.ac-actions[data-v-360ec615] {
  display: flex; gap: 10px; justify-content: flex-end;
  margin-top: 10px;
}
.ac-btn[data-v-360ec615] {
  height: 34px; padding: 0 16px; border-radius: 8px;
  font-size: 13px; font-weight: 600; cursor: pointer;
  border: 1px solid transparent; font-family: inherit;
  transition:
    background   0.18s cubic-bezier(0.2, 0, 0, 1),
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    color        0.18s cubic-bezier(0.2, 0, 0, 1);
}
.ac-btn-g[data-v-360ec615] {
  background: transparent;
  color: var(--vp-c-text-2, #64748b);
  border-color: var(--vp-c-divider, #e2e8f0);
}
.ac-btn-g[data-v-360ec615]:hover { background: var(--vp-c-bg-soft, #f8fafc);
}
.ac-btn-p[data-v-360ec615] {
  background: #6b9e2c;
  color: #fff;
}
.ac-btn-p[data-v-360ec615]:hover:not(:disabled) { background: #5a8426;
}
.ac-btn-p[data-v-360ec615]:disabled { opacity: 0.5; cursor: not-allowed;
}
.dark { background: #c4f857; color: #0a0b0f;
}
.dark { background: #d5ff7a;
}

.user-center[data-v-8d9d780d] { max-width: 800px; margin: 0 auto; padding: 40px 24px 0; min-height: calc(100vh - 64px);
}
.page-title[data-v-8d9d780d] { font-size: 28px; font-weight: 700; color: var(--vp-c-text-1); margin-bottom: 24px;
}
.login-prompt[data-v-8d9d780d] { text-align: center; padding: 80px 20px;
}
.login-prompt p[data-v-8d9d780d] { font-size: 16px; color: var(--vp-c-text-2); margin-bottom: 16px;
}
.tabs[data-v-8d9d780d] {
  display: flex; gap: 4px; border-bottom: 1px solid var(--vp-c-divider); margin-bottom: 24px;
  /* Allow horizontal scroll on narrow viewports instead of letting
     the row compress each tab into a vertical strip. -webkit-mask
     fades the trailing edge so the overflow hint is obvious without
     a scrollbar. */
  overflow-x: auto; flex-wrap: nowrap;
  scrollbar-width: none;
}
.tabs[data-v-8d9d780d]::-webkit-scrollbar { display: none;
}
.tab[data-v-8d9d780d] {
  padding: 10px 20px; border: none; background: none;
  font-size: 14px; font-weight: 500; color: var(--vp-c-text-2);
  cursor: pointer; border-bottom: 2px solid transparent;
  flex-shrink: 0; white-space: nowrap;
  transition:
    color              0.2s cubic-bezier(0.2, 0, 0, 1),
    border-bottom-color 0.2s cubic-bezier(0.2, 0, 0, 1);
}
@media (max-width: 600px) {
.tab[data-v-8d9d780d] { padding: 8px 12px; font-size: 13px;
}
}
.tab.active[data-v-8d9d780d] { color: #6b9e2c; border-bottom-color: #6b9e2c;
}
.tab[data-v-8d9d780d]:hover { color: var(--vp-c-text-1);
}
.profile-card[data-v-8d9d780d] {
  display: flex; gap: 24px; padding: 24px;
  background: var(--vp-c-bg-soft); border-radius: 12px;
}
.profile-avatar-wrap[data-v-8d9d780d] {
  display: flex; flex-direction: column; align-items: center; gap: 8px; flex-shrink: 0;
}
.profile-avatar[data-v-8d9d780d] {
  width: 72px; height: 72px; border-radius: 50%;
  background: linear-gradient(135deg, #6b9e2c, #568620);
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 26px; font-weight: 700; flex-shrink: 0;
  background-size: cover; background-position: center;
}
.profile-avatar.is-image[data-v-8d9d780d] {
  background-repeat: no-repeat;
  border: 1px solid var(--vp-c-divider);
}
.profile-avatar-upload[data-v-8d9d780d] {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 4px 10px;
  font-size: 12px; color: var(--vp-c-text-2);
  border: 1px solid var(--vp-c-divider); border-radius: 999px;
  background: var(--vp-c-bg);
  cursor: pointer; user-select: none;
  transition: border-color 0.15s, color 0.15s;
}
.profile-avatar-upload[data-v-8d9d780d]:hover { border-color: #6b9e2c; color: #6b9e2c;
}
.profile-avatar-upload.is-uploading[data-v-8d9d780d] { opacity: 0.7; cursor: wait;
}
.profile-avatar-upload input[type="file"][data-v-8d9d780d] { display: none;
}
.profile-info[data-v-8d9d780d] { flex: 1;
}
.profile-row[data-v-8d9d780d] { margin-bottom: 12px; font-size: 15px; color: var(--vp-c-text-1);
}
.profile-row .label[data-v-8d9d780d] { display: inline-block; width: 60px; color: var(--vp-c-text-3); font-size: 13px;
}
.edit-input[data-v-8d9d780d] {
  height: 32px; padding: 0 10px; border: 1px solid var(--vp-c-divider);
  border-radius: 6px; font-size: 14px; background: var(--vp-c-bg);
  color: var(--vp-c-text-1); outline: none;
}
.edit-input[data-v-8d9d780d]:focus { border-color: #6b9e2c;
}
.bio-input[data-v-8d9d780d] { width: 100%; max-width: 480px;
}
.privacy-row[data-v-8d9d780d] { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.privacy-badge[data-v-8d9d780d] {
  font-size: 12px; padding: 2px 10px; border-radius: 999px;
  background: var(--vp-c-bg-soft); color: var(--vp-c-text-3);
  border: 1px solid var(--vp-c-divider);
}
.privacy-badge.on[data-v-8d9d780d] { background: rgba(107, 158, 44, 0.12); color: #6b9e2c; border-color: rgba(107, 158, 44, 0.3);
}
.privacy-toggle[data-v-8d9d780d] { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--vp-c-text-2);
}
.privacy-toggle input[data-v-8d9d780d] { accent-color: #6b9e2c;
}
.profile-link[data-v-8d9d780d] { font-size: 13px; color: #6b9e2c; text-decoration: none;
}
.profile-link[data-v-8d9d780d]:hover { text-decoration: underline;
}
.profile-actions[data-v-8d9d780d] { margin-top: 16px; display: flex; gap: 8px;
}
.btn-primary[data-v-8d9d780d], .btn-primary-sm[data-v-8d9d780d] {
  padding: 8px 20px; border: none; border-radius: 8px;
  background: #6b9e2c; color: #fff; font-size: 14px; font-weight: 500; cursor: pointer;
}
.btn-primary[data-v-8d9d780d]:hover, .btn-primary-sm[data-v-8d9d780d]:hover { background: #568620;
}
.btn-outline[data-v-8d9d780d] {
  padding: 8px 20px; border: 1px solid var(--vp-c-divider); border-radius: 8px;
  background: transparent; color: var(--vp-c-text-2); font-size: 14px; cursor: pointer;
}
.btn-outline[data-v-8d9d780d]:hover { border-color: var(--vp-c-text-3);
}
.empty[data-v-8d9d780d] { text-align: center; padding: 60px 20px; color: var(--vp-c-text-3); font-size: 15px;
}

/* Subscription tab */
.sub-empty[data-v-8d9d780d] {
  text-align: center;
  padding: 56px 20px;
  /* Brand wash — olive 5% → lemon 5%. Prior wash was blue→purple
     (pre-brand) and jarred against the olive CTA sitting on top. */
  background: linear-gradient(180deg,
    rgba(107, 158, 44, 0.05),
    rgba(196, 248, 87, 0.05));
  border-radius: 16px;
  border: 1px solid rgba(107, 158, 44, 0.14);
}
.dark {
  background: linear-gradient(180deg,
    rgba(196, 248, 87, 0.05),
    rgba(107, 158, 44, 0.06));
  border-color: rgba(196, 248, 87, 0.16);
}
.sub-empty-icon[data-v-8d9d780d] { font-size: 48px; margin-bottom: 16px;
}
.sub-empty h3[data-v-8d9d780d] { font-size: 19px; font-weight: 700; margin: 0 0 8px; color: var(--vp-c-text-1);
}
.sub-empty p[data-v-8d9d780d] { font-size: 14px; color: var(--vp-c-text-2); margin: 0 0 24px;
}
.sub-empty .btn-primary[data-v-8d9d780d] {
  display: inline-flex;
  padding: 12px 28px;
  background: linear-gradient(135deg, #6b9e2c, #568620);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  border-radius: 10px;
  text-decoration: none;
  /* Button already uses olive fill; the shadow should agree with
     that. Was leaking blue 32%/40% alpha from the pre-brand era —
     so the button was olive with a blue halo, visibly mismatched. */
  box-shadow: 0 6px 20px rgba(107, 158, 44, 0.32);
  transition:
    transform  0.18s cubic-bezier(0.2, 0, 0, 1),
    box-shadow 0.22s cubic-bezier(0.2, 0, 0, 1);
}
.sub-empty .btn-primary[data-v-8d9d780d]:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 28px rgba(107, 158, 44, 0.4);
}
.sub-active-card[data-v-8d9d780d] {
  padding: 28px 32px;
  border-radius: 16px;
  background: var(--vp-c-bg);
  border: 1px solid rgba(16, 185, 129, 0.25);
  box-shadow: 0 8px 32px rgba(16, 185, 129, 0.06);
}
.sub-active-header[data-v-8d9d780d] {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 20px;
  font-size: 15px;
  color: #059669;
}
.sub-status-dot[data-v-8d9d780d] {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #10b981;
  box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.18);
  animation: pulse-8d9d780d 2s ease-in-out infinite;
}
@keyframes pulse-8d9d780d {
0%, 100% { box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.18);
}
50%      { box-shadow: 0 0 0 6px rgba(16, 185, 129, 0.3);
}
}
.sub-active-row[data-v-8d9d780d] {
  display: flex;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid var(--vp-c-divider);
  font-size: 14px;
}
.sub-active-row[data-v-8d9d780d]:last-of-type { border-bottom: none;
}
.sub-active-row .label[data-v-8d9d780d] { color: var(--vp-c-text-3);
}
.sub-active-row .value[data-v-8d9d780d] { color: var(--vp-c-text-1); font-weight: 500;
}
.sub-active-row .sub-hint[data-v-8d9d780d] { color: var(--vp-c-text-3); font-weight: 400; font-size: 12px; margin-left: 6px;
}
.sub-active-actions[data-v-8d9d780d] {
  display: flex;
  gap: 12px;
  margin-top: 20px;
  flex-wrap: wrap;
}
.sub-active-actions .btn-outline[data-v-8d9d780d] {
  flex: 1;
  min-width: 140px;
  padding: 11px 20px;
  text-align: center;
  border: 1px solid var(--vp-c-divider);
  border-radius: 10px;
  background: transparent;
  color: var(--vp-c-text-1);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  transition:
    border-color 0.18s cubic-bezier(0.2, 0, 0, 1),
    color        0.18s cubic-bezier(0.2, 0, 0, 1);
}
.sub-active-actions .btn-outline[data-v-8d9d780d]:hover {
  border-color: var(--vp-c-brand-1);
  color: var(--vp-c-brand-1);
}
.course-grid[data-v-8d9d780d] { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px;
}
.course-card[data-v-8d9d780d] {
  border: 1px solid var(--vp-c-divider); border-radius: 12px; overflow: hidden;
  text-decoration: none;
  transition:
    transform  0.22s cubic-bezier(0.2, 0, 0, 1),
    box-shadow 0.22s cubic-bezier(0.2, 0, 0, 1);
}
.course-card[data-v-8d9d780d]:hover { box-shadow: 0 4px 16px rgba(0,0,0,0.08); transform: translateY(-2px);
}
.course-cover[data-v-8d9d780d] { width: 100%; height: 140px; object-fit: cover;
}
.course-cover.placeholder[data-v-8d9d780d] { display: flex; align-items: center; justify-content: center; background: var(--vp-c-bg-soft); color: var(--vp-c-text-3); font-size: 14px;
}
.course-meta[data-v-8d9d780d] { padding: 12px;
}
.course-meta h4[data-v-8d9d780d] { font-size: 15px; font-weight: 600; color: var(--vp-c-text-1); margin: 0 0 4px;
}
.enrolled-date[data-v-8d9d780d] { font-size: 12px; color: var(--vp-c-text-3);
}
.order-list[data-v-8d9d780d] { display: flex; flex-direction: column; gap: 12px;
}
.order-card[data-v-8d9d780d] {
  padding: 16px; border: 1px solid var(--vp-c-divider); border-radius: 10px;
  cursor: pointer;
  transition:
    border-color 0.15s cubic-bezier(0.2, 0, 0, 1),
    background   0.15s cubic-bezier(0.2, 0, 0, 1);
}
.order-card[data-v-8d9d780d]:hover { border-color: var(--vp-c-brand-soft, rgba(107,158,44,0.2));
}
.order-card.expanded[data-v-8d9d780d] { border-color: #6b9e2c;
}
.order-course[data-v-8d9d780d] { margin-bottom: 8px;
}
.order-course-info[data-v-8d9d780d] { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;
}
.order-course-title[data-v-8d9d780d] { font-size: 15px; font-weight: 600; color: var(--vp-c-text-1);
}
.order-no[data-v-8d9d780d] { font-size: 12px; color: var(--vp-c-text-3); font-family: monospace;
}
.order-status[data-v-8d9d780d] { font-size: 12px; padding: 2px 8px; border-radius: 4px; font-weight: 500;
}
.order-status.paid[data-v-8d9d780d] { background: rgba(34,197,94,0.1); color: #16a34a;
}
.order-status.pending[data-v-8d9d780d] { background: rgba(234,179,8,0.1); color: #ca8a04;
}
.order-status.refunded[data-v-8d9d780d] { background: rgba(148,163,184,0.1); color: #64748b;
}
.order-body[data-v-8d9d780d] { display: flex; align-items: center; gap: 12px; font-size: 15px; color: var(--vp-c-text-1);
}
.order-amount[data-v-8d9d780d] { font-weight: 600;
}
.order-date[data-v-8d9d780d] { font-size: 13px; color: var(--vp-c-text-3);
}
.order-expand-hint[data-v-8d9d780d] { margin-left: auto; font-size: 12px; color: var(--vp-c-text-3);
}
.order-detail[data-v-8d9d780d] {
  margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--vp-c-divider);
}
.detail-row[data-v-8d9d780d] {
  display: flex; justify-content: space-between;
  font-size: 13px; color: var(--vp-c-text-2); padding: 4px 0;
}
.detail-label[data-v-8d9d780d] { color: var(--vp-c-text-3);
}
.btn-pay[data-v-8d9d780d] {
  margin-top: 12px; width: 100%;
  padding: 10px; background: #6b9e2c; color: #fff;
  border: none; border-radius: 8px; font-size: 14px;
  font-weight: 600; cursor: pointer; transition: background 0.2s;
}
.btn-pay[data-v-8d9d780d]:hover { background: #568620;
}
.like-list[data-v-8d9d780d], .favorite-list[data-v-8d9d780d] { display: flex; flex-direction: column; gap: 8px;
}
.like-item[data-v-8d9d780d], .favorite-item[data-v-8d9d780d] {
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 16px; border: 1px solid var(--vp-c-divider); border-radius: 8px;
  text-decoration: none; color: var(--vp-c-text-1);
  transition:
    border-color 0.15s cubic-bezier(0.2, 0, 0, 1),
    background   0.15s cubic-bezier(0.2, 0, 0, 1);
}
.like-item[data-v-8d9d780d]:hover, .favorite-item[data-v-8d9d780d]:hover { border-color: #6b9e2c; background: rgba(107,158,44,0.04);
}
.like-path[data-v-8d9d780d], .favorite-title[data-v-8d9d780d] { font-size: 14px; font-weight: 500;
}
.like-date[data-v-8d9d780d], .favorite-date[data-v-8d9d780d] { font-size: 12px; color: var(--vp-c-text-3);
}

/* ===== Browsing history ===== */
.history-summary[data-v-8d9d780d] {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 4px 14px; font-size: 13px; color: var(--vp-c-text-2);
}
.history-summary strong[data-v-8d9d780d] { color: var(--vp-c-text-1); font-weight: 700;
}
.btn-outline-sm[data-v-8d9d780d] {
  font-size: 12.5px; padding: 5px 12px;
  background: transparent; color: var(--vp-c-text-2);
  border: 1px solid var(--vp-c-divider); border-radius: 6px;
  cursor: pointer; transition: all 0.15s;
}
.btn-outline-sm[data-v-8d9d780d]:hover:not(:disabled) {
  border-color: #6b9e2c; color: #6b9e2c;
}
.btn-outline-sm[data-v-8d9d780d]:disabled { opacity: 0.6; cursor: wait;
}
.history-list[data-v-8d9d780d] { display: flex; flex-direction: column; gap: 6px;
}
.history-item[data-v-8d9d780d] {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px;
  border: 1px solid var(--vp-c-divider); border-radius: 8px;
  text-decoration: none; color: inherit;
  transition:
    border-color 0.15s cubic-bezier(0.2, 0, 0, 1),
    background   0.15s cubic-bezier(0.2, 0, 0, 1);
}
.history-item[data-v-8d9d780d]:hover {
  border-color: #6b9e2c;
  background: rgba(107, 158, 44, 0.04);
}
.hi-main[data-v-8d9d780d] { flex: 1; min-width: 0;
}
.hi-title[data-v-8d9d780d] {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 14px; font-weight: 500; color: var(--vp-c-text-1);
  margin-bottom: 4px;
}
.hi-book-tag[data-v-8d9d780d] {
  font-size: 11px; padding: 2px 8px;
  background: rgba(107, 158, 44, 0.1); color: #6b9e2c;
  border-radius: 4px; flex-shrink: 0;
}
.hi-chapter[data-v-8d9d780d] {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0; flex: 1;
}
.hi-read-mark[data-v-8d9d780d] {
  font-size: 12px; color: #10b981; font-weight: 700;
  flex-shrink: 0;
}
.hi-meta[data-v-8d9d780d] {
  font-size: 12px; color: var(--vp-c-text-3);
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.hi-dot[data-v-8d9d780d] { color: var(--vp-c-text-3); opacity: 0.5;
}
.hi-arrow[data-v-8d9d780d] {
  font-size: 18px; color: var(--vp-c-text-3); flex-shrink: 0;
  font-weight: 300;
}

/* ===== Learning stats tab ===== */
.ls-wrap[data-v-8d9d780d] { display: flex; flex-direction: column; gap: 18px;
}
.ls-overview[data-v-8d9d780d] {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
@media (min-width: 640px) {
.ls-overview[data-v-8d9d780d] { grid-template-columns: repeat(6, 1fr);
}
}
.ls-stat[data-v-8d9d780d] {
  padding: 16px 12px;
  background: var(--vp-c-bg-soft); border-radius: 10px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  text-align: center;
}
.ls-stat-num[data-v-8d9d780d] {
  font-size: 22px; font-weight: 700; color: var(--vp-c-text-1);
  font-variant-numeric: tabular-nums;
}
.ls-stat-label[data-v-8d9d780d] {
  font-size: 12px; color: var(--vp-c-text-3);
}
.ls-side[data-v-8d9d780d] {
  display: flex; gap: 10px; flex-wrap: wrap;
}
.ls-side-item[data-v-8d9d780d] {
  flex: 1; min-width: 180px;
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 14px;
  background: var(--vp-c-bg-soft); border-radius: 10px;
  font-size: 13px;
}
.ls-side-key[data-v-8d9d780d] { color: var(--vp-c-text-3);
}
.ls-side-val[data-v-8d9d780d] { font-weight: 600; color: var(--vp-c-text-1);
}
.ls-top-card[data-v-8d9d780d] {
  display: block; text-decoration: none;
  padding: 22px 24px;
  border-radius: 14px; color: #fff;
  transition: transform 0.2s cubic-bezier(0.2, 0, 0, 1);
}
.ls-top-card[data-v-8d9d780d]:hover { transform: translateY(-2px); text-decoration: none; color: #fff;
}
.ls-top-label[data-v-8d9d780d] { font-size: 12px; opacity: 0.85; letter-spacing: 0.08em;
}
.ls-top-title[data-v-8d9d780d] { font-size: 20px; font-weight: 700; margin: 6px 0 8px;
}
.ls-top-meta[data-v-8d9d780d] { font-size: 13px; opacity: 0.92;
}
.ls-section-title[data-v-8d9d780d] {
  font-size: 14px; font-weight: 600; color: var(--vp-c-text-2);
  margin: 6px 0 -4px;
}
.ls-book-list[data-v-8d9d780d] { display: flex; flex-direction: column; gap: 10px;
}
.ls-book-card[data-v-8d9d780d] {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 14px;
  background: var(--vp-c-bg-soft); border-radius: 10px;
  text-decoration: none; color: inherit;
  transition: transform 0.15s cubic-bezier(0.2, 0, 0, 1);
}
.ls-book-card[data-v-8d9d780d]:hover { transform: translateY(-1px); text-decoration: none; color: inherit;
}
.ls-book-cover[data-v-8d9d780d] {
  width: 48px; height: 48px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 14px;
  flex-shrink: 0;
}
.ls-book-main[data-v-8d9d780d] { flex: 1; min-width: 0;
}
.ls-book-title[data-v-8d9d780d] {
  font-size: 14px; font-weight: 600; color: var(--vp-c-text-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ls-book-progress-bar[data-v-8d9d780d] {
  height: 4px; background: var(--vp-c-divider); border-radius: 999px;
  margin: 6px 0 4px; overflow: hidden;
}
.ls-book-progress-fill[data-v-8d9d780d] {
  height: 100%; background: linear-gradient(90deg, #6b9e2c, #8bc34a);
  border-radius: 999px;
  transition: width 0.35s cubic-bezier(0.2, 0, 0, 1);
}
.ls-book-meta[data-v-8d9d780d] {
  font-size: 12px; color: var(--vp-c-text-3);
  display: flex; flex-wrap: wrap; gap: 4px;
}
.ls-book-last[data-v-8d9d780d] { margin-left: auto;
}

.VPLocalSearchBox[data-v-ce626c7c] {
  position: fixed;
  z-index: 100;
  inset: 0;
  display: flex;
}
.backdrop[data-v-ce626c7c] {
  position: absolute;
  inset: 0;
  background: var(--vp-backdrop-bg-color);
  transition: opacity 0.5s;
}
.shell[data-v-ce626c7c] {
  position: relative;
  padding: 12px;
  margin: 64px auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  background: var(--vp-local-search-bg);
  width: min(100vw - 60px, 900px);
  height: min-content;
  max-height: min(100vh - 128px, 900px);
  border-radius: 6px;
}
@media (max-width: 767px) {
.shell[data-v-ce626c7c] {
    margin: 0;
    width: 100vw;
    height: 100vh;
    max-height: none;
    border-radius: 0;
}
}
.search-bar[data-v-ce626c7c] {
  border: 1px solid var(--vp-c-divider);
  border-radius: 4px;
  display: flex;
  align-items: center;
  padding: 0 12px;
  cursor: text;
}
@media (max-width: 767px) {
.search-bar[data-v-ce626c7c] {
    padding: 0 8px;
}
}
.search-bar[data-v-ce626c7c]:focus-within {
  border-color: var(--vp-c-brand-1);
}
.local-search-icon[data-v-ce626c7c] {
  display: block;
  font-size: 18px;
}
.navigate-icon[data-v-ce626c7c] {
  display: block;
  font-size: 14px;
}
.search-icon[data-v-ce626c7c] {
  margin: 8px;
}
@media (max-width: 767px) {
.search-icon[data-v-ce626c7c] {
    display: none;
}
}
.search-input[data-v-ce626c7c] {
  padding: 6px 12px;
  font-size: inherit;
  width: 100%;
}
@media (max-width: 767px) {
.search-input[data-v-ce626c7c] {
    padding: 6px 4px;
}
}
.search-actions[data-v-ce626c7c] {
  display: flex;
  gap: 4px;
}
@media (any-pointer: coarse) {
.search-actions[data-v-ce626c7c] {
    gap: 8px;
}
}
@media (min-width: 769px) {
.search-actions.before[data-v-ce626c7c] {
    display: none;
}
}
.search-actions button[data-v-ce626c7c] {
  padding: 8px;
}
.search-actions button[data-v-ce626c7c]:not([disabled]):hover,
.toggle-layout-button.detailed-list[data-v-ce626c7c] {
  color: var(--vp-c-brand-1);
}
.search-actions button.clear-button[data-v-ce626c7c]:disabled {
  opacity: 0.37;
}
.search-keyboard-shortcuts[data-v-ce626c7c] {
  font-size: 0.8rem;
  opacity: 75%;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  line-height: 14px;
}
.search-keyboard-shortcuts span[data-v-ce626c7c] {
  display: flex;
  align-items: center;
  gap: 4px;
}
@media (max-width: 767px) {
.search-keyboard-shortcuts[data-v-ce626c7c] {
    display: none;
}
}
.search-keyboard-shortcuts kbd[data-v-ce626c7c] {
  background: rgba(128, 128, 128, 0.1);
  border-radius: 4px;
  padding: 3px 6px;
  min-width: 24px;
  display: inline-block;
  text-align: center;
  vertical-align: middle;
  border: 1px solid rgba(128, 128, 128, 0.15);
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1);
}
.results[data-v-ce626c7c] {
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.result[data-v-ce626c7c] {
  display: flex;
  align-items: center;
  gap: 8px;
  border-radius: 4px;
  transition: none;
  line-height: 1rem;
  border: solid 2px var(--vp-local-search-result-border);
  outline: none;
}
.result > div[data-v-ce626c7c] {
  margin: 12px;
  width: 100%;
  overflow: hidden;
}
@media (max-width: 767px) {
.result > div[data-v-ce626c7c] {
    margin: 8px;
}
}
.titles[data-v-ce626c7c] {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  position: relative;
  z-index: 1001;
  padding: 2px 0;
}
.title[data-v-ce626c7c] {
  display: flex;
  align-items: center;
  gap: 4px;
}
.title.main[data-v-ce626c7c] {
  font-weight: 500;
}
.title-icon[data-v-ce626c7c] {
  opacity: 0.5;
  font-weight: 500;
  color: var(--vp-c-brand-1);
}
.title svg[data-v-ce626c7c] {
  opacity: 0.5;
}
.result.selected[data-v-ce626c7c] {
  --vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);
  border-color: var(--vp-local-search-result-selected-border);
}
.excerpt-wrapper[data-v-ce626c7c] {
  position: relative;
}
.excerpt[data-v-ce626c7c] {
  opacity: 50%;
  pointer-events: none;
  max-height: 140px;
  overflow: hidden;
  position: relative;
  margin-top: 4px;
}
.result.selected .excerpt[data-v-ce626c7c] {
  opacity: 1;
}
.excerpt[data-v-ce626c7c] * {
  font-size: 0.8rem !important;
  line-height: 130% !important;
}
.titles[data-v-ce626c7c] mark,
.excerpt[data-v-ce626c7c] mark {
  background-color: var(--vp-local-search-highlight-bg);
  color: var(--vp-local-search-highlight-text);
  border-radius: 2px;
  padding: 0 2px;
}
.excerpt[data-v-ce626c7c] .vp-code-group .tabs {
  display: none;
}
.excerpt[data-v-ce626c7c] .vp-code-group div[class*='language-'] {
  border-radius: 8px !important;
}
.excerpt-gradient-bottom[data-v-ce626c7c] {
  position: absolute;
  bottom: -1px;
  left: 0;
  width: 100%;
  height: 8px;
  background: linear-gradient(transparent, var(--vp-local-search-result-bg));
  z-index: 1000;
}
.excerpt-gradient-top[data-v-ce626c7c] {
  position: absolute;
  top: -1px;
  left: 0;
  width: 100%;
  height: 8px;
  background: linear-gradient(var(--vp-local-search-result-bg), transparent);
  z-index: 1000;
}
.result.selected .titles[data-v-ce626c7c],
.result.selected .title-icon[data-v-ce626c7c] {
  color: var(--vp-c-brand-1) !important;
}
.no-results[data-v-ce626c7c] {
  font-size: 0.9rem;
  text-align: center;
  padding: 12px;
}
svg[data-v-ce626c7c] {
  flex: none;
}
